/// <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; } } }
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; }
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; }
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."); } } }
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; }
public void Return(IMemoryPoolBlock leased) { ArrayPool <byte> .Shared.Return(leased.Data.Array); }