public override object FromReaderInt(object obj) { var expectedType = obj.GetType(); if (expectedType == typeof(object)) { throw Error("Unable to read into untyped object"); } if (BinaryOptions.AutoSignature) { CheckSignature(); } if (!ReadCompatibleType(expectedType)) { throw Error("Incompatible type to read into {0}", expectedType.Name); } MergeValueFunc(expectedType)(obj); return(obj); }
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); }