/// <summary> /// Finds the appriopriate encoder within specified category /// </summary> /// <param name="o">Object to find the encoder for</param> /// <param name="category">Category of encoders to consider</param> /// <returns>An encoder method appropriate for that object or null if not found</returns> protected virtual BinaryEncoderData GetSpecificEncoder(object o, ConverterCategory category) { BinaryEncoderMethod encoder; Func <object, IEnumerable <byte> > encoderMethod; switch (category) { case ConverterCategory.ANY: return(GetEncoder(o)); case ConverterCategory.CUSTOM: encoder = GetCustomEncoder(o.GetType()); return((encoder == null) ? null : new BinaryEncoderData(encoder.Encoder)); case ConverterCategory.CUSTOM_PREDEFINED: encoder = GetPredefinedCustomEncoder(o.GetType()); return((encoder == null) ? null : new BinaryEncoderData(encoder.Encoder)); case ConverterCategory.CUSTOM_FOR_CLASS: encoderMethod = GetCustomClassEncoder(o); return((encoderMethod == null) ? null : new BinaryEncoderData(encoderMethod)); case ConverterCategory.GLOBAL_FOR_CLASS: encoderMethod = GetGlobalClassEncoder(o.GetType()); return((encoderMethod == null) ? null : new BinaryEncoderData(encoderMethod)); case ConverterCategory.DEFAULT: encoder = GetDefaultEncoder(o.GetType()); return((encoder == null) ? null : new BinaryEncoderData(encoder.Encoder)); case ConverterCategory.DEFAULT_PREDEFINED: encoder = GetPredefinedDefaultEncoder(o.GetType()); return((encoder == null) ? null : new BinaryEncoderData(encoder.Encoder)); case ConverterCategory.PRIMITIVE: if (o.GetType().IsSerializable) { return(new BinaryEncoderData(PrimitiveTypeEncoder)); } return(null); case ConverterCategory.SERIALIZABLE: if (o.GetType().IsSerializable) { return(new BinaryEncoderData(SerializableTypeEncoder)); } return(null); case ConverterCategory.COMPLEX: if (!o.GetType().IsPrimitive) { return(new BinaryEncoderData(ComplexTypeEncoder)); } return(null); default: throw new NotImplementedException("Provided category was not implemented"); } }
public virtual BinaryCodeBuilder Encode(object o, ConverterCategory converterCategory = ConverterCategory.ANY, BinaryCodeBuilder builder = null) { if (builder == null) { builder = new BinaryCodeBuilder(); } BinaryEncoderData encoderData = GetSpecificEncoder(o, converterCategory); IEnumerable <byte> encodedObject = null; if (encoderData.ConverterType == ConverterType.NULL) { builder.AppendBit(0); builder.AppendBit(0); return(builder); } else if (encoderData.ConverterType == ConverterType.EXCLUSIVE) { encodedObject = encoderData.Encoder.Invoke(o); builder.AppendBit(0); builder.AppendBit(1); byte[] typeBytes = EncodeType(o.GetType()); builder.Append(EncodeLength((uint)typeBytes.Length)); builder.AppendBytes(typeBytes); } else { encodedObject = encoderData.Encoder.Invoke(o); builder.AppendBit(1); if (encoderData.ConverterType == ConverterType.INCLUSIVE_SERIALIZABLE) { // Inclusive serializable, no need to encode type builder.AppendBit(0); } else { // Inclusive primitive, no need to encode type builder.AppendBit(1); } } uint length = (uint)encodedObject.Count(); builder.Append(EncodeLength(length)); builder.AppendBytes(encodedObject); return(builder); }
public virtual object Decode(byte[] bytes, ConverterCategory converterCategory = ConverterCategory.ANY) { return(Decode(new BinaryCodeReader(bytes), converterCategory)); }
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))); } } }
/// <summary> /// Finds the appriopriate decoder within specified category /// </summary> /// <param name="o">Object to find the decoder for</param> /// <param name="category">Category of decoders to consider</param> /// <returns>An encoder method appropriate for that object or null if not found</returns> protected virtual BinaryDecoderData GetSpecificDecoder(object o, ConverterCategory category, ConverterCategory[] disallowed = null) { BinaryDecoderMethod decoder; Func <IEnumerable <byte>, object> decoderMethod; if (disallowed == null) { disallowed = new ConverterCategory[] { } } ; switch (category) { case ConverterCategory.ANY: return(GetDecoder(o)); case ConverterCategory.CUSTOM: decoder = GetCustomDecoder(o.GetType()); return((decoder == null && !disallowed.Contains(ConverterCategory.CUSTOM)) ? null : new BinaryDecoderData(decoder.Decoder)); case ConverterCategory.CUSTOM_PREDEFINED: decoder = GetPredefinedCustomDecoder(o.GetType()); return((decoder == null && !disallowed.Contains(ConverterCategory.CUSTOM_PREDEFINED)) ? null : new BinaryDecoderData(decoder.Decoder)); case ConverterCategory.CUSTOM_FOR_CLASS: decoderMethod = GetCustomClassEncoder(o); return((decoderMethod == null && !disallowed.Contains(ConverterCategory.CUSTOM_FOR_CLASS)) ? null : new BinaryDecoderData(decoderMethod)); case ConverterCategory.GLOBAL_FOR_CLASS: decoderMethod = GetGlobalClassDecoder(o.GetType()); return((decoderMethod == null && !disallowed.Contains(ConverterCategory.GLOBAL_FOR_CLASS)) ? null : new BinaryDecoderData(decoderMethod)); case ConverterCategory.DEFAULT: decoder = GetDefaultDecoder(o.GetType()); return((decoder == null && !disallowed.Contains(ConverterCategory.DEFAULT)) ? null : new BinaryDecoderData(decoder.Decoder)); case ConverterCategory.DEFAULT_PREDEFINED: decoder = GetPredefinedDefaultDecoder(o.GetType()); return((decoder == null && !disallowed.Contains(ConverterCategory.DEFAULT_PREDEFINED)) ? null : new BinaryDecoderData(decoder.Decoder)); case ConverterCategory.PRIMITIVE: if (o.GetType().IsPrimitive&& !disallowed.Contains(ConverterCategory.PRIMITIVE)) { return(new BinaryDecoderData(PrimitiveTypeDecoder)); } return(null); case ConverterCategory.SERIALIZABLE: if (o.GetType().IsSerializable&& !disallowed.Contains(ConverterCategory.SERIALIZABLE)) { return(new BinaryDecoderData(SerializableTypeDecoder)); } return(null); case ConverterCategory.COMPLEX: if (!o.GetType().IsPrimitive&& !disallowed.Contains(ConverterCategory.COMPLEX)) { return(new BinaryDecoderData(ComplexTypeDecoder)); } return(null); default: throw new NotImplementedException("Provided category was not implemented"); } }
/// <summary> /// Finds the appropriate decoder for provided object /// </summary> /// <param name="o">Object to find the decoder for</param> /// <returns>An decoder method appropriate for that object</returns> protected virtual BinaryDecoderData GetDecoder(object o, ConverterCategory[] disallowed = null) { Type objectType = o.GetType(); BinaryDecoderMethod decoder; Func <IEnumerable <byte>, object> decoderMethod; if (disallowed == null) { disallowed = new ConverterCategory[] { } } ; // Step 1. Looking for a custom converter added manually to the converters list decoder = GetCustomDecoder(objectType); if (decoder != null && !disallowed.Contains(ConverterCategory.CUSTOM)) { // Found the appropriate decoder return(new BinaryDecoderData(decoder.Decoder)); } // Step 2. Looking for a custom converter defined within the converter class decoder = GetPredefinedCustomDecoder(objectType); if (decoder != null && !disallowed.Contains(ConverterCategory.CUSTOM_PREDEFINED)) { // Found the appropriate decoder return(new BinaryDecoderData(decoder.Decoder)); } // Step 3. Looking for a custom converter defined within the converted class decoderMethod = GetCustomClassDecoder(o); if (decoderMethod != null && !disallowed.Contains(ConverterCategory.CUSTOM_FOR_CLASS)) { return(new BinaryDecoderData(decoderMethod)); } // Step 4. Looking for a global converter defined for the class decoderMethod = GetGlobalClassDecoder(objectType); if (decoderMethod != null && !disallowed.Contains(ConverterCategory.GLOBAL_FOR_CLASS)) { return(new BinaryDecoderData(decoderMethod)); } // Step 5. Looking for a default converter added manually to the converters list decoder = GetDefaultDecoder(objectType); if (decoder != null && !disallowed.Contains(ConverterCategory.DEFAULT)) { return(new BinaryDecoderData(decoder.Decoder)); } // Step 6. Looking for a default converter defined within the converter class decoder = GetPredefinedDefaultDecoder(objectType); if (decoder != null && !disallowed.Contains(ConverterCategory.DEFAULT_PREDEFINED)) { return(new BinaryDecoderData(decoder.Decoder)); } // Step 7. Attempting a converter for a primitive type if (objectType.IsPrimitive && !disallowed.Contains(ConverterCategory.PRIMITIVE)) { return(new BinaryDecoderData(PrimitiveTypeDecoder, ConverterType.INCLUSIVE_PRIMITIVE)); } // Step 8. Attempting a converter for a serializable type if (objectType.IsSerializable && !disallowed.Contains(ConverterCategory.SERIALIZABLE)) { return(new BinaryDecoderData(SerializableTypeDecoder, ConverterType.INCLUSIVE_SERIALIZABLE)); } // Step 9. None of the above is valid, apply the default decoder if (!disallowed.Contains(ConverterCategory.COMPLEX)) { return(new BinaryDecoderData(ComplexTypeDecoder)); } return(null); }
public Converter(ConverterCategory category) { ConverterType = category; }