protected virtual object ComplexTypeDecoder(IEnumerable <byte> bytes) { Type currentType = CurrentDecodedType; object uninitialized = FormatterServices.GetUninitializedObject(currentType); BinaryCodeReader reader = new BinaryCodeReader(bytes); uint length; string fieldName; object value; while (!reader.EndOfSource()) { while (reader.ReadNextBit() == 1) { currentType = currentType.BaseType; if (currentType == null) { // TODO: throw valid exception } } length = DecodeLength(reader); fieldName = DecodeFieldName(reader.ReadNextBytes(length)); var prop = currentType.GetField( fieldName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public ); value = Decode(reader); prop.SetValue(uninitialized, value); } return(uninitialized); }
public void TestReadBytes() { var bytes = new byte[] { 113, 25, 45, 79, 13, 51 }; var reader = new BinaryCodeReader(bytes); for (int i = 0; i < bytes.Length; i++) { Assert.AreEqual(bytes[i], reader.ReadNextByte()); } }
protected uint DecodeLength(BinaryCodeReader reader) { int lengthSizeInBytes = (reader.ReadNextBit() + 1) + reader.ReadNextBit() * 2; var lengthBytes = new byte[4] { 0, 0, 0, 0 }; for (int i = 0; i < lengthSizeInBytes; i++) { lengthBytes[i] = reader.ReadNextByte(); } return(BitConverter.ToUInt32(lengthBytes, 0)); }
public void TestReadAfterMove() { var bytes = new byte[] { 117, 243, 11, 3, 57 }; var reader = new BinaryCodeReader(bytes); reader.MoveBytePointer(1); Assert.AreEqual(bytes[1], reader.ReadNextByte()); reader.MoveBytePointer(-1); reader.MoveBitPointer(3); Assert.AreEqual(126, reader.ReadNextByte()); reader.MoveBitPointer(5); Assert.AreEqual(3, reader.ReadNextByte()); reader.MoveBytePointer(-4); Assert.AreEqual(117, reader.ReadNextByte()); }
public void TestReadBits() { var bytes = new byte[] { 113, 11, 51 }; var bits = new byte[] { 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0 }; var reader = new BinaryCodeReader(bytes); for (int i = 0; i < bits.Length; i++) { Assert.AreEqual(bits[i], reader.ReadNextBit()); } }
public virtual object Decode(BinaryCodeReader bytes, ConverterCategory converterCategory = ConverterCategory.ANY) { byte tmpByte = bytes.ReadNextBit(); CurrentDecodedType = null; if (tmpByte == 0) { tmpByte = bytes.ReadNextBit(); if (tmpByte == 0) { // Null return(null); } else { // Exclusive uint typeLength = DecodeLength(bytes); Type decodedType = DecodeType(bytes.ReadNextBytes(typeLength)); CurrentDecodedType = decodedType; object uninitialized = FormatterServices.GetUninitializedObject(decodedType); var decoder = GetSpecificDecoder( uninitialized, converterCategory, new ConverterCategory[] { ConverterCategory.PRIMITIVE, ConverterCategory.SERIALIZABLE // The only inclusive types when it comes to BinaryConverter } ); if (decoder != null) { uint length = DecodeLength(bytes); object result = decoder.Decoder.Invoke(bytes.ReadNextBytes(length)); CurrentDecodedType = null; return(result); } else { CurrentDecodedType = null; throw new ArgumentException("Could not find proper decoder for that set of bytes within provided range. Type encoded as exclusive, of type " + decodedType.FullName); } } } else { tmpByte = bytes.ReadNextBit(); if (tmpByte == 0) { // Inclusive serializable if (converterCategory != ConverterCategory.ANY && converterCategory != ConverterCategory.SERIALIZABLE) { throw new ArgumentException("Object is encoded as inclusive serializable, requested converter category not allowing for that kind of conversion"); } uint length = DecodeLength(bytes); return(SerializableTypeDecoder(bytes.ReadNextBytes(length))); } else { // Inclusive serializable if (converterCategory != ConverterCategory.ANY && converterCategory != ConverterCategory.PRIMITIVE) { throw new ArgumentException("Object is encoded as inclusive primitive, requested converter category not allowing for that kind of conversion"); } uint length = DecodeLength(bytes); return(PrimitiveTypeDecoder(bytes.ReadNextBytes(length))); } } }