private void SeekBackward(int offset)
        {
            IntPtr memSegPtr = _memSegPtr;

            int writeIndex = _writeIndex;
            int nextWrited = _nextWrited;
            int readIndex  = _readIndex - offset;

            while (readIndex < -1)
            {
                nextWrited += MemorySegment.GetUsed(memSegPtr);

                memSegPtr = MemorySegment.GetPrev(memSegPtr);
                if (memSegPtr == IntPtr.Zero)
                {
                    throw new UnexpectedEndOfBufferException();
                }
                writeIndex = MemorySegment.GetUsed(memSegPtr) - 1;
                readIndex += writeIndex;
            }

            _memSegPtr  = memSegPtr;
            _memSegSize = MemorySegment.GetSize(_memSegPtr);
            unsafe
            {
                _dataPtr = (byte *)(void *)MemorySegment.GetDataPtr(_memSegPtr);
            }
            _writeIndex = writeIndex;
            _nextWrited = nextWrited;
            _readIndex  = readIndex;
        }
        public override void ReleaseReaded()
        {
            IntPtr prev = MemorySegment.GetPrev(_memSegPtr);

            // Отвязываем от текущего.
            MemorySegment.SetPrev(_memSegPtr, IntPtr.Zero);

            while (prev != IntPtr.Zero)
            {
                IntPtr toRelease = prev;
                prev = MemorySegment.GetPrev(prev);

                MemorySegment.SetPrev(toRelease, IntPtr.Zero);
                MemorySegment.SetNext(toRelease, IntPtr.Zero);

                MemorySegment.ClearBeforeRelease(toRelease);
                _byteBufProvider.Release(toRelease);
            }
        }
        public void TestHeader()
        {
            IntPtr ptrFirst  = IntPtr.Zero;
            IntPtr ptrSecond = IntPtr.Zero;

            try
            {
                Assert.True(IntPtr.Size == 8);

                ptrFirst  = Alloc(10);
                ptrSecond = Alloc(10);

                MemorySegment.SetNext(ptrFirst, IntPtr.Zero);
                MemorySegment.SetPrev(ptrSecond, IntPtr.Zero);

                MemorySegment.SetSize(ptrFirst, 0);
                MemorySegment.SetSize(ptrSecond, 0);

                MemorySegment.SetUsed(ptrFirst, 0);
                MemorySegment.SetUsed(ptrSecond, 0);

                Assert.True(MemorySegment.GetNext(ptrFirst) == IntPtr.Zero);
                Assert.True(MemorySegment.GetPrev(ptrSecond) == IntPtr.Zero);

                Assert.True(MemorySegment.GetSize(ptrFirst) == 0);
                Assert.True(MemorySegment.GetSize(ptrSecond) == 0);

                Assert.True(MemorySegment.GetUsed(ptrFirst) == 0);
                Assert.True(MemorySegment.GetUsed(ptrSecond) == 0);

                MemorySegment.SetNext(ptrFirst, ptrSecond);
                MemorySegment.SetPrev(ptrSecond, ptrFirst);

                MemorySegment.SetSize(ptrFirst, 10);
                MemorySegment.SetSize(ptrSecond, 9);

                MemorySegment.SetUsed(ptrFirst, 8);
                MemorySegment.SetUsed(ptrSecond, 4);

                Assert.True(MemorySegment.GetNext(ptrFirst) == ptrSecond);
                Assert.True(MemorySegment.GetPrev(ptrSecond) == ptrFirst);

                Assert.True(MemorySegment.GetSize(ptrFirst) == 10);
                Assert.True(MemorySegment.GetSize(ptrSecond) == 9);

                Assert.True(MemorySegment.GetUsed(ptrFirst) == 8);
                Assert.True(MemorySegment.GetUsed(ptrSecond) == 4);

                Assert.True(
                    MemorySegment.GetUsed(ptrFirst) ==
                    MemorySegment.GetUsed(
                        MemorySegment.GetMemSegPtrByDataPtr(
                            MemorySegment.GetDataPtr(ptrFirst)
                            )
                        )
                    );
            }
            finally
            {
                Release(ptrFirst);
                Release(ptrSecond);
            }
        }