示例#1
0
        private void ValidatePropertyInfo(PropertyInfo prop)
        {
            // Get a possible binary member configuration or use the default one.
            BinaryMemberAttribute attrib = prop.GetCustomAttribute <BinaryMemberAttribute>();
            bool hasAttrib = attrib != null;

            attrib = attrib ?? new BinaryMemberAttribute();

            // Property must have getter and setter - if not, throw an exception if it is explicitly decorated.
            if (hasAttrib && (prop.GetMethod == null || prop.SetMethod == null))
            {
                throw new InvalidOperationException($"Getter and setter on property {prop} not found.");
            }
            // Property must be decorated or getter and setter public.
            if (hasAttrib ||
                (!Attribute.Explicit && prop.GetMethod?.IsPublic == true && prop.SetMethod?.IsPublic == true))
            {
                // For properties of enumerable type ElementCount must be specified.
                if (prop.PropertyType.IsEnumerable() && attrib.Length <= 0)
                {
                    throw new InvalidOperationException(
                              $"Property {prop} requires an element count specified with a {nameof(BinaryMemberAttribute)}.");
                }

                Members.Add(new MemberData(prop, prop.PropertyType, attrib));
            }
        }
示例#2
0
        // ---- METHODS (PRIVATE) --------------------------------------------------------------------------------------

        private void ValidateFieldInfo(FieldInfo field)
        {
            // Get a possible binary member configuration or use the default one.
            BinaryMemberAttribute attrib = field.GetCustomAttribute <BinaryMemberAttribute>();
            bool hasAttrib = attrib != null;

            attrib = attrib ?? new BinaryMemberAttribute();

            // Field must be decorated or public.
            if (hasAttrib || (!Attribute.Explicit && field.IsPublic))
            {
                // For fields of enumerable type ElementCount must be specified.
                if (field.FieldType.IsEnumerable() && attrib.Length <= 0)
                {
                    throw new InvalidOperationException(
                              $"Field {field} requires an element count specified with a {nameof(BinaryMemberAttribute)}.");
                }

                // Store member in a deterministic order.
                MemberData memberData = new MemberData(field, field.FieldType, attrib);
                if (attrib.Order == Int32.MinValue)
                {
                    UnorderedMembers.Add(field.Name, memberData);
                }
                else
                {
                    OrderedMembers.Add(attrib.Order, memberData);
                }
            }
        }
示例#3
0
 private void WriteObject(object instance, BinaryMemberAttribute attribute, Type type, object value)
 {
     if (attribute.Converter == null)
     {
         if (value == null)
         {
             return;
         }
         if (type == typeof(String))
         {
             Write((String)value, attribute.StringFormat);
         }
         else if (type.TryGetEnumerableElementType(out Type elementType))
         {
             foreach (object element in (IEnumerable)value)
             {
                 WriteObject(null, BinaryMemberAttribute.Default, elementType, element);
             }
         }
         else if (type == typeof(Boolean))
         {
             Write((Boolean)value, attribute.BooleanFormat);
         }
         else if (type == typeof(Byte))
         {
             Write((Byte)value);
         }
         else if (type == typeof(DateTime))
         {
             Write((DateTime)value, attribute.DateTimeFormat);
         }
         else if (type == typeof(Decimal))
         {
             Write((Decimal)value);
         }
         else if (type == typeof(Double))
         {
             Write((Double)value);
         }
         else if (type == typeof(Int16))
         {
             Write((Int16)value);
         }
         else if (type == typeof(Int32))
         {
             Write((Int32)value);
         }
         else if (type == typeof(Int64))
         {
             Write((Int64)value);
         }
         else if (type == typeof(SByte))
         {
             Write((SByte)value);
         }
         else if (type == typeof(Single))
         {
             Write((Single)value);
         }
         else if (type == typeof(UInt16))
         {
             Write((UInt16)value);
         }
         else if (type == typeof(UInt32))
         {
             Write((UInt32)value);
         }
         else if (type == typeof(UInt64))
         {
             Write((UInt32)value);
         }
         else if (type.GetTypeInfo().IsEnum)
         {
             WriteEnum(type, value, attribute.Strict);
         }
         else
         {
             WriteCustomObject(type, value, Position);
         }
     }
     else
     {
         // Let a converter do all the work.
         IBinaryConverter converter = BinaryConverterCache.GetConverter(attribute.Converter);
         converter.Write(this, instance, attribute, value);
     }
 }
示例#4
0
        // ---- CONSTRUCTORS & DESTRUCTOR ------------------------------------------------------------------------------

        /// <summary>
        /// Initializes a new instance of the <see cref="MemberData"/> class for the given <paramref name="memberInfo"/>
        /// with the specified <paramref name="attribute"/> configuration.
        /// </summary>
        /// <param name="memberInfo">The <see cref="MemberData"/> to represent.</param>
        /// <param name="type">The type of the value stored by the member.</param>
        /// <param name="attribute">The <see cref="BinaryMemberAttribute"/> configuration.</param>
        internal MemberData(MemberInfo memberInfo, Type type, BinaryMemberAttribute attribute)
        {
            MemberInfo = memberInfo;
            Type       = type;
            Attribute  = attribute;
        }
示例#5
0
 private object ReadObject(object instance, BinaryMemberAttribute attribute, Type type)
 {
     if (attribute.Converter == null)
     {
         if (type == typeof(String))
         {
             if (attribute.StringFormat == StringDataFormat.Raw)
             {
                 return(ReadString(attribute.Length));
             }
             else
             {
                 return(ReadString(attribute.StringFormat));
             }
         }
         else if (type.IsEnumerable())
         {
             throw new InvalidOperationException("Multidimensional arrays cannot be read directly.");
         }
         else if (type == typeof(Boolean))
         {
             return(ReadBoolean(attribute.BooleanFormat));
         }
         else if (type == typeof(Byte))
         {
             return(ReadByte());
         }
         else if (type == typeof(DateTime))
         {
             return(ReadDateTime(attribute.DateTimeFormat));
         }
         else if (type == typeof(Decimal))
         {
             return(ReadDecimal());
         }
         else if (type == typeof(Double))
         {
             return(ReadDouble());
         }
         else if (type == typeof(Int16))
         {
             return(ReadInt16());
         }
         else if (type == typeof(Int32))
         {
             return(ReadInt32());
         }
         else if (type == typeof(Int64))
         {
             return(ReadInt64());
         }
         else if (type == typeof(SByte))
         {
             return(ReadSByte());
         }
         else if (type == typeof(Single))
         {
             return(ReadSingle());
         }
         else if (type == typeof(UInt16))
         {
             return(ReadUInt16());
         }
         else if (type == typeof(UInt32))
         {
             return(ReadUInt32());
         }
         else if (type == typeof(UInt64))
         {
             return(ReadUInt64());
         }
         else if (type.GetTypeInfo().IsEnum)
         {
             return(ReadEnum(type, attribute.Strict));
         }
         else
         {
             return(ReadCustomObject(type, null, Position));
         }
     }
     else
     {
         // Let a converter do all the work.
         IBinaryConverter converter = BinaryConverterCache.GetConverter(attribute.Converter);
         return(converter.Read(this, instance, attribute));
     }
 }
示例#6
0
        private static void WriteObject(Stream stream, object instance, BinaryMemberAttribute attribute, Type type,
                                        object value, ByteConverter converter)
        {
            converter = converter ?? ByteConverter.System;

            if (attribute.Converter == null)
            {
                if (value == null)
                {
                    return;
                }
                else if (type == typeof(String))
                {
                    stream.Write((String)value, attribute.StringFormat, converter: converter);
                }
                else if (type.TryGetEnumerableElementType(out Type elementType))
                {
                    foreach (object element in (IEnumerable)value)
                    {
                        WriteObject(stream, null, BinaryMemberAttribute.Default, elementType, element, converter);
                    }
                }
                else if (type == typeof(Boolean))
                {
                    stream.Write((Boolean)value, attribute.BooleanFormat, converter);
                }
                else if (type == typeof(Byte))
                {
                    stream.Write((Byte)value);
                }
                else if (type == typeof(DateTime))
                {
                    stream.Write((DateTime)value, attribute.DateTimeFormat, converter);
                }
                else if (type == typeof(Decimal))
                {
                    stream.Write((Decimal)value);
                }
                else if (type == typeof(Double))
                {
                    stream.Write((Double)value, converter);
                }
                else if (type == typeof(Int16))
                {
                    stream.Write((Int16)value, converter);
                }
                else if (type == typeof(Int32))
                {
                    stream.Write((Int32)value, converter);
                }
                else if (type == typeof(Int64))
                {
                    stream.Write((Int64)value, converter);
                }
                else if (type == typeof(SByte))
                {
                    stream.Write((SByte)value);
                }
                else if (type == typeof(Single))
                {
                    stream.Write((Single)value, converter);
                }
                else if (type == typeof(UInt16))
                {
                    stream.Write((UInt16)value, converter);
                }
                else if (type == typeof(UInt32))
                {
                    stream.Write((UInt32)value, converter);
                }
                else if (type == typeof(UInt64))
                {
                    stream.Write((UInt64)value, converter);
                }
                else if (type.IsEnum)
                {
                    WriteEnum(stream, type, value, attribute.Strict, converter);
                }
                else
                {
                    if (stream.CanSeek)
                    {
                        WriteCustomObject(stream, type, value, stream.Position, converter);
                    }
                    else
                    {
                        WriteCustomObject(stream, type, value, -1, converter);
                    }
                }
            }
            else
            {
                // Let a binary converter do all the work.
                IBinaryConverter binaryConverter = BinaryConverterCache.GetConverter(attribute.Converter);
                binaryConverter.Write(stream, instance, attribute, value, converter);
            }
        }
示例#7
0
 private static object ReadObject(Stream stream, object instance, BinaryMemberAttribute attribute,
                                  Type type, ByteConverter converter)
 {
     if (attribute.Converter == null)
     {
         if (type == typeof(String))
         {
             if (attribute.StringFormat == StringCoding.Raw)
             {
                 return(stream.ReadString(attribute.Length));
             }
             else
             {
                 return(stream.ReadString(attribute.StringFormat, converter: converter));
             }
         }
         else if (type.IsEnumerable())
         {
             throw new InvalidOperationException("Multidimensional arrays cannot be read directly.");
         }
         else if (type == typeof(Boolean))
         {
             return(stream.ReadBoolean(attribute.BooleanFormat));
         }
         else if (type == typeof(Byte))
         {
             return(stream.Read1Byte());
         }
         else if (type == typeof(DateTime))
         {
             return(stream.ReadDateTime(attribute.DateTimeFormat, converter));
         }
         else if (type == typeof(Decimal))
         {
             return(stream.ReadDecimal());
         }
         else if (type == typeof(Double))
         {
             return(stream.ReadDouble(converter));
         }
         else if (type == typeof(Int16))
         {
             return(stream.ReadInt16(converter));
         }
         else if (type == typeof(Int32))
         {
             return(stream.ReadInt32(converter));
         }
         else if (type == typeof(Int64))
         {
             return(stream.ReadInt64(converter));
         }
         else if (type == typeof(SByte))
         {
             return(stream.ReadSByte());
         }
         else if (type == typeof(Single))
         {
             return(stream.ReadSingle(converter));
         }
         else if (type == typeof(UInt16))
         {
             return(stream.ReadUInt16(converter));
         }
         else if (type == typeof(UInt32))
         {
             return(stream.ReadUInt32(converter));
         }
         else if (type == typeof(UInt64))
         {
             return(stream.ReadUInt64(converter));
         }
         else if (type.IsEnum)
         {
             return(ReadEnum(stream, type, attribute.Strict, converter));
         }
         else
         {
             if (stream.CanSeek)
             {
                 return(ReadCustomObject(stream, type, null, stream.Position, converter));
             }
             else
             {
                 return(ReadCustomObject(stream, type, null, -1, converter));
             }
         }
     }
     else
     {
         // Let a binary converter do all the work.
         IBinaryConverter binaryConverter = BinaryConverterCache.GetConverter(attribute.Converter);
         return(binaryConverter.Read(stream, instance, attribute, converter));
     }
 }