/// <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)); }
/// <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)); }