1 /* -*- c++ -*- */
2 /*
3 * Copyright 2010,2013 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 "annotator_raw_impl.h"
28 #include <gnuradio/io_signature.h>
29 #include <string.h>
30 #include <iomanip>
31 #include <iostream>
32 #include <stdexcept>
33
34 using namespace pmt;
35
36 namespace gr {
37 namespace blocks {
38
make(size_t sizeof_stream_item)39 annotator_raw::sptr annotator_raw::make(size_t sizeof_stream_item)
40 {
41 return gnuradio::get_initial_sptr(new annotator_raw_impl(sizeof_stream_item));
42 }
43
annotator_raw_impl(size_t sizeof_stream_item)44 annotator_raw_impl::annotator_raw_impl(size_t sizeof_stream_item)
45 : sync_block("annotator_raw",
46 io_signature::make(1, 1, sizeof_stream_item),
47 io_signature::make(1, 1, sizeof_stream_item)),
48 d_itemsize(sizeof_stream_item)
49 {
50 set_tag_propagation_policy(TPP_ONE_TO_ONE);
51 set_relative_rate(1, 1);
52 }
53
~annotator_raw_impl()54 annotator_raw_impl::~annotator_raw_impl() {}
55
add_tag(uint64_t offset,pmt_t key,pmt_t val)56 void annotator_raw_impl::add_tag(uint64_t offset, pmt_t key, pmt_t val)
57 {
58 gr::thread::scoped_lock l(d_mutex);
59
60 tag_t tag;
61 tag.srcid = pmt::intern(name());
62 tag.key = key;
63 tag.value = val;
64 tag.offset = offset;
65
66 // add our new tag
67 d_queued_tags.push_back(tag);
68 // make sure our tags are in offset order
69 std::sort(d_queued_tags.begin(), d_queued_tags.end(), tag_t::offset_compare);
70 // make sure we are not adding an item in the past!
71 if (tag.offset > nitems_read(0)) {
72 throw std::runtime_error(
73 "annotator_raw::add_tag: item added too far in the past\n.");
74 }
75 }
76
work(int noutput_items,gr_vector_const_void_star & input_items,gr_vector_void_star & output_items)77 int annotator_raw_impl::work(int noutput_items,
78 gr_vector_const_void_star& input_items,
79 gr_vector_void_star& output_items)
80 {
81 gr::thread::scoped_lock l(d_mutex);
82
83 const char* in = (const char*)input_items[0];
84 char* out = (char*)output_items[0];
85
86 uint64_t start_N = nitems_read(0);
87 uint64_t end_N = start_N + (uint64_t)(noutput_items);
88
89 // locate queued tags that fall in this range and insert them when appropriate
90 std::vector<tag_t>::iterator i = d_queued_tags.begin();
91 while (i != d_queued_tags.end()) {
92 if ((*i).offset >= start_N && (*i).offset < end_N) {
93 add_item_tag(0, (*i).offset, (*i).key, (*i).value, (*i).srcid);
94 i = d_queued_tags.erase(i);
95 } else {
96 break;
97 }
98 }
99
100 // copy data across
101 memcpy(out, in, noutput_items * d_itemsize);
102 return noutput_items;
103 }
104
105 } /* namespace blocks */
106 } /* namespace gr */
107