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 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))); } } }