NVorbis.StreamReadBuffer.EnsureBufferSize C# (CSharp) Method

EnsureBufferSize() static private method

static private EnsureBufferSize ( int reqSize, bool copyContents, int copyOffset ) : void
reqSize int
copyContents bool
copyOffset int
return void
        void EnsureBufferSize(int reqSize, bool copyContents, int copyOffset)
        {
            byte[] newBuf = _data;
            if (reqSize > _data.Length)
            {
                if (reqSize > _maxSize)
                {
                    if (_wrapper.Source.CanSeek || reqSize - _discardCount <= _maxSize)
                    {
                        // lose some of the earlier data...
                        var ofs = reqSize - _maxSize;
                        copyOffset += ofs;
                        reqSize = _maxSize;
                    }
                    else
                    {
                        throw new InvalidOperationException("Not enough room in the buffer!  Increase the maximum size and try again.");
                    }
                }
                else
                {
                    // find the new size
                    var size = _data.Length;
                    while (size < reqSize)
                    {
                        size *= 2;
                    }
                    reqSize = size;
                }

                // if we discarded some bytes above, don't resize the buffer unless we have to...
                if (reqSize > _data.Length)
                {
                    newBuf = new byte[reqSize];
                }
            }

            if (copyContents)
            {
                // adjust the position of the data
                if ((copyOffset > 0 && copyOffset < _end) || (copyOffset == 0 && newBuf != _data))
                {
                    // copy forward
                    Buffer.BlockCopy(_data, copyOffset, newBuf, 0, _end - copyOffset);

                    // adjust our discard count
                    if ((_discardCount -= copyOffset) < 0) _discardCount = 0;
                }
                else if (copyOffset < 0 && -copyOffset < _end)
                {
                    // copy backward
                    // be clever... if we're moving to a new buffer or the ranges don't overlap, just use a block copy
                    if (newBuf != _data || _end <= -copyOffset)
                    {
                        Buffer.BlockCopy(_data, 0, newBuf, -copyOffset, Math.Max(_end, Math.Min(_end, _data.Length + copyOffset)));
                    }
                    else
                    {
                        // this shouldn't happen often, so we can get away with a full buffer refill
                        _end = copyOffset;
                    }

                    // adjust our discard count
                    _discardCount = 0;
                }
                else
                {
                    _end = copyOffset;
                    _discardCount = 0;
                }

                // adjust our markers
                _baseOffset += copyOffset;
                _end -= copyOffset;
                if (_end > newBuf.Length) _end = newBuf.Length;
            }
            else
            {
                _discardCount = 0;
                // we can't set _baseOffset since our caller hasn't told us what it should be...
                _end = 0;
            }

            _data = newBuf;
        }