/// <summary> /// Returns the memory to write to that is at least the requested size. /// </summary> /// <param name="sizeHint">The minimum length of the returned memory.</param> /// <returns>The memory block of at least the size <paramref name="sizeHint"/>.</returns> /// <exception cref="OutOfMemoryException">The requested buffer size is not available.</exception> public Span <T> GetSpan(int sizeHint = 0) { if (sizeHint < 0) { throw new ArgumentOutOfRangeException(nameof(sizeHint)); } Span <T> result; int? newSize; if (extraBuffer.IsEmpty) { newSize = IGrowableBuffer <T> .GetBufferSize(sizeHint, initialBuffer.Length, position); // need to copy initial buffer if (newSize.HasValue) { extraBuffer = allocator.Invoke(newSize.GetValueOrDefault(), false); initialBuffer.CopyTo(extraBuffer.Memory.Span); initialBuffer.Clear(); result = extraBuffer.Memory.Span; } else { result = initialBuffer; } } else { newSize = IGrowableBuffer <T> .GetBufferSize(sizeHint, extraBuffer.Length, position); // no need to copy initial buffer if (newSize.HasValue) { var newBuffer = allocator.Invoke(newSize.GetValueOrDefault(), false); extraBuffer.Memory.CopyTo(newBuffer.Memory); extraBuffer.Dispose(); extraBuffer = newBuffer; } result = extraBuffer.Memory.Span; } return(result.Slice(position)); }