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); }
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); }
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); }