Пример #1
0
        /// <summary>
        /// Gets an array segment containing all written data with automated disposal
        /// </summary>
        /// <returns>A single array segment containing all written data</returns>
        /// <remarks>The buffer is rented from the array pool. Does not 'finish' the final segment, so writing can potentially continue without allocating/renting.</remarks>
        public AutoArraySegment <T> ToAutoArray()
        {
            // Grab a buffer that represents the entire contents of this Writer
            var BufferLength = (int)Length;
            var Buffer       = _Pool.Rent(BufferLength);

            if (TryGetMemory(out var Memory))
            {
                Memory.CopyTo(Buffer);
            }
            else
            {
                // Copy our current chain of buffers into it
                new ReadOnlySequence <T>(_HeadSegment !, 0, _TailSegment !, _TailSegment !.Memory.Length).CopyTo(Buffer);

                // Copy the final segment (if any)
                if (_CurrentOffset > 0)
                {
                    _CurrentBuffer.Slice(0, _CurrentOffset).CopyTo(Buffer.AsMemory((int)_TailSegment.RunningIndex + _TailSegment.Memory.Length));
                }
            }

            return(AutoArraySegment.Over(new ArraySegment <T>(Buffer, 0, BufferLength), _Pool));
        }
Пример #2
0
        /// <summary>
        /// Flushes the Buffer Writer, returning the current buffer (if possible) as an <see cref="AutoArraySegment{T}"/> and resetting the writer
        /// </summary>
        /// <param name="clearBuffers">True to clear the buffers when the <see cref="AutoArraySegment{T}"/> is disposed</param>
        /// <returns>A single array segment containing all written data</returns>
        /// <remarks>The Buffer Writer will be empty after this call, and can be safely written without affecting the result. Buffers will not be copied if the writer has only used a single array, and can be released using <see cref="AutoArraySegment{T}"/></remarks>
        public AutoArraySegment <T> FlushArray(bool clearBuffers)
        {
            if (TryGetMemory(out var Memory))
            {
                if (MemoryMarshal.TryGetArray(Memory, out var Segment))
                {
                    var Result = AutoArraySegment.Over(Segment, _Pool);

                    // Release the current buffer into the hands of the AutoSequence
                    _CurrentBuffer = Memory <T> .Empty;
                    _CurrentOffset = 0;
                    _TailSegment   = _HeadSegment = null;

                    return(Result);
                }

                // Should never happen
            }

            // More than one buffer is in use, so we need to copy to a single segment
            var BufferLength = (int)Length;
            var Buffer       = _Pool.Rent(BufferLength);

            // Copy our current chain of buffers into it
            new ReadOnlySequence <T>(_HeadSegment !, 0, _TailSegment !, _TailSegment !.Memory.Length).CopyTo(Buffer);

            // Copy the final segment (if any)
            if (_CurrentOffset > 0)
            {
                _CurrentBuffer.Slice(0, _CurrentOffset).CopyTo(Buffer.AsMemory((int)_TailSegment.RunningIndex + _TailSegment.Memory.Length));
            }

            Reset(clearBuffers);             // Reset the writer

            return(AutoArraySegment.Over(new ArraySegment <T>(Buffer, 0, BufferLength), _Pool));
        }