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