public override bool TryRead(ref ReadOnlySpan <byte> remaining, out Dictionary <string, T> result, PropertyMap propMap = null) { result = default; if (EtfReader.TryReadNullSafe(ref remaining)) { result = null; return(true); } remaining = remaining.Slice(1); uint length = BinaryPrimitives.ReadUInt32BigEndian(remaining); remaining = remaining.Slice(4); result = new Dictionary <string, T>(); // TODO: We need a resizable dictionary w/ pooling for (int i = 0; i < length; i++) { if (!EtfReader.TryReadString(ref remaining, out var key)) { return(false); } if (!_innerConverter.TryRead(ref remaining, out var value, propMap)) { return(false); } if (result.ContainsKey(key)) { return(false); } result[key] = value; } return(true); }
public override bool TryRead(ref ReadOnlySpan <byte> remaining, out Utf8String result, PropertyMap propMap = null) { if (EtfReader.TryReadNullSafe(ref remaining)) { result = null; return(true); } return(EtfReader.TryReadUtf8String(ref remaining, out result)); }
public override bool TryRead(ref ReadOnlySpan <byte> remaining, out T[] result, PropertyMap propMap = null) { if (EtfReader.TryReadNullSafe(ref remaining)) { result = null; return(true); } if (!JsonCollectionReader.TryRead(_serializer, ref remaining, out result, propMap, _innerConverter, _pool, _serializer.Pool)) { return(false); } return(true); }
public override bool TryRead(ref ReadOnlySpan <byte> remaining, out T?result, PropertyMap propMap = null) { result = null; if (EtfReader.TryReadNullSafe(ref remaining)) { return(true); } if (!_innerConverter.TryRead(ref remaining, out var resultValue, propMap)) { return(false); } result = resultValue; return(true); }
public override bool TryRead(ref ReadOnlySpan <byte> remaining, out List <T> result, PropertyMap propMap = null) { if (EtfReader.TryReadNullSafe(ref remaining)) { result = null; return(true); } if (!JsonCollectionReader.TryRead(_serializer, ref remaining, out var resultArray, propMap, _innerConverter, _pool, _serializer.Pool)) { result = default; return(false); } result = new List <T>(resultArray); // TODO: This is probably inefficient 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); } }