Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | /*****************************************************************************\r |
2 | \r | |
3 | The following code is derived, directly or indirectly, from the SystemC\r | |
4 | source code Copyright (c) 1996-2004 by all Contributors.\r | |
5 | All Rights reserved.\r | |
6 | \r | |
7 | The contents of this file are subject to the restrictions and limitations\r | |
8 | set forth in the SystemC Open Source License Version 2.4 (the "License");\r | |
9 | You may not use this file except in compliance with such restrictions and\r | |
10 | limitations. You may obtain instructions on how to receive a copy of the\r | |
11 | License at http://www.systemc.org/. Software distributed by Contributors\r | |
12 | under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF\r | |
13 | ANY KIND, either express or implied. See the License for the specific\r | |
14 | language governing rights and limitations under the License.\r | |
15 | \r | |
16 | *****************************************************************************/\r | |
17 | \r | |
18 | \r | |
19 | //\r | |
20 | // To the LRM writer : this class is purely an artifact of the implementation.\r | |
21 | //\r | |
22 | \r | |
23 | #ifndef CIRCULAR_BUFFER_HEADER\r | |
24 | #define CIRCULAR_BUFFER_HEADER\r | |
25 | \r | |
26 | #include <iostream>\r | |
27 | \r | |
28 | using std::cout;\r | |
29 | using std::endl;\r | |
30 | \r | |
31 | template < typename T >\r | |
32 | class circular_buffer\r | |
33 | {\r | |
34 | public:\r | |
35 | circular_buffer( int size );\r | |
36 | \r | |
37 | circular_buffer<T> &operator=( const circular_buffer<T> & ); \r | |
38 | \r | |
39 | ~circular_buffer() { delete [] m_buf; }\r | |
40 | \r | |
41 | void resize( int size );\r | |
42 | \r | |
43 | const T &read();\r | |
44 | void write( const T & );\r | |
45 | \r | |
46 | bool is_empty() const { return used() == 0; }\r | |
47 | bool is_full() const { return free() == 0; }\r | |
48 | \r | |
49 | int size() const { return m_size; }\r | |
50 | int used() const { return m_used; }\r | |
51 | int free() const { return m_free; }\r | |
52 | \r | |
53 | T &write_data() { return m_buf[m_wi]; }\r | |
54 | const T &read_data() const { return m_buf[m_ri]; }\r | |
55 | \r | |
56 | const T &peek_data( int i ) const { return m_buf[(m_ri + i) % size()]; }\r | |
57 | T &poke_data( int i ) { return m_buf[(m_ri + i) % size()]; }\r | |
58 | \r | |
59 | void increment_write_pos( int i = 1 );\r | |
60 | void increment_read_pos( int i = 1 );\r | |
61 | \r | |
62 | void init();\r | |
63 | \r | |
64 | void debug() const;\r | |
65 | \r | |
66 | private:\r | |
67 | circular_buffer( const circular_buffer<T> &b ); // disabled\r | |
68 | void copy( const circular_buffer<T> &b );\r | |
69 | \r | |
70 | private:\r | |
71 | int m_size; // size of the buffer\r | |
72 | T* m_buf; // the buffer\r | |
73 | int m_free; // number of free spaces\r | |
74 | int m_used; // number of used spaces\r | |
75 | int m_ri; // index of next read\r | |
76 | int m_wi; // index of next write\r | |
77 | \r | |
78 | };\r | |
79 | \r | |
80 | template< typename T >\r | |
81 | void\r | |
82 | circular_buffer<T>::debug() const\r | |
83 | {\r | |
84 | \r | |
85 | cout << "Buffer debug" << endl;\r | |
86 | cout << "Size : " << size() << endl;\r | |
87 | cout << "Free/Used " << free() << "/" << used() << endl;\r | |
88 | cout << "Indeces : r/w = " << m_ri << "/" << m_wi << endl;\r | |
89 | \r | |
90 | if( is_empty() ) {\r | |
91 | \r | |
92 | cout << "empty" << endl;\r | |
93 | \r | |
94 | }\r | |
95 | \r | |
96 | if( is_full() ) {\r | |
97 | \r | |
98 | cout << "full" << endl;\r | |
99 | \r | |
100 | }\r | |
101 | \r | |
102 | cout << "Data : " << endl;\r | |
103 | for( int i = 0; i < used(); i++ ) {\r | |
104 | \r | |
105 | cout << peek_data( i ) << endl;\r | |
106 | \r | |
107 | }\r | |
108 | \r | |
109 | \r | |
110 | }\r | |
111 | \r | |
112 | template < typename T >\r | |
113 | circular_buffer<T>::\r | |
114 | circular_buffer( int size ) {\r | |
115 | \r | |
116 | m_size = size;\r | |
117 | m_buf = new T[m_size];\r | |
118 | \r | |
119 | init();\r | |
120 | \r | |
121 | }\r | |
122 | \r | |
123 | template < typename T >\r | |
124 | circular_buffer<T> &\r | |
125 | circular_buffer<T>::operator=( const circular_buffer<T> &b ) {\r | |
126 | \r | |
127 | init();\r | |
128 | \r | |
129 | for( int i = 0; i < size() && i < b.used(); i++ ) {\r | |
130 | \r | |
131 | write( b.peek_data( i ) );\r | |
132 | \r | |
133 | }\r | |
134 | \r | |
135 | return *this;\r | |
136 | \r | |
137 | }\r | |
138 | \r | |
139 | template < typename T >\r | |
140 | void\r | |
141 | circular_buffer<T>::resize( int size )\r | |
142 | {\r | |
143 | \r | |
144 | int i;\r | |
145 | T *new_buf = new T[size];\r | |
146 | \r | |
147 | for( i = 0; i < size && i < used(); i++ ) {\r | |
148 | \r | |
149 | new_buf[i] = peek_data( i );\r | |
150 | \r | |
151 | }\r | |
152 | \r | |
153 | delete [] m_buf;\r | |
154 | \r | |
155 | m_size = size;\r | |
156 | m_ri = 0;\r | |
157 | m_wi = i % m_size;\r | |
158 | m_used = i;\r | |
159 | m_free = m_size - m_used;\r | |
160 | \r | |
161 | m_buf = new_buf;\r | |
162 | \r | |
163 | }\r | |
164 | \r | |
165 | \r | |
166 | template < typename T >\r | |
167 | void\r | |
168 | circular_buffer<T>::init() {\r | |
169 | \r | |
170 | m_free = m_size;\r | |
171 | m_used = 0;\r | |
172 | m_ri = 0;\r | |
173 | m_wi = 0;\r | |
174 | \r | |
175 | }\r | |
176 | \r | |
177 | template < typename T >\r | |
178 | void\r | |
179 | circular_buffer<T>::copy( const circular_buffer<T> &b )\r | |
180 | {\r | |
181 | \r | |
182 | m_size = b.m_size; // size of the buffer\r | |
183 | m_buf = b.m_buf; // the buffer\r | |
184 | m_free = b.m_free; // number of free spaces\r | |
185 | m_used = b.m_used; // number of used spaces\r | |
186 | m_ri = b.m_ri; // index of next read\r | |
187 | m_wi = b.m_wi; // index of next write \r | |
188 | \r | |
189 | }\r | |
190 | \r | |
191 | template < typename T >\r | |
192 | const T &\r | |
193 | circular_buffer<T>::read()\r | |
194 | {\r | |
195 | \r | |
196 | const T &t = read_data();\r | |
197 | \r | |
198 | increment_read_pos();\r | |
199 | \r | |
200 | return t;\r | |
201 | \r | |
202 | }\r | |
203 | \r | |
204 | template < typename T >\r | |
205 | void\r | |
206 | circular_buffer<T>::write( const T &t )\r | |
207 | {\r | |
208 | \r | |
209 | write_data() = t;\r | |
210 | increment_write_pos();\r | |
211 | \r | |
212 | }\r | |
213 | \r | |
214 | \r | |
215 | template < typename T >\r | |
216 | void\r | |
217 | circular_buffer<T>::increment_write_pos( int i ) {\r | |
218 | \r | |
219 | m_wi = ( m_wi + i ) % m_size;\r | |
220 | m_used += i;\r | |
221 | m_free -= i;\r | |
222 | \r | |
223 | }\r | |
224 | \r | |
225 | template < typename T >\r | |
226 | void\r | |
227 | circular_buffer<T>::increment_read_pos( int i ) {\r | |
228 | \r | |
229 | m_ri = ( m_ri + i ) % m_size;\r | |
230 | m_used -= i;\r | |
231 | m_free += i;\r | |
232 | \r | |
233 | }\r | |
234 | \r | |
235 | #endif\r | |
236 | \r |