Example #1
0
        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));
 }
Example #3
0
        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);
        }
Example #4
0
        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);
        }
Example #5
0
        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);
            }
        }