The behavior of Slice(offset, SequencePosition) should match GetPosition(offset) and Slice(offset).
I should be able to slice a ReadOnlySequence past the current sequence if the next one is empty (for example: [97] -> []).
[Fact]
public static void ReadOnlySequenceTest()
{
string jsonString = "a";
ReadOnlyMemory<byte> dataMemory = Encoding.UTF8.GetBytes(jsonString);
var firstSegment = new BufferSegment<byte>(dataMemory.Slice(0, 1));
ReadOnlyMemory<byte> secondMem = dataMemory.Slice(0, 0);
BufferSegment<byte> secondSegment = firstSegment.Append(secondMem);
// A two segment sequence where the second one is empty: [a]-> []
var sequence = new ReadOnlySequence<byte>(firstSegment, 0, secondSegment, secondMem.Length);
SequencePosition expectedPosition = sequence.GetPosition(1);
Console.WriteLine(expectedPosition.GetInteger()); // 0
Console.WriteLine(expectedPosition.GetObject()); // System.Text.Json.Tests.BufferSegment`1[System.Byte]
Assert.True(((ReadOnlySequenceSegment<byte>)expectedPosition.GetObject()).Memory.IsEmpty);
SequencePosition actualPosition = sequence.Slice(1).Start;
Console.WriteLine(actualPosition.GetInteger()); // 0
Console.WriteLine(actualPosition.GetObject()); // System.Text.Json.Tests.BufferSegment`1[System.Byte]
Assert.True(((ReadOnlySequenceSegment<byte>)actualPosition.GetObject()).Memory.IsEmpty);
Assert.Equal(expectedPosition, actualPosition); // True
SequencePosition actualPosition2 = sequence.GetPosition(1, sequence.Start);
Console.WriteLine(actualPosition2.GetInteger()); // 0
Console.WriteLine(actualPosition2.GetObject()); // System.Text.Json.Tests.BufferSegment`1[System.Byte]
Assert.True(((ReadOnlySequenceSegment<byte>)actualPosition2.GetObject()).Memory.IsEmpty);
// System.ArgumentOutOfRangeException : Specified argument was out of the range of valid values.
/*
System.ArgumentOutOfRangeException : Specified argument was out of the range of valid values.
Parameter name: start
Stack Trace:
E:\GitHub\Fork\corefx\src\System.Memory\src\System\ThrowHelper.cs(31,0): at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument)
E:\GitHub\Fork\corefx\src\System.Memory\src\System\Buffers\ReadOnlySequence.cs(281,0): at System.Buffers.ReadOnlySequence`1.Slice(Int64 start, SequencePosition end)
E:\GitHub\Fork\corefx\src\System.Memory\src\System\Buffers\ReadOnlySequence.cs(388,0): at System.Buffers.ReadOnlySequence`1.Slice(Int32 start, SequencePosition end)
E:\GitHub\Fork\corefx\src\System.Text.Json\tests\Utf8JsonReaderTests.TryGet.cs(357,0): at System.Text.Json.Tests.Utf8JsonReaderTests.ReadOnlySequenceTest()
*/
sequence = sequence.Slice(1, sequence.Start);
}
We need to use the Slice overload that takes a SequencePosition for performance to avoid having to scan the segments from the beginning every time. Using GetPosition with long is too slow:
https://github.com/dotnet/corefxlab/blob/63ef1a5db4fdbfcf9822b8cd2cbc3921b3d3cb9e/src/System.Text.JsonLab/System/Text/Json/JsonUtf8Reader.cs#L112
cc @pakrym, @davidfowl
The behavior of
Slice(offset, SequencePosition)should matchGetPosition(offset)andSlice(offset).I should be able to slice a
ReadOnlySequencepast the current sequence if the next one is empty (for example:[97] -> []).We need to use the Slice overload that takes a
SequencePositionfor performance to avoid having to scan the segments from the beginning every time. UsingGetPositionwithlongis too slow:https://github.com/dotnet/corefxlab/blob/63ef1a5db4fdbfcf9822b8cd2cbc3921b3d3cb9e/src/System.Text.JsonLab/System/Text/Json/JsonUtf8Reader.cs#L112
cc @pakrym, @davidfowl