public static MemoryBlockSegment Clone(ReadIterator beginBuffer, ReadIterator endBuffer) { var beginOrig = beginBuffer.Segment; var endOrig = endBuffer.Segment; if (beginOrig == endOrig) { return(new MemoryBlockSegment(beginOrig.Block, beginBuffer.Index, endBuffer.Index)); } var beginClone = new MemoryBlockSegment(beginOrig.Block, beginBuffer.Index, beginOrig.End); var endClone = beginClone; beginOrig = beginOrig.Next; while (beginOrig != endOrig) { endClone.Next = new MemoryBlockSegment(beginOrig.Block, beginOrig.Start, beginOrig.End); endClone = endClone.Next; beginOrig = beginOrig.Next; } endClone.Next = new MemoryBlockSegment(endOrig.Block, endOrig.Start, endBuffer.Index); return(beginClone); }
public ReadableBuffer Slice(ReadIterator start, int length) { var begin = start; var actual = begin.Seek(length); return(Slice(begin, actual)); }
public void Append(ReadIterator begin, ReadIterator end) { var clonedBegin = MemoryBlockSegment.Clone(begin, end); var clonedEnd = clonedBegin; while (clonedEnd.Next != null) { clonedEnd = clonedEnd.Next; } if (_tail == null) { _head = clonedBegin; _headIndex = clonedBegin.Start; } else { Debug.Assert(_tail.Block != null); Debug.Assert(_tail.Next == null); Debug.Assert(_tail.End == _tailIndex); _tail.Next = clonedBegin; } _tail = clonedEnd; _tailIndex = clonedEnd.End; }
internal int GetLength(ReadIterator end) { if (IsDefault) { return(0); } var segment = _segment; var index = _index; var length = 0; checked { while (true) { if (segment == end._segment) { return(length + end._index - index); } else if (segment.Next == null) { return(length); } else { length += segment.End - index; segment = segment.Next; index = segment.Start; } } } }
public ReadableBuffer Slice(int start, ReadIterator end) { var begin = _start; if (start != 0) { begin.Seek(start); } return(Slice(begin, end)); }
internal bool TryGetBuffer(ReadIterator end, out BufferSpan span) { span = default(BufferSpan); if (IsDefault) { return(false); } var segment = _segment; var index = _index; // Determine if we might attempt to copy data from segment.Next before // calculating "following" so we don't risk skipping data that could // be added after segment.End when we decide to copy from segment.Next. // segment.End will always be advanced before segment.Next is set. int following = 0; while (true) { var wasLastBlock = segment.Next == null || end.Segment == segment; if (end.Segment == segment) { following = end.Index - index; } else { following = segment.End - index; } if (following > 0) { break; } if (wasLastBlock) { return(false); } else { segment = segment.Next; index = segment.Start; } } span = new BufferSpan(segment, index, following); _segment = segment; _index = index + following; return(true); }
public ReadableBuffer(ReadIterator start, ReadIterator end, bool isOwner) { _start = start; _end = end; _isOwner = isOwner; _disposed = false; var begin = start; begin.TryGetBuffer(end, out _span); begin = start; _length = begin.GetLength(end); }
public ReadableBuffer Clone() { var begin = _start; var end = _end; var segmentHead = MemoryBlockSegment.Clone(begin, end); var segmentTail = segmentHead; while (segmentTail.Next != null) { segmentTail = segmentTail.Next; } begin = new ReadIterator(segmentHead); end = new ReadIterator(segmentTail, segmentTail.End); return(new ReadableBuffer(begin, end, isOwner: true)); }
public void EndRead( ReadIterator consumed, ReadIterator examined) { MemoryBlockSegment returnStart = null; MemoryBlockSegment returnEnd = null; lock (_sync) { if (!consumed.IsDefault) { returnStart = _head; returnEnd = consumed.Segment; _head = consumed.Segment; _head.Start = consumed.Index; } if (!examined.IsDefault && examined.IsEnd && Completion.Status == TaskStatus.WaitingForActivation) { Interlocked.CompareExchange( ref _awaitableState, _awaitableIsNotCompleted, _awaitableIsCompleted); } } while (returnStart != returnEnd) { var returnSegment = returnStart; returnStart = returnStart.Next; returnSegment.Dispose(); } if (Interlocked.CompareExchange(ref _consumingState, 0, 1) != 1) { throw new InvalidOperationException("No ongoing consuming operation to complete."); } }
public static void EndRead(this IReadableChannel input, ReadIterator consumed) { input.EndRead(consumed, consumed); }
public void EndRead(ReadIterator consumed, ReadIterator examined) => _channel.EndRead(consumed, examined);
public ReadableBuffer Slice(ReadIterator start, ReadIterator end) { return(new ReadableBuffer(start, end)); }
public ReadableBuffer(ReadIterator start, ReadIterator end) : this(start, end, isOwner : false) { }
public void EndRead(ReadIterator end) { EndRead(end, end); }