3 * Copyright 2006 Free Software Foundation, Inc.
5 * This file is part of GNU Radio
7 * GNU Radio is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
12 * GNU Radio is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Radio; see the file COPYING. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street,
20 * Boston, MA 02110-1301, USA.
23 #ifndef INCLUDED_CODE_IO_H
24 #define INCLUDED_CODE_IO_H
26 #include "code_types.h"
32 * code_io provides classes which do the input and output for these
33 * codes. One can add another class with its specific needs primarily
34 * by changing the way that the provided data is manipulated to read
35 * or write data items.
45 inline code_io (size_t n_streams) {
47 std::cerr << "code_io::code_io: Error:" <<
48 "Provided # of streams (" << n_streams <<
49 ") must be at least 1.\n";
52 d_n_streams = n_streams;
53 d_buf_ptrs.resize (d_n_streams);
56 virtual ~code_io () {};
58 inline void set_buffer (void** buffer, size_t n_items) {
60 std::cerr << "code_io::set_buffer: Error:" <<
61 "Provided buffer is NULL.\n";
65 std::cerr << "code_io::set_buffer: Warning:" <<
66 "Provided # of items is 0!\n";
69 d_n_items = d_n_items_left = n_items;
70 for (size_t m = 0; m < d_n_streams; m++) {
71 d_buf_ptrs[m] = d_buf[m];
75 inline void set_buffer (std::vector<void*>* buffer, size_t n_items) {
76 set_buffer (&((*buffer)[0]), n_items);};
78 inline void set_buffer (std::vector<void*>& buffer, size_t n_items) {
79 set_buffer (&(buffer[0]), n_items);};
81 inline virtual void increment_indices () {
82 if (d_n_items_left == 0) {
83 std::cerr << "code_io::increment_indices: Warning: "
89 // methods for getting info on class internals
91 const size_t& n_items_left () {return (d_n_items_left);};
92 const size_t n_items_used () {return (d_n_items - d_n_items_left);};
93 const size_t n_streams () {return (d_n_streams);};
97 std::vector<void*> d_buf_ptrs;
98 size_t d_n_streams, d_n_items, d_n_items_left;
105 class code_input : public code_io
108 inline code_input (size_t n_streams) : code_io (n_streams) {};
109 virtual ~code_input () {};
110 virtual void read_item (void* item, size_t stream_n) = 0;
111 virtual void read_items (void* items) = 0;
112 inline virtual void increment_indices () {code_io::increment_indices ();};
115 typedef code_input* code_input_ptr;
117 class code_input_id : public code_input
120 typedef double input_t;
124 * class code_input_id : public code_input
127 * 'i': one stream per code input as defined by the instantiated
128 * code ("individual", not mux'ed);
129 * 'f': streams of double;
131 inline code_input_id (size_t n_streams) : code_input (n_streams) {};
132 virtual ~code_input_id () {};
134 inline virtual void read_item (void* item, size_t stream_n) {
135 /* no error checking for better speed! */
136 input_t* t_item = (input_t*) item;
137 (*t_item) = (*((input_t*)(d_buf_ptrs[stream_n])));
139 inline virtual void read_items (void* items) {
140 /* no error checking for better speed! */
141 input_t* t_items = (input_t*) items;
142 for (size_t m = 0; m < d_n_streams; m++) {
143 t_items[m] = (*((input_t*)(d_buf_ptrs[m])));
146 inline virtual void increment_indices () {
147 code_input::increment_indices ();
148 for (size_t m = 0; m < d_n_streams; m++) {
149 input_t* t_buf = (input_t*) d_buf_ptrs[m];
150 d_buf_ptrs[m] = (void*)(++t_buf);
155 class code_input_if : public code_input
158 typedef float input_t;
162 * class code_input_if : public code_input
165 * 'i': one stream per code input as defined by the instantiated
166 * code ("individual", not mux'ed);
167 * 'f': streams of float;
169 inline code_input_if (size_t n_streams) : code_input (n_streams) {};
170 virtual ~code_input_if () {};
172 inline virtual void read_item (void* item, size_t stream_n) {
173 /* no error checking for better speed! */
174 input_t* t_item = (input_t*) item;
175 (*t_item) = (*((input_t*)(d_buf_ptrs[stream_n])));
177 inline virtual void read_items (void* items) {
178 /* no error checking for better speed! */
179 input_t* t_items = (input_t*) items;
180 for (size_t m = 0; m < d_n_streams; m++) {
181 t_items[m] = (*((input_t*)(d_buf_ptrs[m])));
184 inline virtual void increment_indices () {
185 code_input::increment_indices ();
186 for (size_t m = 0; m < d_n_streams; m++) {
187 input_t* t_buf = (input_t*) d_buf_ptrs[m];
188 d_buf_ptrs[m] = (void*)(++t_buf);
193 class code_input_ic : public code_input
196 typedef char input_t;
200 * class code_input_is : public code_input
203 * 'i': one stream per code input as defined by the instantiated
204 * code ("individual", not mux'ed);
205 * 'c': streams of char;
207 inline code_input_ic (size_t n_streams) : code_input (n_streams) {};
208 virtual ~code_input_ic () {};
210 inline virtual void read_item (void* item, size_t stream_n) {
211 /* no error checking for better speed! */
212 input_t* t_item = (input_t*) item;
213 (*t_item) = (*((input_t*)(d_buf_ptrs[stream_n])));
215 inline virtual void read_items (void* items) {
216 /* no error checking for better speed! */
217 input_t* t_items = (input_t*) items;
218 for (size_t m = 0; m < d_n_streams; m++) {
219 t_items[m] = (*((input_t*)(d_buf_ptrs[m])));
222 inline virtual void increment_indices () {
223 code_input::increment_indices ();
224 for (size_t m = 0; m < d_n_streams; m++) {
225 input_t* t_buf = (input_t*) d_buf_ptrs[m];
226 d_buf_ptrs[m] = (void*)(++t_buf);
231 class code_input_is : public code_input
234 typedef short input_t;
238 * class code_input_is : public code_input
241 * 'i': one stream per code input as defined by the instantiated
242 * code ("individual", not mux'ed);
243 * 's': streams of short;
245 inline code_input_is (size_t n_streams) : code_input (n_streams) {};
246 virtual ~code_input_is () {};
248 inline virtual void read_item (void* item, size_t stream_n) {
249 /* no error checking for better speed! */
250 input_t* t_item = (input_t*) item;
251 (*t_item) = (*((input_t*)(d_buf_ptrs[stream_n])));
253 inline virtual void read_items (void* items) {
254 /* no error checking for better speed! */
255 input_t* t_items = (input_t*) items;
256 for (size_t m = 0; m < d_n_streams; m++) {
257 t_items[m] = (*((input_t*)(d_buf_ptrs[m])));
260 inline virtual void increment_indices () {
261 code_input::increment_indices ();
262 for (size_t m = 0; m < d_n_streams; m++) {
263 input_t* t_buf = (input_t*) d_buf_ptrs[m];
264 d_buf_ptrs[m] = (void*)(++t_buf);
269 class code_input_il : public code_input
272 typedef long input_t;
276 * class code_input_il : public code_input
279 * 'i': one stream per code input as defined by the instantiated
280 * code ("individual", not mux'ed);
281 * 'l': streams of long;
283 inline code_input_il (size_t n_streams) : code_input (n_streams) {};
284 virtual ~code_input_il () {};
286 inline virtual void read_item (void* item, size_t stream_n) {
287 /* no error checking for better speed! */
288 input_t* t_item = (input_t*) item;
289 (*t_item) = (*((input_t*)(d_buf_ptrs[stream_n])));
291 inline virtual void read_items (void* items) {
292 /* no error checking for better speed! */
293 input_t* t_items = (input_t*) items;
294 for (size_t m = 0; m < d_n_streams; m++) {
295 t_items[m] = (*((input_t*)(d_buf_ptrs[m])));
298 inline virtual void increment_indices () {
299 code_input::increment_indices ();
300 for (size_t m = 0; m < d_n_streams; m++) {
301 input_t* t_buf = (input_t*) d_buf_ptrs[m];
302 d_buf_ptrs[m] = (void*)(++t_buf);
307 class code_input_ill : public code_input
310 typedef long long input_t;
314 * class code_input_ill : public code_input
317 * 'i': one stream per code input as defined by the instantiated
318 * code ("individual", not mux'ed);
319 * 'll': streams of long long;
321 inline code_input_ill (size_t n_streams) : code_input (n_streams) {};
322 virtual ~code_input_ill () {};
324 inline virtual void read_item (void* item, size_t stream_n) {
325 /* no error checking for better speed! */
326 input_t* t_item = (input_t*) item;
327 (*t_item) = (*((input_t*)(d_buf_ptrs[stream_n])));
329 inline virtual void read_items (void* items) {
330 /* no error checking for better speed! */
331 input_t* t_items = (input_t*) items;
332 for (size_t m = 0; m < d_n_streams; m++) {
333 t_items[m] = (*((input_t*)(d_buf_ptrs[m])));
336 inline virtual void increment_indices () {
337 code_input::increment_indices ();
338 for (size_t m = 0; m < d_n_streams; m++) {
339 input_t* t_buf = (input_t*) d_buf_ptrs[m];
340 d_buf_ptrs[m] = (void*)(++t_buf);
345 class code_input_ic1 : public code_input
349 * class code_input_ic1 : public code_input
352 * 'i': one stream per code input as defined by the instantiated
353 * code ("individual", not mux'ed);
354 * 'c': streams of char;
355 * '1': single bit per char;
356 * --> which bit to choose left to an inheriting class
359 inline code_input_ic1 (size_t n_streams) : code_input (n_streams) {};
360 virtual ~code_input_ic1 () {};
362 inline virtual void read_item (void* item, size_t stream_n) {
363 /* no error checking for better speed! */
364 char* t_item = (char*) item;
365 (*t_item) = (*((char*)(d_buf_ptrs[stream_n]))) & d_which_bit;
367 inline virtual void read_items (void* items) {
368 /* no error checking for better speed! */
369 char* t_items = (char*) items;
370 for (size_t m = 0; m < d_n_streams; m++) {
371 t_items[m] = (*((char*)(d_buf_ptrs[m]))) & d_which_bit;
374 inline virtual void increment_indices () {
375 code_input::increment_indices ();
376 for (size_t m = 0; m < d_n_streams; m++) {
377 char* t_buf = (char*) d_buf_ptrs[m];
378 d_buf_ptrs[m] = (void*)(++t_buf);
386 class code_input_ic1l : public code_input_ic1
390 * class code_input_ic1l : public code_input_ic1
393 * 'i': one stream per code input as defined by the instantiated
394 * code ("individual", not mux'ed);
395 * 'c': streams of char;
396 * '1': single bit per char;
397 * 'l': using only the LSB of the char.
400 inline code_input_ic1l (size_t n_streams) :
401 code_input_ic1 (n_streams) {d_which_bit = 1;};
402 virtual ~code_input_ic1l () {};
405 class code_input_ic1h : public code_input_ic1
409 * class code_input_ic1h : public code_input_ic1
412 * 'i': one stream per code input as defined by the instantiated
413 * code ("individual", not mux'ed);
414 * 'c': streams of char;
415 * '1': single bit per char;
416 * 'h': using only the MSB of the char.
419 inline code_input_ic1h (size_t n_streams)
420 : code_input_ic1 (n_streams) {d_which_bit = 128;};
421 virtual ~code_input_ic1h () {};
424 class code_input_ic8l : public code_input_ic1l
428 const static size_t g_num_bits_per_byte = 8;
432 * class code_input_ic8l : public code_input_ic1l
435 * 'i': one stream per code input as defined by the instantiated
436 * code ("individual", not mux'ed);
437 * 'c': streams of char;
438 * '8': using all 8 bits per char;
439 * 'l': starting with the LSB and working up
442 inline code_input_ic8l (size_t n_streams) :
443 code_input_ic1l (n_streams) {d_bit_shift = 0;};
445 virtual ~code_input_ic8l () {};
447 inline virtual void increment_indices () {
448 code_input::increment_indices ();
449 if (++d_bit_shift % g_num_bits_per_byte == 0) {
451 for (size_t m = 0; m < d_n_streams; m++) {
452 char* t_buf = (char*) d_buf_ptrs[m];
453 d_buf_ptrs[m] = (void*)(++t_buf);
456 for (size_t m = 0; m < d_n_streams; m++) {
457 char* t_buf = (char*) d_buf_ptrs[m];
464 class code_input_ic8h : public code_input_ic1h
468 const static size_t g_num_bits_per_byte = 8;
472 * class code_input_ic8h : public code_input_ic1h
475 * 'i': one stream per code input as defined by the instantiated
476 * code ("individual", not mux'ed);
477 * 'c': streams of char;
478 * '8': using all 8 bits per char;
479 * 'h': starting with the MSB and working down
482 inline code_input_ic8h (size_t n_streams) :
483 code_input_ic1h (n_streams) {d_bit_shift = 0;};
485 virtual ~code_input_ic8h () {};
487 inline virtual void increment_indices () {
488 code_input::increment_indices ();
489 if (++d_bit_shift % g_num_bits_per_byte == 0) {
491 for (size_t m = 0; m < d_n_streams; m++) {
492 char* t_buf = (char*) d_buf_ptrs[m];
493 d_buf_ptrs[m] = (void*)(++t_buf);
496 for (size_t m = 0; m < d_n_streams; m++) {
497 char* t_buf = (char*) d_buf_ptrs[m];
508 class code_output : public code_io
511 code_output (size_t n_streams) : code_io (n_streams) {};
512 virtual ~code_output () {};
513 virtual void write_item (const void* item, size_t stream_n) = 0;
514 virtual void write_items (const void* items) = 0;
515 virtual inline void increment_indices () {code_io::increment_indices ();};
518 typedef code_output* code_output_ptr;
520 class code_output_ic1l : public code_output
524 * class code_output_ic1l : public code_output
526 * 'i': one stream per code input as defined by the instantiated
527 * code ("individual", not mux'ed);
528 * 'c': streams of char;
529 * '1': single bit per char;
530 * 'l': using only the right-most justified (LSB).
533 inline code_output_ic1l (size_t n_streams) : code_output (n_streams) {};
534 virtual ~code_output_ic1l () {};
536 inline virtual void write_item (const void* item, size_t stream_n) {
537 /* no error checking for better speed! */
538 const char* t_item = (char*) item;
539 (*((char*)(d_buf_ptrs[stream_n]))) = (*t_item) & 1;
541 inline virtual void write_items (const void* items) {
542 /* no error checking for better speed! */
543 const char* t_items = (char*) items;
544 for (size_t m = 0; m < d_n_streams; m++)
545 (*((char*)(d_buf_ptrs[m]))) = (t_items[m]) & 1;
547 inline virtual void increment_indices () {
548 code_output::increment_indices ();
549 for (size_t m = 0; m < d_n_streams; m++) {
550 char* t_buf = (char*) d_buf_ptrs[m];
551 d_buf_ptrs[m] = (void*)(++t_buf);
556 #endif /* INCLUDED_CODE_IO_H */