1*44bedb31SLionel Sambuc // 2*44bedb31SLionel Sambuc // � Copyright Henrik Ravn 2004 3*44bedb31SLionel Sambuc // 4*44bedb31SLionel Sambuc // Use, modification and distribution are subject to the Boost Software License, Version 1.0. 5*44bedb31SLionel Sambuc // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6*44bedb31SLionel Sambuc // 7*44bedb31SLionel Sambuc 8*44bedb31SLionel Sambuc using System; 9*44bedb31SLionel Sambuc using System.Diagnostics; 10*44bedb31SLionel Sambuc 11*44bedb31SLionel Sambuc namespace DotZLib 12*44bedb31SLionel Sambuc { 13*44bedb31SLionel Sambuc 14*44bedb31SLionel Sambuc /// <summary> 15*44bedb31SLionel Sambuc /// This class implements a circular buffer 16*44bedb31SLionel Sambuc /// </summary> 17*44bedb31SLionel Sambuc internal class CircularBuffer 18*44bedb31SLionel Sambuc { 19*44bedb31SLionel Sambuc #region Private data 20*44bedb31SLionel Sambuc private int _capacity; 21*44bedb31SLionel Sambuc private int _head; 22*44bedb31SLionel Sambuc private int _tail; 23*44bedb31SLionel Sambuc private int _size; 24*44bedb31SLionel Sambuc private byte[] _buffer; 25*44bedb31SLionel Sambuc #endregion 26*44bedb31SLionel Sambuc CircularBuffer(int capacity)27*44bedb31SLionel Sambuc public CircularBuffer(int capacity) 28*44bedb31SLionel Sambuc { 29*44bedb31SLionel Sambuc Debug.Assert( capacity > 0 ); 30*44bedb31SLionel Sambuc _buffer = new byte[capacity]; 31*44bedb31SLionel Sambuc _capacity = capacity; 32*44bedb31SLionel Sambuc _head = 0; 33*44bedb31SLionel Sambuc _tail = 0; 34*44bedb31SLionel Sambuc _size = 0; 35*44bedb31SLionel Sambuc } 36*44bedb31SLionel Sambuc 37*44bedb31SLionel Sambuc public int Size { get { return _size; } } 38*44bedb31SLionel Sambuc Put(byte[] source, int offset, int count)39*44bedb31SLionel Sambuc public int Put(byte[] source, int offset, int count) 40*44bedb31SLionel Sambuc { 41*44bedb31SLionel Sambuc Debug.Assert( count > 0 ); 42*44bedb31SLionel Sambuc int trueCount = Math.Min(count, _capacity - Size); 43*44bedb31SLionel Sambuc for (int i = 0; i < trueCount; ++i) 44*44bedb31SLionel Sambuc _buffer[(_tail+i) % _capacity] = source[offset+i]; 45*44bedb31SLionel Sambuc _tail += trueCount; 46*44bedb31SLionel Sambuc _tail %= _capacity; 47*44bedb31SLionel Sambuc _size += trueCount; 48*44bedb31SLionel Sambuc return trueCount; 49*44bedb31SLionel Sambuc } 50*44bedb31SLionel Sambuc Put(byte b)51*44bedb31SLionel Sambuc public bool Put(byte b) 52*44bedb31SLionel Sambuc { 53*44bedb31SLionel Sambuc if (Size == _capacity) // no room 54*44bedb31SLionel Sambuc return false; 55*44bedb31SLionel Sambuc _buffer[_tail++] = b; 56*44bedb31SLionel Sambuc _tail %= _capacity; 57*44bedb31SLionel Sambuc ++_size; 58*44bedb31SLionel Sambuc return true; 59*44bedb31SLionel Sambuc } 60*44bedb31SLionel Sambuc Get(byte[] destination, int offset, int count)61*44bedb31SLionel Sambuc public int Get(byte[] destination, int offset, int count) 62*44bedb31SLionel Sambuc { 63*44bedb31SLionel Sambuc int trueCount = Math.Min(count,Size); 64*44bedb31SLionel Sambuc for (int i = 0; i < trueCount; ++i) 65*44bedb31SLionel Sambuc destination[offset + i] = _buffer[(_head+i) % _capacity]; 66*44bedb31SLionel Sambuc _head += trueCount; 67*44bedb31SLionel Sambuc _head %= _capacity; 68*44bedb31SLionel Sambuc _size -= trueCount; 69*44bedb31SLionel Sambuc return trueCount; 70*44bedb31SLionel Sambuc } 71*44bedb31SLionel Sambuc Get()72*44bedb31SLionel Sambuc public int Get() 73*44bedb31SLionel Sambuc { 74*44bedb31SLionel Sambuc if (Size == 0) 75*44bedb31SLionel Sambuc return -1; 76*44bedb31SLionel Sambuc 77*44bedb31SLionel Sambuc int result = (int)_buffer[_head++ % _capacity]; 78*44bedb31SLionel Sambuc --_size; 79*44bedb31SLionel Sambuc return result; 80*44bedb31SLionel Sambuc } 81*44bedb31SLionel Sambuc 82*44bedb31SLionel Sambuc } 83*44bedb31SLionel Sambuc } 84