rlm@1
|
1 /***************************************************************************
|
rlm@1
|
2 * Copyright (C) 2008 by Sindre AamÄs *
|
rlm@1
|
3 * aamas@stud.ntnu.no *
|
rlm@1
|
4 * *
|
rlm@1
|
5 * This program is free software; you can redistribute it and/or modify *
|
rlm@1
|
6 * it under the terms of the GNU General Public License version 2 as *
|
rlm@1
|
7 * published by the Free Software Foundation. *
|
rlm@1
|
8 * *
|
rlm@1
|
9 * This program is distributed in the hope that it will be useful, *
|
rlm@1
|
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
rlm@1
|
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
rlm@1
|
12 * GNU General Public License version 2 for more details. *
|
rlm@1
|
13 * *
|
rlm@1
|
14 * You should have received a copy of the GNU General Public License *
|
rlm@1
|
15 * version 2 along with this program; if not, write to the *
|
rlm@1
|
16 * Free Software Foundation, Inc., *
|
rlm@1
|
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
rlm@1
|
18 ***************************************************************************/
|
rlm@1
|
19 #ifndef RINGBUFFER_H
|
rlm@1
|
20 #define RINGBUFFER_H
|
rlm@1
|
21
|
rlm@1
|
22 #include "Array.h"
|
rlm@1
|
23 #include <cstddef>
|
rlm@1
|
24 #include <algorithm>
|
rlm@1
|
25 #include <cstring>
|
rlm@1
|
26
|
rlm@1
|
27 template<typename T>
|
rlm@1
|
28 class RingBuffer {
|
rlm@1
|
29 Array<T> buf;
|
rlm@1
|
30 std::size_t sz;
|
rlm@1
|
31 std::size_t rpos;
|
rlm@1
|
32 std::size_t wpos;
|
rlm@1
|
33
|
rlm@1
|
34 public:
|
rlm@1
|
35 RingBuffer(const std::size_t sz_in = 0) : sz(0), rpos(0), wpos(0) { reset(sz_in); }
|
rlm@1
|
36
|
rlm@1
|
37 std::size_t avail() const {
|
rlm@1
|
38 return (wpos < rpos ? 0 : sz) + rpos - wpos - 1;
|
rlm@1
|
39 }
|
rlm@1
|
40
|
rlm@1
|
41 void clear() {
|
rlm@1
|
42 wpos = rpos = 0;
|
rlm@1
|
43 }
|
rlm@1
|
44
|
rlm@1
|
45 void fill(T value);
|
rlm@1
|
46
|
rlm@1
|
47 void read(T *out, std::size_t num);
|
rlm@1
|
48
|
rlm@1
|
49 void reset(std::size_t sz_in);
|
rlm@1
|
50
|
rlm@1
|
51 std::size_t size() const {
|
rlm@1
|
52 return sz - 1;
|
rlm@1
|
53 }
|
rlm@1
|
54
|
rlm@1
|
55 std::size_t used() const {
|
rlm@1
|
56 return (wpos < rpos ? sz : 0) + wpos - rpos;
|
rlm@1
|
57 }
|
rlm@1
|
58
|
rlm@1
|
59 void write(const T *in, std::size_t num);
|
rlm@1
|
60 };
|
rlm@1
|
61
|
rlm@1
|
62 template<typename T>
|
rlm@1
|
63 void RingBuffer<T>::fill(const T value) {
|
rlm@1
|
64 std::fill(buf + 0, buf + sz, value);
|
rlm@1
|
65 rpos = 0;
|
rlm@1
|
66 wpos = sz - 1;
|
rlm@1
|
67 }
|
rlm@1
|
68
|
rlm@1
|
69 template<typename T>
|
rlm@1
|
70 void RingBuffer<T>::read(T *out, std::size_t num) {
|
rlm@1
|
71 if (rpos + num > sz) {
|
rlm@1
|
72 const std::size_t n = sz - rpos;
|
rlm@1
|
73
|
rlm@1
|
74 std::memcpy(out, buf + rpos, n * sizeof(T));
|
rlm@1
|
75
|
rlm@1
|
76 rpos = 0;
|
rlm@1
|
77 num -= n;
|
rlm@1
|
78 out += n;
|
rlm@1
|
79 }
|
rlm@1
|
80
|
rlm@1
|
81 std::memcpy(out, buf + rpos, num * sizeof(T));
|
rlm@1
|
82
|
rlm@1
|
83 if ((rpos += num) == sz)
|
rlm@1
|
84 rpos = 0;
|
rlm@1
|
85 }
|
rlm@1
|
86
|
rlm@1
|
87 template<typename T>
|
rlm@1
|
88 void RingBuffer<T>::reset(const std::size_t sz_in) {
|
rlm@1
|
89 sz = sz_in + 1;
|
rlm@1
|
90 rpos = wpos = 0;
|
rlm@1
|
91 buf.reset(sz_in ? sz : 0);
|
rlm@1
|
92 }
|
rlm@1
|
93
|
rlm@1
|
94 template<typename T>
|
rlm@1
|
95 void RingBuffer<T>::write(const T *in, std::size_t num) {
|
rlm@1
|
96 if (wpos + num > sz) {
|
rlm@1
|
97 const std::size_t n = sz - wpos;
|
rlm@1
|
98
|
rlm@1
|
99 std::memcpy(buf + wpos, in, n * sizeof(T));
|
rlm@1
|
100
|
rlm@1
|
101 wpos = 0;
|
rlm@1
|
102 num -= n;
|
rlm@1
|
103 in += n;
|
rlm@1
|
104 }
|
rlm@1
|
105
|
rlm@1
|
106 std::memcpy(buf + wpos, in, num * sizeof(T));
|
rlm@1
|
107
|
rlm@1
|
108 if ((wpos += num) == sz)
|
rlm@1
|
109 wpos = 0;
|
rlm@1
|
110 }
|
rlm@1
|
111
|
rlm@1
|
112 #endif
|