public async Task <object> DeserializeAsync(Stream stream, Type type, CancellationToken cancellationToken = default) { var headerBuffer = new byte[9]; await stream.ReadAsync(headerBuffer, 0, HeaderLength, cancellationToken).ConfigureAwait(false); var offset = 0; var header = SerializerBinary.ReadByte(headerBuffer, ref offset); if (header != Header) { throw new Exception("Not expected header error"); } var compressedLength = SerializerBinary.ReadInt32Fixed(headerBuffer, ref offset); var uncompressedLength = SerializerBinary.ReadInt32Fixed(headerBuffer, ref offset); var buffer = ArrayPool <byte> .Shared.Rent(compressedLength + uncompressedLength); try { await stream.ReadAsync(buffer, 0, compressedLength, cancellationToken).ConfigureAwait(false); LZ4Codec.Decode( buffer, 0, compressedLength, buffer, compressedLength, uncompressedLength); object obj = DeserializeCore(buffer, compressedLength, uncompressedLength); return(obj); } finally { ArrayPool <byte> .Shared.Return(buffer); } }
public void Deserialize(byte[] buffer, ref int offset, ref Type value) { int mode = SerializerBinary.ReadUInt32Bias(buffer, ref offset, Bias); // Null if (mode == Null) { value = null; return; } var typeCache = _serializer.InstanceData.TypeCache; // Existing if (mode >= 0) { var id = mode; value = typeCache.GetExistingObject <Type>(id); return; } bool isComposite = mode == NewComposite; if (isComposite) // composite aka "closed generic" { // Read main type var compositeProxy = typeCache.CreateDeserializationProxy <Type>(); Type baseType = value; Deserialize(buffer, ref offset, ref baseType); // Read count var argCount = SerializerBinary.ReadByte(buffer, ref offset); Type[] genericArgs = new Type[argCount]; for (int i = 0; i < argCount; i++) { var genericArgProxy = typeCache.CreateDeserializationProxy <Type>(); Deserialize(buffer, ref offset, ref genericArgProxy.Value); genericArgs[i] = genericArgProxy.Value; } value = _typeBinder.GetTypeFromBaseAndAgruments(baseType.FullName, genericArgs); compositeProxy.Value = value; // make it available for future deserializations } else { var proxy = typeCache.CreateDeserializationProxy <Type>(); string baseTypeName = SerializerBinary.ReadString(buffer, ref offset); value = _typeBinder.GetTypeFromBase(baseTypeName); proxy.Value = value; } }
public void Deserialize(byte[] buffer, ref int offset, ref IPAddress value) { var isIPv4 = SerializerBinary.ReadByte(buffer, ref offset) == 0; var bytes = new byte[isIPv4 ? 4 : 16]; for (var i = 0; i < bytes.Length; i++) { bytes[i] = SerializerBinary.ReadByte(buffer, ref offset); } value = new IPAddress(bytes); }
public void Deserialize(byte[] buffer, ref int offset, ref Color value) { bool isKnownColor = SerializerBinary.ReadByte(buffer, ref offset) != 0; if (isKnownColor) { int knownColor = SerializerBinary.ReadInt32Fixed(buffer, ref offset); value = Color.FromKnownColor((KnownColor)knownColor); } else { var argb = SerializerBinary.ReadInt32Fixed(buffer, ref offset); value = Color.FromArgb(argb); } }
public void Deserialize(byte[] buffer, ref int offset, ref Type value) { int mode = SerializerBinary.ReadUInt32Bias(buffer, ref offset, Bias); // Null if (mode == Null) { value = null; return; } var typeCache = _serializer.InstanceData.TypeCache; // Existing if (mode >= 0) { var id = mode; value = typeCache.GetExistingObject <Type>(id); return; } bool isComposite = mode == NewGeneric; if (isComposite) // composite aka "closed generic" { // Read base type first (example: Dictionary<T1, T2>) Type baseType = value; Deserialize(buffer, ref offset, ref baseType); // Read count (example: 2) var argCount = SerializerBinary.ReadByte(buffer, ref offset); Type[] genericArgs = new Type[argCount]; // Read all inner type definitions (in our example: 'string' and 'object) for (int i = 0; i < argCount; i++) { Deserialize(buffer, ref offset, ref genericArgs[i]); } // Read construct full composite (example: Dictionary<string, object>) var compositeProxy = typeCache.CreateDeserializationProxy <Type>(); value = _typeBinder.GetTypeFromBaseAndAgruments(baseType.FullName, genericArgs); compositeProxy.Value = value; // make it available for future deserializations } else { var proxy = typeCache.CreateDeserializationProxy <Type>(); string baseTypeName = SerializerBinary.ReadString(buffer, ref offset); value = _typeBinder.GetTypeFromBase(baseTypeName); proxy.Value = value; } // todo: what to do when the type is not written because it is the same already? // a) force writing the type when embedding version info // b) just write schema, assuming the type if (_serializer.Config.VersionTolerance == VersionTolerance.AutomaticEmbedded) { if (!CerasSerializer.FrameworkAssemblies.Contains(value.Assembly)) { _serializer.ReadSchemaForType(buffer, ref offset, value); } } }
public void Deserialize(byte[] buffer, ref int offset, ref Type type) { int mode = SerializerBinary.ReadUInt32Bias(buffer, ref offset, Bias); // Null if (mode == Null) { type = null; return; } var typeCache = _serializer.InstanceData.TypeCache; // Existing if (mode >= 0) { var id = mode; type = typeCache.GetExistingObject(id); return; } bool isComposite = mode == NewGeneric; if (isComposite) // composite aka "closed generic" { // Read base type first (example: Dictionary<T1, T2>) Type baseType = type; Deserialize(buffer, ref offset, ref baseType); // Read count (example: 2) var argCount = SerializerBinary.ReadByte(buffer, ref offset); Type[] genericArgs = new Type[argCount]; // Read all inner type definitions (in our example: 'string' and 'object) for (int i = 0; i < argCount; i++) { Deserialize(buffer, ref offset, ref genericArgs[i]); } // Read construct full composite (example: Dictionary<string, object>) var compositeProxy = typeCache.CreateDeserializationProxy(); type = _typeBinder.GetTypeFromBaseAndAgruments(baseType.FullName, genericArgs); compositeProxy.Type = type; // make it available for future deserializations if (_isSealed) { ThrowSealed(type, false); } } else { var proxy = typeCache.CreateDeserializationProxy(); string baseTypeName = SerializerBinary.ReadString(buffer, ref offset); type = _typeBinder.GetTypeFromBase(baseTypeName); proxy.Type = type; if (_isSealed) { ThrowSealed(type, false); } } }
public void Deserialize(byte[] buffer, ref int offset, ref T member) { // What type? Type type = null; _typeFormatter.Deserialize(buffer, ref offset, ref type); // What kind of member? var bindingData = SerializerBinary.ReadByte(buffer, ref offset); UnpackBindingData(bindingData, out bool isStatic, out MemberType memberType); var bindingFlags = isStatic ? BindingAllStatic : BindingAllInstance; string name = null; switch (memberType) { case MemberType.Constructor: case MemberType.Method: _stringFormatter.Deserialize(buffer, ref offset, ref name); var numArgs = SerializerBinary.ReadInt32(buffer, ref offset); Type[] args = new Type[numArgs]; for (int i = 0; i < numArgs; i++) { _typeFormatter.Deserialize(buffer, ref offset, ref args[i]); } if (memberType == MemberType.Constructor) { member = (T)(MemberInfo)type.GetConstructor(bindingFlags, null, args, null); return; } else { // todo: add a full "isGenericMethod" flag to the binding information, support open and half open definitions... var resolvedMethod = ReflectionHelper.ResolveMethod(type, name, args); if (resolvedMethod != null) { member = (T)(MemberInfo)resolvedMethod; return; } } throw new AmbiguousMatchException($"Can't resolve method named '{name}' with '{numArgs}' arguments."); case MemberType.Field: case MemberType.Property: _stringFormatter.Deserialize(buffer, ref offset, ref name); Type fieldOrPropType = null; _typeFormatter.Deserialize(buffer, ref offset, ref fieldOrPropType); if (memberType == MemberType.Field) { member = (T)(MemberInfo)type.GetField(name, bindingFlags); } else { member = (T)(MemberInfo)type.GetProperty(name, bindingFlags, null, fieldOrPropType, types: new Type[0], null); } break; default: throw new ArgumentOutOfRangeException("Cannot deserialize member type '" + memberType + "'"); } }
public void Deserialize(byte[] buffer, ref int offset, ref T member) { // What type? Type type = null; _typeFormatter.Deserialize(buffer, ref offset, ref type); // What kind of member? var bindingData = SerializerBinary.ReadByte(buffer, ref offset); UnpackBindingData(bindingData, out bool isStatic, out MemberType memberType); var bindingFlags = isStatic ? BindingAllStatic : BindingAllInstance; string name = null; switch (memberType) { case MemberType.Constructor: case MemberType.Method: _stringFormatter.Deserialize(buffer, ref offset, ref name); var numArgs = SerializerBinary.ReadInt32(buffer, ref offset); Type[] args = new Type[numArgs]; for (int i = 0; i < numArgs; i++) { _typeFormatter.Deserialize(buffer, ref offset, ref args[i]); } if (memberType == MemberType.Constructor) { member = (T)(MemberInfo)type.GetConstructor(bindingFlags, null, args, null); } else { member = (T)(MemberInfo)type.GetMethod(name, bindingFlags, binder: null, types: args, modifiers: null); } break; case MemberType.Field: case MemberType.Property: _stringFormatter.Deserialize(buffer, ref offset, ref name); Type fieldOrPropType = null; _typeFormatter.Deserialize(buffer, ref offset, ref fieldOrPropType); if (memberType == MemberType.Field) { member = (T)(MemberInfo)type.GetField(name, bindingFlags); } else { member = (T)(MemberInfo)type.GetProperty(name, bindingFlags, null, fieldOrPropType, types: new Type[0], null); } break; default: throw new ArgumentOutOfRangeException("Cannot deserialize member type '" + memberType + "'"); } }
public void Deserialize(byte[] buffer, ref int offset, ref sbyte value) { value = (sbyte)SerializerBinary.ReadByte(buffer, ref offset); }