Updated FSF address in all files. Fixes ticket:51
[debian/gnuradio] / gr-error-correcting-codes / src / lib / libecc / code_io.h
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2006 Free Software Foundation, Inc.
4  * 
5  * This file is part of GNU Radio
6  * 
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)
10  * any later version.
11  * 
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.
16  * 
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.
21  */
22
23 #ifndef INCLUDED_CODE_IO_H
24 #define INCLUDED_CODE_IO_H
25
26 #include "code_types.h"
27 #include <vector>
28 #include <assert.h>
29 #include <iostream>
30
31 /*
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.
36  */
37
38 /*
39  * combined io classes
40  */
41
42 class code_io
43 {
44 public:
45   inline code_io (size_t n_streams) {
46     if (n_streams < 1) {
47       std::cerr << "code_io::code_io: Error:" <<
48         "Provided # of streams (" << n_streams <<
49         ") must be at least 1.\n";
50       assert (0);
51     }
52     d_n_streams = n_streams;
53     d_buf_ptrs.resize (d_n_streams);
54   };
55
56   virtual ~code_io () {};
57
58   inline void set_buffer (void** buffer, size_t n_items) {
59     if (buffer == 0) {
60       std::cerr << "code_io::set_buffer: Error:" <<
61         "Provided buffer is NULL.\n";
62       assert (0);
63     }
64     if (n_items == 0) {
65       std::cerr << "code_io::set_buffer: Warning:" <<
66         "Provided # of items is 0!\n";
67     }
68     d_buf = buffer;
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];
72     }
73   };
74
75   inline void set_buffer (std::vector<void*>* buffer, size_t n_items) {
76     set_buffer (&((*buffer)[0]), n_items);};
77
78   inline void set_buffer (std::vector<void*>& buffer, size_t n_items) {
79     set_buffer (&(buffer[0]), n_items);};
80
81   inline virtual void increment_indices () {
82     if (d_n_items_left == 0) {
83       std::cerr << "code_io::increment_indices: Warning: "
84         "No items left!\n";
85     } else
86       d_n_items_left--;
87   };
88
89   // methods for getting info on class internals
90
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);};
94
95 protected:
96   void** d_buf;
97   std::vector<void*> d_buf_ptrs;
98   size_t d_n_streams, d_n_items, d_n_items_left;
99 };
100
101 /*
102  * input classes
103  */
104
105 class code_input : public code_io
106 {
107 public:
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 ();};
113 };
114
115 typedef code_input* code_input_ptr;
116
117 class code_input_id : public code_input
118 {
119 private:
120   typedef double input_t;
121
122 public:
123 /*!
124  * class code_input_id : public code_input
125  *
126  * "id":
127  *   'i': one stream per code input as defined by the instantiated
128  *        code ("individual", not mux'ed);
129  *   'f': streams of double;
130  */
131   inline code_input_id (size_t n_streams) : code_input (n_streams) {};
132   virtual ~code_input_id () {};
133
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])));
138   };
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])));
144     }
145   };
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);
151     }
152   };
153 };
154
155 class code_input_if : public code_input
156 {
157 private:
158   typedef float input_t;
159
160 public:
161 /*!
162  * class code_input_if : public code_input
163  *
164  * "if":
165  *   'i': one stream per code input as defined by the instantiated
166  *        code ("individual", not mux'ed);
167  *   'f': streams of float;
168  */
169   inline code_input_if (size_t n_streams) : code_input (n_streams) {};
170   virtual ~code_input_if () {};
171
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])));
176   };
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])));
182     }
183   };
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);
189     }
190   };
191 };
192
193 class code_input_ic : public code_input
194 {
195 private:
196   typedef char input_t;
197
198 public:
199 /*!
200  * class code_input_is : public code_input
201  *
202  * "ic":
203  *   'i': one stream per code input as defined by the instantiated
204  *        code ("individual", not mux'ed);
205  *   'c': streams of char;
206  */
207   inline code_input_ic (size_t n_streams) : code_input (n_streams) {};
208   virtual ~code_input_ic () {};
209
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])));
214   };
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])));
220     }
221   };
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);
227     }
228   };
229 };
230
231 class code_input_is : public code_input
232 {
233 private:
234   typedef short input_t;
235
236 public:
237 /*!
238  * class code_input_is : public code_input
239  *
240  * "is":
241  *   'i': one stream per code input as defined by the instantiated
242  *        code ("individual", not mux'ed);
243  *   's': streams of short;
244  */
245   inline code_input_is (size_t n_streams) : code_input (n_streams) {};
246   virtual ~code_input_is () {};
247
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])));
252   };
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])));
258     }
259   };
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);
265     }
266   };
267 };
268
269 class code_input_il : public code_input
270 {
271 private:
272   typedef long input_t;
273
274 public:
275 /*!
276  * class code_input_il : public code_input
277  *
278  * "il":
279  *   'i': one stream per code input as defined by the instantiated
280  *        code ("individual", not mux'ed);
281  *   'l': streams of long;
282  */
283   inline code_input_il (size_t n_streams) : code_input (n_streams) {};
284   virtual ~code_input_il () {};
285
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])));
290   };
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])));
296     }
297   };
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);
303     }
304   };
305 };
306
307 class code_input_ill : public code_input
308 {
309 private:
310   typedef long long input_t;
311
312 public:
313 /*!
314  * class code_input_ill : public code_input
315  *
316  * "ill":
317  *   'i': one stream per code input as defined by the instantiated
318  *        code ("individual", not mux'ed);
319  *   'll': streams of long long;
320  */
321   inline code_input_ill (size_t n_streams) : code_input (n_streams) {};
322   virtual ~code_input_ill () {};
323
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])));
328   };
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])));
334     }
335   };
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);
341     }
342   };
343 };
344
345 class code_input_ic1 : public code_input
346 {
347 public:
348 /*!
349  * class code_input_ic1 : public code_input
350  *
351  * "ic":
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
357  */
358
359   inline code_input_ic1 (size_t n_streams) : code_input (n_streams) {};
360   virtual ~code_input_ic1 () {};
361
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;
366   };
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;
372     }
373   };
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);
379     }
380   };
381
382 protected:
383   char d_which_bit;
384 };
385
386 class code_input_ic1l : public code_input_ic1
387 {
388 public:
389 /*!
390  * class code_input_ic1l : public code_input_ic1
391  *
392  * "ic1l":
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. 
398  */
399
400   inline code_input_ic1l (size_t n_streams) :
401     code_input_ic1 (n_streams) {d_which_bit = 1;};
402   virtual ~code_input_ic1l () {};
403 };
404
405 class code_input_ic1h : public code_input_ic1
406 {
407 public:
408 /*!
409  * class code_input_ic1h : public code_input_ic1
410  *
411  * "ic1h":
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.
417  */
418
419   inline code_input_ic1h (size_t n_streams)
420     : code_input_ic1 (n_streams) {d_which_bit = 128;};
421   virtual ~code_input_ic1h () {};
422 };
423
424 class code_input_ic8l : public code_input_ic1l
425 {
426 protected:
427   size_t d_bit_shift;
428   const static size_t g_num_bits_per_byte = 8;
429
430 public:
431 /*!
432  * class code_input_ic8l : public code_input_ic1l
433  *
434  * "ic8l":
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
440  */
441
442   inline code_input_ic8l (size_t n_streams) :
443     code_input_ic1l (n_streams) {d_bit_shift = 0;};
444
445   virtual ~code_input_ic8l () {};
446
447   inline virtual void increment_indices () {
448     code_input::increment_indices ();
449     if (++d_bit_shift % g_num_bits_per_byte == 0) {
450       d_bit_shift = 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);
454       }
455     } else {
456       for (size_t m = 0; m < d_n_streams; m++) {
457         char* t_buf = (char*) d_buf_ptrs[m];
458         (*t_buf) >>= 1;
459       }
460     }
461   };
462 };
463
464 class code_input_ic8h : public code_input_ic1h
465 {
466 protected:
467   size_t d_bit_shift;
468   const static size_t g_num_bits_per_byte = 8;
469
470 public:
471 /*!
472  * class code_input_ic8h : public code_input_ic1h
473  *
474  * "ic8h":
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
480  */
481
482   inline code_input_ic8h (size_t n_streams) :
483     code_input_ic1h (n_streams) {d_bit_shift = 0;};
484
485   virtual ~code_input_ic8h () {};
486
487   inline virtual void increment_indices () {
488     code_input::increment_indices ();
489     if (++d_bit_shift % g_num_bits_per_byte == 0) {
490       d_bit_shift = 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);
494       }
495     } else {
496       for (size_t m = 0; m < d_n_streams; m++) {
497         char* t_buf = (char*) d_buf_ptrs[m];
498         (*t_buf) <<= 1;
499       }
500     }
501   };
502 };
503
504 /*
505  * output classes
506  */
507
508 class code_output : public code_io
509 {
510 public:
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 ();};
516 };
517
518 typedef code_output* code_output_ptr;
519
520 class code_output_ic1l : public code_output
521 {
522 public:
523 /*!
524  * class code_output_ic1l : public code_output
525  *
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).
531  */
532
533   inline code_output_ic1l (size_t n_streams) : code_output (n_streams) {};
534   virtual ~code_output_ic1l () {};
535
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;
540   };
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;
546   };
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);
552     }
553   };
554 };
555
556 #endif /* INCLUDED_CODE_IO_H */