Created
June 29, 2011 23:48
-
-
Save LordJZ/1055297 to your computer and use it in GitHub Desktop.
PackedData
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections; | |
using System.IO; | |
using System.Text; | |
namespace Kamilla.WorldOfWarcraft.Latest.OpcodeDatas | |
{ | |
public abstract class PackedData : OpcodeData | |
{ | |
protected abstract int[] MaskSequence { get; } | |
protected abstract int[] ByteSequence { get; } | |
protected abstract int ByteXorValue { get; } | |
public sealed override void Read(StreamHandler reader) | |
{ | |
var seq_b = ByteSequence; | |
var seq_m = MaskSequence; | |
var b_xor = ByteXorValue; | |
int size = seq_b.Length; | |
if (size != seq_m.Length) | |
throw new InvalidOperationException("Length of Mask Sequence must be equal to length of Byte Sequence."); | |
if (size / 8 * 8 != size) | |
throw new InvalidOperationException("Size of PackedData in bytes must be a multiple of 8."); | |
byte[] data = new byte[size]; | |
BitArray src = new BitArray(reader.ReadBytes(size / 8)); | |
BitArray dst = new BitArray(size); | |
for (int i = 0; i < size; ++i) | |
dst[seq_m[i]] = src[i]; | |
for (int i = 0; i < size; ++i) | |
{ | |
if (dst[seq_b[i]]) | |
data[seq_b[i]] = (byte)(reader.ReadByte() ^ b_xor); | |
} | |
ActualRead(data); | |
} | |
protected virtual void ActualRead(StreamHandler reader) | |
{ | |
throw new NotImplementedException("Reading " + this.GetType().Name + " is not implemented."); | |
} | |
protected virtual void ActualRead(byte[] data) | |
{ | |
using (var reader = new StreamHandler(data)) | |
ActualRead(reader); | |
} | |
public sealed override void Save(StreamHandler writer) | |
{ | |
var seq_b = ByteSequence; | |
var seq_m = MaskSequence; | |
var b_xor = ByteXorValue; | |
int size = seq_b.Length; | |
if (size != seq_m.Length) | |
throw new InvalidOperationException("Length of Mask Sequence must be equal to length of Byte Sequence."); | |
if (size / 8 * 8 != size) | |
throw new InvalidOperationException("Size of PackedData in bytes must be a multiple of 8."); | |
byte[] data = new byte[size]; | |
ActualSave(data); | |
BitArray mask = new BitArray(size); | |
for (int i = 0; i < size; ++i) | |
{ | |
if (data[seq_m[i]] != 0) | |
mask[i] = true; | |
} | |
for (int i = 0; i < size; ) | |
{ | |
byte b = 0; | |
for (int j = 0; j < 8; ++j, ++i) | |
{ | |
if (mask[i]) | |
b |= (byte)(1 << i); | |
} | |
writer.WriteByte(b); | |
} | |
for (int i = 0; i < size; ++i) | |
{ | |
if (data[seq_b[i]] != 0) | |
writer.WriteByte((byte)(data[seq_b[i]] ^ b_xor)); | |
} | |
} | |
protected virtual void ActualSave(StreamHandler writer) | |
{ | |
throw new NotImplementedException("Saving " + this.GetType().Name + " is not implemented."); | |
} | |
protected virtual void ActualSave(byte[] data) | |
{ | |
using (var writer = new StreamHandler(data)) | |
ActualSave(writer); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment