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

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

            while (readIndex > writeIndex)
            {
                memSegPtr = MemorySegment.GetNext(memSegPtr);
                if (memSegPtr == IntPtr.Zero)
                {
                    throw new UnexpectedEndOfBufferException();
                }
                int used = MemorySegment.GetUsed(memSegPtr);

                readIndex -= writeIndex + 1;

                writeIndex  = used - 1;
                nextWrited -= used;
            }

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

            IntPtr next = _memSegPtr;

            while (next != IntPtr.Zero)
            {
                IntPtr toRelease = next;
                next = MemorySegment.GetNext(next);

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

                MemorySegment.ClearBeforeRelease(toRelease);
                _byteBufProvider.Release(toRelease);
            }

            _byteBufProvider.Release(this);
            _released = true;
        }
        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);
            }
        }