コード例 #1
0
        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);
        }
コード例 #2
0
        public ReadableBuffer Slice(ReadIterator start, int length)
        {
            var begin  = start;
            var actual = begin.Seek(length);

            return(Slice(begin, actual));
        }
コード例 #3
0
        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;
        }
コード例 #4
0
        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;
                    }
                }
            }
        }
コード例 #5
0
        public ReadableBuffer Slice(int start, ReadIterator end)
        {
            var begin = _start;

            if (start != 0)
            {
                begin.Seek(start);
            }
            return(Slice(begin, end));
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        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));
        }
コード例 #9
0
ファイル: MemoryPoolChannel.cs プロジェクト: ericl85/Channels
        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.");
            }
        }
コード例 #10
0
 public static void EndRead(this IReadableChannel input, ReadIterator consumed)
 {
     input.EndRead(consumed, consumed);
 }
コード例 #11
0
ファイル: ReadableChannel.cs プロジェクト: ericl85/Channels
 public void EndRead(ReadIterator consumed, ReadIterator examined) => _channel.EndRead(consumed, examined);
コード例 #12
0
 public ReadableBuffer Slice(ReadIterator start, ReadIterator end)
 {
     return(new ReadableBuffer(start, end));
 }
コード例 #13
0
 public ReadableBuffer(ReadIterator start, ReadIterator end) :
     this(start, end, isOwner : false)
 {
 }
コード例 #14
0
ファイル: MemoryPoolChannel.cs プロジェクト: ericl85/Channels
 public void EndRead(ReadIterator end)
 {
     EndRead(end, end);
 }