public void Append(ref ReadableBuffer buffer) { MemoryBlockSegment clonedEnd; var clonedBegin = MemoryBlockSegment.Clone(buffer.Start, buffer.End, out clonedEnd); 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 void Append(ReadableBuffer buffer) { if (buffer.IsEmpty) { return; // nothing to do } EnsureAlloc(); BufferSegment clonedEnd; var clonedBegin = BufferSegment.Clone(buffer.Start, buffer.End, out clonedEnd); if (_writingHead == null) { // No active write 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.Next = clonedBegin; } } else { Debug.Assert(_writingHead.Next == null); // Active write, append as next segment _writingHead.Next = clonedBegin; } // Move write head to end of buffer _writingHead = clonedEnd; }
public static void EndRead(this IReadableChannel input, ReadableBuffer consumed) { input.EndRead(consumed.End, consumed.End); }
/// <summary> /// /// </summary> /// <param name="buffer"></param> public MemoryEnumerator(ref ReadableBuffer buffer) { _buffer = buffer; _current = default(Memory <byte>); }
/// <summary> /// This transfers ownership of the buffer from the <see cref="IReadableChannel"/> 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)); }
/// <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); }
public Enumerator(ref ReadableBuffer buffer) { _buffer = buffer; _current = default(BufferSpan); }
/// <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(ref ReadableBuffer buffer) { _channel.Append(ref buffer); }
public Enumerator(ref ReadableBuffer buffer) { _buffer = buffer; _current = default(MemoryBlockSpan); }
public void Append(ReadableBuffer buffer) { Append(buffer.Start, buffer.End); }
internal PreservedBuffer(ref ReadableBuffer buffer) { _buffer = buffer; }
protected abstract Task WriteAsync(ReadableBuffer buffer);