/// <inheritdoc/>
    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 == _fieldType)
        {
            TSurrogate surrogate = default;
            _surrogateSerializer.Deserialize(ref reader, ref surrogate);
            var result = _converter.ConvertFromSurrogate(in 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(default);
Exemple #2
0
    object IFieldCodec <object> .ReadValue <TInput>(ref Reader <TInput> reader, Field field)
    {
        if (field.WireType == WireType.Reference)
        {
            return(ReferenceCodec.ReadReference <object, TInput>(ref reader, field));
        }

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

        var    placeholderReferenceId = ReferenceCodec.CreateRecordPlaceholder(reader.Session);
        object result  = null;
        Type   type    = null;
        uint   fieldId = 0;

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

            fieldId += header.FieldIdDelta;
            switch (fieldId)
            {
            case 0:
                ReferenceCodec.MarkValueField(reader.Session);
                type = reader.Session.TypeCodec.ReadLengthPrefixed(ref reader);
                break;

            case 1:
                if (type is null)
                {
                    ThrowTypeFieldMissing();
                }

                // To possibly improve efficiency, this could be converted to read a ReadOnlySequence<byte> instead of a byte array.
                var serializedValue = StringCodec.ReadValue(ref reader, header);
                result = JsonConvert.DeserializeObject(serializedValue, type, _options.SerializerSettings);
                ReferenceCodec.RecordObject(reader.Session, result, placeholderReferenceId);
                break;

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

        return(result);
    }
Exemple #3
0
        public object ReadValue(ref Reader reader, SerializerSession session, Field field)
        {
            if (field.WireType == WireType.Reference)
            {
                return(ReferenceCodec.ReadReference(ref reader, session, field, null));
            }

            var placeholderReferenceId = ReferenceCodec.CreateRecordPlaceholder(session);
            var header = reader.ReadFieldHeader(session);

            var type = this.typeCodec.ReadValue(ref reader, session, header);

            if (type.IsValueType)
            {
                var serializer = this.valueTypeSerializerFactory.GetSerializer(type);
                return(serializer.ReadValue(ref reader, session, type, placeholderReferenceId));
            }

            return(this.objectSerializer.ReadValue(ref reader, session, type, placeholderReferenceId));
        }
        public object ReadValue <TInput>(ref Reader <TInput> reader, Field field)
        {
            if (field.WireType == WireType.Reference)
            {
                return(ReferenceCodec.ReadReference <object, TInput>(ref reader, field));
            }

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

            var type = _typeCodec.ReadValue(ref reader, header);

            if (type.IsValueType)
            {
                var serializer = _valueTypeSerializerFactory.GetSerializer(type);
                return(serializer.ReadValue(ref reader, type, placeholderReferenceId));
            }

            return(_objectSerializer.ReadValue(ref reader, type, placeholderReferenceId));
        }
Exemple #5
0
    /// <inheritdoc/>
    object IFieldCodec <object> .ReadValue <TInput>(ref Reader <TInput> reader, Field field)
    {
        if (field.WireType == WireType.Reference)
        {
            return(ReferenceCodec.ReadReference <object, TInput>(ref reader, field));
        }

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

        var    placeholderReferenceId = ReferenceCodec.CreateRecordPlaceholder(reader.Session);
        object result  = null;
        Type   type    = null;
        uint   fieldId = 0;

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

            fieldId += header.FieldIdDelta;
            switch (fieldId)
            {
            case 0:
                ReferenceCodec.MarkValueField(reader.Session);
                type = reader.Session.TypeCodec.ReadLengthPrefixed(ref reader);
                break;

            case 1:
                if (type is null)
                {
                    ThrowTypeFieldMissing();
                }

                ReferenceCodec.MarkValueField(reader.Session);
                var length = reader.ReadVarUInt32();

                // To possibly improve efficiency, this could be converted to read a ReadOnlySequence<byte> instead of a byte array.
                ReadOnlySequence <byte> sequence = default;
                var tempBuffer = new PooledArrayBufferWriter();
                try
                {
                    reader.ReadBytes(ref tempBuffer, (int)length);
                    sequence = tempBuffer.RentReadOnlySequence();
                    var jsonReader = new Utf8JsonReader(sequence, _options.ReaderOptions);
                    result = JsonSerializer.Deserialize(ref jsonReader, type, _options.SerializerOptions);
                }
                finally
                {
                    tempBuffer.ReturnReadOnlySequence(sequence);
                    tempBuffer.Reset();
                }

                break;

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

        ReferenceCodec.RecordObject(reader.Session, result, placeholderReferenceId);
        return(result);
    }