public void WriteField <TBufferWriter>(ref Writer <TBufferWriter> writer,
                                        uint fieldIdDelta,
                                        Type expectedType,
                                        SerializationEntrySurrogate value) where TBufferWriter : IBufferWriter <byte>
 {
     ReferenceCodec.MarkValueField(writer.Session);
     writer.WriteFieldHeader(fieldIdDelta, expectedType, SerializationEntryType, WireType.TagDelimited);
     StringCodec.WriteField(ref writer, 0, typeof(string), value.Name);
     ObjectCodec.WriteField(ref writer, 1, typeof(object), value.Value);
     writer.WriteEndObject();
 }
    public unsafe IdSpan ReadValue <TInput>(ref Reader <TInput> reader, Field field)
    {
        ReferenceCodec.MarkValueField(reader.Session);

        var length   = reader.ReadVarUInt32() - sizeof(int);
        var hashCode = reader.ReadInt32();

        var payloadArray = reader.ReadBytes(length);
        var value        = IdSpan.UnsafeCreate(payloadArray, hashCode);

        return(value);
    }
Beispiel #3
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);
    }
Beispiel #4
0
 public void WriteField(
     Writer writer,
     SerializerSession session,
     uint fieldIdDelta,
     Type expectedType,
     SerializationEntrySurrogate value)
 {
     ReferenceCodec.MarkValueField(session);
     writer.WriteFieldHeader(session, fieldIdDelta, expectedType, SerializationEntryType, WireType.TagDelimited);
     this.stringCodec.WriteField(writer, session, 0, typeof(string), value.Name);
     this.objectCodec.WriteField(writer, session, 1, typeof(object), value.Value);
     writer.WriteEndObject();
 }
Beispiel #5
0
        void IFieldCodec <ValueTuple <T> > .WriteField <TBufferWriter>(
            ref Writer <TBufferWriter> writer,
            uint fieldIdDelta,
            Type expectedType,
            ValueTuple <T> value)
        {
            ReferenceCodec.MarkValueField(writer.Session);
            writer.WriteFieldHeader(fieldIdDelta, expectedType, value.GetType(), WireType.TagDelimited);

            _valueCodec.WriteField(ref writer, 1, typeof(T), value.Item1);

            writer.WriteEndObject();
        }
Beispiel #6
0
        public void WriteField <TBufferWriter>(ref Writer <TBufferWriter> writer, uint fieldIdDelta, Type expectedType, SiloAddress value) where TBufferWriter : IBufferWriter <byte>
        {
            if (value is null)
            {
                ReferenceCodec.WriteNullReference(ref writer, fieldIdDelta, expectedType);
                return;
            }

            ReferenceCodec.MarkValueField(writer.Session);
            writer.WriteStartObject(fieldIdDelta, expectedType, _codecFieldType);
            IPEndPointCodec.WriteField(ref writer, 0U, _iPEndPointType, value.Endpoint);
            Int32Codec.WriteField(ref writer, 1U, _int32Type, value.Generation);
            writer.WriteEndObject();
        }
Beispiel #7
0
    public unsafe IdSpan ReadValue <TInput>(ref Reader <TInput> reader, Field field)
    {
        ReferenceCodec.MarkValueField(reader.Session);

        byte[] payloadArray = default;
        var    length       = reader.ReadVarUInt32() - sizeof(int);
        var    hashCode     = reader.ReadInt32();

        if (!reader.TryReadBytes((int)length, out var payloadSpan))
        {
            payloadSpan = payloadArray = reader.ReadBytes(length);
        }

        // Search through
        var candidateHashCode = hashCode;

        while (_cache.TryGetValue(candidateHashCode, out var existing))
        {
            if (existing.GetHashCode() != hashCode)
            {
                break;
            }

            var existingSpan = new ReadOnlySpan <byte>(IdSpan.UnsafeGetArray(existing));
            if (existingSpan.SequenceEqual(payloadSpan))
            {
                return(existing);
            }

            // Try the next slot.
            ++candidateHashCode;
        }

        if (payloadArray is null)
        {
            payloadArray = new byte[length];
            payloadSpan.CopyTo(payloadArray);
        }

        var value = IdSpan.UnsafeCreate(payloadArray, hashCode);

        while (!_cache.TryAdd(candidateHashCode++, value))
        {
            // Insert the value at the first available position.
        }

        return(value);
    }
    public void WriteField <TBufferWriter>(
        ref Writer <TBufferWriter> writer,
        uint fieldIdDelta,
        Type expectedType,
        IdSpan value)
        where TBufferWriter : IBufferWriter <byte>
    {
        ReferenceCodec.MarkValueField(writer.Session);
        writer.WriteFieldHeaderExpected(fieldIdDelta, WireType.LengthPrefixed);
        var hashCode    = value.GetHashCode();
        var bytes       = IdSpan.UnsafeGetArray(value);
        var bytesLength = value.IsDefault ? 0 : bytes.Length;

        writer.WriteVarUInt32((uint)(sizeof(int) + bytesLength));
        writer.WriteInt32(hashCode);
        writer.Write(bytes);
    }
Beispiel #9
0
    /// <inheritdoc/>
    void IFieldCodec <object> .WriteField <TBufferWriter>(ref Writer <TBufferWriter> writer, uint fieldIdDelta, Type expectedType, object value)
    {
        if (ReferenceCodec.TryWriteReferenceField(ref writer, fieldIdDelta, expectedType, value))
        {
            return;
        }

        // The schema type when serializing the field is the type of the codec.
        // In practice it could be any unique type as long as this codec is registered as the handler.
        // By checking against the codec type in IsSupportedType, the codec could also just be registered as an IGenericCodec.
        // Note that the codec is responsible for serializing the type of the value itself.
        writer.WriteFieldHeader(fieldIdDelta, expectedType, SelfType, WireType.TagDelimited);

        var type = value.GetType();

        // Write the type name
        ReferenceCodec.MarkValueField(writer.Session);
        writer.WriteFieldHeader(0, typeof(byte[]), typeof(byte[]), WireType.LengthPrefixed);
        writer.Session.TypeCodec.WriteLengthPrefixed(ref writer, type);

        // Write the serialized payload
        // Note that the Utf8JsonWriter and PooledArrayBufferWriter could be pooled as long as they're correctly
        // reset at the end of each use.
        var bufferWriter = new BufferWriterBox <PooledArrayBufferWriter>(new PooledArrayBufferWriter());

        try
        {
            using var jsonWriter = new Utf8JsonWriter(bufferWriter);
            JsonSerializer.Serialize(jsonWriter, value, _options.SerializerOptions);
            jsonWriter.Flush();

            ReferenceCodec.MarkValueField(writer.Session);
            writer.WriteFieldHeader(1, typeof(byte[]), typeof(byte[]), WireType.LengthPrefixed);
            writer.WriteVarUInt32((uint)bufferWriter.Value.Length);
            bufferWriter.Value.CopyTo(ref writer);
        }
        finally
        {
            bufferWriter.Value.Dispose();
        }

        writer.WriteEndObject();
    }
Beispiel #10
0
        public SiloAddress ReadValue <TReaderInput>(ref Reader <TReaderInput> reader, Field field)
        {
            if (field.WireType == WireType.Reference)
            {
                return(ReferenceCodec.ReadReference <SiloAddress, TReaderInput>(ref reader, field));
            }

            ReferenceCodec.MarkValueField(reader.Session);
            int        id         = 0;
            Field      header     = default;
            IPEndPoint endpoint   = default;
            int        generation = default;

            while (true)
            {
                id = OrleansGeneratedCodeHelper.ReadHeader(ref reader, ref header, id);
                if (id == 0)
                {
                    endpoint = IPEndPointCodec.ReadValue(ref reader, header);
                    id       = OrleansGeneratedCodeHelper.ReadHeader(ref reader, ref header, id);
                }

                if (id == 1)
                {
                    generation = Int32Codec.ReadValue(ref reader, header);
                    id         = OrleansGeneratedCodeHelper.ReadHeaderExpectingEndBaseOrEndObject(ref reader, ref header, id);
                }

                if (id == -1)
                {
                    break;
                }

                reader.ConsumeUnknownField(header);
            }

            return(SiloAddress.New(endpoint, generation));
        }
        public SerializationEntrySurrogate ReadValue <TInput>(ref Reader <TInput> reader, Field field)
        {
            ReferenceCodec.MarkValueField(reader.Session);
            var  result  = new SerializationEntrySurrogate();
            uint fieldId = 0;

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

                fieldId += header.FieldIdDelta;
                switch (fieldId)
                {
                case 0:
                    result.Name = StringCodec.ReadValue(ref reader, header);
                    break;

                case 1:
                    result.Value = ObjectCodec.ReadValue(ref reader, header);
                    break;

                case 2:
                    result.ObjectType = TypeSerializerCodec.ReadValue(ref reader, header);
                    break;

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

            return(result);
        }
Beispiel #12
0
        private static void FormatField <TInput>(ref Reader <TInput> reader, Field field, string typeName, uint id, StringBuilder res, int indentation)
        {
            var indentString = new string(' ', indentation);

            AppendAddress(ref reader, res);
            res.Append(indentString);

            // References cannot themselves be referenced.
            if (field.WireType == WireType.Reference)
            {
                ReferenceCodec.MarkValueField(reader.Session);
                var refId  = reader.ReadVarUInt32();
                var exists = reader.Session.ReferencedObjects.TryGetReferencedObject(refId, out var refd);
                res.Append('[');
                FormatFieldHeader(res, reader.Session, field, id, typeName);
                res.Append($" Reference: {refId} ({(exists ? $"{refd}" : "unknown")})");
                res.Append(']');
                return;
            }

            // Record a placeholder so that this field can later be correctly deserialized if it is referenced.
            ReferenceCodec.RecordObject(reader.Session, new UnknownFieldMarker(field, reader.Position));
            res.Append('[');
            FormatFieldHeader(res, reader.Session, field, id, typeName);
            res.Append(']');
            res.Append(" Value: ");

            switch (field.WireType)
            {
            case WireType.VarInt:
            {
                var a = reader.ReadVarUInt64();
                if (a < 10240)
                {
                    res.Append($"{a} (0x{a:X})");
                }
                else
                {
                    res.Append($"0x{a:X}");
                }
            }
            break;

            case WireType.TagDelimited:
                // Since tag delimited fields can be comprised of other fields, recursively consume those, too.

                res.Append($"{{\n");
                reader.FormatTagDelimitedField(res, indentation + 1);
                res.AppendLine();
                AppendAddress(ref reader, res);
                res.Append($"{indentString}}}");
                break;

            case WireType.LengthPrefixed:
            {
                var length = reader.ReadVarUInt32();
                res.Append($"(length: {length}b) [");
                var a = reader.ReadBytes(length);
                FormatByteArray(res, a);
                res.Append(']');
            }
            break;

            case WireType.Fixed32:
            {
                var a = reader.ReadUInt32();
                if (a < 10240)
                {
                    res.Append($"{a} (0x{a:X})");
                }
                else
                {
                    res.Append($"0x{a:X}");
                }
            }
            break;

            case WireType.Fixed64:
            {
                var a = reader.ReadUInt64();
                if (a < 10240)
                {
                    res.Append($"{a} (0x{a:X})");
                }
                else
                {
                    res.Append($"0x{a:X}");
                }
            }
            break;

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

            default:
                SkipFieldExtension.ThrowUnexpectedWireType(field);
                break;
            }
        }
        public void DeserializeNew <TInput>(ref global::Hagar.Buffers.Reader <TInput> reader, global::Benchmarks.Models.IntClass instance)
        {
            int   id     = 0;
            Field header = default;

            while (true)
            {
                id = ReadHeader(ref reader, ref header, id);

                if (id == 0)
                {
                    ReferenceCodec.MarkValueField(reader.Session);
                    instance.MyProperty1 = reader.ReadInt32(header.WireType);
                    id = ReadHeader(ref reader, ref header, id);
                }

                if (id == 1)
                {
                    ReferenceCodec.MarkValueField(reader.Session);
                    instance.MyProperty2 = reader.ReadInt32(header.WireType);
                    id = ReadHeader(ref reader, ref header, id);
                }

                if (id == 2)
                {
                    ReferenceCodec.MarkValueField(reader.Session);
                    instance.MyProperty3 = reader.ReadInt32(header.WireType);
                    id = ReadHeader(ref reader, ref header, id);
                }

                if (id == 3)
                {
                    ReferenceCodec.MarkValueField(reader.Session);
                    instance.MyProperty4 = reader.ReadInt32(header.WireType);
                    id = ReadHeader(ref reader, ref header, id);
                }

                if (id == 4)
                {
                    ReferenceCodec.MarkValueField(reader.Session);
                    instance.MyProperty5 = reader.ReadInt32(header.WireType);
                    id = ReadHeader(ref reader, ref header, id);
                }

                if (id == 5)
                {
                    ReferenceCodec.MarkValueField(reader.Session);
                    instance.MyProperty6 = reader.ReadInt32(header.WireType);
                    id = ReadHeader(ref reader, ref header, id);
                }

                if (id == 6)
                {
                    ReferenceCodec.MarkValueField(reader.Session);
                    instance.MyProperty7 = reader.ReadInt32(header.WireType);
                    id = ReadHeader(ref reader, ref header, id);
                }

                if (id == 7)
                {
                    ReferenceCodec.MarkValueField(reader.Session);
                    instance.MyProperty8 = reader.ReadInt32(header.WireType);
                    id = ReadHeader(ref reader, ref header, id);
                }

                if (id == 8)
                {
                    ReferenceCodec.MarkValueField(reader.Session);
                    instance.MyProperty9 = reader.ReadInt32(header.WireType);
                    id = ReadHeaderExpectingEndBaseOrEndObject(ref reader, ref header, id);
                }

                if (id == -1)
                {
                    break;
                }

                reader.ConsumeUnknownField(header);
            }
        }
Beispiel #14
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);
    }