public override bool TryRead(ref ReadOnlySpan <byte> remaining, out T result, PropertyMap propMap = null) { result = default; switch (JsonReader.GetTokenType(ref remaining)) { case JsonTokenType.StartObject: break; case JsonTokenType.Null: remaining = remaining.Slice(4); result = null; return(true); default: return(false); } remaining = remaining.Slice(1); result = _map.CreateUninitialized();; if (JsonReader.GetTokenType(ref remaining) == JsonTokenType.EndObject) { remaining = remaining.Slice(1); return(true); } uint dependencies = 0; var deferred = new DeferredPropertyList <byte, byte>(); bool isFirst = true; bool incomplete = true; while (incomplete) { switch (JsonReader.GetTokenType(ref remaining)) { case JsonTokenType.None: return(false); case JsonTokenType.EndObject: remaining = remaining.Slice(1); incomplete = false; continue; case JsonTokenType.ListSeparator: if (isFirst) { return(false); } remaining = remaining.Slice(1); break; default: if (!isFirst) { return(false); } isFirst = false; break; } if (!JsonReader.TryReadUtf8String(ref remaining, out var key)) { return(false); } if (JsonReader.GetTokenType(ref remaining) != JsonTokenType.KeyValueSeparator) { return(false); } remaining = remaining.Slice(1); // Unknown Property if (!_map.TryGetProperty(key, out var innerPropMap, out bool isIgnored)) { if (!isIgnored) { _serializer.RaiseUnknownProperty(_map, key); } if (!JsonReader.Skip(ref remaining, out _)) { return(false); } continue; } if (!innerPropMap.CanRead) { return(false); } // Property depends on another that hasn't been deserialized yet if (!innerPropMap.HasReadConverter(result, dependencies)) { if (!JsonReader.Skip(ref remaining, out var skipped)) { return(false); } if (!deferred.Add(key, skipped)) { return(false); } continue; } var restore = remaining; if (!innerPropMap.TryRead(result, ref remaining, dependencies)) { if (innerPropMap.IgnoreErrors) { remaining = restore; if (!JsonReader.Skip(ref remaining, out var skipped)) { return(false); } _serializer.RaiseFailedProperty(_map, innerPropMap); continue; } else { return(false); } } dependencies |= innerPropMap.IndexMask; } // Process all deferred properties for (int i = 0; i < deferred.Count; i++) { if (!_map.TryGetProperty(deferred.GetKey(i), out var innerPropMap, out bool isIgnored)) { return(false); } var value = deferred.GetValue(i); if (!innerPropMap.TryRead(result, ref value, dependencies)) { if (innerPropMap.IgnoreErrors) { _serializer.RaiseFailedProperty(_map, innerPropMap); } else { return(false); } } } return(true); }
public override bool TryRead(ref ReadOnlySpan <byte> remaining, out T result, PropertyMap propMap = null) { if (EtfReader.TryReadNullSafe(ref remaining)) { result = null; return(true); } result = default; switch (EtfReader.GetTokenType(ref remaining)) { case EtfTokenType.Map: if (remaining.Length < 5) { return(false); } remaining = remaining.Slice(1); uint arity = BinaryPrimitives.ReadUInt32BigEndian(remaining); // count remaining = remaining.Slice(4); result = _map.CreateUninitialized(); if (arity == 0) { return(true); } uint dependencies = 0; var deferred = new DeferredPropertyList <byte, byte>(); for (int i = 0; i < arity; i++) { if (!EtfReader.TryReadUtf8String(ref remaining, out var key)) { return(false); } // Unknown Property if (!_map.TryGetProperty(key, out var innerPropMap, out bool isIgnored)) { if (!isIgnored) { _serializer.RaiseUnknownProperty(_map, key); } if (!EtfReader.Skip(ref remaining, out _)) { return(false); } continue; } if (!innerPropMap.CanRead) { return(false); } // Property depends on another that hasn't been deserialized yet if (!innerPropMap.HasReadConverter(result, dependencies)) { if (!EtfReader.Skip(ref remaining, out var skipped)) { return(false); } if (!deferred.Add(key, skipped)) { return(false); } continue; } var restore = remaining; if (!innerPropMap.TryRead(result, ref remaining, dependencies)) { if (innerPropMap.IgnoreErrors) { remaining = restore; if (!EtfReader.Skip(ref remaining, out var skipped)) { return(false); } _serializer.RaiseFailedProperty(_map, innerPropMap); continue; } else { return(false); } } dependencies |= innerPropMap.IndexMask; } // Process all deferred properties for (int i = 0; i < deferred.Count; i++) { if (!_map.TryGetProperty(deferred.GetKey(i), out var innerPropMap, out _)) { return(false); } var value = deferred.GetValue(i); if (!innerPropMap.TryRead(result, ref value, dependencies)) { if (innerPropMap.IgnoreErrors) { _serializer.RaiseFailedProperty(_map, innerPropMap); } else { return(false); } } } return(true); default: return(false); } }