Skip to content

Commit

Permalink
Remove buffer copy when writing base64 JSON value (#97687)
Browse files Browse the repository at this point in the history
  • Loading branch information
habbes authored Jan 30, 2024
1 parent 558cde6 commit b76ef7f
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ private void WriteBase64Minimized(ReadOnlySpan<char> escapedPropertyName, ReadOn

output[BytesPending++] = JsonConstants.Quote;

Base64EncodeAndWrite(bytes, output, encodedLength);
Base64EncodeAndWrite(bytes, output);

output[BytesPending++] = JsonConstants.Quote;
}
Expand Down Expand Up @@ -272,7 +272,7 @@ private void WriteBase64Minimized(ReadOnlySpan<byte> escapedPropertyName, ReadOn

output[BytesPending++] = JsonConstants.Quote;

Base64EncodeAndWrite(bytes, output, encodedLength);
Base64EncodeAndWrite(bytes, output);

output[BytesPending++] = JsonConstants.Quote;
}
Expand Down Expand Up @@ -322,7 +322,7 @@ private void WriteBase64Indented(ReadOnlySpan<char> escapedPropertyName, ReadOnl

output[BytesPending++] = JsonConstants.Quote;

Base64EncodeAndWrite(bytes, output, encodedLength);
Base64EncodeAndWrite(bytes, output);

output[BytesPending++] = JsonConstants.Quote;
}
Expand Down Expand Up @@ -373,7 +373,7 @@ private void WriteBase64Indented(ReadOnlySpan<byte> escapedPropertyName, ReadOnl

output[BytesPending++] = JsonConstants.Quote;

Base64EncodeAndWrite(bytes, output, encodedLength);
Base64EncodeAndWrite(bytes, output);

output[BytesPending++] = JsonConstants.Quote;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ private void WriteBase64Minimized(ReadOnlySpan<byte> bytes)
}
output[BytesPending++] = JsonConstants.Quote;

Base64EncodeAndWrite(bytes, output, encodingLength);
Base64EncodeAndWrite(bytes, output);

output[BytesPending++] = JsonConstants.Quote;
}
Expand Down Expand Up @@ -130,7 +130,7 @@ private void WriteBase64Indented(ReadOnlySpan<byte> bytes)

output[BytesPending++] = JsonConstants.Quote;

Base64EncodeAndWrite(bytes, output, encodingLength);
Base64EncodeAndWrite(bytes, output);

output[BytesPending++] = JsonConstants.Quote;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,29 +35,13 @@ private void ValidateWritingValue()
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void Base64EncodeAndWrite(ReadOnlySpan<byte> bytes, Span<byte> output, int encodingLength)
private void Base64EncodeAndWrite(ReadOnlySpan<byte> bytes, Span<byte> output)
{
byte[]? outputText = null;

Span<byte> encodedBytes = encodingLength <= JsonConstants.StackallocByteThreshold ?
stackalloc byte[JsonConstants.StackallocByteThreshold] :
(outputText = ArrayPool<byte>.Shared.Rent(encodingLength));

OperationStatus status = Base64.EncodeToUtf8(bytes, encodedBytes, out int consumed, out int written);
Span<byte> destination = output.Slice(BytesPending);
OperationStatus status = Base64.EncodeToUtf8(bytes, destination, out int consumed, out int written);
Debug.Assert(status == OperationStatus.Done);
Debug.Assert(consumed == bytes.Length);

encodedBytes = encodedBytes.Slice(0, written);
Span<byte> destination = output.Slice(BytesPending);

Debug.Assert(destination.Length >= written);
encodedBytes.Slice(0, written).CopyTo(destination);
BytesPending += written;

if (outputText != null)
{
ArrayPool<byte>.Shared.Return(outputText);
}
}
}
}

0 comments on commit b76ef7f

Please sign in to comment.