Example #1
0
        /// <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));
        }