-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDataPacket.cpp
More file actions
178 lines (145 loc) · 6.11 KB
/
DataPacket.cpp
File metadata and controls
178 lines (145 loc) · 6.11 KB
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#include <cmath>
#include <cstdint>
#include <limits>
#include <list>
#include "DataField.hpp"
#include "DataPacket.hpp"
#include "misc.hpp"
//==============================================================================
DataPacket::DataPacket(unsigned int alignment,
misc::DataUnits alignment_units) :
DataField()
{
setAlignment(alignment, alignment_units);
}
//==============================================================================
DataPacket::~DataPacket()
{
}
//==============================================================================
unsigned long DataPacket::readRaw(std::uint8_t* buffer,
misc::ByteOrder source_byte_order)
{
unsigned long bits_read = 0;
// When buffer is incremented this is adjusted so it's less than
// BITS_PER_BYTE
unsigned long offset_bits = 0;
for (std::list<DataField*>::const_iterator i = data_fields.begin();
i != data_fields.end();
++i)
{
// This will take all the bytes out of offset_bits and bump buffer
// accordingly. As a result offset_bits will be < BITS_PER_BYTE. Does
// nothing on the first iteration, since offset_bits always equals 0
// then.
normalizeMemoryLocation(buffer, offset_bits);
unsigned long offset_bits_initial = offset_bits;
// Tell the current field to read and record the number of bits it read
offset_bits += (*i)->readRaw(buffer, source_byte_order, offset_bits);
// smallestMultipleOfXGreaterOrEqualToY take two longs, which means we
// could go out of range with our offset here
if (offset_bits > static_cast<unsigned long>(
std::numeric_limits<long>::max()))
{
throw std::runtime_error(
"Maximum representable offset bit count exceeded");
}
// Bump the offset to the next alignment point
offset_bits = static_cast<unsigned long>(
misc::smallestMultipleOfXGreaterOrEqualToY(
static_cast<long>(alignment_bits),
static_cast<long>(offset_bits)));
// This field plus the padding after it
bits_read += offset_bits - offset_bits_initial;
}
return bits_read;
}
//==============================================================================
unsigned long DataPacket::readRaw(const std::uint8_t* buffer,
misc::ByteOrder source_byte_order)
{
unsigned long bits_read = 0;
// When buffer is incremented this is adjusted so it's less than
// BITS_PER_BYTE
unsigned long offset_bits = 0;
for (std::list<DataField*>::const_iterator i = data_fields.begin();
i != data_fields.end();
++i)
{
unsigned long offset_bits_initial = offset_bits;
// Tell the current field to read and record the number of bits it read
offset_bits += (*i)->readRaw(buffer, source_byte_order, offset_bits);
// smallestMultipleOfXGreaterOrEqualToY take two longs, which means we
// could go out of range with our offset here
if (offset_bits > static_cast<unsigned long>(
std::numeric_limits<long>::max()))
{
throw std::runtime_error(
"Maximum representable offset bit count exceeded");
}
// Bump the offset to the next alignment point
offset_bits = static_cast<unsigned long>(
misc::smallestMultipleOfXGreaterOrEqualToY(
static_cast<long>(alignment_bits),
static_cast<long>(offset_bits)));
// This field plus the padding after it
bits_read += offset_bits - offset_bits_initial;
}
return bits_read;
}
//==============================================================================
unsigned long DataPacket::writeRaw(std::uint8_t* buffer,
misc::ByteOrder destination_byte_order) const
{
unsigned long bits_written = 0;
// When buffer is incremented this is adjusted so it's less than
// BITS_PER_BYTE
unsigned long offset_bits = 0;
for (std::list<DataField*>::const_iterator i = data_fields.begin();
i != data_fields.end();
++i)
{
// This will take all the bytes out of offset_bits and bump buffer
// accordingly. As a result offset_bits will be < BITS_PER_BYTE.
normalizeMemoryLocation(buffer, offset_bits);
unsigned long offset_bits_initial = offset_bits;
// Tell the current field to read and record the number of bits it read
offset_bits +=
(*i)->writeRaw(buffer, destination_byte_order, offset_bits);
// smallestMultipleOfXGreaterOrEqualToY take two longs, which means we
// could go out of range with our offset here
if (offset_bits > static_cast<unsigned long>(
std::numeric_limits<long>::max()))
{
throw std::runtime_error(
"Maximum representable offset bit count exceeded");
}
// Bump the offset to the next alignment point
offset_bits = static_cast<unsigned long>(
misc::smallestMultipleOfXGreaterOrEqualToY(
static_cast<long>(alignment_bits),
static_cast<long>(offset_bits)));
// This field plus the padding after it
bits_written += offset_bits - offset_bits_initial;
}
// The number of bits we actually wrote
return bits_written;
}
//==============================================================================
unsigned long DataPacket::getLengthBits() const
{
unsigned long length_bits = 0;
for (std::list<DataField*>::const_iterator i = data_fields.begin();
i != data_fields.end();
++i)
{
// Increase packet length by the length of the current packet
length_bits += (*i)->getLengthBits();
// Increase packet length again to account for alignment
length_bits = static_cast<unsigned long>(
misc::smallestMultipleOfXGreaterOrEqualToY(
static_cast<long>(alignment_bits),
static_cast<long>(length_bits)));
}
return length_bits;
}