/// <summary> /// Does not support deserializing of anonymous types /// Type should be covered by preceeding resolvers in complex/standard resolver /// </summary> private object DeserializeByTypeName(string typeName, byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize) { // try get type with assembly name, throw if not found var type = Type.GetType(typeName, true); var ti = type.GetTypeInfo(); KeyValuePair <object, DeserializeMethod> formatterAndDelegate; if (type == typeof(object)) { formatterAndDelegate = new KeyValuePair <object, DeserializeMethod>(null, (object p1, byte[] p2, int p3, IFormatterResolver p4, out int p5) => { p5 = 0; return(new object()); }); } else { lock (deserializers) { if (!deserializers.TryGetValue(type, out formatterAndDelegate)) { var formatter = formatterResolver.GetFormatterDynamic(type); if (formatter == null) { throw new FormatterNotRegisteredException(type.FullName + " is not registered in this resolver. resolver:" + formatterResolver.GetType().Name); } var formatterType = typeof(IMessagePackFormatter <>).MakeGenericType(type); var param0 = Expression.Parameter(typeof(object), "formatter"); var param1 = Expression.Parameter(typeof(byte[]), "bytes"); var param2 = Expression.Parameter(typeof(int), "offset"); var param3 = Expression.Parameter(typeof(IFormatterResolver), "formatterResolver"); var param4 = Expression.Parameter(typeof(int).MakeByRefType(), "readSize"); var deserializeMethodInfo = formatterType.GetRuntimeMethod("Deserialize", new[] { typeof(byte[]), typeof(int), typeof(IFormatterResolver), typeof(int).MakeByRefType() }); var deserialize = Expression.Call( Expression.Convert(param0, formatterType), deserializeMethodInfo, param1, param2, param3, param4); Expression body = deserialize; if (ti.IsValueType) { body = Expression.Convert(deserialize, typeof(object)); } var lambda = Expression.Lambda <DeserializeMethod>(body, param0, param1, param2, param3, param4).Compile(); formatterAndDelegate = new KeyValuePair <object, DeserializeMethod>(formatter, lambda); deserializers[type] = formatterAndDelegate; } } } return(formatterAndDelegate.Value(formatterAndDelegate.Key, bytes, offset, formatterResolver, out readSize)); }
protected U DeSerializeProperty <U>(Func <object> valueFormatterHandler, byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize) { var initialSize = offset; if (bytes[offset] == 0xc0) { readSize = 1; return(default(U)); } //int fieldNameSize = 0; //_ = MessagePackBinary.ReadString(bytes, offset, out fieldNameSize); //offset += fieldNameSize; var fromResolver = formatterResolver.GetFormatterDynamic(typeof(U)); var fromHandler = valueFormatterHandler != null?valueFormatterHandler() : fromResolver; var primaryElementFormatter = fromResolver != null ? fromResolver : fromHandler; int valueSize = 0; object instance = DeSerializeField(typeof(U), bytes, offset, primaryElementFormatter, formatterResolver, out valueSize); offset += valueSize; readSize = offset - initialSize; return((U)instance); }
public int Serialize(ref byte[] bytes, int offset, object value, IFormatterResolver formatterResolver) { if (value == null) { return(MessagePackBinary.WriteNil(ref bytes, offset)); } var type = value.GetType(); var ti = type.GetTypeInfo(); if (type == typeof(object)) { // serialize to empty map return(MessagePackBinary.WriteMapHeader(ref bytes, offset, 0)); } KeyValuePair <object, SerializeMethod> formatterAndDelegate; lock (serializers) { if (!serializers.TryGetValue(type, out formatterAndDelegate)) { var formatter = formatterResolver.GetFormatterDynamic(type); if (formatter == null) { throw new FormatterNotRegisteredException(type.FullName + " is not registered in this resolver. resolver:" + formatterResolver.GetType().Name); } serializers.TryAdd(type, t => { var formatterType = typeof(IMessagePackFormatter <>).MakeGenericType(t); var param0 = Expression.Parameter(typeof(object), "formatter"); var param1 = Expression.Parameter(typeof(byte[]).MakeByRefType(), "bytes"); var param2 = Expression.Parameter(typeof(int), "offset"); var param3 = Expression.Parameter(typeof(object), "value"); var param4 = Expression.Parameter(typeof(IFormatterResolver), "formatterResolver"); var serializeMethodInfo = formatterType.GetRuntimeMethod("Serialize", new[] { typeof(byte[]).MakeByRefType(), typeof(int), t, typeof(IFormatterResolver) }); var body = Expression.Call( Expression.Convert(param0, formatterType), serializeMethodInfo, param1, param2, ti.IsValueType ? Expression.Unbox(param3, t) : Expression.Convert(param3, t), param4); var lambda = Expression.Lambda <SerializeMethod>(body, param0, param1, param2, param3, param4).Compile(); formatterAndDelegate = new KeyValuePair <object, SerializeMethod>(formatter, lambda); return(formatterAndDelegate); }); } } return(formatterAndDelegate.Value(formatterAndDelegate.Key, ref bytes, offset, value, formatterResolver)); }
/// <summary> /// Check whether type is readable. /// </summary> /// <param name="type">Type to check.</param> /// <returns></returns> /// <exception cref="T:System.ArgumentNullException"><paramref name="type"/> is <see langword="null"/></exception> public bool CanRead(Type type) { if (type == null) { throw new ArgumentNullException(nameof(type)); } if (!_readableTypes.TryGetValue(type, out bool canRead)) { canRead = _formatterResolver.GetFormatterDynamic(type) != null; _readableTypes = _readableTypes.Add(type, canRead); return(canRead); } return(canRead); }
private static void GetFormatterAndDelegateSlow(Type type, IFormatterResolver formatterResolver, out KeyValuePair <object, DeserializeMethod> formatterAndDelegate) { lock (s_deserializers) { if (!s_deserializers.TryGetValue(type, out formatterAndDelegate)) { var formatter = formatterResolver.GetFormatterDynamic(type); if (formatter == null) { ThrowHelper.ThrowFormatterNotRegisteredException(type, formatterResolver); } var formatterType = typeof(IMessagePackFormatter <>).GetCachedGenericType(type); var param0 = Expression.Parameter(typeof(object), "formatter"); var param1 = Expression.Parameter(typeof(MessagePackReader).MakeByRefType(), "reader"); var param2 = Expression.Parameter(typeof(IFormatterResolver), "formatterResolver"); var deserializeMethodInfo = formatterType.GetRuntimeMethod("Deserialize", new[] { typeof(MessagePackReader).MakeByRefType(), typeof(IFormatterResolver) }); var deserialize = Expression.Call( Expression.Convert(param0, formatterType), deserializeMethodInfo, param1, param2); Expression body = deserialize; if (type.IsValueType) { body = Expression.Convert(deserialize, typeof(object)); } var lambda = Expression.Lambda <DeserializeMethod>(body, param0, param1, param2).Compile(); formatterAndDelegate = new KeyValuePair <object, DeserializeMethod>(formatter, lambda); s_deserializers.TryAdd(type, formatterAndDelegate); } } }
private static void GetFormatterAndDelegateSlow(Type expectedType, IFormatterResolver formatterResolver, out KeyValuePair <object, SerializeMethod> formatterAndDelegate) { lock (s_serializers) // double check locking... { if (!s_serializers.TryGetValue(expectedType, out formatterAndDelegate)) { var formatter = formatterResolver.GetFormatterDynamic(expectedType); if (formatter == null) { ThrowHelper.ThrowFormatterNotRegisteredException(expectedType, formatterResolver); } var formatterType = typeof(IMessagePackFormatter <>).GetCachedGenericType(expectedType); var param0 = Expression.Parameter(typeof(object), "formatter"); var param1 = Expression.Parameter(typeof(MessagePackWriter).MakeByRefType(), "writer"); var param2 = Expression.Parameter(typeof(int).MakeByRefType(), "idx"); var param3 = Expression.Parameter(typeof(object), "value"); var param4 = Expression.Parameter(typeof(IFormatterResolver), "formatterResolver"); var serializeMethodInfo = formatterType.GetRuntimeMethod("Serialize", new[] { typeof(MessagePackWriter).MakeByRefType(), typeof(int).MakeByRefType(), expectedType, typeof(IFormatterResolver) }); var body = Expression.Call( Expression.Convert(param0, formatterType), serializeMethodInfo, param1, param2, expectedType.IsValueType ? Expression.Unbox(param3, expectedType) : Expression.Convert(param3, expectedType), param4); var lambda = Expression.Lambda <SerializeMethod>(body, param0, param1, param2, param3, param4).Compile(); formatterAndDelegate = new KeyValuePair <object, SerializeMethod>(formatter, lambda); s_serializers.TryAdd(expectedType, formatterAndDelegate); } } }
protected int SerializeProperty <U>(ref byte[] bytes, int offset, string name, U contents, IFormatterResolver formatterResolver, Func <object> valueFormatterHandler = null) { var initialSize = offset; offset += formatterResolver.GetFormatter <string>().Serialize(ref bytes, offset, name, formatterResolver); if (contents == null) { offset += MessagePackBinary.WriteNil(ref bytes, offset); return(offset - initialSize); } // element value var fromResolver = formatterResolver.GetFormatterDynamic(contents.GetType()); var fromHandler = valueFormatterHandler != null?valueFormatterHandler() : fromResolver; var primaryElementFormatter = fromResolver == null?valueFormatterHandler() : fromResolver; offset += SerializeField(ref bytes, offset, contents, primaryElementFormatter, formatterResolver); return(offset - initialSize); }
public int Serialize(ref byte[] bytes, int offset, object value, IFormatterResolver formatterResolver) { if (value == null) { return(MessagePackBinary.WriteNil(ref bytes, offset)); } var type = value.GetType(); var ti = type.GetTypeInfo(); if ((PrimitiveObjectFormatter.IsSupportedType(type, ti, value) && !(value is DateTime) && !(value is IDictionary) && !(value is ICollection)) || ti.IsAnonymous()) { return(DynamicObjectTypeFallbackFormatter.Instance.Serialize(ref bytes, offset, value, formatterResolver)); } var typeName = BuildTypeName(type); if (blacklistCheck.Contains(type.FullName)) { throw new InvalidOperationException("Type is in blacklist:" + type.FullName); } KeyValuePair <object, SerializeMethod> formatterAndDelegate; if (type == typeof(object)) { formatterAndDelegate = new KeyValuePair <object, SerializeMethod>(null, (object p1, ref byte[] p2, int p3, object p4, IFormatterResolver p5) => 0); } else { lock (serializers) { if (!serializers.TryGetValue(type, out formatterAndDelegate)) { var formatter = formatterResolver.GetFormatterDynamic(type); if (formatter == null) { throw new FormatterNotRegisteredException(type.FullName + " is not registered in this resolver. resolver:" + formatterResolver.GetType().Name); } var formatterType = typeof(IMessagePackFormatter <>).MakeGenericType(type); var param0 = Expression.Parameter(typeof(object), "formatter"); var param1 = Expression.Parameter(typeof(byte[]).MakeByRefType(), "bytes"); var param2 = Expression.Parameter(typeof(int), "offset"); var param3 = Expression.Parameter(typeof(object), "value"); var param4 = Expression.Parameter(typeof(IFormatterResolver), "formatterResolver"); var serializeMethodInfo = formatterType.GetRuntimeMethod("Serialize", new[] { typeof(byte[]).MakeByRefType(), typeof(int), type, typeof(IFormatterResolver) }); var body = Expression.Call( Expression.Convert(param0, formatterType), serializeMethodInfo, param1, param2, ti.IsValueType ? Expression.Unbox(param3, type) : Expression.Convert(param3, type), param4); var lambda = Expression.Lambda <SerializeMethod>(body, param0, param1, param2, param3, param4).Compile(); formatterAndDelegate = new KeyValuePair <object, SerializeMethod>(formatter, lambda); serializers[type] = formatterAndDelegate; } } } // mark as extension with code 100 var startOffset = offset; offset += 6; // mark will be written at the end, when size is known offset += MessagePackBinary.WriteString(ref bytes, offset, typeName); offset += formatterAndDelegate.Value(formatterAndDelegate.Key, ref bytes, offset, value, formatterResolver); MessagePackBinary.WriteExtensionFormatHeaderForceExt32Block(ref bytes, startOffset, (sbyte)TypelessFormatter.ExtensionTypeCode, offset - startOffset - 6); return(offset - startOffset); }
/// <summary> /// Does not support deserializing of anonymous types /// Type should be covered by preceeding resolvers in complex/standard resolver. /// </summary> private object DeserializeByTypeName(ArraySegment <byte> typeName, ref MessagePackReader byteSequence, MessagePackSerializerOptions options) { // try get type with assembly name, throw if not found Type type; if (!this.typeCache.TryGetValue(typeName, out type)) { var buffer = new byte[typeName.Count]; Buffer.BlockCopy(typeName.Array, typeName.Offset, buffer, 0, buffer.Length); var str = StringEncoding.UTF8.GetString(buffer); type = this.BindToType(str); if (type == null) { if (IsMscorlib && str.Contains("System.Private.CoreLib")) { str = str.Replace("System.Private.CoreLib", "mscorlib"); type = Type.GetType(str, true); // throw } else if (!IsMscorlib && str.Contains("mscorlib")) { str = str.Replace("mscorlib", "System.Private.CoreLib"); type = Type.GetType(str, true); // throw } else { type = Type.GetType(str, true); // re-throw } } this.typeCache.TryAdd(buffer, type); } KeyValuePair <object, DeserializeMethod> formatterAndDelegate; if (!this.deserializers.TryGetValue(type, out formatterAndDelegate)) { lock (this.deserializers) { if (!this.deserializers.TryGetValue(type, out formatterAndDelegate)) { TypeInfo ti = type.GetTypeInfo(); IFormatterResolver resolver = options.Resolver; var formatter = resolver.GetFormatterDynamic(type); if (formatter == null) { throw new FormatterNotRegisteredException(type.FullName + " is not registered in this resolver. resolver:" + resolver.GetType().Name); } Type formatterType = typeof(IMessagePackFormatter <>).MakeGenericType(type); ParameterExpression param0 = Expression.Parameter(typeof(object), "formatter"); ParameterExpression param1 = Expression.Parameter(typeof(MessagePackReader).MakeByRefType(), "reader"); ParameterExpression param2 = Expression.Parameter(typeof(MessagePackSerializerOptions), "options"); MethodInfo deserializeMethodInfo = formatterType.GetRuntimeMethod("Deserialize", new[] { typeof(MessagePackReader).MakeByRefType(), typeof(MessagePackSerializerOptions) }); MethodCallExpression deserialize = Expression.Call( Expression.Convert(param0, formatterType), deserializeMethodInfo, param1, param2); Expression body = deserialize; if (ti.IsValueType) { body = Expression.Convert(deserialize, typeof(object)); } DeserializeMethod lambda = Expression.Lambda <DeserializeMethod>(body, param0, param1, param2).Compile(); formatterAndDelegate = new KeyValuePair <object, DeserializeMethod>(formatter, lambda); this.deserializers.TryAdd(type, formatterAndDelegate); } } } return(formatterAndDelegate.Value(formatterAndDelegate.Key, ref byteSequence, options)); }
public void Serialize(ref MessagePackWriter writer, object value, MessagePackSerializerOptions options) { if (value == null) { writer.WriteNil(); return; } Type type = value.GetType(); byte[] typeName; if (!this.typeNameCache.TryGetValue(type, out typeName)) { if (BlacklistCheck.Contains(type.FullName)) { throw new InvalidOperationException("Type is in blacklist:" + type.FullName); } TypeInfo ti = type.GetTypeInfo(); if (ti.IsAnonymous() || UseBuiltinTypes.Contains(type)) { typeName = null; } else { typeName = StringEncoding.UTF8.GetBytes(this.BuildTypeName(type)); } this.typeNameCache.TryAdd(type, typeName); } if (typeName == null) { Resolvers.TypelessFormatterFallbackResolver.Instance.GetFormatter <object>().Serialize(ref writer, value, options); return; } // don't use GetOrAdd for avoid closure capture. KeyValuePair <object, SerializeMethod> formatterAndDelegate; if (!this.serializers.TryGetValue(type, out formatterAndDelegate)) { // double check locking... lock (this.serializers) { if (!this.serializers.TryGetValue(type, out formatterAndDelegate)) { TypeInfo ti = type.GetTypeInfo(); IFormatterResolver resolver = options.Resolver; var formatter = resolver.GetFormatterDynamic(type); if (formatter == null) { throw new FormatterNotRegisteredException(type.FullName + " is not registered in this resolver. resolver:" + resolver.GetType().Name); } Type formatterType = typeof(IMessagePackFormatter <>).MakeGenericType(type); ParameterExpression param0 = Expression.Parameter(typeof(object), "formatter"); ParameterExpression param1 = Expression.Parameter(typeof(MessagePackWriter).MakeByRefType(), "writer"); ParameterExpression param2 = Expression.Parameter(typeof(object), "value"); ParameterExpression param3 = Expression.Parameter(typeof(MessagePackSerializerOptions), "options"); MethodInfo serializeMethodInfo = formatterType.GetRuntimeMethod("Serialize", new[] { typeof(MessagePackWriter).MakeByRefType(), type, typeof(MessagePackSerializerOptions) }); MethodCallExpression body = Expression.Call( Expression.Convert(param0, formatterType), serializeMethodInfo, param1, ti.IsValueType ? Expression.Unbox(param2, type) : Expression.Convert(param2, type), param3); SerializeMethod lambda = Expression.Lambda <SerializeMethod>(body, param0, param1, param2, param3).Compile(); formatterAndDelegate = new KeyValuePair <object, SerializeMethod>(formatter, lambda); this.serializers.TryAdd(type, formatterAndDelegate); } } } // mark will be written at the end, when size is known using (var scratch = new Nerdbank.Streams.Sequence <byte>()) { MessagePackWriter scratchWriter = writer.Clone(scratch); scratchWriter.WriteString(typeName); formatterAndDelegate.Value(formatterAndDelegate.Key, ref scratchWriter, value, options); scratchWriter.Flush(); // mark as extension with code 100 writer.WriteExtensionFormat(new ExtensionResult((sbyte)TypelessFormatter.ExtensionTypeCode, scratch.AsReadOnlySequence)); } }
protected override bool CanReadType(Type type) { return(_resolver.GetFormatterDynamic(type) != null && base.CanReadType(type)); }
protected override bool CanWriteType(Type type) { return(_resolver.GetFormatterDynamic(type) != null); }
public override bool CanReadType(Type type) { return(_resolver.GetFormatterDynamic(type) != null); }
/// <summary> /// Does not support deserializing of anonymous types /// Type should be covered by preceeding resolvers in complex/standard resolver /// </summary> private object DeserializeByTypeName(ArraySegment <byte> typeName, byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize) { // try get type with assembly name, throw if not found Type type; if (!typeCache.TryGetValue(typeName, out type)) { var buffer = new byte[typeName.Count]; Buffer.BlockCopy(typeName.Array, typeName.Offset, buffer, 0, buffer.Length); var str = StringEncoding.UTF8.GetString(buffer); type = BindToType(str); if (type == null) { if (isMscorlib && str.Contains("System.Private.CoreLib")) { str = str.Replace("System.Private.CoreLib", "mscorlib"); type = Type.GetType(str, true); // throw } else if (!isMscorlib && str.Contains("mscorlib")) { str = str.Replace("mscorlib", "System.Private.CoreLib"); type = Type.GetType(str, true); // throw } else { type = Type.GetType(str, true); // re-throw } } typeCache.TryAdd(buffer, type); } KeyValuePair <object, DeserializeMethod> formatterAndDelegate; if (!deserializers.TryGetValue(type, out formatterAndDelegate)) { lock (deserializers) { if (!deserializers.TryGetValue(type, out formatterAndDelegate)) { var ti = type.GetTypeInfo(); var formatter = formatterResolver.GetFormatterDynamic(type); if (formatter == null) { throw new FormatterNotRegisteredException(type.FullName + " is not registered in this resolver. resolver:" + formatterResolver.GetType().Name); } var formatterType = typeof(IMessagePackFormatter <>).MakeGenericType(type); var param0 = Expression.Parameter(typeof(object), "formatter"); var param1 = Expression.Parameter(typeof(byte[]), "bytes"); var param2 = Expression.Parameter(typeof(int), "offset"); var param3 = Expression.Parameter(typeof(IFormatterResolver), "formatterResolver"); var param4 = Expression.Parameter(typeof(int).MakeByRefType(), "readSize"); var deserializeMethodInfo = formatterType.GetRuntimeMethod("Deserialize", new[] { typeof(byte[]), typeof(int), typeof(IFormatterResolver), typeof(int).MakeByRefType() }); var deserialize = Expression.Call( Expression.Convert(param0, formatterType), deserializeMethodInfo, param1, param2, param3, param4); Expression body = deserialize; if (ti.IsValueType) { body = Expression.Convert(deserialize, typeof(object)); } var lambda = Expression.Lambda <DeserializeMethod>(body, param0, param1, param2, param3, param4).Compile(); formatterAndDelegate = new KeyValuePair <object, DeserializeMethod>(formatter, lambda); deserializers.TryAdd(type, formatterAndDelegate); } } } return(formatterAndDelegate.Value(formatterAndDelegate.Key, bytes, offset, formatterResolver, out readSize)); }
public int Serialize(ref byte[] bytes, int offset, object value, IFormatterResolver formatterResolver) { if (value == null) { return(MessagePackBinary.WriteNil(ref bytes, offset)); } var type = value.GetType(); byte[] typeName; if (!typeNameCache.TryGetValue(type, out typeName)) { if (blacklistCheck.Contains(type.FullName)) { throw new InvalidOperationException("Type is in blacklist:" + type.FullName); } var ti = type.GetTypeInfo(); if (ti.IsAnonymous() || useBuiltinTypes.Contains(type)) { typeName = null; } else { typeName = StringEncoding.UTF8.GetBytes(BuildTypeName(type)); } typeNameCache.TryAdd(type, typeName); } if (typeName == null) { return(Resolvers.TypelessFormatterFallbackResolver.Instance.GetFormatter <object>().Serialize(ref bytes, offset, value, formatterResolver)); } // don't use GetOrAdd for avoid closure capture. KeyValuePair <object, SerializeMethod> formatterAndDelegate; if (!serializers.TryGetValue(type, out formatterAndDelegate)) { lock (serializers) // double check locking... { if (!serializers.TryGetValue(type, out formatterAndDelegate)) { var ti = type.GetTypeInfo(); var formatter = formatterResolver.GetFormatterDynamic(type); if (formatter == null) { throw new FormatterNotRegisteredException(type.FullName + " is not registered in this resolver. resolver:" + formatterResolver.GetType().Name); } var formatterType = typeof(IMessagePackFormatter <>).MakeGenericType(type); var param0 = Expression.Parameter(typeof(object), "formatter"); var param1 = Expression.Parameter(typeof(byte[]).MakeByRefType(), "bytes"); var param2 = Expression.Parameter(typeof(int), "offset"); var param3 = Expression.Parameter(typeof(object), "value"); var param4 = Expression.Parameter(typeof(IFormatterResolver), "formatterResolver"); var serializeMethodInfo = formatterType.GetRuntimeMethod("Serialize", new[] { typeof(byte[]).MakeByRefType(), typeof(int), type, typeof(IFormatterResolver) }); var body = Expression.Call( Expression.Convert(param0, formatterType), serializeMethodInfo, param1, param2, ti.IsValueType ? Expression.Unbox(param3, type) : Expression.Convert(param3, type), param4); var lambda = Expression.Lambda <SerializeMethod>(body, param0, param1, param2, param3, param4).Compile(); formatterAndDelegate = new KeyValuePair <object, SerializeMethod>(formatter, lambda); serializers.TryAdd(type, formatterAndDelegate); } } } // mark as extension with code 100 var startOffset = offset; offset += 6; // mark will be written at the end, when size is known offset += MessagePackBinary.WriteStringBytes(ref bytes, offset, typeName); offset += formatterAndDelegate.Value(formatterAndDelegate.Key, ref bytes, offset, value, formatterResolver); MessagePackBinary.WriteExtensionFormatHeaderForceExt32Block(ref bytes, startOffset, (sbyte)TypelessFormatter.ExtensionTypeCode, offset - startOffset - 6); return(offset - startOffset); }