Пример #1
0
        public void Serialize(ref JsonWriter writer, object value, IJsonFormatterResolver formatterResolver)
        {
            if (value == null)
            {
                writer.WriteNull(); return;
            }

            var type = value.GetType();

            if (type == typeof(object))
            {
                // serialize to empty object
                writer.WriteBeginObject();
                writer.WriteEndObject();
                return;
            }

            KeyValuePair <object, Tuple <SerializeMethod, bool> > formatterAndDelegate;

            if (!serializers.TryGetValue(type, out formatterAndDelegate))
            {
                lock (serializers)
                {
                    if (!serializers.TryGetValue(type, out formatterAndDelegate))
                    {
                        object formatter = null;
                        foreach (var innerResolver in innerResolvers)
                        {
                            formatter = innerResolver.GetFormatterDynamic(type);
                            if (formatter != null)
                            {
                                break;
                            }
                        }
                        if (formatter == null)
                        {
                            throw new FormatterNotRegisteredException(type.FullName + " is not registered in this resolver. resolvers:" + string.Join(", ", innerResolvers.Select(x => x.GetType().Name).ToArray()));
                        }

                        var t = type;
                        {
                            var dm = new DynamicMethod("Serialize", null, new[] { typeof(object), typeof(JsonWriter).MakeByRefType(), typeof(object), typeof(IJsonFormatterResolver) }, type.Module, true);
                            var il = dm.GetILGenerator();

                            // delegate void SerializeMethod(object dynamicFormatter, ref JsonWriter writer, object value, IJsonFormatterResolver formatterResolver);

                            il.EmitLdarg(0);
                            il.Emit(OpCodes.Castclass, typeof(IJsonFormatter <>).MakeGenericType(t));
                            il.EmitLdarg(1);
                            il.EmitLdarg(2);
                            il.EmitUnboxOrCast(t);
                            il.EmitLdarg(3);

                            il.EmitCall(Resolvers.Internal.DynamicObjectTypeBuilder.EmitInfo.Serialize(t));

                            il.Emit(OpCodes.Ret);

                            var writeTypeName = BuiltinResolver.HasFormatter(type);
                            formatterAndDelegate = new KeyValuePair <object, Tuple <SerializeMethod, bool> >(formatter, Tuple.Create((SerializeMethod)dm.CreateDelegate(typeof(SerializeMethod)), writeTypeName));
                        }

                        serializers.TryAdd(t, formatterAndDelegate);
                    }
                }
            }

            if (formatterAndDelegate.Value.Item2)
            {
                writer.WriteBeginObject();
                writer.WritePropertyName("$type");
                var typeName = SubtractFullNameRegex.Replace(type.AssemblyQualifiedName, "");
                writer.WriteString(typeName);
                writer.WriteValueSeparator();
                writer.WritePropertyName("$value");
            }

            formatterAndDelegate.Value.Item1(formatterAndDelegate.Key, ref writer, value, formatterResolver);

            if (formatterAndDelegate.Value.Item2)
            {
                writer.WriteEndObject();
            }
        }
Пример #2
0
        public object Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterResolver)
        {
            if (reader.ReadIsNull())
            {
                return(null);
            }

            var typeName = reader.ReadTypeNameWithVerify();

            if (typeName == null)
            {
                return(null);
            }
            var type = GetTypeFast(typeName);

            if (type == null)
            {
                throw new UnknownTypeException(typeName);
            }

            KeyValuePair <object, Tuple <DeserializeMethod, bool> > formatterAndDelegate;

            if (!deserializers.TryGetValue(type, out formatterAndDelegate))
            {
                lock (deserializers)
                {
                    if (!deserializers.TryGetValue(type, out formatterAndDelegate))
                    {
                        object formatter = null;
                        foreach (var innerResolver in innerResolvers)
                        {
                            formatter = innerResolver.GetFormatterDynamic(type);
                            if (formatter != null)
                            {
                                break;
                            }
                        }
                        if (formatter == null)
                        {
                            throw new FormatterNotRegisteredException(type.FullName + " is not registered in this resolver. resolvers:" + string.Join(", ", innerResolvers.Select(x => x.GetType().Name).ToArray()));
                        }

                        var t = type;
                        {
                            var dm = new DynamicMethod("Deserialize", typeof(object), new[] { typeof(object), typeof(JsonReader).MakeByRefType(), typeof(IJsonFormatterResolver) }, type.Module, true);
                            var il = dm.GetILGenerator();

                            // delegate object DeserializeMethod(object dynamicFormatter, ref JsonReader reader, IJsonFormatterResolver formatterResolver);

                            il.EmitLdarg(0);
                            il.Emit(OpCodes.Castclass, typeof(IJsonFormatter <>).MakeGenericType(t));
                            il.EmitLdarg(1);
                            il.EmitLdarg(2);

                            il.EmitCall(Resolvers.Internal.DynamicObjectTypeBuilder.EmitInfo.Deserialize(t));

                            il.EmitBoxOrDoNothing(type);

                            il.Emit(OpCodes.Ret);

                            var writeTypeName = BuiltinResolver.HasFormatter(type);
                            formatterAndDelegate = new KeyValuePair <object, Tuple <DeserializeMethod, bool> >(formatter, Tuple.Create((DeserializeMethod)dm.CreateDelegate(typeof(DeserializeMethod)), writeTypeName));
                        }

                        deserializers.TryAdd(t, formatterAndDelegate);
                    }
                }
            }

            if (formatterAndDelegate.Value.Item2)
            {
                reader.ReadIsBeginObjectWithVerify();
                if (reader.ReadPropertyName() != "$type")
                {
                    throw new JsonParsingException("$type missing");
                }
                reader.ReadString();
                reader.ReadIsValueSeparatorWithVerify();
                if (reader.ReadPropertyName() != "$value")
                {
                    throw new JsonParsingException("$value missing");
                }
            }

            var value = formatterAndDelegate.Value.Item1(formatterAndDelegate.Key, ref reader, formatterResolver);

            if (formatterAndDelegate.Value.Item2)
            {
                reader.ReadIsEndObject();
            }

            return(value);
        }