예제 #1
0
    /// <inheritdoc/>
    object IDeepCopier <object> .DeepCopy(object input, CopyContext context)
    {
        if (input is null)
        {
            return(null);
        }

        var bufferWriter = new BufferWriterBox <PooledArrayBufferWriter>(new PooledArrayBufferWriter());

        using var jsonWriter = new Utf8JsonWriter(bufferWriter);
        JsonSerializer.Serialize(jsonWriter, input, _options.SerializerOptions);
        var sequence = bufferWriter.Value.RentReadOnlySequence();

        try
        {
            var jsonReader = new Utf8JsonReader(sequence, _options.ReaderOptions);
            var result     = JsonSerializer.Deserialize(ref jsonReader, input.GetType(), _options.SerializerOptions);
            context.RecordCopy(input, result);
            return(result);
        }
        finally
        {
            bufferWriter.Value.ReturnReadOnlySequence(sequence);
        }
    }
예제 #2
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();
    }