1275793eaSopenharmony_ci// 2275793eaSopenharmony_ci// � Copyright Henrik Ravn 2004 3275793eaSopenharmony_ci// 4275793eaSopenharmony_ci// Use, modification and distribution are subject to the Boost Software License, Version 1.0. 5275793eaSopenharmony_ci// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6275793eaSopenharmony_ci// 7275793eaSopenharmony_ci 8275793eaSopenharmony_ciusing System; 9275793eaSopenharmony_ciusing System.Diagnostics; 10275793eaSopenharmony_ci 11275793eaSopenharmony_cinamespace DotZLib 12275793eaSopenharmony_ci{ 13275793eaSopenharmony_ci 14275793eaSopenharmony_ci /// <summary> 15275793eaSopenharmony_ci /// This class implements a circular buffer 16275793eaSopenharmony_ci /// </summary> 17275793eaSopenharmony_ci internal class CircularBuffer 18275793eaSopenharmony_ci { 19275793eaSopenharmony_ci #region Private data 20275793eaSopenharmony_ci private int _capacity; 21275793eaSopenharmony_ci private int _head; 22275793eaSopenharmony_ci private int _tail; 23275793eaSopenharmony_ci private int _size; 24275793eaSopenharmony_ci private byte[] _buffer; 25275793eaSopenharmony_ci #endregion 26275793eaSopenharmony_ci 27275793eaSopenharmony_ci public CircularBuffer(int capacity) 28275793eaSopenharmony_ci { 29275793eaSopenharmony_ci Debug.Assert( capacity > 0 ); 30275793eaSopenharmony_ci _buffer = new byte[capacity]; 31275793eaSopenharmony_ci _capacity = capacity; 32275793eaSopenharmony_ci _head = 0; 33275793eaSopenharmony_ci _tail = 0; 34275793eaSopenharmony_ci _size = 0; 35275793eaSopenharmony_ci } 36275793eaSopenharmony_ci 37275793eaSopenharmony_ci public int Size { get { return _size; } } 38275793eaSopenharmony_ci 39275793eaSopenharmony_ci public int Put(byte[] source, int offset, int count) 40275793eaSopenharmony_ci { 41275793eaSopenharmony_ci Debug.Assert( count > 0 ); 42275793eaSopenharmony_ci int trueCount = Math.Min(count, _capacity - Size); 43275793eaSopenharmony_ci for (int i = 0; i < trueCount; ++i) 44275793eaSopenharmony_ci _buffer[(_tail+i) % _capacity] = source[offset+i]; 45275793eaSopenharmony_ci _tail += trueCount; 46275793eaSopenharmony_ci _tail %= _capacity; 47275793eaSopenharmony_ci _size += trueCount; 48275793eaSopenharmony_ci return trueCount; 49275793eaSopenharmony_ci } 50275793eaSopenharmony_ci 51275793eaSopenharmony_ci public bool Put(byte b) 52275793eaSopenharmony_ci { 53275793eaSopenharmony_ci if (Size == _capacity) // no room 54275793eaSopenharmony_ci return false; 55275793eaSopenharmony_ci _buffer[_tail++] = b; 56275793eaSopenharmony_ci _tail %= _capacity; 57275793eaSopenharmony_ci ++_size; 58275793eaSopenharmony_ci return true; 59275793eaSopenharmony_ci } 60275793eaSopenharmony_ci 61275793eaSopenharmony_ci public int Get(byte[] destination, int offset, int count) 62275793eaSopenharmony_ci { 63275793eaSopenharmony_ci int trueCount = Math.Min(count,Size); 64275793eaSopenharmony_ci for (int i = 0; i < trueCount; ++i) 65275793eaSopenharmony_ci destination[offset + i] = _buffer[(_head+i) % _capacity]; 66275793eaSopenharmony_ci _head += trueCount; 67275793eaSopenharmony_ci _head %= _capacity; 68275793eaSopenharmony_ci _size -= trueCount; 69275793eaSopenharmony_ci return trueCount; 70275793eaSopenharmony_ci } 71275793eaSopenharmony_ci 72275793eaSopenharmony_ci public int Get() 73275793eaSopenharmony_ci { 74275793eaSopenharmony_ci if (Size == 0) 75275793eaSopenharmony_ci return -1; 76275793eaSopenharmony_ci 77275793eaSopenharmony_ci int result = (int)_buffer[_head++ % _capacity]; 78275793eaSopenharmony_ci --_size; 79275793eaSopenharmony_ci return result; 80275793eaSopenharmony_ci } 81275793eaSopenharmony_ci 82275793eaSopenharmony_ci } 83275793eaSopenharmony_ci} 84