コード例 #1
0
        public static void WriteSerializable(this BinaryWriter writer, IResolveProxyIds resolver, Type type, object value, bool writeHeader = true)
        {
            if (writeHeader)
            {
                writer.Write((byte)ObjectType.Serializable);
                writer.Write(type, false);
            }

            if (value is ISerializable serializable)
            {
                //true for custom serialization
                writer.Write(true);

                type.getCtor();

                var context = new StreamingContext(StreamingContextStates.All, resolver);
                var info    = new SerializationInfo(type, new DefaultFormatterConverter());
                serializable.GetObjectData(info, context);

                var start = writer.BaseStream.Position;
                writer.Write(new byte[sizeof(int)], 0, sizeof(int));

                var length = 0;
                foreach (var entry in info)
                {
                    length++;
                    writer.Write(entry.Name);
                    writer.Write(entry.ObjectType, false);
                    writer.Write(entry.Value?.GetType() ?? entry.ObjectType, entry.Value, resolver);
                }

                var stop = writer.BaseStream.Position;
                writer.BaseStream.Position = start;
                writer.Write(length);
                writer.BaseStream.Position = stop;
            }
            else
            {
                //false for custom serialization
                writer.Write(false);

                foreach (var field in type.getFields())
                {
                    var fieldValue = field.GetValue(value);
                    writer.Write(fieldValue?.GetType() ?? field.FieldType, fieldValue, resolver);
                }
            }
        }
コード例 #2
0
        public static async Task <object> ReadSerializable(this BinaryReader reader, IResolveProxyIds resolver, Type type = null)
        {
            type = type ?? reader.ReadType();

            var useCustomSerializer = reader.ReadBoolean();

            if (useCustomSerializer)
            {
                var context = new StreamingContext(StreamingContextStates.All, resolver);
                var info    = new SerializationInfo(type, new DefaultFormatterConverter());
                var length  = reader.ReadInt32();

                for (var index = 0; index < length; index++)
                {
                    var itemName = reader.ReadString();
                    var itemType = reader.ReadType();
                    var item     = await reader.ReadObject(resolver).ConfigureAwait(false);

                    info.AddValue(itemName, item, itemType);
                }

                var ctor = type.getCtor();

                return(ctor.Invoke(new object[]
                {
                    info, context
                }));
            }

            var returnValue = FormatterServices.GetUninitializedObject(type);

            foreach (var field in type.getFields())
            {
                field.SetValue(returnValue, await reader.ReadObject(resolver).ConfigureAwait(false));
            }

            return(returnValue);
        }
コード例 #3
0
 public static Task <object> ReadObject(this BinaryReader reader, IResolveProxyIds resolver) => reader.ReadObject((ObjectType)reader.ReadByte(), resolver);
コード例 #4
0
        public static async Task <object> ReadObject(this BinaryReader reader, ObjectType objectType, IResolveProxyIds resolver)
        {
            switch (objectType)
            {
            case ObjectType.Array:
                return(await reader.ReadArray(resolver).ConfigureAwait(false));

            case ObjectType.Serializable:
                return(await reader.ReadSerializable(resolver).ConfigureAwait(false));

            case ObjectType.Enum:
                return(reader.ReadEnum());

            case ObjectType.Null:
                return(null);

            case ObjectType.Proxy:
                var id = reader.ReadInt64();
                return(resolver.TryToGetInstance(id, out var instance) ? instance : null);

            case ObjectType.Type:
                return(reader.ReadType());

            case ObjectType.DateTime:
                return(reader.ReadDateTime());

            case ObjectType.Guid:
                return(await reader.ReadGuid().ConfigureAwait(false));

            case ObjectType.TimeSpan:
                return(reader.ReadTimeSpan());

            case ObjectType.Byte:
                return(reader.ReadByte());

            case ObjectType.Bytes:
                var bytes     = new byte[reader.ReadInt32()];
                var byteIndex = 0;
                while (byteIndex < bytes.Length)
                {
                    byteIndex += await reader.BaseStream.ReadAsync(bytes, byteIndex, bytes.Length - byteIndex).ConfigureAwait(false);
                }
                return(bytes);

            case ObjectType.Boolean:
                return(reader.ReadBoolean());

            case ObjectType.Char:
                return(reader.ReadChar());

            case ObjectType.Decimal:
                return(reader.ReadDecimal());

            case ObjectType.Double:
                return(reader.ReadDouble());

            case ObjectType.Float:
                return(reader.ReadSingle());

            case ObjectType.Int:
                return(reader.ReadInt32());

            case ObjectType.Long:
                return(reader.ReadInt64());

            case ObjectType.SByte:
                return(reader.ReadSByte());

            case ObjectType.Short:
                return(reader.ReadInt16());

            case ObjectType.Str:
                return(reader.ReadString());

            case ObjectType.UInt:
                return(reader.ReadUInt32());

            case ObjectType.ULong:
                return(reader.ReadUInt64());

            case ObjectType.UShort:
                return(reader.ReadUInt16());

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
コード例 #5
0
 public Task <object> Deserialize(BinaryReader reader, Type valueType, IResolveProxyIds resolver, CancellationToken token) => throw new NotSupportedException();
コード例 #6
0
        public static void Write(this BinaryWriter writer, Type valueType, object value, IResolveProxyIds resolver, bool writeHeader = true)
        {
            if (value == null)
            {
                writer.WriteNull();
                return;
            }

            if (typeof(Type).IsAssignableFrom(valueType))
            {
                writer.Write((Type)value);
                return;
            }

            if (valueType.IsArray)
            {
                writer.Write(valueType, (Array)value, resolver, writeHeader);
                return;
            }

            if (valueType.IsEnum)
            {
                writer.WriteEnum(valueType, value, writeHeader);
                return;
            }

            if (valueType.IsClass &&
                !valueType.IsSealed &&
                resolver.TryToGetInstanceId(value, out var id))
            {
                if (writeHeader)
                {
                    writer.Write((byte)ObjectType.Proxy);
                }
                writer.Write(id);
                return;
            }

            if (valueType == typeof(DateTime) || valueType == typeof(DateTime?))
            {
                writer.Write((DateTime)value, writeHeader);
                return;
            }

            if (valueType == typeof(Guid) || valueType == typeof(Guid?))
            {
                writer.Write((Guid)value, writeHeader);
                return;
            }

            if (valueType == typeof(TimeSpan) || valueType == typeof(TimeSpan?))
            {
                writer.Write((TimeSpan)value, writeHeader);
                return;
            }

            if (valueType == typeof(bool) || valueType == typeof(bool?))
            {
                if (writeHeader)
                {
                    writer.Write((byte)ObjectType.Boolean);
                }
                writer.Write((bool)value);
                return;
            }

            if (valueType == typeof(byte) || valueType == typeof(byte?))
            {
                if (writeHeader)
                {
                    writer.Write((byte)ObjectType.Byte);
                }
                writer.Write((byte)value);
                return;
            }

            if (valueType == typeof(byte[]))
            {
                if (writeHeader)
                {
                    writer.Write((byte)ObjectType.Bytes);
                }
                var valueBytes = (byte[])value;
                writer.Write(valueBytes.Length);
                writer.BaseStream.Write(valueBytes, 0, valueBytes.Length);
                return;
            }

            if (valueType == typeof(char) || valueType == typeof(char?))
            {
                if (writeHeader)
                {
                    writer.Write((byte)ObjectType.Char);
                }
                writer.Write((char)value);
                return;
            }

            if (valueType == typeof(decimal) || valueType == typeof(decimal?))
            {
                if (writeHeader)
                {
                    writer.Write((byte)ObjectType.Decimal);
                }
                writer.Write((decimal)value);
                return;
            }

            if (valueType == typeof(double) || valueType == typeof(double?))
            {
                if (writeHeader)
                {
                    writer.Write((byte)ObjectType.Double);
                }
                writer.Write((double)value);
                return;
            }

            if (valueType == typeof(float) || valueType == typeof(float?))
            {
                if (writeHeader)
                {
                    writer.Write((byte)ObjectType.Float);
                }
                writer.Write((float)value);
                return;
            }

            if (valueType == typeof(int) || valueType == typeof(int?))
            {
                if (writeHeader)
                {
                    writer.Write((byte)ObjectType.Int);
                }
                writer.Write((int)value);
                return;
            }

            if (valueType == typeof(long) || valueType == typeof(long?))
            {
                if (writeHeader)
                {
                    writer.Write((byte)ObjectType.Long);
                }
                writer.Write((long)value);
                return;
            }

            if (valueType == typeof(sbyte) || valueType == typeof(sbyte?))
            {
                if (writeHeader)
                {
                    writer.Write((byte)ObjectType.SByte);
                }
                writer.Write((sbyte)value);
                return;
            }

            if (valueType == typeof(short) || valueType == typeof(short?))
            {
                if (writeHeader)
                {
                    writer.Write((byte)ObjectType.Short);
                }
                writer.Write((short)value);
                return;
            }

            if (valueType == typeof(string))
            {
                if (writeHeader)
                {
                    writer.Write((byte)ObjectType.Str);
                }
                writer.Write((string)value);
                return;
            }

            if (valueType == typeof(uint) || valueType == typeof(uint?))
            {
                if (writeHeader)
                {
                    writer.Write((byte)ObjectType.UInt);
                }
                writer.Write((uint)value);
                return;
            }

            if (valueType == typeof(ulong) || valueType == typeof(ulong?))
            {
                if (writeHeader)
                {
                    writer.Write((byte)ObjectType.ULong);
                }
                writer.Write((ulong)value);
                return;
            }

            if (valueType == typeof(ushort) || valueType == typeof(ushort?))
            {
                if (writeHeader)
                {
                    writer.Write((byte)ObjectType.UShort);
                }
                writer.Write((ushort)value);
                return;
            }

            if (valueType.IsSerializable)
            {
                writer.WriteSerializable(resolver, valueType, value, writeHeader);
                return;
            }

            throw new ArgumentException($"Unable serialize: {value.GetType()}");
        }
コード例 #7
0
 public Task Serialize(BinaryWriter writer, Type valueType, object value, IResolveProxyIds resolver)
 {
     writer.Write(valueType, value, resolver);
     return(Task.CompletedTask);
 }
コード例 #8
0
 public Task Serialize(BinaryWriter writer, Type valueType, object value, IResolveProxyIds resolver) => throw new NotSupportedException();
コード例 #9
0
 public Task <object> Deserialize(BinaryReader reader, Type valueType, IResolveProxyIds resolver, CancellationToken token) =>
 reader.ReadObject(resolver);
コード例 #10
0
        private static async Task read(this BinaryReader reader, Array array, ObjectType?elementObjectType, Type elementType, bool nullable, int dimension, int[] indexArray, IResolveProxyIds resolver)
        {
            var upperBound    = array.GetUpperBound(dimension);
            var lastDimension = dimension == array.Rank - 1;

            for (indexArray[dimension] = array.GetLowerBound(dimension); indexArray[dimension] <= upperBound; indexArray[dimension]++)
            {
                if (lastDimension)
                {
                    if (nullable)
                    {
                        if (reader.ReadBoolean())
                        {
                            continue;
                        }
                    }

                    object element;
                    switch (elementObjectType)
                    {
                    case null:
                        element = await reader.ReadObject(resolver).ConfigureAwait(false);

                        break;

                    case ObjectType.Enum:
                        element = reader.ReadEnum(elementType);
                        break;

                    default:
                        element = await reader.ReadObject(elementObjectType.Value, resolver).ConfigureAwait(false);

                        break;
                    }

                    array.SetValue(element, indexArray);
                }
                else
                {
                    await reader.read(array, elementObjectType, elementType, nullable, dimension + 1, indexArray, resolver).ConfigureAwait(false);
                }
            }
        }
コード例 #11
0
        public static async Task <object> ReadArray(this BinaryReader reader, IResolveProxyIds resolver)
        {
            var elementType = reader.ReadType();
            var rank        = (int)reader.ReadByte();

            var lengths     = new int[rank];
            var lowerBounds = new int[rank];

            for (var dimension = 0; dimension < rank; dimension++)
            {
                lengths[dimension]     = reader.ReadInt32();
                lowerBounds[dimension] = reader.ReadInt32();
            }

            var array = Array.CreateInstance(elementType, lengths, lowerBounds);

            var underlyingType = Nullable.GetUnderlyingType(elementType);
            var nullable       = !elementType.IsValueType || underlyingType != null;

            elementType = underlyingType ?? elementType;

            ObjectType?elementObjectType;

            if (elementType.IsArray)
            {
                elementObjectType = ObjectType.Array;
            }
            else if (elementType.IsEnum)
            {
                elementObjectType = ObjectType.Enum;
            }
            else if (elementType.IsClass && !elementType.IsSealed)
            {
                elementObjectType = null;
            }
            else if (elementType == typeof(DateTime))
            {
                elementObjectType = ObjectType.DateTime;
            }
            else if (elementType == typeof(Guid))
            {
                elementObjectType = ObjectType.Guid;
            }
            else if (elementType == typeof(TimeSpan))
            {
                elementObjectType = ObjectType.TimeSpan;
            }
            else if (elementType == typeof(Type))
            {
                elementObjectType = ObjectType.Type;
            }
            else if (elementType == typeof(bool))
            {
                elementObjectType = ObjectType.Boolean;
            }
            else if (elementType == typeof(byte))
            {
                elementObjectType = ObjectType.Byte;
            }
            else if (elementType == typeof(byte[]))
            {
                elementObjectType = ObjectType.Bytes;
            }
            else if (elementType == typeof(char))
            {
                elementObjectType = ObjectType.Char;
            }
            else if (elementType == typeof(decimal))
            {
                elementObjectType = ObjectType.Decimal;
            }
            else if (elementType == typeof(double))
            {
                elementObjectType = ObjectType.Double;
            }
            else if (elementType == typeof(float))
            {
                elementObjectType = ObjectType.Float;
            }
            else if (elementType == typeof(int))
            {
                elementObjectType = ObjectType.Int;
            }
            else if (elementType == typeof(long))
            {
                elementObjectType = ObjectType.Long;
            }
            else if (elementType == typeof(sbyte))
            {
                elementObjectType = ObjectType.SByte;
            }
            else if (elementType == typeof(short))
            {
                elementObjectType = ObjectType.Short;
            }
            else if (elementType == typeof(string))
            {
                elementObjectType = ObjectType.Str;
            }
            else if (elementType == typeof(uint))
            {
                elementObjectType = ObjectType.UInt;
            }
            else if (elementType == typeof(ulong))
            {
                elementObjectType = ObjectType.ULong;
            }
            else if (elementType == typeof(ushort))
            {
                elementObjectType = ObjectType.Short;
            }
            else if (elementType == typeof(ushort))
            {
                elementObjectType = ObjectType.Short;
            }
            else if (elementType.IsSerializable)
            {
                elementObjectType = ObjectType.Serializable;
            }
            else
            {
                throw new ArgumentException($"Unable serialize array with elements of: {elementType}");
            }

            await reader.read(array, elementObjectType, elementType, nullable, 0, new int[array.Rank], resolver).ConfigureAwait(false);

            return(array);
        }
コード例 #12
0
        public static void Write(this BinaryWriter writer, Type arrayType, Array array, IResolveProxyIds resolver, bool writeHeader = true)
        {
            if (writeHeader)
            {
                writer.Write((byte)ObjectType.Array);
            }

            var elementType = arrayType.GetElementType();

            // ReSharper disable once PossibleNullReferenceException
            var nullable = !elementType.IsValueType || Nullable.GetUnderlyingType(elementType) != null;

            writer.Write(elementType, false);
            writer.Write((byte)array.Rank);

            for (var dimension = 0; dimension < array.Rank; dimension++)
            {
                writer.Write(array.GetLength(dimension));
                writer.Write(array.GetLowerBound(dimension));
            }

            writer.write(array, nullable, elementType.IsClass && !elementType.IsSealed, 0, new int[array.Rank], resolver);
        }
コード例 #13
0
        private static void write(this BinaryWriter writer, Array array, bool nullable, bool writeHeader, int dimension, int[] indexArray, IResolveProxyIds resolver)
        {
            var upperBound    = array.GetUpperBound(dimension);
            var lastDimension = dimension == array.Rank - 1;

            for (indexArray[dimension] = array.GetLowerBound(dimension); indexArray[dimension] <= upperBound; indexArray[dimension]++)
            {
                if (lastDimension)
                {
                    var element = array.GetValue(indexArray);

                    if (nullable)
                    {
                        writer.Write(element == null);
                    }

                    if (element != null)
                    {
                        writer.Write(element.GetType(), element, resolver, writeHeader);
                    }
                }
                else
                {
                    writer.write(array, nullable, writeHeader, dimension + 1, indexArray, resolver);
                }
            }
        }