/// <summary>
        /// Save the data at the current location then move to the next available space.
        /// </summary>
        /// <param name="data">The byte to be saved.</param>
        /// <returns>true if the operation successes. false if can't find available space.</returns>
        public bool Put(byte data)
        {
            if (_block == null)
            {
                return(false);
            }
            else if (_index < _block.End)
            {
                _block.Data.Array[_index++] = data;
                return(true);
            }

            var block = _block;
            var index = _index;

            while (true)
            {
                if (index < block.End)
                {
                    _block = block;
                    _index = index + 1;
                    block.Data.Array[index] = data;
                    return(true);
                }
                else if (block.Next == null)
                {
                    return(false);
                }
                else
                {
                    block = block.Next;
                    index = block.Start;
                }
            }
        }
Esempio n. 2
0
        public MemoryPoolIterator IncomingStart()
        {
            if (_tail == null)
            {
                _tail = _memory.Lease();
            }

            if (_head == null)
            {
                _head = _tail;
            }

            return(new MemoryPoolIterator(_tail, _tail.End));
        }
        public void CopyFrom(byte[] data, int offset, int count)
        {
            if (IsDefault)
            {
                return;
            }

            Debug.Assert(_block != null, "Block == null!");
            Debug.Assert(_block.Next == null, "Block.Next != null!");
            Debug.Assert(_block.End == _index, "At the end");

            var pool       = _block.Pool;
            var block      = _block;
            var blockIndex = _index;

            var bufferIndex      = offset;
            var remaining        = count;
            var bytesLeftInBlock = block.Data.Offset + block.Data.Count - blockIndex;

            while (remaining > 0)
            {
                if (bytesLeftInBlock == 0)
                {
                    var nextBlock = pool.Lease();
                    block.End  = blockIndex;
                    block.Next = nextBlock;
                    block      = nextBlock;

                    blockIndex       = block.Data.Offset;
                    bytesLeftInBlock = block.Data.Count;
                }

                var bytesToCopy = remaining < bytesLeftInBlock ? remaining : bytesLeftInBlock;

                Buffer.BlockCopy(data, bufferIndex, block.Data.Array, blockIndex, bytesToCopy);

                blockIndex       += bytesToCopy;
                bufferIndex      += bytesToCopy;
                remaining        -= bytesToCopy;
                bytesLeftInBlock -= bytesToCopy;
            }

            block.End = blockIndex;
            _block    = block;
            _index    = blockIndex;
        }
Esempio n. 4
0
        public void Dispose()
        {
            AbortAwaiting();

            // Return all blocks
            var block = _head;

            while (block != null)
            {
                var returnBlock = block;
                block = block.Next;

                returnBlock.Pool.Return(returnBlock);
            }

            _head = null;
            _tail = null;
        }
Esempio n. 5
0
        public void ConsumingComplete(
            MemoryPoolIterator consumed,
            MemoryPoolIterator examined)
        {
            lock (_sync)
            {
                IMemoryPoolBlock returnStart = null;
                IMemoryPoolBlock returnEnd   = null;

                if (!consumed.IsDefault)
                {
                    returnStart = _head;
                    returnEnd   = consumed.Block;
                    _head       = consumed.Block;
                    _head.Start = consumed.Index;
                }

                if (!examined.IsDefault &&
                    examined.IsEnd &&
                    DataComplete == false &&
                    _awaitableError == null)
                {
                    _manualResetEvent.Reset();

                    Interlocked.CompareExchange(
                        ref _awaitableState,
                        _awaitableIsNotCompleted,
                        _awaitableIsCompleted);
                }

                while (returnStart != returnEnd)
                {
                    var returnBlock = returnStart;
                    returnStart = returnStart.Next;
                    returnBlock.Pool.Return(returnBlock);
                }

                if (Interlocked.CompareExchange(ref _consumingState, 0, 1) != 1)
                {
                    throw new InvalidOperationException("No ongoing consuming operation to complete.");
                }
            }
        }
Esempio n. 6
0
        public void IncomingComplete(MemoryPoolIterator iter, bool completed, Exception error)
        {
            lock (_sync)
            {
                if (!iter.IsDefault)
                {
                    _tail     = iter.Block;
                    _tail.End = iter.Index;
                }

                DataComplete = completed;

                if (error != null)
                {
                    _awaitableError = error;
                }

                Complete();
            }
        }
        public void Skip(int bytesToSkip)
        {
            if (_block == null)
            {
                return;
            }
            var following = _block.End - _index;

            if (following >= bytesToSkip)
            {
                _index += bytesToSkip;
                return;
            }

            var block = _block;
            var index = _index;

            while (true)
            {
                if (block.Next == null)
                {
                    return;
                }
                else
                {
                    bytesToSkip -= following;
                    block        = block.Next;
                    index        = block.Start;
                }
                following = block.End - index;
                if (following >= bytesToSkip)
                {
                    _block = block;
                    _index = index + bytesToSkip;
                    return;
                }
            }
        }
        public int Take()
        {
            var block = _block;

            if (block == null)
            {
                return(-1);
            }

            var index = _index;

            if (index < block.End)
            {
                _index = index + 1;
                return(block.Data.Array[index]);
            }

            do
            {
                if (block.Next == null)
                {
                    return(-1);
                }
                else
                {
                    block = block.Next;
                    index = block.Start;
                }

                if (index < block.End)
                {
                    _block = block;
                    _index = index + 1;
                    return(block.Data.Array[index]);
                }
            } while (true);
        }
 public MemoryPoolIterator(IMemoryPoolBlock block, int index)
 {
     _block = block;
     _index = index;
 }
 public MemoryPoolIterator(IMemoryPoolBlock block)
 {
     _block = block;
     _index = _block?.Start ?? 0;
 }
Esempio n. 11
0
 public void Return(IMemoryPoolBlock leased)
 {
     ArrayPool <byte> .Shared.Return(leased.Data.Array);
 }