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