Example #1
0
        private Dictionary <TKey, TValue> CreateInstance(IEqualityComparer <TKey> comparer, SerializerSession session, uint placeholderReferenceId)
        {
            var result = this.activator.Create(comparer);

            ReferenceCodec.RecordObject(session, result, placeholderReferenceId);
            return(result);
        }
Example #2
0
        public static string ReadValue(ref Reader reader, Field field)
        {
            if (field.WireType == WireType.Reference)
            {
                return(ReferenceCodec.ReadReference <string>(ref reader, field));
            }
            if (field.WireType != WireType.LengthPrefixed)
            {
                ThrowUnsupportedWireTypeException(field);
            }
            var length = reader.ReadVarUInt32();

            string result;

#if NETCOREAPP2_1
            if (reader.TryReadBytes((int)length, out var span))
            {
                result = Encoding.UTF8.GetString(span);
            }
            else
#endif
            {
                var bytes = reader.ReadBytes(length);
                result = Encoding.UTF8.GetString(bytes);
            }

            ReferenceCodec.RecordObject(reader.Session, result);
            return(result);
        }
Example #3
0
        public TField ReadValue <TInput>(ref Reader <TInput> reader, Field field)
        {
            if (field.WireType == WireType.Reference)
            {
                return(ReferenceCodec.ReadReference <TField, TInput>(ref reader, field));
            }

            var placeholderReferenceId = ReferenceCodec.CreateRecordPlaceholder(reader.Session);
            var fieldType = field.FieldType;

            if (fieldType is null || fieldType == CodecFieldType)
            {
                TSurrogate surrogate = default;
                _surrogateSerializer.Deserialize(ref reader, ref surrogate);
                var result = ConvertFromSurrogate(ref surrogate);
                ReferenceCodec.RecordObject(reader.Session, result, placeholderReferenceId);
                return(result);
            }

            // The type is a descendant, not an exact match, so get the specific serializer for it.
            var specificSerializer = reader.Session.CodecProvider.GetCodec(fieldType);

            if (specificSerializer != null)
            {
                return((TField)specificSerializer.ReadValue(ref reader, field));
            }

            ThrowSerializerNotFoundException(fieldType);
            return(null);
        }
Example #4
0
        public T[] ReadValue <TInput>(ref Reader <TInput> reader, Field field)
        {
            if (field.WireType == WireType.Reference)
            {
                return(ReferenceCodec.ReadReference <T[], TInput>(ref reader, field));
            }

            if (field.WireType != WireType.TagDelimited)
            {
                ThrowUnsupportedWireTypeException(field);
            }

            var placeholderReferenceId = ReferenceCodec.CreateRecordPlaceholder(reader.Session);

            T[]  result  = null;
            uint fieldId = 0;
            var  length  = 0;
            var  index   = 0;

            while (true)
            {
                var header = reader.ReadFieldHeader();
                if (header.IsEndBaseOrEndObject)
                {
                    break;
                }

                fieldId += header.FieldIdDelta;
                switch (fieldId)
                {
                case 0:
                    length = Int32Codec.ReadValue(ref reader, header);
                    result = new T[length];
                    ReferenceCodec.RecordObject(reader.Session, result, placeholderReferenceId);
                    break;

                case 1:
                    if (result is null)
                    {
                        return(ThrowLengthFieldMissing());
                    }

                    if (index >= length)
                    {
                        return(ThrowIndexOutOfRangeException(length));
                    }

                    result[index] = _fieldCodec.ReadValue(ref reader, header);
                    ++index;
                    break;

                default:
                    reader.ConsumeUnknownField(header);
                    break;
                }
            }

            return(result);
        }
Example #5
0
        List <T> IFieldCodec <List <T> > .ReadValue <TInput>(ref Reader <TInput> reader, Field field)
        {
            if (field.WireType == WireType.Reference)
            {
                return(ReferenceCodec.ReadReference <List <T>, TInput>(ref reader, field));
            }

            if (field.WireType != WireType.TagDelimited)
            {
                ThrowUnsupportedWireTypeException(field);
            }

            var      placeholderReferenceId = ReferenceCodec.CreateRecordPlaceholder(reader.Session);
            List <T> result  = null;
            uint     fieldId = 0;
            var      length  = 0;
            var      index   = 0;

            while (true)
            {
                var header = reader.ReadFieldHeader();
                if (header.IsEndBaseOrEndObject)
                {
                    break;
                }

                fieldId += header.FieldIdDelta;
                switch (fieldId)
                {
                case 0:
                    length          = Int32Codec.ReadValue(ref reader, header);
                    result          = _activator.Create(length);
                    result.Capacity = length;
                    ReferenceCodec.RecordObject(reader.Session, result, placeholderReferenceId);
                    break;

                case 1:
                    if (result is null)
                    {
                        ThrowLengthFieldMissing();
                    }

                    if (index >= length)
                    {
                        ThrowIndexOutOfRangeException(length);
                    }
                    // ReSharper disable once PossibleNullReferenceException
                    result.Add(_fieldCodec.ReadValue(ref reader, header));
                    ++index;
                    break;

                default:
                    reader.ConsumeUnknownField(header);
                    break;
                }
            }

            return(result);
        }
Example #6
0
        public List <T> ReadValue(Reader reader, SerializerSession session, Field field)
        {
            if (field.WireType == WireType.Reference)
            {
                return(ReferenceCodec.ReadReference <List <T> >(reader, session, field, this.codecProvider));
            }
            if (field.WireType != WireType.TagDelimited)
            {
                ThrowUnsupportedWireTypeException(field);
            }

            var      placeholderReferenceId = ReferenceCodec.CreateRecordPlaceholder(session);
            List <T> result  = null;
            uint     fieldId = 0;
            var      length  = 0;
            var      index   = 0;

            while (true)
            {
                var header = reader.ReadFieldHeader(session);
                if (header.IsEndBaseOrEndObject)
                {
                    break;
                }
                fieldId += header.FieldIdDelta;
                switch (fieldId)
                {
                case 0:
                    length          = this.intCodec.ReadValue(reader, session, header);
                    result          = this.activator.Create(length);
                    result.Capacity = length;
                    ReferenceCodec.RecordObject(session, result, placeholderReferenceId);
                    break;

                case 1:
                    if (result == null)
                    {
                        ThrowLengthFieldMissing();
                    }
                    if (index >= length)
                    {
                        ThrowIndexOutOfRangeException(length);
                    }
                    // ReSharper disable once PossibleNullReferenceException
                    result.Add(this.fieldCodec.ReadValue(reader, session, header));
                    ++index;
                    break;

                default:
                    reader.ConsumeUnknownField(session, header);
                    break;
                }
            }

            return(result);
        }
Example #7
0
        /// <summary>
        /// Consumes an unknown field.
        /// </summary>
        public static void ConsumeUnknownField(this Reader reader, SerializerSession session, Field field)
        {
            // References cannot themselves be referenced.
            if (field.WireType == WireType.Reference)
            {
                reader.ReadVarUInt32();
                return;
            }

            // Record a placeholder so that this field can later be correctly deserialized if it is referenced.
            ReferenceCodec.RecordObject(session, new UnknownFieldMarker(field, reader.CurrentPosition));

            // TODO: Advance the reader without actually reading bytes / allocating.
            switch (field.WireType)
            {
            case WireType.VarInt:
                reader.ReadVarUInt64();
                break;

            case WireType.TagDelimited:
                // Since tag delimited fields can be comprised of other fields, recursively consume those, too.
                ConsumeTagDelimitedField(reader, session);
                break;

            case WireType.LengthPrefixed:
                SkipFieldExtension.SkipLengthPrefixedField(reader);
                break;

            case WireType.Fixed32:
                reader.ReadUInt();
                break;

            case WireType.Fixed64:
                reader.ReadULong();
                break;

            case WireType.Fixed128:
                reader.ReadULong();
                reader.ReadULong();
                break;

            case WireType.Extended:
                SkipFieldExtension.ThrowUnexpectedExtendedWireType(field);
                break;

            default:
                SkipFieldExtension.ThrowUnexpectedWireType(field);
                break;
            }
        }
Example #8
0
        public TField ReadValue <TInput>(ref Reader <TInput> reader, Field field)
        {
            if (field.WireType == WireType.Reference)
            {
                return(ReferenceCodec.ReadReference <TField, TInput>(ref reader, field));
            }

            var        placeholderReferenceId = ReferenceCodec.CreateRecordPlaceholder(reader.Session);
            TSurrogate surrogate = default;

            _surrogateSerializer.Deserialize(ref reader, ref surrogate);
            var result = ConvertFromSurrogate(ref surrogate);

            ReferenceCodec.RecordObject(reader.Session, result, placeholderReferenceId);
            return(result);
        }
Example #9
0
        public static byte[] ReadValue(ref Reader reader, SerializerSession session, Field field)
        {
            if (field.WireType == WireType.Reference)
            {
                return(ReferenceCodec.ReadReference <byte[]>(ref reader, session, field));
            }
            if (field.WireType != WireType.LengthPrefixed)
            {
                ThrowUnsupportedWireTypeException(field);
            }
            var length = reader.ReadVarUInt32();
            var result = reader.ReadBytes(length);

            ReferenceCodec.RecordObject(session, result);
            return(result);
        }
Example #10
0
        byte[] IFieldCodec <byte[]> .ReadValue(Reader reader, SerializerSession session, Field field)
        {
            if (field.WireType == WireType.Reference)
            {
                return(ReferenceCodec.ReadReference <byte[]>(reader, session, field, this.codecProvider));
            }
            if (field.WireType != WireType.LengthPrefixed)
            {
                ThrowUnsupportedWireTypeException(field);
            }
            var length = reader.ReadVarUInt32();
            var result = reader.ReadBytes((int)length);

            ReferenceCodec.RecordObject(session, result);
            return(result);
        }
Example #11
0
        public static object ReadValue(ref Reader reader, Field field)
        {
            if (field.WireType == WireType.Reference)
            {
                return(ReferenceCodec.ReadReference <object>(ref reader, field));
            }
            if (field.FieldType == ObjectType || field.FieldType == null)
            {
                reader.ReadVarUInt32();
                var result = new object();
                ReferenceCodec.RecordObject(reader.Session, result);
                return(result);
            }

            var specificSerializer = reader.Session.CodecProvider.GetCodec(field.FieldType);

            return(specificSerializer.ReadValue(ref reader, field));
        }
Example #12
0
        Tuple <T> IFieldCodec <Tuple <T> > .ReadValue <TInput>(ref Reader <TInput> reader, Field field)
        {
            if (field.WireType == WireType.Reference)
            {
                return(ReferenceCodec.ReadReference <Tuple <T>, TInput>(ref reader, field));
            }

            if (field.WireType != WireType.TagDelimited)
            {
                ThrowUnsupportedWireTypeException(field);
            }

            var  placeholderReferenceId = ReferenceCodec.CreateRecordPlaceholder(reader.Session);
            var  item1   = default(T);
            uint fieldId = 0;

            while (true)
            {
                var header = reader.ReadFieldHeader();
                if (header.IsEndBaseOrEndObject)
                {
                    break;
                }

                fieldId += header.FieldIdDelta;
                switch (fieldId)
                {
                case 1:
                    item1 = _valueCodec.ReadValue(ref reader, header);
                    break;

                default:
                    reader.ConsumeUnknownField(header);
                    break;
                }
            }

            var result = new Tuple <T>(item1);

            ReferenceCodec.RecordObject(reader.Session, result, placeholderReferenceId);
            return(result);
        }
Example #13
0
        public Tuple <T> ReadValue(Reader reader, SerializerSession session, Field field)
        {
            if (field.WireType != WireType.TagDelimited)
            {
                ThrowUnsupportedWireTypeException(field);
            }

            var  placeholderReferenceId = ReferenceCodec.CreateRecordPlaceholder(session);
            var  item1   = default(T);
            uint fieldId = 0;

            while (true)
            {
                var header = reader.ReadFieldHeader(session);
                if (header.IsEndBaseOrEndObject)
                {
                    break;
                }
                fieldId += header.FieldIdDelta;
                switch (fieldId)
                {
                case 0:
                    item1 = this.valueCodec.ReadValue(reader, session, header);
                    break;

                default:
                    reader.ConsumeUnknownField(session, header);
                    break;
                }
            }

            var result = new Tuple <T>(item1);

            ReferenceCodec.RecordObject(session, result, placeholderReferenceId);
            return(result);
        }
        public object ReadValue(ref Reader reader, SerializerSession session, Field field)
        {
            if (field.WireType == WireType.Reference)
            {
                return(ReferenceCodec.ReadReference <T[]>(ref reader, session, field));
            }
            if (field.WireType != WireType.TagDelimited)
            {
                ThrowUnsupportedWireTypeException(field);
            }

            var   placeholderReferenceId = ReferenceCodec.CreateRecordPlaceholder(session);
            Array result  = null;
            uint  fieldId = 0;

            int[] lengths = null;
            int[] indices = null;
            var   rank    = 0;

            while (true)
            {
                var header = reader.ReadFieldHeader(session);
                if (header.IsEndBaseOrEndObject)
                {
                    break;
                }
                fieldId += header.FieldIdDelta;
                switch (fieldId)
                {
                case 0:
                {
                    lengths = this.intArrayCodec.ReadValue(ref reader, session, header);
                    rank    = lengths.Length;

                    // Multi-dimensional arrays must be indexed using indexing arrays, so create one now.
                    indices = new int[rank];
                    result  = Array.CreateInstance(typeof(T), lengths);
                    ReferenceCodec.RecordObject(session, result, placeholderReferenceId);
                    break;
                }

                case 1:
                {
                    if (result == null)
                    {
                        return(ThrowLengthsFieldMissing());
                    }
                    var element = this.elementCodec.ReadValue(ref reader, session, header);
                    result.SetValue(element, indices);

                    // Increment the indices array by 1.
                    var idx = rank - 1;
                    while (idx >= 0 && ++indices[idx] >= lengths[idx])
                    {
                        indices[idx] = 0;
                        --idx;
                    }

                    break;
                }

                default:
                    reader.ConsumeUnknownField(session, header);
                    break;
                }
            }

            return(result);
        }