Skip to content

Instantly share code, notes, and snippets.

@LordJZ
Created June 29, 2011 23:48
Show Gist options
  • Save LordJZ/1055297 to your computer and use it in GitHub Desktop.
Save LordJZ/1055297 to your computer and use it in GitHub Desktop.
PackedData
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