Skip to content

Commit

Permalink
Fix PooledByteBufferWriter handling of sizeHint <= 0 (dotnet#110031)
Browse files Browse the repository at this point in the history
* Fix PooledByteBufferWriter handling of sizeHint <= 0

* Add MinimumBufferSize constant and update usage
  • Loading branch information
stephentoub authored and mikelle-rogers committed Dec 4, 2024
1 parent 13bbe8d commit ee2668d
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Buffers;
Expand All @@ -8,19 +8,20 @@ namespace System.Net.ServerSentEvents
{
internal sealed class PooledByteBufferWriter : IBufferWriter<byte>, IDisposable
{
private const int MinimumBufferSize = 256;
private ArrayBuffer _buffer = new(initialSize: 256, usePool: true);

public void Advance(int count) => _buffer.Commit(count);

public Memory<byte> GetMemory(int sizeHint = 0)
{
_buffer.EnsureAvailableSpace(sizeHint);
_buffer.EnsureAvailableSpace(Math.Max(sizeHint, MinimumBufferSize));
return _buffer.AvailableMemory;
}

public Span<byte> GetSpan(int sizeHint = 0)
{
_buffer.EnsureAvailableSpace(sizeHint);
_buffer.EnsureAvailableSpace(Math.Max(sizeHint, MinimumBufferSize));
return _buffer.AvailableSpan;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Buffers;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.Json;
Expand Down Expand Up @@ -117,6 +118,35 @@ async IAsyncEnumerable<SseItem<string>> GetItemsAsync([EnumeratorCancellation] C
}
}

[Fact]
public static async Task WriteLargeItems_DataWrittenSuccessfully()
{
const int NumberOfItems = 10;
byte[] expected = Encoding.UTF8.GetBytes(string.Concat(Enumerable.Repeat("This is a test. This is only a test.", 100)));

MemoryStream memoryStream = new();
await SseFormatter.WriteAsync(GetBuffersAsync(), memoryStream, (item, writer) => writer.Write(item.Data));

memoryStream.Position = 0;
int count = 0;
foreach (SseItem<byte[]> item in SseParser.Create(memoryStream, (eventType, data) => data.ToArray()).Enumerate())
{
Assert.Equal(expected, item.Data);
count++;
}

Assert.Equal(NumberOfItems, count);

async IAsyncEnumerable<SseItem<byte[]>> GetBuffersAsync()
{
await Task.Yield();
for (int i = 0; i < NumberOfItems; i++)
{
yield return new SseItem<byte[]>(expected);
}
}
}

[Fact]
public static async Task WriteAsync_ParserCanRoundtripJsonEvents()
{
Expand Down

0 comments on commit ee2668d

Please sign in to comment.