test_bin_parser.cpp
Go to the documentation of this file.
1 // -- BEGIN LICENSE BLOCK ----------------------------------------------
2 // Copyright 2022 Universal Robots A/S
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 //
7 // * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 //
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 //
14 // * Neither the name of the {copyright_holder} nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 // POSSIBILITY OF SUCH DAMAGE.
29 // -- END LICENSE BLOCK ------------------------------------------------
30 
31 #include <gtest/gtest.h>
33 
34 using namespace urcl;
35 
36 TEST(bin_parser, parse_string)
37 {
38  uint8_t buffer[] = { 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20,
39  0x62, 0x65, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x64 };
40  comm::BinParser bp(buffer, sizeof(buffer));
41 
42  std::string expected_message = "String to be parsed";
43  std::string parsed_message;
44  bp.parse(parsed_message, sizeof(buffer));
45 
46  EXPECT_EQ(expected_message, parsed_message);
47 
48  // Parse partial string
49  comm::BinParser bp1(buffer, sizeof(buffer));
50  size_t partial_string = 6;
51  parsed_message.clear();
52  bp1.parse(parsed_message, partial_string);
53 
54  EXPECT_EQ("String", parsed_message);
55 
56  // Parse the rest of the string
57  parsed_message.clear();
58  bp1.parseRemainder(parsed_message);
59 
60  EXPECT_EQ(" to be parsed", parsed_message);
61 }
62 
63 TEST(bin_parser, parse_array)
64 {
65  // Parse vector3d_t
66  uint8_t buffer3d[] = { 0x40, 0x01, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a, 0xc0, 0x08, 0xcc, 0xcc,
67  0xcc, 0xcc, 0xcc, 0xcd, 0x40, 0x11, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcd };
68  comm::BinParser bp3d(buffer3d, sizeof(buffer3d));
69 
70  vector3d_t expected_values3d = { 2.2, -3.1, 4.45 };
71  vector3d_t parsed_values3d;
72  bp3d.parse(parsed_values3d);
73 
74  for (unsigned int i = 0; i < parsed_values3d.size(); ++i)
75  {
76  EXPECT_EQ(expected_values3d[i], parsed_values3d[i]);
77  }
78 
79  // Parse vector6d_t
80  uint8_t buffer6d[] = {
81  0xc0, 0x01, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a, 0x40, 0x08, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcd,
82  0x40, 0x11, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcd, 0x3f, 0xf1, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a,
83  0x40, 0x08, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcd, 0xc0, 0x10, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcd
84  };
85  comm::BinParser bp6d(buffer6d, sizeof(buffer6d));
86 
87  vector6d_t expected_values6d = { -2.2, 3.1, 4.45, 1.1, 3.1, -4.2 };
88  vector6d_t parsed_values6d;
89  bp6d.parse(parsed_values6d);
90 
91  for (unsigned int i = 0; i < parsed_values6d.size(); ++i)
92  {
93  EXPECT_EQ(expected_values6d[i], parsed_values6d[i]);
94  }
95 
96  // Parse vector6int32_t
97  uint8_t buffer6i[] = { 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff,
98  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x05 };
99  comm::BinParser bp6i(buffer6i, sizeof(buffer6i));
100 
101  vector6int32_t expected_values6i = { -2, 3, -1, 4, 14, 5 };
102  vector6int32_t parsed_values6i;
103  bp6i.parse(parsed_values6i);
104 
105  for (unsigned int i = 0; i < parsed_values6i.size(); ++i)
106  {
107  EXPECT_EQ(expected_values6i[i], parsed_values6i[i]);
108  }
109 
110  // Parse vector6uint32_t
111  uint8_t buffer6u[] = { 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01,
112  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x05 };
113  comm::BinParser bp6u(buffer6u, sizeof(buffer6u));
114 
115  vector6uint32_t expected_values6u = { 2, 3, 1, 4, 14, 5 };
116  vector6int32_t parsed_values6u;
117  bp6u.parse(parsed_values6u);
118 
119  for (unsigned int i = 0; i < parsed_values6u.size(); ++i)
120  {
121  EXPECT_EQ(expected_values6u[i], parsed_values6u[i]);
122  }
123 
124  // Parse std::array
125  uint8_t buffer4i[] = { 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05,
126  0x00, 0x00, 0x00, 0x03, 0x0ff, 0x0ff, 0x0ff, 0x0ff };
127  comm::BinParser bp4i(buffer4i, sizeof(buffer4i));
128 
129  std::array<int32_t, 4> expected_values4i = { 2, 5, 3, -1 };
130  std::array<int32_t, 4> parsed_values4i;
131  bp4i.parse(parsed_values4i);
132 
133  for (unsigned int i = 0; i < parsed_values4i.size(); ++i)
134  {
135  EXPECT_EQ(expected_values4i[i], parsed_values4i[i]);
136  }
137 }
138 
139 TEST(bin_parser, parse_data_types)
140 {
141  // Parse float value
142  uint8_t buffer_float[] = { 0x41, 0xb2, 0xb8, 0x52 };
143  comm::BinParser bp_float(buffer_float, sizeof(buffer_float));
144 
145  float expected_float = 22.34;
146  float parsed_float;
147  bp_float.parse(parsed_float);
148 
149  EXPECT_EQ(expected_float, parsed_float);
150 
151  // Parse double value
152  uint8_t buffer_double[] = { 0x41, 0xb2, 0xb8, 0x52, 0xcc, 0x55, 0x00, 0x00 };
153  comm::BinParser bp_double(buffer_double, sizeof(buffer_double));
154 
155  float expected_double = 22.34;
156  float parsed_double;
157  bp_double.parse(parsed_double);
158 
159  EXPECT_EQ(expected_double, parsed_double);
160 
161  // Parse boolean
162  uint8_t buffer_bool[] = { 0x01 };
163  comm::BinParser bp_bool(buffer_bool, sizeof(buffer_bool));
164 
165  bool expected_bool = true;
166  bool parsed_bool;
167  bp_bool.parse(parsed_bool);
168 
169  EXPECT_EQ(expected_bool, parsed_bool);
170 
171  // Parse int32_t
172  uint8_t buffer_int[] = { 0xff, 0xff, 0xff, 0xea };
173  comm::BinParser bp_int(buffer_int, sizeof(buffer_int));
174 
175  int32_t expected_int = -22;
176  int32_t parsed_int;
177  bp_int.parse<int32_t>(parsed_int);
178 
179  EXPECT_EQ(expected_int, parsed_int);
180 }
181 
182 TEST(bin_parser, check_size)
183 {
184  uint8_t buffer[] = { 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20,
185  0x62, 0x65, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x64 };
186  comm::BinParser bp(buffer, sizeof(buffer));
187  size_t len = sizeof(buffer);
188 
189  // The whole buffer length should remain unparsed in the buffer
190  EXPECT_TRUE(bp.checkSize(len));
191 
192  std::string parsed_string;
193  bp.parse(parsed_string, len - (len - 1));
194 
195  // Only one uint8_t should remain unparsed in the buffer
196  EXPECT_FALSE(bp.checkSize(len));
197  EXPECT_TRUE(bp.checkSize<uint8_t>());
198 
199  bp.parseRemainder(parsed_string);
200 
201  // No bytes should remain unparsed in the buffer
202  EXPECT_FALSE(bp.checkSize<uint8_t>());
203 }
204 
205 TEST(bin_parser, consume)
206 {
207  // The buffer represents the string 'String to be parsed'
208  uint8_t buffer[] = { 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20,
209  0x62, 0x65, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x64 };
210  comm::BinParser bp(buffer, sizeof(buffer));
211  bp.consume();
212 
213  EXPECT_TRUE(bp.empty());
214 
215  comm::BinParser bp1(buffer, sizeof(buffer));
216  bp1.consume(10);
217 
218  std::string expected_message = "be parsed";
219  std::string parsed_message;
220  bp1.parseRemainder(parsed_message);
221  EXPECT_EQ(expected_message, parsed_message);
222 
223  // Once the rest of the message has been parsed the parser should be empty
224  EXPECT_TRUE(bp1.empty());
225 }
226 
227 TEST(bin_parser, raw_data_parser)
228 {
229  uint8_t buffer[] = { 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20,
230  0x62, 0x65, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x64 };
231  comm::BinParser bp(buffer, sizeof(buffer));
232 
233  std::unique_ptr<uint8_t> raw_data;
234  size_t size;
235  bp.rawData(raw_data, size);
236 
237  // The buffer should be empty afterwards
238  EXPECT_TRUE(bp.empty());
239 
240  for (unsigned int i = 0; i < size; ++i)
241  {
242  EXPECT_EQ(buffer[i], raw_data.get()[i]);
243  }
244 }
245 
246 TEST(bin_parser, bitset_parser)
247 {
248  uint8_t buffer[] = { 0x00, 0x00, 0x00, 0x01 };
249  comm::BinParser bp(buffer, sizeof(buffer));
250 
251  std::bitset<4> expected_set = std::bitset<4>(1);
252  std::bitset<4> parsed_set;
253  bp.parse<int32_t>(parsed_set);
254 
255  EXPECT_EQ(expected_set, parsed_set);
256 }
257 
258 TEST(bin_parser, parse_outside_buffer_length)
259 {
260  uint8_t buffer[] = { 0x00, 0x00, 0x00, 0x01 };
261  comm::BinParser bp(buffer, sizeof(buffer));
262 
263  int32_t expected_int = 1;
264  int32_t parsed_int;
265  bp.parse<int32_t>(parsed_int);
266 
267  EXPECT_EQ(expected_int, parsed_int);
268 
269  // Parse outside buffer length
270  EXPECT_THROW(bp.parse<int32_t>(parsed_int), UrException);
271 }
272 
273 TEST(bin_parser, bin_parser_parent)
274 {
275  // The buffer represents the string 'String to be parsed'
276  uint8_t buffer[] = { 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20,
277  0x62, 0x65, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x64 };
278  comm::BinParser bp_parent(buffer, sizeof(buffer));
279 
280  comm::BinParser bp_child(bp_parent, sizeof(buffer) - 10);
281 
282  std::string expected_message = "String to";
283  std::string parsed_message;
284  bp_child.parseRemainder(parsed_message);
285 
286  EXPECT_EQ(expected_message, parsed_message);
287 
288  // Destroying the child parser, should move the parents parser
289  bp_child.~BinParser();
290 
291  expected_message = " be parsed";
292  parsed_message.clear();
293  bp_parent.parseRemainder(parsed_message);
294 
295  EXPECT_EQ(expected_message, parsed_message);
296 }
297 
298 int main(int argc, char* argv[])
299 {
300  ::testing::InitGoogleTest(&argc, argv);
301 
302  return RUN_ALL_TESTS();
303 }
void parse(T &val)
Parses the next bytes as given type.
Definition: bin_parser.h:139
TEST(bin_parser, parse_string)
void parseRemainder(std::string &val)
Parses the remaining bytes as a string.
Definition: bin_parser.h:255
bool empty()
Checks if no unparsed bytes remain in the buffer.
Definition: bin_parser.h:362
The BinParser class handles a byte buffer and functionality to iteratively parse the content...
Definition: bin_parser.h:44
int main(int argc, char *argv[])
void rawData(std::unique_ptr< uint8_t > &buffer, size_t &buffer_length)
Writes the remaining bytes into a given buffer without parsing them.
Definition: bin_parser.h:242
std::array< double, 3 > vector3d_t
Definition: types.h:29
void consume()
Sets the current buffer position to the end of the buffer, finishing parsing.
Definition: bin_parser.h:318
bool checkSize(size_t bytes)
Checks if at least a given number of bytes is still remaining unparsed in the buffer.
Definition: bin_parser.h:339
~BinParser()
Deconstructor for the BinParser.
Definition: bin_parser.h:108
std::array< int32_t, 6 > vector6int32_t
Definition: types.h:31
std::array< uint32_t, 6 > vector6uint32_t
Definition: types.h:32
std::array< double, 6 > vector6d_t
Definition: types.h:30
Our base class for exceptions. Specialized exceptions should inherit from those.
Definition: exceptions.h:41


ur_client_library
Author(s): Thomas Timm Andersen, Simon Rasmussen, Felix Exner, Lea Steffen, Tristan Schnell
autogenerated on Tue Jul 4 2023 02:09:47