Exemplo n.º 1
0
        internal void Append(ReadableBuffer buffer)
        {
            if (buffer.IsEmpty)
            {
                return; // nothing to do
            }

            EnsureAlloc();

            var clonedBegin = BufferSegment.Clone(buffer.Start, buffer.End, out BufferSegment clonedEnd);

            if (_writingHead == null)
            {
                // No active write
                lock (_sync)
                {
                    if (_commitHead == null)
                    {
                        // No allocated buffers yet, not locking as _readHead will be null
                        _commitHead = clonedBegin;
                    }
                    else
                    {
                        Debug.Assert(_commitHead.Next == null);
                        // Allocated buffer, append as next segment
                        _commitHead.SetNext(clonedBegin);
                    }
                }
            }
            else
            {
                Debug.Assert(_writingHead.Next == null);
                // Active write, append as next segment
                _writingHead.SetNext(clonedBegin);
            }

            // Move write head to end of buffer
            _writingHead         = clonedEnd;
            _currentWriteLength += buffer.Length;
        }
        /// <summary>
        /// Checks to see if the <see cref="ReadableBuffer"/> is Equal to the specified <see cref="Span{Byte}"/>.
        /// </summary>
        /// <param name="value">The <see cref="Span{Byte}"/> to compare to</param>
        /// <returns>True if the bytes are equal, false if not</returns>
        public static bool EqualsTo(this ReadableBuffer buffer, Span <byte> value)
        {
            if (value.Length != buffer.Length)
            {
                return(false);
            }

            if (buffer.IsSingleSpan)
            {
                return(buffer.First.Span.SequenceEqual(value));
            }

            foreach (var memory in buffer)
            {
                var compare = value.Slice(0, memory.Length);
                if (!memory.Span.SequenceEqual(compare))
                {
                    return(false);
                }

                value = value.Slice(memory.Length);
            }
            return(true);
        }
Exemplo n.º 3
0
        /// <summary>
        /// This transfers ownership of the buffer from the <see cref="IPipelineReader"/> to the caller of this method. Preserved buffers must be disposed to avoid
        /// memory leaks.
        /// </summary>
        public PreservedBuffer Preserve()
        {
            var buffer = new ReadableBuffer(ref this);

            return(new PreservedBuffer(ref buffer));
        }
Exemplo n.º 4
0
        /// <summary>
        /// Searches for a byte in the <see cref="ReadableBuffer"/> and returns a sliced <see cref="ReadableBuffer"/> that
        /// contains all data up to and excluding the byte, and a <see cref="ReadCursor"/> that points to the byte.
        /// </summary>
        /// <param name="b1">The first byte to search for</param>
        /// <param name="slice">A <see cref="ReadableBuffer"/> slice that contains all data up to and excluding the first byte.</param>
        /// <param name="cursor">A <see cref="ReadCursor"/> that points to the second byte</param>
        /// <returns>True if the byte sequence was found, false if not found</returns>
        public bool TrySliceTo(byte b1, out ReadableBuffer slice, out ReadCursor cursor)
        {
            if (IsEmpty)
            {
                slice  = default(ReadableBuffer);
                cursor = default(ReadCursor);
                return(false);
            }

            var byte0Vector = CommonVectors.GetVector(b1);

            var seek = 0;

            foreach (var memory in this)
            {
                var currentSpan = memory.Span;
                var found       = false;

                if (Vector.IsHardwareAccelerated)
                {
                    while (currentSpan.Length >= VectorWidth)
                    {
                        var data        = currentSpan.Read <Vector <byte> >();
                        var byte0Equals = Vector.Equals(data, byte0Vector);

                        if (byte0Equals.Equals(Vector <byte> .Zero))
                        {
                            currentSpan = currentSpan.Slice(VectorWidth);
                            seek       += VectorWidth;
                        }
                        else
                        {
                            var index = FindFirstEqualByte(ref byte0Equals);
                            seek += index;
                            found = true;
                            break;
                        }
                    }
                }

                if (!found)
                {
                    // Slow search
                    for (int i = 0; i < currentSpan.Length; i++)
                    {
                        if (currentSpan[i] == b1)
                        {
                            found = true;
                            break;
                        }
                        seek++;
                    }
                }

                if (found)
                {
                    cursor = _start.Seek(seek);
                    slice  = Slice(_start, cursor);
                    return(true);
                }
            }

            slice  = default(ReadableBuffer);
            cursor = default(ReadCursor);
            return(false);
        }
Exemplo n.º 5
0
 /// <summary>
 /// Appends the <see cref="ReadableBuffer"/> to the <see cref="WritableBuffer"/> in-place without copies.
 /// </summary>
 /// <param name="buffer">The <see cref="ReadableBuffer"/> to append</param>
 public void Append(ReadableBuffer buffer)
 {
     Pipe.Append(buffer);
 }
Exemplo n.º 6
0
 public ReadableBufferSequence(ReadableBuffer buffer) : this()
 {
     _buffer = buffer;
 }
        /// <summary>
        /// Searches for 2 sequential bytes in the <see cref="ReadableBuffer"/> and returns a sliced <see cref="ReadableBuffer"/> that
        /// contains all data up to and excluding the first byte, and a <see cref="ReadCursor"/> that points to the second byte.
        /// </summary>
        /// <param name="b1">The first byte to search for</param>
        /// <param name="b2">The second byte to search for</param>
        /// <param name="slice">A <see cref="ReadableBuffer"/> slice that contains all data up to and excluding the first byte.</param>
        /// <param name="cursor">A <see cref="ReadCursor"/> that points to the second byte</param>
        /// <returns>True if the byte sequence was found, false if not found</returns>
        public static unsafe bool TrySliceTo(this ReadableBuffer buffer, byte b1, byte b2, out ReadableBuffer slice, out ReadCursor cursor)
        {
            // use address of ushort rather than stackalloc as the inliner won't inline functions with stackalloc
            ushort twoBytes;
            byte * byteArray = (byte *)&twoBytes;

            byteArray[0] = b1;
            byteArray[1] = b2;
            return(buffer.TrySliceTo(new Span <byte>(byteArray, 2), out slice, out cursor));
        }
Exemplo n.º 8
0
 public ReadableBufferReader(ReadableBuffer buffer) : this(buffer.Start, buffer.End)
 {
 }
Exemplo n.º 9
0
 internal PreservedBuffer(ref ReadableBuffer buffer)
 {
     _buffer = buffer;
 }
Exemplo n.º 10
0
 protected abstract Task WriteAsync(ReadableBuffer buffer);
Exemplo n.º 11
0
 /// <summary>
 /// Appends the <see cref="ReadableBuffer"/> to the <see cref="WritableBuffer"/> in-place without copies.
 /// </summary>
 /// <param name="buffer">The <see cref="ReadableBuffer"/> to append</param>
 public void Append(ReadableBuffer buffer)
 {
     _output.Append(buffer);
 }