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