Imported Upstream version 3.2.2
[debian/gnuradio] / gnuradio-core / src / lib / general / gr_test.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2006,2008 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 3, 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 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <gr_test.h>
28 #include <gr_io_signature.h>
29 #include <stdexcept>
30 #include <iostream>
31 #include <string.h>
32
33 gr_test_sptr gr_make_test (const std::string &name,
34         int min_inputs, int max_inputs, unsigned int sizeof_input_item,
35         int min_outputs, int max_outputs, unsigned int sizeof_output_item,
36         unsigned int history,unsigned int output_multiple,double relative_rate,
37         bool fixed_rate,gr_consume_type_t cons_type, gr_produce_type_t prod_type)
38 {
39   return gr_test_sptr (new gr_test (name, min_inputs,max_inputs,sizeof_input_item,
40              min_outputs,max_outputs,sizeof_output_item,
41              history,output_multiple,relative_rate,fixed_rate,cons_type, prod_type));
42 }
43
44   gr_test::gr_test (const std::string &name,int min_inputs, int max_inputs, unsigned int sizeof_input_item,
45                                    int min_outputs, int max_outputs, unsigned int sizeof_output_item,
46                                    unsigned int history,unsigned int output_multiple,double relative_rate,
47                                    bool fixed_rate,gr_consume_type_t cons_type, gr_produce_type_t prod_type): gr_block (name,
48                    gr_make_io_signature (min_inputs, max_inputs, sizeof_input_item),
49                    gr_make_io_signature (min_outputs, max_outputs, sizeof_output_item)),
50                    d_sizeof_input_item(sizeof_input_item),
51                    d_sizeof_output_item(sizeof_output_item),
52                    d_check_topology(true),
53                    d_consume_type(cons_type),
54                    d_min_consume(0),
55                    d_max_consume(0),
56                    d_produce_type(prod_type),
57                    d_min_produce(0),
58                    d_max_produce(0)
59   {
60     set_history(history);
61     set_output_multiple(output_multiple);
62     set_relative_rate(relative_rate);
63     set_fixed_rate(fixed_rate);
64   }
65
66 int 
67 gr_test::general_work (int noutput_items,
68                             gr_vector_int &ninput_items,
69                             gr_vector_const_void_star &input_items,
70                             gr_vector_void_star &output_items)
71    {
72      //touch all inputs and outputs to detect segfaults
73      unsigned ninputs = input_items.size ();
74      unsigned noutputs= output_items.size();
75      for (unsigned i = 0; i < ninputs; i++)
76      {
77        char * in=(char *)input_items[i];
78        if (ninput_items[i]< (int)(noutput_items+history()))
79        {
80          std::cerr << "ERROR: ninput_items[" << i << "] < noutput_items+history()" << std::endl;
81          std::cerr << "ninput_items[" << i << "] = " << ninput_items[i] <<  std::endl;
82          std::cerr << "noutput_items+history() = " << noutput_items+history() <<  std::endl;
83          std::cerr << "noutput_items = " << noutput_items <<  std::endl;
84          std::cerr << "history() = " << history() <<  std::endl;
85          throw std::runtime_error ("gr_test");
86        } else
87        {
88          for (int j=0;j<ninput_items[i];j++)
89          {
90            //Touch every available input_item
91            //We use a class variable to avoid the compiler to optimize this away
92            for(unsigned int k=0;k<d_sizeof_input_item;k++)
93              d_temp= in[j*d_sizeof_input_item+k];
94          }
95          switch (d_consume_type)
96          {
97            case CONSUME_NOUTPUT_ITEMS:
98              consume(i,noutput_items);
99              break;
100            case CONSUME_NOUTPUT_ITEMS_LIMIT_MAX:
101              consume(i,std::min(noutput_items,d_max_consume));
102              break;
103            case CONSUME_NOUTPUT_ITEMS_LIMIT_MIN:
104              consume(i,std::min(std::max(noutput_items,d_min_consume),ninput_items[i]));
105              break;
106            case CONSUME_ALL_AVAILABLE:
107              consume(i,ninput_items[i]);
108              break;
109            case CONSUME_ALL_AVAILABLE_LIMIT_MAX:
110              consume(i,std::min(ninput_items[i],d_max_consume));
111              break;
112 /*         //This could result in segfault, uncomment if you want to test this     
113            case CONSUME_ALL_AVAILABLE_LIMIT_MIN:
114              consume(i,std::max(ninput_items[i],d_max_consume));
115              break;*/
116            case CONSUME_ZERO:
117              consume(i,0);
118              break;
119            case CONSUME_ONE:
120              consume(i,1);
121              break;
122            case CONSUME_MINUS_ONE:
123              consume(i,-1);
124              break;
125            default:
126              consume(i,noutput_items);
127          }
128        }
129      }
130      for (unsigned i = 0; i < noutputs; i++)
131      {
132        char * out=(char *)output_items[i];
133        {
134          for (int j=0;j<noutput_items;j++)
135          {
136            //Touch every available output_item
137            for(unsigned int k=0;k<d_sizeof_output_item;k++)
138              out[j*d_sizeof_input_item+k]=0;
139          }       
140        }
141      } 
142      //Now copy input to output until max ninputs or max noutputs is reached
143      int common_nports=std::min(ninputs,noutputs); 
144      if(d_sizeof_output_item==d_sizeof_input_item)   
145        for (int i = 0; i < common_nports; i++)
146        {
147          memcpy(output_items[i],input_items[i],noutput_items*d_sizeof_input_item);
148        }
149      int noutput_items_produced=0;
150      switch (d_produce_type){
151            case PRODUCE_NOUTPUT_ITEMS:
152              noutput_items_produced=noutput_items;
153              break;
154            case PRODUCE_NOUTPUT_ITEMS_LIMIT_MAX:
155              noutput_items_produced=std::min(noutput_items,d_max_produce);
156              break;
157 /*         //This could result in segfault, uncomment if you want to test this         
158              case PRODUCE_NOUTPUT_ITEMS_LIMIT_MIN:
159              noutput_items_produced=std::max(noutput_items,d_min_produce);
160              break;*/
161            case PRODUCE_ZERO:
162              noutput_items_produced=0;
163              break;
164            case PRODUCE_ONE:
165              noutput_items_produced=1;
166              break;
167            case PRODUCE_MINUS_ONE:
168              noutput_items_produced=-1;
169              break;
170            default:
171              noutput_items_produced=noutput_items;
172        }
173      return noutput_items_produced;
174    }
175
176
177