예제 #1
0
        internal bool TryGetBuffer(ReadCursor end, out MemoryBlockSpan span)
        {
            if (IsDefault)
            {
                span = default(MemoryBlockSpan);
                return(false);
            }

            var segment = _segment;
            var index   = _index;

            if (end.Segment == segment)
            {
                var following = end.Index - index;

                if (following > 0)
                {
                    span = new MemoryBlockSpan(segment.Block, index, following);

                    _index = index + following;
                    return(true);
                }

                span = default(MemoryBlockSpan);
                return(false);
            }
            else
            {
                return(TryGetBufferMultiBlock(end, out span));
            }
        }
예제 #2
0
        private bool TryGetBufferMultiBlock(ReadCursor end, out MemoryBlockSpan span)
        {
            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)
                {
                    span = default(MemoryBlockSpan);
                    return(false);
                }
                else
                {
                    segment = segment.Next;
                    index   = segment.Start;
                }
            }

            span = new MemoryBlockSpan(segment.Block, index, following);

            _segment = segment;
            _index   = index + following;
            return(true);
        }
예제 #3
0
        private ReadableBuffer(ref ReadableBuffer buffer)
        {
            _channel = buffer._channel;

            var begin = buffer._start;
            var end   = buffer._end;

            MemoryBlockSegment segmentTail;
            var segmentHead = MemoryBlockSegment.Clone(begin, end, out segmentTail);

            begin = new ReadCursor(segmentHead);
            end   = new ReadCursor(segmentTail, segmentTail.End);

            _start   = begin;
            _end     = end;
            _isOwner = true;
            _span    = buffer._span;

            _length = buffer._length;
        }
예제 #4
0
 public Enumerator(ref ReadableBuffer buffer)
 {
     _buffer  = buffer;
     _current = default(MemoryBlockSpan);
 }