private T ReadInternal <T>(Type givenType)
        {
            if (Reader.TokenType == TrwTokenType.Null)
            {
                Reader.MoveNext();
                return(default(T));
            }

            if (Reader.TokenType != TrwTokenType.StartObject)
            {
                if (givenType == typeof(object))
                {
                    throw new InvalidDataException($"No type specified for an ambiguous value. (Ln {Reader.LineNumber} Col {Reader.LinePosition})");
                }
                if (options.ExplicitTypes == TrwSerializationExplicitTypes.Always)
                {
                    throw new InvalidDataException($"ExplicitTypes option is set to Always, but a typeless value found. (Ln {Reader.LineNumber} Col {Reader.LinePosition})");
                }
                return(typeof(T) == givenType
                    ? handlers.GetHandler <T>().LoadContent(this)
                    : (T)handlers.GetHandler(givenType).LoadContent(this));
            }

            Reader.MoveNext();

            Type type;

            if (Reader.TokenType == TrwTokenType.PropertyName && Reader.ValueAsString == options.TypePropertyName)
            {
                Reader.MoveNext();
                type = ReadType();
            }
            else
            {
                type = givenType;
            }

            if (type == null)
            {
                throw new InvalidDataException($"No type specified for an ambiguous value. (Ln {Reader.LineNumber} Col {Reader.LinePosition})");
            }

            if (Reader.TokenType == TrwTokenType.PropertyName && Reader.ValueAsString == options.ValuePropertyName)
            {
                Reader.MoveNext();
            }

            var obj = typeof(T) == type
                ? handlers.GetHandler <T>().LoadContent(this)
                : (T)handlers.GetHandler(type).LoadContent(this);

            Reader.CheckAndMoveNext(TrwTokenType.EndObject);
            return(obj);
        }
Пример #2
0
        public bool TryCreateHandlerFor(Type type, ITrwSerializationHandlerContainer container, out ITrwSerializationHandler handler)
        {
            if (!type.IsNullable())
            {
                handler = null;
                return(false);
            }

            var actualType     = type.GetGenericArguments().Single();
            var contentIsProps = container.GetHandler(actualType).ContentIsProperties;
            var constructor    = typeof(NullableTrwHandler <>).MakeGenericType(actualType).GetConstructor(new [] { typeof(bool) });

            Debug.Assert(constructor != null, "constructor != null");
            handler = (ITrwSerializationHandler)constructor.Invoke(new object[] { contentIsProps });
            return(true);
        }
Пример #3
0
        private void WriteInternal <T>(T value, Type explicitType)
        {
            if (value == null)
            {
                Writer.WriteValue().Null();
                return;
            }

            var ambiguous    = !explicitType.IsSealed;
            var type         = ResolveRedirect(ambiguous ? value.GetType() : explicitType);
            var handler      = handlers.GetHandler(type);
            var typedHandler = handler as ITrwSerializationHandler <T>;

            void WriteContentWithHandler()
            {
                if (typedHandler != null)
                {
                    typedHandler.SaveContent(this, value);
                }
                else
                {
                    handler.SaveContent(this, value);
                }
            }

            bool writeType;

            switch (options.ExplicitTypes)
            {
            case TrwSerializationExplicitTypes.Never:
                writeType = false;
                break;

            case TrwSerializationExplicitTypes.WhenAmbiguous:
                writeType = ambiguous;
                break;

            case TrwSerializationExplicitTypes.WhenObject:
                writeType = handler.ContentIsProperties;
                break;

            case TrwSerializationExplicitTypes.WhenAmbiguousOrObject:
                writeType = ambiguous || handler.ContentIsProperties;
                break;

            case TrwSerializationExplicitTypes.Always:
                writeType = true;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            if (writeType)
            {
                Writer.StartObject();
                Writer.AddProperty(options.TypePropertyName);
                WriteType(type);
                if (!handler.ContentIsProperties)
                {
                    Writer.AddProperty(options.ValuePropertyName);
                }
                WriteContentWithHandler();
                Writer.EndObject();
            }
            else
            {
                if (!handler.ContentIsProperties)
                {
                    WriteContentWithHandler();
                }
                else
                {
                    Writer.StartObject();
                    WriteContentWithHandler();
                    Writer.EndObject();
                }
            }
        }
        public void ApplyDiff <T>(T target, ITrwDiff diff, TrwDiffDirection direction)
        {
            var type = ResolveRedirect(target.GetType());

            handlers.GetHandler(type).ApplyDiff(this, target, diff, direction);
        }