forked from gnuradio/gnuradio
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathheader_buffer.cc
111 lines (93 loc) · 2.64 KB
/
header_buffer.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/* -*- c++ -*- */
/* Copyright 2015 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gnuradio/digital/header_buffer.h>
#include <volk/volk.h>
#include <algorithm>
#include <cstring>
#include <stdexcept>
namespace gr {
namespace digital {
header_buffer::header_buffer(uint8_t* bytes_out)
{
d_offset = 0;
d_buffer = bytes_out;
}
header_buffer::~header_buffer() {}
void header_buffer::clear()
{
if (d_buffer) // TX mode
d_offset = 0;
else // RX mode
d_input.clear();
}
size_t header_buffer::length() const
{
if (d_buffer) // TX mode
return d_offset;
else // RX mode
return d_input.size();
}
const uint8_t* header_buffer::header() const { return d_buffer; }
void header_buffer::add_field8(uint8_t data, int len, bool bs)
{
int nbytes = len / 8;
if (d_buffer) {
memcpy(&d_buffer[d_offset], &data, nbytes);
d_offset += nbytes;
}
}
void header_buffer::add_field16(uint16_t data, int len, bool bs)
{
add_field64(data, len, bs);
}
void header_buffer::add_field32(uint32_t data, int len, bool bs)
{
add_field64(data, len, bs);
}
void header_buffer::add_field64(uint64_t data, int len, bool bs)
{
int nbytes = len / 8;
if (d_buffer) {
for (int i = 0; i < nbytes; i++) {
int shift = bs ? i : (nbytes - i - 1);
d_buffer[d_offset++] = (data >> (8 * shift)) & 0xff;
}
}
}
void header_buffer::insert_bit(int bit) { d_input.push_back(bit); }
template <class T>
T header_buffer::extract_field(int pos, int len, bool bs, bool lsb_first)
{
if (len > 8 * (int)sizeof(T)) {
throw std::runtime_error(
std::string("header_buffer::extract_field for length must be <= ") +
std::to_string(8 * sizeof(T)));
}
T field = 0;
std::vector<bool>::iterator itr;
if (lsb_first) {
for (itr = d_input.begin() + pos + len - 1; itr >= d_input.begin() + pos; itr--) {
field = (field << 1) | ((*itr) & 0x1);
}
} else {
for (itr = d_input.begin() + pos; itr != d_input.begin() + pos + len; itr++) {
field = (field << 1) | ((*itr) & 0x1);
}
}
return field;
}
template DIGITAL_API uint8_t header_buffer::extract_field(int, int, bool, bool);
template DIGITAL_API uint16_t header_buffer::extract_field(int, int, bool, bool);
template DIGITAL_API uint32_t header_buffer::extract_field(int, int, bool, bool);
template DIGITAL_API uint64_t header_buffer::extract_field(int, int, bool, bool);
} /* namespace digital */
} /* namespace gr */