Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 45 additions & 9 deletions src/Npgsql/Internal/TypeHandlers/JsonHandler.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Buffers;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Text;
Expand Down Expand Up @@ -65,10 +66,8 @@ protected internal override int ValidateAndGetLengthCustom<TAny>([DisallowNull]
if (lengthCache.IsPopulated)
return lengthCache.Get();

var data = SerializeJsonDocument((JsonDocument)(object)value!);
if (parameter != null)
parameter.ConvertedValue = data;
return lengthCache.Set(data.Length + _headerLen);
var paramLength = GetSizeOfSerializedValue(parameter, (object)value!);
return lengthCache.Set(paramLength + _headerLen);
}

// User POCO, need to serialize. At least internally ArrayPool buffers are used...
Expand All @@ -79,6 +78,28 @@ protected internal override int ValidateAndGetLengthCustom<TAny>([DisallowNull]
return _textHandler.ValidateAndGetLength(s, ref lengthCache, parameter) + _headerLen;
}

private int GetSizeOfSerializedValue(NpgsqlParameter? parameter, object value)
{
if (parameter?.ConvertedValue != null)
{
if (parameter.ConvertedValue is ReadOnlySequence<byte> sequence)
{
return (int)sequence.Length;
}
else
{
return ((byte[])parameter.ConvertedValue).Length;
}
}
var serializedBytes = SerializeJsonDocument((JsonDocument)value);
if (parameter != null)
{
parameter.ConvertedValue = serializedBytes;
}

return serializedBytes.Length;
}

/// <inheritdoc />
protected override async Task WriteWithLengthCustom<TAny>([DisallowNull] TAny value, NpgsqlWriteBuffer buf, NpgsqlLengthCache? lengthCache, NpgsqlParameter? parameter, bool async, CancellationToken cancellationToken = default)
{
Expand All @@ -104,10 +125,25 @@ protected override async Task WriteWithLengthCustom<TAny>([DisallowNull] TAny va
await _textHandler.Write((byte[])(object)value!, buf, lengthCache, parameter, async, cancellationToken);
else if (typeof(TAny) == typeof(JsonDocument))
{
var data = parameter?.ConvertedValue != null
? (byte[])parameter.ConvertedValue
: SerializeJsonDocument((JsonDocument)(object)value!);
await buf.WriteBytesRaw(data, async, cancellationToken);
if (parameter?.ConvertedValue != null)
{
if (parameter.ConvertedValue is ReadOnlySequence<byte> sequence)
{
foreach (var segment in sequence)
{
buf.DirectWrite(segment.Span);
}
}
else
{
await buf.WriteBytesRaw((byte[])parameter.ConvertedValue, async, cancellationToken);
}
}
else
{
var data = SerializeJsonDocument((JsonDocument)(object)value!);
await buf.WriteBytesRaw(data, async, cancellationToken);
}
}
else
{
Expand Down Expand Up @@ -227,4 +263,4 @@ byte[] SerializeJsonDocument(JsonDocument document)
writer.Flush();
return stream.ToArray();
}
}
}