protected virtual object ReadFieldsCompact(object obj) { var meta = Meta.Get(obj.GetType(), Options); if (!meta.IsCompact) { if (meta.Surrogate.FuncFrom == null) { throw Error("Attempt to read non-compact type '{0}' from compact format", obj.GetType()); } return(meta.Surrogate.FuncFrom( ReadFieldsCompact(Activator.CreateInstance(meta.Surrogate.SurrogateType)))); } meta.BeforeDeserialization.Run(obj); bool isFirst = true; objStack.Push(obj); try { foreach (var yi in meta.Items) { if (!isFirst) { Require(','); } isFirst = false; yi.SetValue(obj, ReadValueFunc(yi.Type)()); } } finally { objStack.Pop(); } Require(']'); meta.AfterDeserialization.Run(obj); return(obj); }
protected object ReadAny() { var t = ReadType(); if (t == typeof(object)) { throw Error("Unable to read pure object"); } return(ReadValueFunc(t)()); }
private object ReadTypedPrimitive(Type t) { Require(','); if (RequireUnescapedString() != JsonOptions.ValueTag) { throw Error("Primitive type value expected"); } Require(':'); var result = ReadValueFunc(t)(); Require('}'); return(result); }
// T is neither a collection nor a bare object. private T ReadObject <T>() where T : class { KillBuf(); var ch = SkipSpaces(); switch (ch) { case 'n': Require("ull"); return(null); case '{': var name = GetNextName(first: true); if (name != JsonOptions.ClassTag) { var meta = Meta.Get(typeof(T), Options); return((T)ReadFields(meta.Factory(), name)); } var typeName = RequireUnescapedString(); var t = FindType(typeName); if (typeof(T).IsAssignableFrom(t)) { var meta = Meta.Get(t, Options); return((T)ReadFields(meta.Factory(), GetNextName(first: false))); } return((T)GetSurrogate <T>(t).FuncFrom( ReadFields(Activator.CreateInstance(t), GetNextName(first: false)))); case '[': { var meta = Meta.Get(typeof(T), Options); return((T)ReadFieldsCompact(meta.Factory())); } case '"': PutBack(ch); return((T)GetSurrogate <T>(typeof(string)).FuncFrom(RequireString())); case 't': case 'f': PutBack(ch); return((T)GetSurrogate <T>(typeof(bool)).FuncFrom(RequireBool())); default: PutBack(ch); var sg = GetSurrogate <T>(null); return((T)sg.FuncFrom(ReadValueFunc(sg.SurrogateType)())); // TODO: Optimize } }
public override T FromReaderInt <T>() { if (BinaryOptions.AutoSignature) { CheckSignature(); } if (typeof(T) == typeof(object)) { return((T)ReadAny()); } if (!ReadCompatibleType(typeof(T))) { throw Error("Incompatible type to read into {0}", typeof(T)); } return((T)ReadValueFunc(typeof(T))()); }
public override T FromReaderInt <T>() => (T)ReadValueFunc(typeof(T))();
protected virtual object ReadFields(object obj, string name) { var meta = Meta.Get(obj.GetType(), Options); meta.BeforeDeserialization.Run(obj); objStack.Push(obj); try { // Optimization: duplicate loop to extract options check. if (JsonOptions.Unordered) { var storage = !Options.AllowUnknownFields || meta.GetUnknownStorage == null ? NullYuzuUnknownStorage.Instance : meta.GetUnknownStorage(obj); storage.Clear(); int requiredCountActiual = 0; while (name != null) { if (!meta.TagToItem.TryGetValue(name, out Meta.Item yi)) { if (!Options.AllowUnknownFields) { throw Error("Unknown field '{0}'", name); } storage.Add(name, ReadAnyObject()); name = GetNextName(false); continue; } if (!yi.IsOptional) { requiredCountActiual += 1; } if (yi.SetValue != null) { yi.SetValue(obj, ReadValueFunc(yi.Type)()); } else { MergeValueFunc(yi.Type)(yi.GetValue(obj)); } name = GetNextName(false); } if (requiredCountActiual != meta.RequiredCount) { throw Error( "Expected {0} required field(s), but found {1} for type {2}", meta.RequiredCount, requiredCountActiual, obj.GetType()); } } else if (Options.AllowUnknownFields) { var storage = meta.GetUnknownStorage == null ? NullYuzuUnknownStorage.Instance : meta.GetUnknownStorage(obj); storage.Clear(); foreach (var yi in meta.Items) { if (ReadUnknownFields(storage, yi.Tag(Options), ref name) != 0) { if (!yi.IsOptional) { throw Error("Expected field '{0}', but found '{1}'", yi.NameTagged(Options), name); } continue; } if (yi.SetValue != null) { yi.SetValue(obj, ReadValueFunc(yi.Type)()); } else { MergeValueFunc(yi.Type)(yi.GetValue(obj)); } name = GetNextName(false); } ReadUnknownFieldsTail(storage, name); } else { foreach (var yi in meta.Items) { if (yi.Tag(Options) != name) { if (!yi.IsOptional) { throw Error("Expected field '{0}', but found '{1}'", yi.NameTagged(Options), name); } continue; } if (yi.SetValue != null) { yi.SetValue(obj, ReadValueFunc(yi.Type)()); } else { MergeValueFunc(yi.Type)(yi.GetValue(obj)); } name = GetNextName(false); } if (name != null) { throw Error("Unknown field '{0}'", name); } } } finally { objStack.Pop(); } meta.AfterDeserialization.Run(obj); return(obj); }
protected object ReadAny() { var t = ReadType(); return(t == typeof(object) ? null : ReadValueFunc(t)()); }