Example #1
0
        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));
        }
Example #3
0
        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);
                }
            }
        }