Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bb9ba7a

Browse files
AlexRadchjozkee
andauthored
Added ArrayBufferWriter<T>.ResetWrittenCount() (#88009)
Co-authored-by: David Cantú <[email protected]>
1 parent 64a6771 commit bb9ba7a

File tree

4 files changed

+124
-24
lines changed

4 files changed

+124
-24
lines changed

src/libraries/Common/src/System/Buffers/ArrayBufferWriter.cs

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,36 @@ public ArrayBufferWriter(int initialCapacity)
8181
/// Clears the data written to the underlying buffer.
8282
/// </summary>
8383
/// <remarks>
84-
/// You must clear the <see cref="ArrayBufferWriter{T}"/> before trying to re-use it.
84+
/// <para>
85+
/// You must reset or clear the <see cref="ArrayBufferWriter{T}"/> before trying to re-use it.
86+
/// </para>
87+
/// <para>
88+
/// The <see cref="ResetWrittenCount"/> method is faster since it only sets to zero the writer's index
89+
/// while the <see cref="Clear"/> method additionally zeroes the content of the underlying buffer.
90+
/// </para>
8591
/// </remarks>
92+
/// <seealso cref="ResetWrittenCount"/>
8693
public void Clear()
8794
{
8895
Debug.Assert(_buffer.Length >= _index);
8996
_buffer.AsSpan(0, _index).Clear();
9097
_index = 0;
9198
}
9299

100+
/// <summary>
101+
/// Resets the data written to the underlying buffer without zeroing its content.
102+
/// </summary>
103+
/// <remarks>
104+
/// <para>
105+
/// You must reset or clear the <see cref="ArrayBufferWriter{T}"/> before trying to re-use it.
106+
/// </para>
107+
/// <para>
108+
/// If you reset the writer using the <see cref="ResetWrittenCount"/> method, the underlying buffer will not be cleared.
109+
/// </para>
110+
/// </remarks>
111+
/// <seealso cref="Clear"/>
112+
public void ResetWrittenCount() => _index = 0;
113+
93114
/// <summary>
94115
/// Notifies <see cref="IBufferWriter{T}"/> that <paramref name="count"/> amount of data was written to the output <see cref="Span{T}"/>/<see cref="Memory{T}"/>
95116
/// </summary>
@@ -121,13 +142,21 @@ public void Advance(int count)
121142
/// Thrown when <paramref name="sizeHint"/> is negative.
122143
/// </exception>
123144
/// <remarks>
145+
/// <para>
124146
/// This will never return an empty <see cref="Memory{T}"/>.
125-
/// </remarks>
126-
/// <remarks>
147+
/// </para>
148+
/// <para>
127149
/// There is no guarantee that successive calls will return the same buffer or the same-sized buffer.
128-
/// </remarks>
129-
/// <remarks>
150+
/// </para>
151+
/// <para>
130152
/// You must request a new buffer after calling Advance to continue writing more data and cannot write to a previously acquired buffer.
153+
/// </para>
154+
/// <para>
155+
/// If you reset the writer using the <see cref="ResetWrittenCount"/> method, this method may return a non-cleared <see cref="Memory{T}"/>.
156+
/// </para>
157+
/// <para>
158+
/// If you clear the writer using the <see cref="Clear"/> method, this method will return a <see cref="Memory{T}"/> with its content zeroed.
159+
/// </para>
131160
/// </remarks>
132161
public Memory<T> GetMemory(int sizeHint = 0)
133162
{
@@ -144,13 +173,21 @@ public Memory<T> GetMemory(int sizeHint = 0)
144173
/// Thrown when <paramref name="sizeHint"/> is negative.
145174
/// </exception>
146175
/// <remarks>
176+
/// <para>
147177
/// This will never return an empty <see cref="Span{T}"/>.
148-
/// </remarks>
149-
/// <remarks>
178+
/// </para>
179+
/// <para>
150180
/// There is no guarantee that successive calls will return the same buffer or the same-sized buffer.
151-
/// </remarks>
152-
/// <remarks>
181+
/// </para>
182+
/// <para>
153183
/// You must request a new buffer after calling Advance to continue writing more data and cannot write to a previously acquired buffer.
184+
/// </para>
185+
/// <para>
186+
/// If you reset the writer using the <see cref="ResetWrittenCount"/> method, this method may return a non-cleared <see cref="Span{T}"/>.
187+
/// </para>
188+
/// <para>
189+
/// If you clear the writer using the <see cref="Clear"/> method, this method will return a <see cref="Span{T}"/> with its content zeroed.
190+
/// </para>
154191
/// </remarks>
155192
public Span<T> GetSpan(int sizeHint = 0)
156193
{

src/libraries/System.Memory/ref/System.Memory.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public ArrayBufferWriter(int initialCapacity) { }
3636
public System.ReadOnlySpan<T> WrittenSpan { get { throw null; } }
3737
public void Advance(int count) { }
3838
public void Clear() { }
39+
public void ResetWrittenCount() { }
3940
public System.Memory<T> GetMemory(int sizeHint = 0) { throw null; }
4041
public System.Span<T> GetSpan(int sizeHint = 0) { throw null; }
4142
}

src/libraries/System.Memory/tests/ArrayBufferWriter/ArrayBufferWriterTests.Byte.cs

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,15 @@ protected override void WriteData(IBufferWriter<byte> bufferWriter, int numBytes
2222
bufferWriter.Advance(numBytes);
2323
}
2424

25-
[Fact]
26-
public void WriteAndCopyToStream()
25+
[Theory]
26+
[InlineData(true)]
27+
[InlineData(false)]
28+
public void WriteAndCopyToStream(bool clearContent)
2729
{
28-
var output = new ArrayBufferWriter<byte>();
30+
ArrayBufferWriter<byte> output = new();
2931
WriteData(output, 100);
3032

31-
using var memStream = new MemoryStream(100);
33+
using MemoryStream memStream = new(100);
3234

3335
Assert.Equal(100, output.WrittenCount);
3436

@@ -40,13 +42,23 @@ public void WriteAndCopyToStream()
4042
Assert.True(transientSpan.SequenceEqual(transientMemory.Span));
4143

4244
Assert.True(transientSpan[0] != 0);
45+
byte expectedFirstByte = transientSpan[0];
4346

4447
memStream.Write(transientSpan.ToArray(), 0, transientSpan.Length);
45-
output.Clear();
46-
47-
Assert.True(transientSpan[0] == 0);
48-
Assert.True(transientMemory.Span[0] == 0);
49-
48+
49+
if (clearContent)
50+
{
51+
expectedFirstByte = 0;
52+
output.Clear();
53+
}
54+
else
55+
{
56+
output.ResetWrittenCount();
57+
}
58+
59+
Assert.Equal(expectedFirstByte, transientSpan[0]);
60+
Assert.Equal(expectedFirstByte, transientMemory.Span[0]);
61+
5062
Assert.Equal(0, output.WrittenCount);
5163
byte[] streamOutput = memStream.ToArray();
5264

@@ -58,13 +70,15 @@ public void WriteAndCopyToStream()
5870
Assert.True(outputSpan.SequenceEqual(streamOutput));
5971
}
6072

61-
[Fact]
62-
public async Task WriteAndCopyToStreamAsync()
73+
[Theory]
74+
[InlineData(true)]
75+
[InlineData(false)]
76+
public async Task WriteAndCopyToStreamAsync(bool clearContent)
6377
{
64-
var output = new ArrayBufferWriter<byte>();
78+
ArrayBufferWriter<byte> output = new();
6579
WriteData(output, 100);
6680

67-
using var memStream = new MemoryStream(100);
81+
using MemoryStream memStream = new(100);
6882

6983
Assert.Equal(100, output.WrittenCount);
7084

@@ -73,11 +87,21 @@ public async Task WriteAndCopyToStreamAsync()
7387
ReadOnlyMemory<byte> transient = output.WrittenMemory;
7488

7589
Assert.True(transient.Span[0] != 0);
90+
byte expectedFirstByte = transient.Span[0];
7691

7792
await memStream.WriteAsync(transient.ToArray(), 0, transient.Length);
78-
output.Clear();
7993

80-
Assert.True(transient.Span[0] == 0);
94+
if (clearContent)
95+
{
96+
expectedFirstByte = 0;
97+
output.Clear();
98+
}
99+
else
100+
{
101+
output.ResetWrittenCount();
102+
}
103+
104+
Assert.True(transient.Span[0] == expectedFirstByte);
81105

82106
Assert.Equal(0, output.WrittenCount);
83107
byte[] streamOutput = memStream.ToArray();

src/libraries/System.Memory/tests/ArrayBufferWriter/ArrayBufferWriterTests.T.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,45 @@ public void Clear()
5757
Assert.False(ReadOnlySpan<T>.Empty.SequenceEqual(output.WrittenSpan));
5858
Assert.False(ReadOnlyMemory<T>.Empty.Span.SequenceEqual(output.WrittenMemory.Span));
5959
Assert.True(output.WrittenSpan.SequenceEqual(output.WrittenMemory.Span));
60+
61+
ReadOnlyMemory<T> transientMemory = output.WrittenMemory;
62+
ReadOnlySpan<T> transientSpan = output.WrittenSpan;
63+
T t0 = transientMemory.Span[0];
64+
T t1 = transientSpan[1];
65+
Assert.NotEqual(default, t0);
66+
Assert.NotEqual(default, t1);
6067
output.Clear();
68+
Assert.Equal(default, transientMemory.Span[0]);
69+
Assert.Equal(default, transientSpan[1]);
70+
71+
Assert.Equal(0, output.WrittenCount);
72+
Assert.True(ReadOnlySpan<T>.Empty.SequenceEqual(output.WrittenSpan));
73+
Assert.True(ReadOnlyMemory<T>.Empty.Span.SequenceEqual(output.WrittenMemory.Span));
74+
Assert.Equal(previousAvailable, output.FreeCapacity);
75+
}
76+
77+
[Fact]
78+
public void ResetWrittenCount()
79+
{
80+
var output = new ArrayBufferWriter<T>(256);
81+
int previousAvailable = output.FreeCapacity;
82+
WriteData(output, 2);
83+
Assert.True(output.FreeCapacity < previousAvailable);
84+
Assert.True(output.WrittenCount > 0);
85+
Assert.False(ReadOnlySpan<T>.Empty.SequenceEqual(output.WrittenSpan));
86+
Assert.False(ReadOnlyMemory<T>.Empty.Span.SequenceEqual(output.WrittenMemory.Span));
87+
Assert.True(output.WrittenSpan.SequenceEqual(output.WrittenMemory.Span));
88+
89+
ReadOnlyMemory<T> transientMemory = output.WrittenMemory;
90+
ReadOnlySpan<T> transientSpan = output.WrittenSpan;
91+
T t0 = transientMemory.Span[0];
92+
T t1 = transientSpan[1];
93+
Assert.NotEqual(default, t0);
94+
Assert.NotEqual(default, t1);
95+
output.ResetWrittenCount();
96+
Assert.Equal(t0, transientMemory.Span[0]);
97+
Assert.Equal(t1, transientSpan[1]);
98+
6199
Assert.Equal(0, output.WrittenCount);
62100
Assert.True(ReadOnlySpan<T>.Empty.SequenceEqual(output.WrittenSpan));
63101
Assert.True(ReadOnlyMemory<T>.Empty.Span.SequenceEqual(output.WrittenMemory.Span));

0 commit comments

Comments
 (0)