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); } } }
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); }
public static Task <object> ReadObject(this BinaryReader reader, IResolveProxyIds resolver) => reader.ReadObject((ObjectType)reader.ReadByte(), resolver);
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(); } }
public Task <object> Deserialize(BinaryReader reader, Type valueType, IResolveProxyIds resolver, CancellationToken token) => throw new NotSupportedException();
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()}"); }
public Task Serialize(BinaryWriter writer, Type valueType, object value, IResolveProxyIds resolver) { writer.Write(valueType, value, resolver); return(Task.CompletedTask); }
public Task Serialize(BinaryWriter writer, Type valueType, object value, IResolveProxyIds resolver) => throw new NotSupportedException();
public Task <object> Deserialize(BinaryReader reader, Type valueType, IResolveProxyIds resolver, CancellationToken token) => reader.ReadObject(resolver);
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); } } }
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); }
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); }
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); } } }