Chris@43: // Chris@43: // © Copyright Henrik Ravn 2004 Chris@43: // Chris@43: // Use, modification and distribution are subject to the Boost Software License, Version 1.0. Chris@43: // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@43: // Chris@43: Chris@43: using System; Chris@43: using System.Diagnostics; Chris@43: Chris@43: namespace DotZLib Chris@43: { Chris@43: Chris@43: /// Chris@43: /// This class implements a circular buffer Chris@43: /// Chris@43: internal class CircularBuffer Chris@43: { Chris@43: #region Private data Chris@43: private int _capacity; Chris@43: private int _head; Chris@43: private int _tail; Chris@43: private int _size; Chris@43: private byte[] _buffer; Chris@43: #endregion Chris@43: Chris@43: public CircularBuffer(int capacity) Chris@43: { Chris@43: Debug.Assert( capacity > 0 ); Chris@43: _buffer = new byte[capacity]; Chris@43: _capacity = capacity; Chris@43: _head = 0; Chris@43: _tail = 0; Chris@43: _size = 0; Chris@43: } Chris@43: Chris@43: public int Size { get { return _size; } } Chris@43: Chris@43: public int Put(byte[] source, int offset, int count) Chris@43: { Chris@43: Debug.Assert( count > 0 ); Chris@43: int trueCount = Math.Min(count, _capacity - Size); Chris@43: for (int i = 0; i < trueCount; ++i) Chris@43: _buffer[(_tail+i) % _capacity] = source[offset+i]; Chris@43: _tail += trueCount; Chris@43: _tail %= _capacity; Chris@43: _size += trueCount; Chris@43: return trueCount; Chris@43: } Chris@43: Chris@43: public bool Put(byte b) Chris@43: { Chris@43: if (Size == _capacity) // no room Chris@43: return false; Chris@43: _buffer[_tail++] = b; Chris@43: _tail %= _capacity; Chris@43: ++_size; Chris@43: return true; Chris@43: } Chris@43: Chris@43: public int Get(byte[] destination, int offset, int count) Chris@43: { Chris@43: int trueCount = Math.Min(count,Size); Chris@43: for (int i = 0; i < trueCount; ++i) Chris@43: destination[offset + i] = _buffer[(_head+i) % _capacity]; Chris@43: _head += trueCount; Chris@43: _head %= _capacity; Chris@43: _size -= trueCount; Chris@43: return trueCount; Chris@43: } Chris@43: Chris@43: public int Get() Chris@43: { Chris@43: if (Size == 0) Chris@43: return -1; Chris@43: Chris@43: int result = (int)_buffer[_head++ % _capacity]; Chris@43: --_size; Chris@43: return result; Chris@43: } Chris@43: Chris@43: } Chris@43: }