public void Serialize(ref MessagePackWriter writer, object value, MessagePackSerializerOptions options) { if (value is null) { writer.WriteNil(); return; } Type type = value.GetType(); TypeInfo ti = type.GetTypeInfo(); if (type == typeof(object)) { // serialize to empty map writer.WriteMapHeader(0); return; } if (PrimitiveObjectFormatter.IsSupportedType(type, ti, value)) { if (!(value is System.Collections.IDictionary || value is System.Collections.ICollection)) { PrimitiveObjectFormatter.Instance.Serialize(ref writer, value, options); return; } } object formatter = options.Resolver.GetFormatterDynamicWithVerify(type); if (!SerializerDelegates.TryGetValue(type, out SerializeMethod serializerDelegate)) { lock (SerializerDelegates) { if (!SerializerDelegates.TryGetValue(type, out serializerDelegate)) { 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); serializerDelegate = Expression.Lambda <SerializeMethod>(body, param0, param1, param2, param3).Compile(); SerializerDelegates.TryAdd(type, serializerDelegate); } } } serializerDelegate(formatter, ref writer, value, options); }
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)) { return(PrimitiveObjectFormatter.Instance.Serialize(ref bytes, offset, value, formatterResolver)); } KeyValuePair <object, SerializeMethod> formatterAndDelegate; lock (serializers) { if (!serializers.TryGetValue(type, out formatterAndDelegate)) { var formatter = DynamicContractlessObjectResolver.Instance.GetFormatterDynamic(type); if (formatter == null) { throw new FormatterNotRegisteredException(type.FullName + " is not registered in this resolver. resolver:" + typeof(DynamicContractlessObjectResolver).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; } } return(formatterAndDelegate.Value(formatterAndDelegate.Key, ref bytes, offset, value, formatterResolver)); }
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); }
public void Serialize(ref MessagePackWriter writer, global::System.Object value, global::MessagePack.MessagePackSerializerOptions options) { if (value == null) { writer.WriteNil(); return; } Type type = value.GetType(); TypeInfo ti = type.GetTypeInfo(); if (type == typeof(Vector3[])) { var values = (Vector3[])value; writer.WriteArrayHeader(values.Length); var formatter = options.Resolver.GetFormatterWithVerify <Vector3>(); foreach (var f in values) { formatter.Serialize(ref writer, f, options); } } else if (value is System.Collections.IDictionary) { var d = value as System.Collections.IDictionary; writer.WriteMapHeader(d.Count); foreach (System.Collections.DictionaryEntry item in d) { this.Serialize(ref writer, item.Key, options); this.Serialize(ref writer, item.Value, options); } return; } else if (value is System.Collections.ICollection) { var c = value as System.Collections.ICollection; writer.WriteArrayHeader(c.Count); foreach (var item in c) { this.Serialize(ref writer, item, options); } return; } else { // all custom types that could appear in actionReturn // must appear here if (type == typeof(Vector3)) { options.Resolver.GetFormatterWithVerify <Vector3>().Serialize(ref writer, (Vector3)value, options); } else if (type == typeof(InitializeReturn)) { options.Resolver.GetFormatterWithVerify <InitializeReturn>().Serialize(ref writer, (InitializeReturn)value, options); } else if (type == typeof(PhysicsRemoteFPSAgentController.WhatDidITouch)) { options.Resolver.GetFormatterWithVerify <PhysicsRemoteFPSAgentController.WhatDidITouch>().Serialize(ref writer, (PhysicsRemoteFPSAgentController.WhatDidITouch)value, options); } else if (type == typeof(UnityEngine.AI.NavMeshPath)) { options.Resolver.GetFormatterWithVerify <UnityEngine.AI.NavMeshPath>().Serialize(ref writer, (UnityEngine.AI.NavMeshPath)value, options); } else if (PrimitiveObjectFormatter.IsSupportedType(type, ti, value)) { PrimitiveObjectFormatter.Instance.Serialize(ref writer, value, options); } else { throw new MessagePackSerializationException("Not supported type: " + type.Name); } } }