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