19e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project//
29e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// � Copyright Henrik Ravn 2004
39e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project//
4381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
59e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
69e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project//
79e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
89e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectusing System;
99e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectusing System.Diagnostics;
109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectnamespace DotZLib
129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project	/// <summary>
159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project	/// This class implements a circular buffer
169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project	/// </summary>
179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project	internal class CircularBuffer
189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project	{
199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        #region Private data
209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        private int _capacity;
219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        private int _head;
229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        private int _tail;
239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        private int _size;
249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        private byte[] _buffer;
259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        #endregion
269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        public CircularBuffer(int capacity)
28381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        {
299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            Debug.Assert( capacity > 0 );
309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            _buffer = new byte[capacity];
319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            _capacity = capacity;
329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            _head = 0;
339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            _tail = 0;
349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            _size = 0;
359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        public int Size { get { return _size; } }
389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        public int Put(byte[] source, int offset, int count)
409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            Debug.Assert( count > 0 );
429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            int trueCount = Math.Min(count, _capacity - Size);
439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            for (int i = 0; i < trueCount; ++i)
449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                _buffer[(_tail+i) % _capacity] = source[offset+i];
459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            _tail += trueCount;
469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            _tail %= _capacity;
479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            _size += trueCount;
489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            return trueCount;
499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        public bool Put(byte b)
529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            if (Size == _capacity) // no room
549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                return false;
559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            _buffer[_tail++] = b;
569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            _tail %= _capacity;
579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            ++_size;
589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            return true;
599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        public int Get(byte[] destination, int offset, int count)
629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            int trueCount = Math.Min(count,Size);
649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            for (int i = 0; i < trueCount; ++i)
659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                destination[offset + i] = _buffer[(_head+i) % _capacity];
669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            _head += trueCount;
679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            _head %= _capacity;
689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            _size -= trueCount;
699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            return trueCount;
709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        public int Get()
739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            if (Size == 0)
759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                return -1;
769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            int result = (int)_buffer[_head++ % _capacity];
789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            --_size;
799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            return result;
809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
84