Skip to content

Commit 7fcc2fb

Browse files
committed
Fixed regression
1 parent 70c7302 commit 7fcc2fb

File tree

2 files changed

+38
-36
lines changed

2 files changed

+38
-36
lines changed

src/DotNext.Tests/Buffers/ChunkSequenceTests.cs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,24 +143,39 @@ public static void CopyFromSequenceAndAdjustPosition()
143143
var destination = new byte[10];
144144
ReadOnlySequence<byte> source = new(RandomBytes(16));
145145

146+
// source > destination, single segment
146147
var bytesWritten = source.CopyTo(destination, out SequencePosition consumed);
147148
Equal(bytesWritten, destination.Length);
148149
Equal(destination, source.Slice(0, consumed).ToArray());
149150

151+
// source > destination, multisegment, segment < destination
152+
Array.Clear(destination);
150153
source = ToReadOnlySequence<byte>(RandomBytes(16), 3);
151154
bytesWritten = source.CopyTo(destination, out consumed);
152155
Equal(destination.Length, bytesWritten);
153156
Equal(destination, source.Slice(0, consumed).ToArray());
154157

158+
// source > destination, multisegment, segment > destination
159+
Array.Clear(destination);
155160
source = ToReadOnlySequence<byte>(RandomBytes(22), 11);
156161
bytesWritten = source.CopyTo(destination, out consumed);
157162
Equal(destination.Length, bytesWritten);
158163
Equal(destination, source.Slice(0, consumed).ToArray());
159164

165+
// source < destination, multisegment, segment < destination
166+
Array.Clear(destination);
160167
source = ToReadOnlySequence<byte>(RandomBytes(6), 3);
161168
bytesWritten = source.CopyTo(destination, out consumed);
162-
Equal(6, bytesWritten);
169+
Equal(source.Length, bytesWritten);
163170
Equal(source.End, consumed);
164-
Equal(destination.AsSpan(0, 6), source.Slice(0, consumed).ToArray().AsSpan());
171+
Equal(destination.AsSpan(0, (int)source.Length), source.Slice(0, consumed).ToArray().AsSpan());
172+
173+
// source < destination, single segment
174+
Array.Clear(destination);
175+
source = new(RandomBytes(3));
176+
bytesWritten = source.CopyTo(destination, out consumed);
177+
Equal(source.Length, bytesWritten);
178+
Equal(source.End, consumed);
179+
Equal(destination.AsSpan(0, (int)source.Length), source.Slice(0, consumed).ToArray().AsSpan());
165180
}
166181
}

src/DotNext/Buffers/Memory.ReadOnlySequence.cs

Lines changed: 21 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ public static ReadOnlySequence<T> Concat<T>(this ReadOnlyMemory<T> first, ReadOn
205205
/// <param name="destination">Destination memory.</param>
206206
/// <param name="writtenCount">The number of copied elements.</param>
207207
/// <typeparam name="T">The type of the elements in the sequence.</typeparam>
208-
public static void CopyTo<T>(this in ReadOnlySequence<T> source, scoped Span<T> destination, out int writtenCount)
208+
public static void CopyTo<T>(this in ReadOnlySequence<T> source, Span<T> destination, out int writtenCount)
209209
{
210210
if (source.IsSingleSegment)
211211
{
@@ -237,61 +237,48 @@ static int CopyToSlow(in ReadOnlySequence<T> source, Span<T> destination)
237237
/// </summary>
238238
/// <param name="source">Source sequence.</param>
239239
/// <param name="destination">Destination memory.</param>
240-
/// <param name="position">The position within <paramref name="source"/> that represents the end of <paramref name="destination"/>.</param>
240+
/// <param name="consumed">The position within <paramref name="source"/> that represents the end of <paramref name="destination"/>.</param>
241241
/// <typeparam name="T">The type of the elements in the sequence.</typeparam>
242242
/// <returns>The number of copied elements.</returns>
243-
public static int CopyTo<T>(this in ReadOnlySequence<T> source, scoped Span<T> destination, out SequencePosition position)
243+
public static int CopyTo<T>(this in ReadOnlySequence<T> source, Span<T> destination, out SequencePosition consumed)
244244
{
245-
int writtenCount;
246-
ReadOnlySpan<T> segment;
247-
if (!source.IsSingleSegment)
248-
{
249-
// slow path - multisegment sequence
250-
writtenCount = CopyToSlow(in source, destination, out position);
251-
}
252-
else if ((segment = source.FirstSpan).Length <= destination.Length)
245+
var writtenCount = 0;
246+
ReadOnlyMemory<T> block;
247+
248+
consumed = source.Start;
249+
if (source.IsSingleSegment)
253250
{
254-
writtenCount = segment.Length;
255-
position = source.End;
251+
block = source.First;
256252
}
257253
else
258254
{
259-
writtenCount = destination.Length;
260-
segment = segment.Slice(0, writtenCount);
261-
segment.CopyTo(destination);
262-
position = source.GetPosition(writtenCount, source.Start);
263-
}
264-
265-
return writtenCount;
266-
267-
static int CopyToSlow(in ReadOnlySequence<T> source, Span<T> destination, out SequencePosition consumed)
268-
{
269-
var result = 0;
270-
271-
ReadOnlyMemory<T> block;
272-
for (var position = consumed = source.Start;
255+
for (var position = consumed;
273256
source.TryGet(ref position, out block) && block.Length <= destination.Length;
274257
consumed = position,
275-
result += block.Length)
258+
writtenCount += block.Length)
276259
{
277260
block.Span.CopyTo(destination);
278261
destination = destination.Slice(block.Length);
279262
}
263+
}
280264

281-
if (block.Length > destination.Length)
265+
writtenCount += CopyLastSegment(source, block.Span, destination, ref consumed);
266+
return writtenCount;
267+
268+
static int CopyLastSegment(in ReadOnlySequence<T> source, ReadOnlySpan<T> segment, Span<T> destination, ref SequencePosition consumed)
269+
{
270+
if (segment.Length > destination.Length)
282271
{
283-
block = block.Slice(0, destination.Length);
272+
segment = segment.Slice(0, destination.Length);
284273
consumed = source.GetPosition(destination.Length, consumed);
285274
}
286275
else
287276
{
288277
consumed = source.End;
289278
}
290-
291-
block.Span.CopyTo(destination);
292-
result += block.Length;
293279

294-
return result;
280+
segment.CopyTo(destination);
281+
return segment.Length;
295282
}
296283
}
297284

0 commit comments

Comments
 (0)