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