Statistics
| Branch: | Tag: | Revision:

root / gnuradio-core / src / lib / runtime / gr_block_detail.cc @ 95eaad32

History | View | Annotate | Download (5.2 kB)

1
/* -*- c++ -*- */
2
/*
3
 * Copyright 2004,2009,2010 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_block_detail.h>
28
#include <gr_buffer.h>
29
30
using namespace pmt;
31
32
static long s_ncurrently_allocated = 0;
33
34
long
35
gr_block_detail_ncurrently_allocated ()
36
{
37
  return s_ncurrently_allocated;
38
}
39
40
gr_block_detail::gr_block_detail (unsigned int ninputs, unsigned int noutputs)
41
  : d_produce_or(0),
42
    d_ninputs (ninputs), d_noutputs (noutputs),
43
    d_input (ninputs), d_output (noutputs),
44
    d_done (false),
45
    d_last_tag(0)
46
{
47
  s_ncurrently_allocated++;
48
}
49
50
gr_block_detail::~gr_block_detail ()
51
{
52
  // should take care of itself
53
  s_ncurrently_allocated--;
54
}
55
56
void
57
gr_block_detail::set_input (unsigned int which, gr_buffer_reader_sptr reader)
58
{
59
  if (which >= d_ninputs)
60
    throw std::invalid_argument ("gr_block_detail::set_input");
61
62
  d_input[which] = reader;
63
}
64
65
void
66
gr_block_detail::set_output (unsigned int which, gr_buffer_sptr buffer)
67
{
68
  if (which >= d_noutputs)
69
    throw std::invalid_argument ("gr_block_detail::set_output");
70
71
  d_output[which] = buffer;
72
}
73
74
gr_block_detail_sptr
75
gr_make_block_detail (unsigned int ninputs, unsigned int noutputs)
76
{
77
  return gr_block_detail_sptr (new gr_block_detail (ninputs, noutputs));
78
}
79
80
void
81
gr_block_detail::set_done (bool done)
82
{
83
  d_done = done;
84
  for (unsigned int i = 0; i < d_noutputs; i++)
85
    d_output[i]->set_done (done);
86
87
  for (unsigned int i = 0; i < d_ninputs; i++)
88
    d_input[i]->set_done (done);
89
}
90
91
void 
92
gr_block_detail::consume (int which_input, int how_many_items)
93
{
94
  if (how_many_items > 0) {
95
    input (which_input)->update_read_pointer (how_many_items);
96
  }
97
}
98
99
100
void
101
gr_block_detail::consume_each (int how_many_items)
102
{
103
  if (how_many_items > 0) {
104
    for (int i = 0; i < ninputs (); i++) {
105
      d_input[i]->update_read_pointer (how_many_items);
106
    }
107
  }
108
}
109
110
void
111
gr_block_detail::produce (int which_output, int how_many_items)
112
{
113
  if (how_many_items > 0){
114
    d_output[which_output]->update_write_pointer (how_many_items);
115
    d_produce_or |= how_many_items;
116
  }
117
}
118
119
void
120
gr_block_detail::produce_each (int how_many_items)
121
{
122
  if (how_many_items > 0) {
123
    for (int i = 0; i < noutputs (); i++) {
124
      d_output[i]->update_write_pointer (how_many_items);
125
    }
126
    d_produce_or |= how_many_items;
127
  }
128
}
129
130
131
void
132
gr_block_detail::_post(pmt_t msg)
133
{
134
  d_tpb.insert_tail(msg);
135
}
136
137
uint64_t
138
gr_block_detail::nitems_read(unsigned int which_input) 
139
{
140
  if(which_input >= d_ninputs)
141
    throw std::invalid_argument ("gr_block_detail::n_input_items");
142
  return d_input[which_input]->nitems_read();
143
}
144
145
uint64_t
146
gr_block_detail::nitems_written(unsigned int which_output) 
147
{
148
  if(which_output >= d_noutputs)
149
    throw std::invalid_argument ("gr_block_detail::n_output_items");
150
  return d_output[which_output]->nitems_written();
151
}
152
153
void
154
gr_block_detail::add_item_tag(unsigned int which_output,
155
                              uint64_t abs_offset,
156
                              const pmt_t &key,
157
                              const pmt_t &value,
158
                              const pmt_t &srcid)
159
{
160
  if(!pmt_is_symbol(key)) {
161
    throw pmt_wrong_type("gr_block_detail::set_item_tag key", key);
162
  }
163
  else {
164
    // build tag tuple
165
    pmt_t nitem = pmt_from_uint64(abs_offset);
166
    pmt_t tuple = pmt_make_tuple(nitem, srcid, key, value);
167
168
    // Add tag to gr_buffer's deque tags
169
    d_output[which_output]->add_item_tag(tuple);
170
  }
171
}
172
173
std::vector<pmt_t>
174
gr_block_detail::get_tags_in_range(unsigned int which_input,
175
                                   uint64_t abs_start,
176
                                   uint64_t abs_end)
177
{
178
  // get from gr_buffer_reader's deque of tags
179
  return d_input[which_input]->get_tags_in_range(abs_start, abs_end);
180
}
181
182
std::vector<pmt_t>
183
gr_block_detail::get_tags_in_range(unsigned int which_input,
184
                                   uint64_t abs_start,
185
                                   uint64_t abs_end,
186
                                   const pmt_t &key)
187
{
188
  std::vector<pmt_t> found_items, found_items_by_key;
189
190
  // get from gr_buffer_reader's deque of tags
191
  found_items = d_input[which_input]->get_tags_in_range(abs_start, abs_end);
192
193
  // Filter further by key name
194
  pmt_t itemkey;
195
  std::vector<pmt_t>::iterator itr;
196
  for(itr = found_items.begin(); itr != found_items.end(); itr++) {
197
    itemkey = pmt_tuple_ref(*itr, 2);
198
    if(pmt_eqv(key, itemkey)) {
199
      found_items_by_key.push_back(*itr);
200
    }
201
  }
202
203
  return found_items_by_key;
204
}
205
206
void 
207
gr_block_detail::handle_tags()
208
{
209
  for(unsigned int i = 0; i < d_ninputs; i++) {
210
    pmt_t tuple;
211
    while(d_input[i]->get_tag(d_last_tag, tuple)) {
212
      d_last_tag++;
213
      if(!sink_p()) {
214
        for(unsigned int o = 0; o < d_noutputs; o++) {
215
          d_output[o]->add_item_tag(tuple);
216
        }
217
      }
218
    }
219
  }
220
}