/// <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); } }
/// <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(); }