private void BoundsCheck(SequencePosition start, SequencePosition position) { int startIndex = start.Index; int endIndex = position.Index; SequenceType type = GetSequenceType(); startIndex = GetIndex(startIndex); endIndex = GetIndex(endIndex); switch (type) { case SequenceType.OwnedMemory: case SequenceType.Array: if (endIndex > startIndex) { ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange(); } return; case SequenceType.MemoryList: IMemoryList <T> segment = (IMemoryList <T>)position.Segment; IMemoryList <T> memoryList = (IMemoryList <T>)start.Segment; if (segment.RunningIndex - startIndex > memoryList.RunningIndex - endIndex) { ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange(); } return; default: ThrowHelper.ThrowInvalidOperationException_UnexpectedSegmentType(); return; } }
internal SequencePosition Seek(SequencePosition start, SequencePosition end, long count, bool checkEndReachable = true) { int startIndex = start.Index; int endIndex = end.Index; SequenceType type = GetSequenceType(); startIndex = GetIndex(startIndex); endIndex = GetIndex(endIndex); switch (type) { case SequenceType.MemoryList: if (start.Segment == end.Segment && endIndex - startIndex >= count) { // end.Index >= count + Index and end.Index is int return(new SequencePosition(start.Segment, startIndex + (int)count)); } return(SeekMultiSegment((IMemoryList <byte>)start.Segment, startIndex, (IMemoryList <byte>)end.Segment, endIndex, count, checkEndReachable)); case SequenceType.OwnedMemory: case SequenceType.Array: if (endIndex - startIndex >= count) { // end.Index >= count + Index and end.Index is int return(new SequencePosition(start.Segment, startIndex + (int)count)); } ThrowHelper.ThrowArgumentOutOfRangeException_CountOutOfRange(); return(default); default: ThrowHelper.ThrowInvalidOperationException_UnexpectedSegmentType(); return(default); } }
internal SequencePosition Seek(SequencePosition start, SequencePosition end, int count, bool checkEndReachable = true) { int startIndex = start.GetInteger(); int endIndex = end.GetInteger(); SequenceType type = GetSequenceType(); startIndex = GetIndex(startIndex); endIndex = GetIndex(endIndex); switch (type) { case SequenceType.MemoryList: if (start.GetObject() == end.GetObject() && endIndex - startIndex >= count) { return(new SequencePosition(start.GetObject(), startIndex + count)); } return(SeekMultiSegment((IMemoryList <byte>)start.GetObject(), startIndex, (IMemoryList <byte>)end.GetObject(), endIndex, count, checkEndReachable)); case SequenceType.OwnedMemory: case SequenceType.Array: if (start.GetObject() != end.GetObject()) { ThrowHelper.ThrowInvalidOperationException_EndPositionNotReached(); } if (endIndex - startIndex >= count) { return(new SequencePosition(start.GetObject(), startIndex + count)); } ThrowHelper.ThrowArgumentOutOfRangeException_CountOutOfRange(); return(default); default: ThrowHelper.ThrowInvalidOperationException_UnexpectedSegmentType(); return(default); } }
private long GetLength(SequencePosition start, SequencePosition end) { int startIndex = start.Index; int endIndex = end.Index; SequenceType type = GetSequenceType(); startIndex = GetIndex(startIndex); endIndex = GetIndex(endIndex); switch (type) { case SequenceType.MemoryList: return(GetLength((IMemoryList <T>)start.Segment, startIndex, (IMemoryList <T>)end.Segment, endIndex)); case SequenceType.OwnedMemory: case SequenceType.Array: return(endIndex - startIndex); default: ThrowHelper.ThrowInvalidOperationException_UnexpectedSegmentType(); return(default); } }
internal bool TryGetBuffer(SequencePosition start, SequencePosition end, out ReadOnlyMemory <T> data, out SequencePosition next) { if (start.Segment == null) { data = default; next = default; return(false); } int startIndex = start.Index; int endIndex = end.Index; SequenceType type = GetSequenceType(); startIndex = GetIndex(startIndex); endIndex = GetIndex(endIndex); switch (type) { case SequenceType.MemoryList: var segment = (IMemoryList <T>)start.Segment; Memory <T> bufferSegmentMemory = segment.Memory; int currentEndIndex = bufferSegmentMemory.Length; if (segment == end.Segment) { currentEndIndex = endIndex; next = default; } else { IMemoryList <T> nextSegment = segment.Next; if (nextSegment == null) { if (end.Segment != null) { ThrowHelper.ThrowInvalidOperationException_EndPositionNotReached(); } next = default; } else { next = new SequencePosition(nextSegment, 0); } } data = bufferSegmentMemory.Slice(startIndex, currentEndIndex - startIndex); return(true); case SequenceType.OwnedMemory: var ownedMemory = (OwnedMemory <T>)start.Segment; if (ownedMemory != end.Segment) { ThrowHelper.ThrowInvalidOperationException_EndPositionNotReached(); } data = ownedMemory.Memory.Slice(startIndex, endIndex - startIndex); next = default; return(true); case SequenceType.Array: var array = (T[])start.Segment; if (array != end.Segment) { ThrowHelper.ThrowInvalidOperationException_EndPositionNotReached(); } data = new Memory <T>(array, startIndex, endIndex - startIndex); next = default; return(true); default: ThrowHelper.ThrowInvalidOperationException_UnexpectedSegmentType(); next = default; data = default; return(false); } }