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