• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <gtest/gtest.h>
18 #include <forward_list>
19 #include <memory>
20 
21 #define PACKET_TESTING
22 #include "os/log.h"
23 #include "packet/bit_inserter.h"
24 #include "packet/parser/test/big_endian_test_packets.h"
25 #include "packet/parser/test/six_bytes.h"
26 #include "packet/parser/test/test_packets.h"
27 #include "packet/raw_builder.h"
28 
29 using ::bluetooth::packet::BitInserter;
30 using ::bluetooth::packet::kLittleEndian;
31 using ::bluetooth::packet::RawBuilder;
32 using ::bluetooth::packet::parser::test::SixBytes;
33 using std::vector;
34 
35 namespace {
36 vector<uint8_t> child_two_two_three = {
37     0x20 /* Reserved : 4, FourBits::TWO */,
38     0x03 /* FourBits::THREE, Reserved : 4 */,
39 };
40 vector<uint8_t> child = {
41     0x12 /* fixed */, 0x02 /* Size of the payload */, 0xa1 /* First byte of the payload */, 0xa2, 0xb1 /* footer */,
42 };
43 vector<uint8_t> child_with_six_bytes = {
44     0x34 /* TwoBytes */,
45     0x12,
46     0xa1 /* First byte of the six_bytes */,
47     0xa2,
48     0xa3,
49     0xa4,
50     0xa5,
51     0xa6,
52     0xb1 /* Second six_bytes*/,
53     0xb2,
54     0xb3,
55     0xb4,
56     0xb5,
57     0xb6,
58 };
59 
60 }  // namespace
61 
62 namespace bluetooth {
63 namespace packet {
64 namespace parser {
65 using namespace test;
66 
TEST(GeneratedPacketTest,testChildTwoTwoThree)67 TEST(GeneratedPacketTest, testChildTwoTwoThree) {
68   auto packet = ChildTwoTwoThreeBuilder::Create();
69 
70   ASSERT_EQ(child_two_two_three.size(), packet->size());
71 
72   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
73   BitInserter it(*packet_bytes);
74   packet->Serialize(it);
75 
76   ASSERT_EQ(packet_bytes->size(), child_two_two_three.size());
77   for (size_t i = 0; i < child_two_two_three.size(); i++) {
78     ASSERT_EQ(packet_bytes->at(i), child_two_two_three[i]);
79   }
80 
81   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
82   ParentView wrong_view = ParentView::Create(packet_bytes_view);
83   ASSERT_FALSE(wrong_view.IsValid());
84 
85   ParentTwoView parent_view = ParentTwoView::Create(packet_bytes_view);
86   ASSERT_TRUE(parent_view.IsValid());
87   ASSERT_EQ(FourBits::TWO, parent_view.GetFourBits());
88 
89   ChildTwoTwoView child_view = ChildTwoTwoView::Create(parent_view);
90   ASSERT_TRUE(child_view.IsValid());
91   ASSERT_EQ(FourBits::THREE, child_view.GetMoreBits());
92 
93   ChildTwoTwoThreeView grandchild_view = ChildTwoTwoThreeView::Create(child_view);
94   ASSERT_TRUE(grandchild_view.IsValid());
95 }
96 
TEST(GeneratedPacketTest,testChild)97 TEST(GeneratedPacketTest, testChild) {
98   uint16_t field_name = 0xa2a1;
99   uint8_t footer = 0xb1;
100   auto packet = ChildBuilder::Create(field_name, footer);
101 
102   ASSERT_EQ(child.size(), packet->size());
103 
104   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
105   BitInserter it(*packet_bytes);
106   packet->Serialize(it);
107 
108   ASSERT_EQ(packet_bytes->size(), child.size());
109   for (size_t i = 0; i < child.size(); i++) {
110     ASSERT_EQ(packet_bytes->at(i), child[i]);
111   }
112 
113   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
114   ParentView parent_view = ParentView::Create(packet_bytes_view);
115   ASSERT_TRUE(parent_view.IsValid());
116   auto payload = parent_view.GetPayload();
117 
118   ASSERT_EQ(child[1 /* skip fixed field */], payload.size());
119   for (size_t i = 0; i < payload.size(); i++) {
120     ASSERT_EQ(child[i + 2 /* fixed & size */], payload[i]);
121   }
122 
123   ChildView child_view = ChildView::Create(parent_view);
124   ASSERT_TRUE(child_view.IsValid());
125 
126   ASSERT_EQ(field_name, child_view.GetFieldName());
127 }
128 
TEST(GeneratedPacketTest,testValidateWayTooSmall)129 TEST(GeneratedPacketTest, testValidateWayTooSmall) {
130   std::vector<uint8_t> too_small_bytes = {0x34};
131   auto too_small = std::make_shared<std::vector<uint8_t>>(too_small_bytes.begin(), too_small_bytes.end());
132 
133   ParentWithSixBytesView invalid_parent = ParentWithSixBytesView::Create(PacketView<kLittleEndian>(too_small));
134   ASSERT_FALSE(invalid_parent.IsValid());
135   ChildWithSixBytesView invalid =
136       ChildWithSixBytesView::Create(ParentWithSixBytesView::Create(PacketView<kLittleEndian>(too_small)));
137   ASSERT_FALSE(invalid.IsValid());
138 }
139 
TEST(GeneratedPacketTest,testValidateTooSmall)140 TEST(GeneratedPacketTest, testValidateTooSmall) {
141   std::vector<uint8_t> too_small_bytes = {0x34, 0x12, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x11};
142   auto too_small = std::make_shared<std::vector<uint8_t>>(too_small_bytes.begin(), too_small_bytes.end());
143 
144   ParentWithSixBytesView valid_parent = ParentWithSixBytesView::Create(PacketView<kLittleEndian>(too_small));
145   ASSERT_TRUE(valid_parent.IsValid());
146   ChildWithSixBytesView invalid =
147       ChildWithSixBytesView::Create(ParentWithSixBytesView::Create(PacketView<kLittleEndian>(too_small)));
148   ASSERT_FALSE(invalid.IsValid());
149 }
150 
TEST(GeneratedPacketTest,testValidateJustRight)151 TEST(GeneratedPacketTest, testValidateJustRight) {
152   std::vector<uint8_t> just_right_bytes = {0x34, 0x12, 0x01, 0x02, 0x03, 0x04, 0x05,
153                                            0x06, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
154   auto just_right = std::make_shared<std::vector<uint8_t>>(just_right_bytes.begin(), just_right_bytes.end());
155 
156   ChildWithSixBytesView valid =
157       ChildWithSixBytesView::Create(ParentWithSixBytesView::Create(PacketView<kLittleEndian>(just_right)));
158   ASSERT_TRUE(valid.IsValid());
159 }
160 
TEST(GeneratedPacketTest,testValidateTooBig)161 TEST(GeneratedPacketTest, testValidateTooBig) {
162   std::vector<uint8_t> too_big_bytes = {0x34, 0x12, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
163                                         0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x20};
164   auto too_big = std::make_shared<std::vector<uint8_t>>(too_big_bytes.begin(), too_big_bytes.end());
165 
166   ChildWithSixBytesView lenient =
167       ChildWithSixBytesView::Create(ParentWithSixBytesView::Create(PacketView<kLittleEndian>(too_big)));
168   ASSERT_TRUE(lenient.IsValid());
169 }
170 
TEST(GeneratedPacketTest,testValidateDeath)171 TEST(GeneratedPacketTest, testValidateDeath) {
172   auto packet = ChildTwoTwoThreeBuilder::Create();
173 
174   ASSERT_EQ(child_two_two_three.size(), packet->size());
175 
176   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
177   BitInserter it(*packet_bytes);
178   packet->Serialize(it);
179 
180   ASSERT_EQ(packet_bytes->size(), child_two_two_three.size());
181   for (size_t i = 0; i < child_two_two_three.size(); i++) {
182     ASSERT_EQ(packet_bytes->at(i), child_two_two_three[i]);
183   }
184 
185   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
186   ParentView wrong_view = ParentView::Create(packet_bytes_view);
187   ASSERT_DEATH(wrong_view.GetPayload(), "validated");
188 }
189 
TEST(GeneratedPacketTest,testValidatedParentDeath)190 TEST(GeneratedPacketTest, testValidatedParentDeath) {
191   uint16_t field_name = 0xa2a1;
192   uint8_t footer = 0xb1;
193   auto packet = ChildBuilder::Create(field_name, footer);
194 
195   ASSERT_EQ(child.size(), packet->size());
196 
197   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
198   BitInserter it(*packet_bytes);
199   packet->Serialize(it);
200 
201   ASSERT_EQ(packet_bytes->size(), child.size());
202   for (size_t i = 0; i < child.size(); i++) {
203     ASSERT_EQ(packet_bytes->at(i), child[i]);
204   }
205 
206   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
207   ParentView parent_view = ParentView::Create(packet_bytes_view);
208   ASSERT_TRUE(parent_view.IsValid());
209   auto payload = parent_view.GetPayload();
210 
211   ASSERT_EQ(child[1 /* skip fixed field */], payload.size());
212   for (size_t i = 0; i < payload.size(); i++) {
213     ASSERT_EQ(child[i + 2 /* fixed & size */], payload[i]);
214   }
215 
216   ChildView child_view = ChildView::Create(parent_view);
217   ASSERT_DEATH(child_view.GetFieldName(), "validated");
218 }
219 
220 vector<uint8_t> middle_four_bits = {
221     0x95,  // low_two = ONE, next_four = FIVE, straddle = TEN
222     0x8a,  // straddle = TEN, four_more = TWO, high_two = TWO
223 };
224 
TEST(GeneratedPacketTest,testMiddleFourBitsPacket)225 TEST(GeneratedPacketTest, testMiddleFourBitsPacket) {
226   TwoBits low_two = TwoBits::ONE;
227   FourBits next_four = FourBits::FIVE;
228   FourBits straddle = FourBits::TEN;
229   FourBits four_more = FourBits::TWO;
230   TwoBits high_two = TwoBits::TWO;
231 
232   auto packet = MiddleFourBitsBuilder::Create(low_two, next_four, straddle, four_more, high_two);
233 
234   ASSERT_EQ(middle_four_bits.size(), packet->size());
235 
236   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
237   BitInserter it(*packet_bytes);
238   packet->Serialize(it);
239 
240   ASSERT_EQ(packet_bytes->size(), middle_four_bits.size());
241   for (size_t i = 0; i < middle_four_bits.size(); i++) {
242     ASSERT_EQ(packet_bytes->at(i), middle_four_bits[i]);
243   }
244 
245   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
246   MiddleFourBitsView view = MiddleFourBitsView::Create(packet_bytes_view);
247   ASSERT_TRUE(view.IsValid());
248   ASSERT_EQ(low_two, view.GetLowTwo());
249   ASSERT_EQ(next_four, view.GetNextFour());
250   ASSERT_EQ(straddle, view.GetStraddle());
251   ASSERT_EQ(four_more, view.GetFourMore());
252   ASSERT_EQ(high_two, view.GetHighTwo());
253 }
254 
TEST(GeneratedPacketTest,testChildWithSixBytes)255 TEST(GeneratedPacketTest, testChildWithSixBytes) {
256   SixBytes six_bytes_a{{0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6}};
257   SixBytes six_bytes_b{{0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6}};
258   auto packet = ChildWithSixBytesBuilder::Create(six_bytes_a, six_bytes_b);
259 
260   ASSERT_EQ(child_with_six_bytes.size(), packet->size());
261 
262   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
263   BitInserter it(*packet_bytes);
264   packet->Serialize(it);
265 
266   ASSERT_EQ(packet_bytes->size(), child_with_six_bytes.size());
267   for (size_t i = 0; i < child_with_six_bytes.size(); i++) {
268     ASSERT_EQ(packet_bytes->at(i), child_with_six_bytes[i]);
269   }
270 
271   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
272   ParentWithSixBytesView parent_view = ParentWithSixBytesView::Create(packet_bytes_view);
273   ASSERT_TRUE(parent_view.IsValid());
274   ASSERT_EQ(six_bytes_a, parent_view.GetSixBytes());
275 
276   ChildWithSixBytesView child_view = ChildWithSixBytesView::Create(parent_view);
277   ASSERT_TRUE(child_view.IsValid());
278 
279   ASSERT_EQ(six_bytes_a, child_view.GetSixBytes());
280   ASSERT_EQ(six_bytes_a, ((ParentWithSixBytesView)child_view).GetSixBytes());
281   ASSERT_EQ(six_bytes_b, child_view.GetChildSixBytes());
282 }
283 
284 namespace {
285 vector<uint8_t> parent_with_sum = {
286     0x11 /* TwoBytes */, 0x12, 0x21 /* Sum Bytes */, 0x22, 0x43 /* Sum, excluding TwoBytes */, 0x00,
287 };
288 
289 }  // namespace
290 
TEST(GeneratedPacketTest,testParentWithSum)291 TEST(GeneratedPacketTest, testParentWithSum) {
292   uint16_t two_bytes = 0x1211;
293   uint16_t sum_bytes = 0x2221;
294   auto packet = ParentWithSumBuilder::Create(two_bytes, sum_bytes, std::make_unique<packet::RawBuilder>());
295 
296   ASSERT_EQ(parent_with_sum.size(), packet->size());
297 
298   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
299   BitInserter it(*packet_bytes);
300   packet->Serialize(it);
301 
302   ASSERT_EQ(packet_bytes->size(), parent_with_sum.size());
303   for (size_t i = 0; i < parent_with_sum.size(); i++) {
304     ASSERT_EQ(packet_bytes->at(i), parent_with_sum[i]);
305   }
306 
307   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
308   ParentWithSumView parent_view = ParentWithSumView::Create(packet_bytes_view);
309   ASSERT_TRUE(parent_view.IsValid());
310   ASSERT_EQ(two_bytes, parent_view.GetTwoBytes());
311 
312   // Corrupt checksum
313   packet_bytes->back()++;
314   PacketView<kLittleEndian> corrupted_bytes_view(packet_bytes);
315   ParentWithSumView corrupted_view = ParentWithSumView::Create(corrupted_bytes_view);
316   ASSERT_FALSE(corrupted_view.IsValid());
317 }
318 
319 namespace {
320 vector<uint8_t> child_with_nested_sum = {
321     0x11 /* TwoBytes */,
322     0x12,
323     0x21 /* Sum Bytes */,
324     0x22,
325     0x31 /* More Bytes */,
326     0x32,
327     0x33,
328     0x34,
329     0xca /* Nested Sum */,
330     0x00,
331     0xd7 /* Sum, excluding TwoBytes */,
332     0x01,
333 };
334 
335 }  // namespace
336 
TEST(GeneratedPacketTest,testChildWithNestedSum)337 TEST(GeneratedPacketTest, testChildWithNestedSum) {
338   uint16_t two_bytes = 0x1211;
339   uint16_t sum_bytes = 0x2221;
340   uint32_t more_bytes = 0x34333231;
341   auto packet = ChildWithNestedSumBuilder::Create(two_bytes, sum_bytes, more_bytes);
342 
343   ASSERT_EQ(child_with_nested_sum.size(), packet->size());
344 
345   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
346   BitInserter it(*packet_bytes);
347   packet->Serialize(it);
348 
349   ASSERT_EQ(packet_bytes->size(), child_with_nested_sum.size());
350   for (size_t i = 0; i < child_with_nested_sum.size(); i++) {
351     ASSERT_EQ(packet_bytes->at(i), child_with_nested_sum[i]);
352   }
353 
354   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
355   ParentWithSumView parent_view = ParentWithSumView::Create(packet_bytes_view);
356   ASSERT_TRUE(parent_view.IsValid());
357   ASSERT_EQ(two_bytes, parent_view.GetTwoBytes());
358 
359   ChildWithNestedSumView child_view = ChildWithNestedSumView::Create(parent_view);
360   ASSERT_TRUE(child_view.IsValid());
361 
362   ASSERT_EQ(more_bytes, child_view.GetMoreBytes());
363 }
364 
TEST(GeneratedPacketTest,testSizedWithSumBadSize)365 TEST(GeneratedPacketTest, testSizedWithSumBadSize) {
366   vector<uint8_t> size_too_big{0x01, 0x02, 0x23, 0x11, 0x22, 0x33, 0x66, 0x00};
367 
368   auto shared_bytes = std::make_shared<std::vector<uint8_t>>(size_too_big);
369   PacketView<kLittleEndian> packet_bytes_view(shared_bytes);
370 
371   auto sws = SizedWithSumView::Create(packet_bytes_view);
372   ASSERT_FALSE(sws.IsValid());
373 }
374 
375 namespace {
376 vector<uint8_t> parent_size_modifier = {
377     0x02 /* Size */,
378     0x11 /* TwoBytes */,
379     0x12,
380 };
381 
382 }  // namespace
383 
TEST(GeneratedPacketTest,testParentSizeModifier)384 TEST(GeneratedPacketTest, testParentSizeModifier) {
385   uint16_t two_bytes = 0x1211;
386   auto packet = ParentSizeModifierBuilder::Create(std::make_unique<RawBuilder>(), two_bytes);
387 
388   ASSERT_EQ(parent_size_modifier.size(), packet->size());
389 
390   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
391   BitInserter it(*packet_bytes);
392   packet->Serialize(it);
393 
394   ASSERT_EQ(parent_size_modifier.size(), packet_bytes->size());
395   for (size_t i = 0; i < parent_size_modifier.size(); i++) {
396     ASSERT_EQ(parent_size_modifier[i], packet_bytes->at(i));
397   }
398 
399   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
400   ParentSizeModifierView parent_view = ParentSizeModifierView::Create(packet_bytes_view);
401   ASSERT_TRUE(parent_view.IsValid());
402   ASSERT_EQ(two_bytes, parent_view.GetTwoBytes());
403 }
404 
405 namespace {
406 vector<uint8_t> child_size_modifier = {
407     0x06 /* PayloadSize (TwoBytes + MoreBytes)*/,
408     0x31 /* MoreBytes */,
409     0x32,
410     0x33,
411     0x34,
412     0x11 /* TwoBytes = 0x1211 */,
413     0x12,
414 };
415 
416 }  // namespace
417 
TEST(GeneratedPacketTest,testChildSizeModifier)418 TEST(GeneratedPacketTest, testChildSizeModifier) {
419   uint16_t two_bytes = 0x1211;
420   uint32_t more_bytes = 0x34333231;
421   auto packet = ChildSizeModifierBuilder::Create(more_bytes);
422 
423   ASSERT_EQ(child_size_modifier.size(), packet->size());
424 
425   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
426   BitInserter it(*packet_bytes);
427   packet->Serialize(it);
428 
429   ASSERT_EQ(child_size_modifier.size(), packet_bytes->size());
430   for (size_t i = 0; i < child_size_modifier.size(); i++) {
431     ASSERT_EQ(child_size_modifier[i], packet_bytes->at(i));
432   }
433 
434   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
435   ParentSizeModifierView parent_view = ParentSizeModifierView::Create(packet_bytes_view);
436   ASSERT_TRUE(parent_view.IsValid());
437   ASSERT_EQ(two_bytes, parent_view.GetTwoBytes());
438 
439   ChildSizeModifierView child_view = ChildSizeModifierView::Create(parent_view);
440   ASSERT_TRUE(child_view.IsValid());
441 
442   ASSERT_EQ(more_bytes, child_view.GetMoreBytes());
443 }
444 
445 namespace {
446 vector<uint8_t> fixed_array_enum{
447     0x01,  // ONE
448     0x00,
449     0x02,  // TWO
450     0x00,
451     0x01,  // ONE_TWO
452     0x02,
453     0x02,  // TWO_THREE
454     0x03,
455     0xff,  // FFFF
456     0xff,
457 };
458 }
459 
TEST(GeneratedPacketTest,testFixedArrayEnum)460 TEST(GeneratedPacketTest, testFixedArrayEnum) {
461   std::array<ForArrays, 5> fixed_array{
462       {ForArrays::ONE, ForArrays::TWO, ForArrays::ONE_TWO, ForArrays::TWO_THREE, ForArrays::FFFF}};
463   auto packet = FixedArrayEnumBuilder::Create(fixed_array);
464   ASSERT_EQ(fixed_array_enum.size(), packet->size());
465 
466   // Verify that the packet is independent from the array.
467   std::array<ForArrays, 5> copy_array(fixed_array);
468   fixed_array[1] = ForArrays::ONE;
469 
470   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
471   BitInserter it(*packet_bytes);
472   packet->Serialize(it);
473 
474   ASSERT_EQ(fixed_array_enum.size(), packet_bytes->size());
475   for (size_t i = 0; i < fixed_array_enum.size(); i++) {
476     ASSERT_EQ(fixed_array_enum[i], packet_bytes->at(i));
477   }
478 
479   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
480   auto view = FixedArrayEnumView::Create(packet_bytes_view);
481   ASSERT_TRUE(view.IsValid());
482   auto array = view.GetEnumArray();
483   ASSERT_EQ(copy_array.size(), array.size());
484   for (size_t i = 0; i < copy_array.size(); i++) {
485     ASSERT_EQ(array[i], copy_array[i]);
486   }
487 }
488 
489 namespace {
490 vector<uint8_t> sized_array_enum{
491     0x0a,  // _size_
492     0x00,
493     0x01,  // ONE
494     0x00,
495     0x02,  // TWO
496     0x00,
497     0x01,  // ONE_TWO
498     0x02,
499     0x02,  // TWO_THREE
500     0x03,
501     0xff,  // FFFF
502     0xff,
503 };
504 }
505 
TEST(GeneratedPacketTest,testSizedArrayEnum)506 TEST(GeneratedPacketTest, testSizedArrayEnum) {
507   std::vector<ForArrays> sized_array{
508       {ForArrays::ONE, ForArrays::TWO, ForArrays::ONE_TWO, ForArrays::TWO_THREE, ForArrays::FFFF}};
509   auto packet = SizedArrayEnumBuilder::Create(sized_array);
510   ASSERT_EQ(sized_array_enum.size(), packet->size());
511 
512   // Copy the original vector and modify it to make sure the packet is independent.
513   std::vector<ForArrays> copy_array(sized_array);
514   sized_array[1] = ForArrays::ONE;
515 
516   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
517   BitInserter it(*packet_bytes);
518   packet->Serialize(it);
519 
520   ASSERT_EQ(sized_array_enum.size(), packet_bytes->size());
521   for (size_t i = 0; i < sized_array_enum.size(); i++) {
522     ASSERT_EQ(sized_array_enum[i], packet_bytes->at(i));
523   }
524 
525   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
526   auto view = SizedArrayEnumView::Create(packet_bytes_view);
527   ASSERT_TRUE(view.IsValid());
528   auto array = view.GetEnumArray();
529   ASSERT_EQ(copy_array.size(), array.size());
530   for (size_t i = 0; i < copy_array.size(); i++) {
531     ASSERT_EQ(array[i], copy_array[i]);
532   }
533 }
534 
535 namespace {
536 vector<uint8_t> count_array_enum{
537     0x03,  // _count_
538     0x01,  // ONE
539     0x00,
540     0x02,  // TWO_THREE
541     0x03,
542     0xff,  // FFFF
543     0xff,
544 };
545 }
546 
TEST(GeneratedPacketTest,testCountArrayEnum)547 TEST(GeneratedPacketTest, testCountArrayEnum) {
548   std::vector<ForArrays> count_array{{ForArrays::ONE, ForArrays::TWO_THREE, ForArrays::FFFF}};
549   auto packet = CountArrayEnumBuilder::Create(count_array);
550   ASSERT_EQ(count_array_enum.size(), packet->size());
551 
552   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
553   BitInserter it(*packet_bytes);
554   packet->Serialize(it);
555 
556   ASSERT_EQ(count_array_enum.size(), packet_bytes->size());
557   for (size_t i = 0; i < count_array_enum.size(); i++) {
558     ASSERT_EQ(count_array_enum[i], packet_bytes->at(i));
559   }
560 
561   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
562   auto view = CountArrayEnumView::Create(packet_bytes_view);
563   ASSERT_TRUE(view.IsValid());
564   auto array = view.GetEnumArray();
565   ASSERT_EQ(count_array.size(), array.size());
566   for (size_t i = 0; i < count_array.size(); i++) {
567     ASSERT_EQ(array[i], count_array[i]);
568   }
569 }
570 
TEST(GeneratedPacketTest,testFixedSizeByteArray)571 TEST(GeneratedPacketTest, testFixedSizeByteArray) {
572   constexpr std::size_t byte_array_size = 32;
573   std::array<uint8_t, byte_array_size> byte_array;
574   for (uint8_t i = 0; i < byte_array_size; i++) byte_array[i] = i;
575 
576   constexpr int word_array_size = 8;
577   std::array<uint32_t, word_array_size> word_array;
578   for (uint32_t i = 0; i < word_array_size; i++) word_array[i] = i;
579 
580   auto packet = PacketWithFixedArraysOfBytesBuilder::Create(byte_array, word_array);
581   ASSERT_EQ((size_t)(2 * (256 / 8)), packet->size());
582 
583   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
584   BitInserter it(*packet_bytes);
585   packet->Serialize(it);
586 
587   ASSERT_EQ(byte_array_size + word_array_size * sizeof(uint32_t), packet_bytes->size());
588 
589   for (size_t i = 0; i < byte_array_size; i++) {
590     ASSERT_EQ(byte_array[i], packet_bytes->at(i));
591   }
592 
593   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
594   auto view = PacketWithFixedArraysOfBytesView::Create(packet_bytes_view);
595   ASSERT_TRUE(view.IsValid());
596   auto array = view.GetFixed256bitInBytes();
597   ASSERT_EQ(byte_array.size(), array.size());
598   for (size_t i = 0; i < array.size(); i++) {
599     ASSERT_EQ(array[i], byte_array[i]);
600   }
601 
602   auto decoded_word_array = view.GetFixed256bitInWords();
603   ASSERT_EQ(word_array.size(), decoded_word_array.size());
604   for (size_t i = 0; i < decoded_word_array.size(); i++) {
605     ASSERT_EQ(word_array[i], decoded_word_array[i]);
606   }
607 }
608 
609 vector<uint8_t> one_variable{
610     0x03, 'o', 'n', 'e',  // "one"
611 };
612 
TEST(GeneratedPacketTest,testOneVariableField)613 TEST(GeneratedPacketTest, testOneVariableField) {
614   Variable variable_one{"one"};
615 
616   auto packet = OneVariableBuilder::Create(variable_one);
617   ASSERT_EQ(one_variable.size(), packet->size());
618 
619   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
620   BitInserter it(*packet_bytes);
621   packet->Serialize(it);
622 
623   ASSERT_EQ(one_variable.size(), packet_bytes->size());
624   for (size_t i = 0; i < one_variable.size(); i++) {
625     ASSERT_EQ(one_variable[i], packet_bytes->at(i));
626   }
627 
628   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
629   auto view = OneVariableView::Create(packet_bytes_view);
630   ASSERT_TRUE(view.IsValid());
631   auto one = view.GetOne();
632   ASSERT_EQ(one->data, variable_one.data);
633 }
634 
635 vector<uint8_t> fou_variable{
636     0x04, 'f', 'o', 'u',  // too short
637 };
638 
TEST(GeneratedPacketTest,testOneVariableFieldTooShort)639 TEST(GeneratedPacketTest, testOneVariableFieldTooShort) {
640   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>(fou_variable);
641   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
642   auto view = OneVariableView::Create(packet_bytes_view);
643   ASSERT_TRUE(view.IsValid());
644   auto one = view.GetOne();
645   ASSERT_EQ(one, nullptr);
646 }
647 
648 vector<uint8_t> sized_array_variable{
649     0x0e,                           // _size_
650     0x03, 'o', 'n', 'e',            // "one"
651     0x03, 't', 'w', 'o',            // "two"
652     0x05, 't', 'h', 'r', 'e', 'e',  // "three"
653 };
654 
TEST(GeneratedPacketTest,testSizedArrayVariableLength)655 TEST(GeneratedPacketTest, testSizedArrayVariableLength) {
656   std::vector<Variable> sized_array;
657   sized_array.emplace_back("one");
658   sized_array.emplace_back("two");
659   sized_array.emplace_back("three");
660 
661   auto packet = SizedArrayVariableBuilder::Create(sized_array);
662   ASSERT_EQ(sized_array_variable.size(), packet->size());
663 
664   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
665   BitInserter it(*packet_bytes);
666   packet->Serialize(it);
667 
668   ASSERT_EQ(sized_array_variable.size(), packet_bytes->size());
669   for (size_t i = 0; i < sized_array_variable.size(); i++) {
670     ASSERT_EQ(sized_array_variable[i], packet_bytes->at(i));
671   }
672 
673   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
674   auto view = SizedArrayVariableView::Create(packet_bytes_view);
675   ASSERT_TRUE(view.IsValid());
676   auto array = view.GetVariableArray();
677   ASSERT_EQ(sized_array.size(), array.size());
678   for (size_t i = 0; i < sized_array.size(); i++) {
679     ASSERT_EQ(array[i].data, sized_array[i].data);
680   }
681 }
682 
683 vector<uint8_t> sized_array_variable_too_short{
684     0x0e,                           // _size_
685     0x03, 'o', 'n', 'e',            // "one"
686     0x03, 't', 'w', 'o',            // "two"
687     0x06, 't', 'h', 'r', 'e', 'e',  // "three" needs another letter to be length 6
688 };
689 
TEST(GeneratedPacketTest,testSizedArrayVariableLengthLastBad)690 TEST(GeneratedPacketTest, testSizedArrayVariableLengthLastBad) {
691   std::vector<Variable> sized_array;
692   sized_array.emplace_back("one");
693   sized_array.emplace_back("two");
694 
695   std::shared_ptr<std::vector<uint8_t>> packet_bytes =
696       std::make_shared<std::vector<uint8_t>>(sized_array_variable_too_short);
697 
698   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
699   auto view = SizedArrayVariableView::Create(packet_bytes_view);
700   ASSERT_TRUE(view.IsValid());
701   auto array = view.GetVariableArray();
702   ASSERT_EQ(sized_array.size(), array.size());
703   for (size_t i = 0; i < sized_array.size(); i++) {
704     ASSERT_EQ(array[i].data, sized_array[i].data);
705   }
706 }
707 
708 vector<uint8_t> sized_array_variable_first_too_short{
709     0x0e,                           // _size_
710     0x02, 'o', 'n', 'e',            // "on"
711     0x03, 't', 'w', 'o',            // "two"
712     0x05, 't', 'h', 'r', 'e', 'e',  // "three"
713 };
714 
TEST(GeneratedPacketTest,testSizedArrayVariableLengthFirstBad)715 TEST(GeneratedPacketTest, testSizedArrayVariableLengthFirstBad) {
716   std::vector<Variable> sized_array;
717   sized_array.emplace_back("on");
718 
719   std::shared_ptr<std::vector<uint8_t>> packet_bytes =
720       std::make_shared<std::vector<uint8_t>>(sized_array_variable_first_too_short);
721 
722   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
723   auto view = SizedArrayVariableView::Create(packet_bytes_view);
724   ASSERT_TRUE(view.IsValid());
725   auto array = view.GetVariableArray();
726   ASSERT_EQ(sized_array.size(), array.size());
727   for (size_t i = 0; i < sized_array.size(); i++) {
728     ASSERT_EQ(array[i].data, sized_array[i].data);
729   }
730 }
731 
732 vector<uint8_t> fixed_array_variable{
733     0x03, 'o', 'n', 'e',            // "one"
734     0x03, 't', 'w', 'o',            // "two"
735     0x05, 't', 'h', 'r', 'e', 'e',  // "three"
736     0x04, 'f', 'o', 'u', 'r',       // "four"
737     0x04, 'f', 'i', 'v', 'e',       // "five"
738 };
739 
TEST(GeneratedPacketTest,testFixedArrayVariableLength)740 TEST(GeneratedPacketTest, testFixedArrayVariableLength) {
741   std::array<Variable, 5> fixed_array{std::string("one"), std::string("two"), std::string("three"), std::string("four"),
742                                       std::string("five")};
743 
744   auto packet = FixedArrayVariableBuilder::Create(fixed_array);
745   ASSERT_EQ(fixed_array_variable.size(), packet->size());
746 
747   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
748   BitInserter it(*packet_bytes);
749   packet->Serialize(it);
750 
751   ASSERT_EQ(fixed_array_variable.size(), packet_bytes->size());
752   for (size_t i = 0; i < fixed_array_variable.size(); i++) {
753     ASSERT_EQ(fixed_array_variable[i], packet_bytes->at(i));
754   }
755 
756   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
757   auto view = FixedArrayVariableView::Create(packet_bytes_view);
758   ASSERT_TRUE(view.IsValid());
759   auto array = view.GetVariableArray();
760   ASSERT_EQ(fixed_array.size(), array.size());
761   for (size_t i = 0; i < fixed_array.size(); i++) {
762     ASSERT_EQ(array[i].data, fixed_array[i].data);
763   }
764 }
765 
766 vector<uint8_t> fixed_array_variable_too_short{
767     0x03, 'o', 'n', 'e',            // "one"
768     0x03, 't', 'w', 'o',            // "two"
769     0x05, 't', 'h', 'r', 'e', 'e',  // "three"
770     0x04, 'f', 'o', 'u', 'r',       // "four"
771     0x05, 'f', 'i', 'v', 'e',       // "five"
772 };
773 
TEST(GeneratedPacketTest,testFixedArrayVariableLengthTooShort)774 TEST(GeneratedPacketTest, testFixedArrayVariableLengthTooShort) {
775   std::array<Variable, 5> fixed_array{std::string("one"), std::string("two"), std::string("three"),
776                                       std::string("four")};
777 
778   std::shared_ptr<std::vector<uint8_t>> packet_bytes =
779       std::make_shared<std::vector<uint8_t>>(fixed_array_variable_too_short);
780 
781   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
782   auto view = FixedArrayVariableView::Create(packet_bytes_view);
783   ASSERT_TRUE(view.IsValid());
784   auto array = view.GetVariableArray();
785   ASSERT_EQ(fixed_array.size(), array.size());
786   for (size_t i = 0; i < fixed_array.size(); i++) {
787     ASSERT_EQ(array[i].data, fixed_array[i].data);
788   }
789 }
790 
791 vector<uint8_t> count_array_variable{
792     0x04,                           // _count_
793     0x03, 'o', 'n', 'e',            // "one"
794     0x03, 't', 'w', 'o',            // "two"
795     0x05, 't', 'h', 'r', 'e', 'e',  // "three"
796     0x04, 'f', 'o', 'u', 'r',       // "four"
797 };
798 
TEST(GeneratedPacketTest,testCountArrayVariableLength)799 TEST(GeneratedPacketTest, testCountArrayVariableLength) {
800   std::vector<Variable> count_array;
801   count_array.emplace_back("one");
802   count_array.emplace_back("two");
803   count_array.emplace_back("three");
804   count_array.emplace_back("four");
805 
806   auto packet = CountArrayVariableBuilder::Create(count_array);
807   ASSERT_EQ(count_array_variable.size(), packet->size());
808 
809   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
810   BitInserter it(*packet_bytes);
811   packet->Serialize(it);
812 
813   ASSERT_EQ(count_array_variable.size(), packet_bytes->size());
814   for (size_t i = 0; i < count_array_variable.size(); i++) {
815     ASSERT_EQ(count_array_variable[i], packet_bytes->at(i));
816   }
817 
818   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
819   auto view = CountArrayVariableView::Create(packet_bytes_view);
820   ASSERT_TRUE(view.IsValid());
821   auto array = view.GetVariableArray();
822   ASSERT_EQ(count_array.size(), array.size());
823   for (size_t i = 0; i < count_array.size(); i++) {
824     ASSERT_EQ(array[i].data, count_array[i].data);
825   }
826 }
827 
828 vector<uint8_t> count_array_variable_extra{
829     0x04,                           // _count_
830     0x03, 'o', 'n', 'e',            // "one"
831     0x03, 't', 'w', 'o',            // "two"
832     0x05, 't', 'h', 'r', 'e', 'e',  // "three"
833     0x04, 'f', 'o', 'u', 'r',       // "four"
834     0x04, 'x', 't', 'r', 'a',       // "xtra"
835 };
836 
TEST(GeneratedPacketTest,testCountArrayVariableLengthExtraData)837 TEST(GeneratedPacketTest, testCountArrayVariableLengthExtraData) {
838   std::vector<Variable> count_array;
839   count_array.emplace_back("one");
840   count_array.emplace_back("two");
841   count_array.emplace_back("three");
842   count_array.emplace_back("four");
843 
844   std::shared_ptr<std::vector<uint8_t>> packet_bytes =
845       std::make_shared<std::vector<uint8_t>>(count_array_variable_extra);
846 
847   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
848   auto view = CountArrayVariableView::Create(packet_bytes_view);
849   ASSERT_TRUE(view.IsValid());
850   auto array = view.GetVariableArray();
851   ASSERT_EQ(count_array.size(), array.size());
852   for (size_t i = 0; i < count_array.size(); i++) {
853     ASSERT_EQ(array[i].data, count_array[i].data);
854   }
855 }
856 
857 vector<uint8_t> count_array_variable_too_few{
858     0x04,                           // _count_
859     0x03, 'o', 'n', 'e',            // "one"
860     0x03, 't', 'w', 'o',            // "two"
861     0x05, 't', 'h', 'r', 'e', 'e',  // "three"
862 };
863 
TEST(GeneratedPacketTest,testCountArrayVariableLengthMissingData)864 TEST(GeneratedPacketTest, testCountArrayVariableLengthMissingData) {
865   std::vector<Variable> count_array;
866   count_array.emplace_back("one");
867   count_array.emplace_back("two");
868   count_array.emplace_back("three");
869 
870   std::shared_ptr<std::vector<uint8_t>> packet_bytes =
871       std::make_shared<std::vector<uint8_t>>(count_array_variable_too_few);
872 
873   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
874   auto view = CountArrayVariableView::Create(packet_bytes_view);
875   ASSERT_TRUE(view.IsValid());
876   auto array = view.GetVariableArray();
877   ASSERT_EQ(count_array.size(), array.size());
878   for (size_t i = 0; i < count_array.size(); i++) {
879     ASSERT_EQ(array[i].data, count_array[i].data);
880   }
881 }
882 
883 vector<uint8_t> one_struct{
884     0x01, 0x02, 0x03,  // id = 0x01, count = 0x0302
885 };
886 
TEST(GeneratedPacketTest,testOneStruct)887 TEST(GeneratedPacketTest, testOneStruct) {
888   TwoRelatedNumbers trn;
889   trn.id_ = 1;
890   trn.count_ = 0x0302;
891 
892   auto packet = OneStructBuilder::Create(trn);
893   ASSERT_EQ(one_struct.size(), packet->size());
894 
895   // Copy the original struct, then modify it to verify independence from the packet.
896   TwoRelatedNumbers copy_trn(trn);
897   trn.id_ = 2;
898 
899   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
900   BitInserter it(*packet_bytes);
901   packet->Serialize(it);
902 
903   ASSERT_EQ(one_struct.size(), packet_bytes->size());
904   for (size_t i = 0; i < one_struct.size(); i++) {
905     ASSERT_EQ(one_struct[i], packet_bytes->at(i));
906   }
907 
908   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
909   auto view = OneStructView::Create(packet_bytes_view);
910   ASSERT_TRUE(view.IsValid());
911   auto one = view.GetOne();
912   ASSERT_EQ(one.id_, copy_trn.id_);
913   ASSERT_EQ(one.count_, copy_trn.count_);
914 }
915 
916 vector<uint8_t> two_structs{
917     0x01, 0x01, 0x02,  // id, id * 0x0201
918     0x02, 0x02, 0x04,
919 };
920 
TEST(GeneratedPacketTest,testTwoStructs)921 TEST(GeneratedPacketTest, testTwoStructs) {
922   std::vector<TwoRelatedNumbers> count_array;
923   for (uint8_t i = 1; i < 3; i++) {
924     TwoRelatedNumbers trn;
925     trn.id_ = i;
926     trn.count_ = 0x0201 * i;
927     count_array.push_back(trn);
928   }
929 
930   auto packet = TwoStructsBuilder::Create(count_array[0], count_array[1]);
931   ASSERT_EQ(two_structs.size(), packet->size());
932 
933   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
934   BitInserter it(*packet_bytes);
935   packet->Serialize(it);
936 
937   ASSERT_EQ(two_structs.size(), packet_bytes->size());
938   for (size_t i = 0; i < two_structs.size(); i++) {
939     ASSERT_EQ(two_structs[i], packet_bytes->at(i));
940   }
941 
942   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
943   auto view = TwoStructsView::Create(packet_bytes_view);
944   ASSERT_TRUE(view.IsValid());
945   auto one = view.GetOne();
946   ASSERT_EQ(one.id_, count_array[0].id_);
947   ASSERT_EQ(one.count_, count_array[0].count_);
948   auto two = view.GetTwo();
949   ASSERT_EQ(two.id_, count_array[1].id_);
950   ASSERT_EQ(two.count_, count_array[1].count_);
951 }
952 
953 vector<uint8_t> array_or_vector_of_struct{
954     0x04,              // _count_
955     0x01, 0x01, 0x02,  // id, id * 0x0201
956     0x02, 0x02, 0x04, 0x03, 0x03, 0x06, 0x04, 0x04, 0x08,
957 };
958 
TEST(GeneratedPacketTest,testVectorOfStruct)959 TEST(GeneratedPacketTest, testVectorOfStruct) {
960   std::vector<TwoRelatedNumbers> count_array;
961   for (uint8_t i = 1; i < 5; i++) {
962     TwoRelatedNumbers trn;
963     trn.id_ = i;
964     trn.count_ = 0x0201 * i;
965     count_array.push_back(trn);
966   }
967 
968   // Make a copy
969   std::vector<TwoRelatedNumbers> copy_array(count_array);
970 
971   auto packet = VectorOfStructBuilder::Create(count_array);
972 
973   // Change the original vector to make sure a copy was made.
974   count_array[0].id_ = count_array[0].id_ + 1;
975 
976   ASSERT_EQ(array_or_vector_of_struct.size(), packet->size());
977 
978   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
979   BitInserter it(*packet_bytes);
980   packet->Serialize(it);
981 
982   ASSERT_EQ(array_or_vector_of_struct.size(), packet_bytes->size());
983   for (size_t i = 0; i < array_or_vector_of_struct.size(); i++) {
984     ASSERT_EQ(array_or_vector_of_struct[i], packet_bytes->at(i));
985   }
986 
987   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
988   auto view = VectorOfStructView::Create(packet_bytes_view);
989   ASSERT_TRUE(view.IsValid());
990   auto array = view.GetArray();
991   ASSERT_EQ(copy_array.size(), array.size());
992   for (size_t i = 0; i < copy_array.size(); i++) {
993     ASSERT_EQ(array[i].id_, copy_array[i].id_);
994     ASSERT_EQ(array[i].count_, copy_array[i].count_);
995   }
996 }
997 
TEST(GeneratedPacketTest,testArrayOfStruct)998 TEST(GeneratedPacketTest, testArrayOfStruct) {
999   std::array<TwoRelatedNumbers, 4> count_array;
1000   for (uint8_t i = 1; i < 5; i++) {
1001     TwoRelatedNumbers trn;
1002     trn.id_ = i;
1003     trn.count_ = 0x0201 * i;
1004     count_array[i - 1] = trn;
1005   }
1006 
1007   // Make a copy
1008   std::array<TwoRelatedNumbers, 4> copy_array(count_array);
1009 
1010   auto packet = ArrayOfStructBuilder::Create(4, count_array);
1011 
1012   // Change the original vector to make sure a copy was made.
1013   count_array[0].id_ = count_array[0].id_ + 1;
1014 
1015   ASSERT_EQ(array_or_vector_of_struct.size(), packet->size());
1016 
1017   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
1018   BitInserter it(*packet_bytes);
1019   packet->Serialize(it);
1020 
1021   ASSERT_EQ(array_or_vector_of_struct.size(), packet_bytes->size());
1022   for (size_t i = 0; i < array_or_vector_of_struct.size(); i++) {
1023     ASSERT_EQ(array_or_vector_of_struct[i], packet_bytes->at(i));
1024   }
1025 
1026   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
1027   auto view = ArrayOfStructView::Create(packet_bytes_view);
1028   ASSERT_TRUE(view.IsValid());
1029   auto array = view.GetArray();
1030   ASSERT_EQ(copy_array.size(), array.size());
1031   for (size_t i = 0; i < copy_array.size(); i++) {
1032     ASSERT_EQ(array[i].id_, copy_array[i].id_);
1033     ASSERT_EQ(array[i].count_, copy_array[i].count_);
1034   }
1035 }
1036 
1037 vector<uint8_t> one_fixed_types_struct{
1038     0x05,                                // four_bits = FIVE, reserved
1039     0xf3,                                // _fixed_
1040     0x0d,                                // id = 0x0d
1041     0x01, 0x02, 0x03,                    // array = { 1, 2, 3}
1042     0x06, 0x01,                          // example_checksum
1043     0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,  // six_bytes
1044 };
1045 
TEST(GeneratedPacketTest,testOneFixedTypesStruct)1046 TEST(GeneratedPacketTest, testOneFixedTypesStruct) {
1047   StructWithFixedTypes swf;
1048   swf.four_bits_ = FourBits::FIVE;
1049   swf.id_ = 0x0d;
1050   swf.array_ = {{0x01, 0x02, 0x03}};
1051   swf.six_bytes_ = SixBytes{{0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6}};
1052 
1053   auto packet = OneFixedTypesStructBuilder::Create(swf);
1054   ASSERT_EQ(one_fixed_types_struct.size(), packet->size());
1055 
1056   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
1057   BitInserter it(*packet_bytes);
1058   packet->Serialize(it);
1059 
1060   ASSERT_EQ(one_fixed_types_struct.size(), packet_bytes->size());
1061   for (size_t i = 0; i < one_fixed_types_struct.size(); i++) {
1062     ASSERT_EQ(one_fixed_types_struct[i], packet_bytes->at(i));
1063   }
1064 
1065   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
1066   auto view = OneFixedTypesStructView::Create(packet_bytes_view);
1067   ASSERT_TRUE(view.IsValid());
1068   auto one = view.GetOne();
1069   ASSERT_EQ(one.four_bits_, swf.four_bits_);
1070   ASSERT_EQ(one.id_, swf.id_);
1071   ASSERT_EQ(one.array_, swf.array_);
1072   ASSERT_EQ(one.six_bytes_, swf.six_bytes_);
1073 }
1074 
1075 vector<uint8_t> array_of_struct_and_another{
1076     0x03,              // _count_
1077     0x01, 0x01, 0x02,  // id, id * 0x0201
1078     0x02, 0x02, 0x04,  // 2
1079     0x03, 0x03, 0x06,  // 3
1080     0x04, 0x04, 0x08,  // Another
1081 };
1082 
TEST(GeneratedPacketTest,testArrayOfStructAndAnother)1083 TEST(GeneratedPacketTest, testArrayOfStructAndAnother) {
1084   std::vector<TwoRelatedNumbers> count_array;
1085   for (uint8_t i = 1; i < 4; i++) {
1086     TwoRelatedNumbers trn;
1087     trn.id_ = i;
1088     trn.count_ = 0x0201 * i;
1089     count_array.push_back(trn);
1090   }
1091   TwoRelatedNumbers another;
1092   another.id_ = 4;
1093   another.count_ = 0x0201 * 4;
1094 
1095   auto packet = ArrayOfStructAndAnotherBuilder::Create(count_array, another);
1096   ASSERT_EQ(array_or_vector_of_struct.size(), packet->size());
1097 
1098   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
1099   BitInserter it(*packet_bytes);
1100   packet->Serialize(it);
1101 
1102   ASSERT_EQ(array_of_struct_and_another.size(), packet_bytes->size());
1103   for (size_t i = 0; i < array_of_struct_and_another.size(); i++) {
1104     ASSERT_EQ(array_of_struct_and_another[i], packet_bytes->at(i));
1105   }
1106 
1107   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
1108   auto view = ArrayOfStructAndAnotherView::Create(packet_bytes_view);
1109   ASSERT_TRUE(view.IsValid());
1110   auto array = view.GetArray();
1111   ASSERT_EQ(count_array.size(), array.size());
1112   for (size_t i = 0; i < count_array.size(); i++) {
1113     ASSERT_EQ(array[i].id_, count_array[i].id_);
1114     ASSERT_EQ(array[i].count_, count_array[i].count_);
1115   }
1116   auto nother = view.GetAnother();
1117   ASSERT_EQ(nother.id_, another.id_);
1118   ASSERT_EQ(nother.count_, another.count_);
1119 }
1120 
1121 DEFINE_AND_INSTANTIATE_OneArrayOfStructAndAnotherStructReflectionTest(array_of_struct_and_another);
1122 
TEST(GeneratedPacketTest,testOneArrayOfStructAndAnotherStruct)1123 TEST(GeneratedPacketTest, testOneArrayOfStructAndAnotherStruct) {
1124   std::shared_ptr<std::vector<uint8_t>> packet_bytes =
1125       std::make_shared<std::vector<uint8_t>>(array_of_struct_and_another);
1126 
1127   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
1128   auto view = OneArrayOfStructAndAnotherStructView::Create(packet_bytes_view);
1129   ASSERT_TRUE(view.IsValid());
1130   auto one = view.GetOne();
1131   ASSERT_EQ(one.array_.size(), 3ul);
1132   ASSERT_EQ(one.another_.id_, 4);
1133   ASSERT_EQ(one.another_.count_, 0x0804);
1134 }
1135 
1136 vector<uint8_t> sized_array_of_struct_and_another{
1137     0x09,              // _size_
1138     0x01, 0x01, 0x02,  // id, id * 0x0201
1139     0x02, 0x02, 0x04,  // 2
1140     0x03, 0x03, 0x06,  // 3
1141     0x04, 0x04, 0x08,  // Another
1142 };
1143 
1144 DEFINE_AND_INSTANTIATE_OneSizedArrayOfStructAndAnotherStructReflectionTest(sized_array_of_struct_and_another);
1145 
1146 vector<uint8_t> bit_field_group_packet{
1147     // seven_bits_ = 0x77, straddle_ = 0x5, five_bits_ = 0x15
1148     0xf7,  // 0x77 | (0x5 & 0x1) << 7
1149     0xaa,  //  0x15 << 3 | (0x5 >> 1)
1150 };
1151 
TEST(GeneratedPacketTest,testBitFieldGroupPacket)1152 TEST(GeneratedPacketTest, testBitFieldGroupPacket) {
1153   uint8_t seven_bits = 0x77;
1154   uint8_t straddle = 0x5;
1155   uint8_t five_bits = 0x15;
1156 
1157   auto packet = BitFieldGroupPacketBuilder::Create(seven_bits, straddle, five_bits);
1158   ASSERT_EQ(bit_field_group_packet.size(), packet->size());
1159 
1160   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
1161   BitInserter it(*packet_bytes);
1162   packet->Serialize(it);
1163 
1164   ASSERT_EQ(bit_field_group_packet.size(), packet_bytes->size());
1165   for (size_t i = 0; i < bit_field_group_packet.size(); i++) {
1166     ASSERT_EQ(bit_field_group_packet[i], packet_bytes->at(i));
1167   }
1168 
1169   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
1170   auto view = BitFieldGroupPacketView::Create(packet_bytes_view);
1171   ASSERT_TRUE(view.IsValid());
1172   ASSERT_EQ(seven_bits, view.GetSevenBits());
1173   ASSERT_EQ(straddle, view.GetStraddle());
1174   ASSERT_EQ(five_bits, view.GetFiveBits());
1175 }
1176 
1177 vector<uint8_t> bit_field_packet{
1178     // seven_bits_ = 0x77, straddle_ = 0x5, five_bits_ = 0x15
1179     0xf7,  // 0x77 | (0x5 & 0x1) << 7
1180     0xaa,  //  0x15 << 3 | (0x5 >> 1)
1181 };
1182 
TEST(GeneratedPacketTest,testBitFieldPacket)1183 TEST(GeneratedPacketTest, testBitFieldPacket) {
1184   BitField bit_field;
1185   bit_field.seven_bits_ = 0x77;
1186   bit_field.straddle_ = 0x5;
1187   bit_field.five_bits_ = 0x15;
1188 
1189   auto packet = BitFieldPacketBuilder::Create(bit_field);
1190   ASSERT_EQ(bit_field_packet.size(), packet->size());
1191 
1192   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
1193   BitInserter it(*packet_bytes);
1194   packet->Serialize(it);
1195 
1196   ASSERT_EQ(bit_field_packet.size(), packet_bytes->size());
1197   for (size_t i = 0; i < bit_field_packet.size(); i++) {
1198     ASSERT_EQ(bit_field_packet[i], packet_bytes->at(i));
1199   }
1200 
1201   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
1202   auto view = BitFieldPacketView::Create(packet_bytes_view);
1203   ASSERT_TRUE(view.IsValid());
1204   BitField bf = view.GetBitField();
1205   ASSERT_EQ(bf.seven_bits_, bit_field.seven_bits_);
1206   ASSERT_EQ(bf.straddle_, bit_field.straddle_);
1207   ASSERT_EQ(bf.five_bits_, bit_field.five_bits_);
1208 }
1209 
1210 vector<uint8_t> bit_field_group_after_unsized_array_packet{
1211     0x01, 0x02, 0x03, 0x04,  // byte array
1212     // seven_bits_ = 0x77, straddle_ = 0x5, five_bits_ = 0x15
1213     0xf7,  // 0x77 | (0x5 & 0x1) << 7
1214     0xaa,  //  0x15 << 3 | (0x5 >> 1)
1215 };
1216 
TEST(GeneratedPacketTest,testBitFieldGroupAfterUnsizedArrayPacket)1217 TEST(GeneratedPacketTest, testBitFieldGroupAfterUnsizedArrayPacket) {
1218   std::vector<uint8_t> count_array;
1219   for (uint8_t i = 1; i < 5; i++) {
1220     count_array.push_back(i);
1221   }
1222   uint8_t seven_bits = 0x77;
1223   uint8_t straddle = 0x5;
1224   uint8_t five_bits = 0x15;
1225 
1226   auto packet = BitFieldGroupAfterUnsizedArrayPacketBuilder::Create(count_array, seven_bits, straddle, five_bits);
1227   ASSERT_EQ(bit_field_group_after_unsized_array_packet.size(), packet->size());
1228 
1229   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
1230   BitInserter it(*packet_bytes);
1231   packet->Serialize(it);
1232 
1233   ASSERT_EQ(bit_field_group_after_unsized_array_packet.size(), packet_bytes->size());
1234   for (size_t i = 0; i < bit_field_group_after_unsized_array_packet.size(); i++) {
1235     ASSERT_EQ(bit_field_group_after_unsized_array_packet[i], packet_bytes->at(i));
1236   }
1237 
1238   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
1239   auto payload_view = BitFieldGroupAfterPayloadPacketView::Create(packet_bytes_view);
1240   ASSERT_TRUE(payload_view.IsValid());
1241   EXPECT_EQ(seven_bits, payload_view.GetSevenBits());
1242   EXPECT_EQ(straddle, payload_view.GetStraddle());
1243   EXPECT_EQ(five_bits, payload_view.GetFiveBits());
1244 
1245   auto view = BitFieldGroupAfterUnsizedArrayPacketView::Create(payload_view);
1246   ASSERT_TRUE(view.IsValid());
1247   auto array = view.GetArray();
1248   ASSERT_EQ(count_array.size(), array.size());
1249   for (size_t i = 0; i < count_array.size(); i++) {
1250     ASSERT_EQ(array[i], count_array[i]);
1251   }
1252   ASSERT_EQ(seven_bits, view.GetSevenBits());
1253   ASSERT_EQ(straddle, view.GetStraddle());
1254   ASSERT_EQ(five_bits, view.GetFiveBits());
1255 }
1256 
1257 vector<uint8_t> bit_field_after_unsized_array_packet{
1258     0x01, 0x02, 0x03, 0x04,  // byte array
1259     // seven_bits_ = 0x77, straddle_ = 0x5, five_bits_ = 0x15
1260     0xf7,  // 0x77 | (0x5 & 0x1) << 7
1261     0xaa,  //  0x15 << 3 | (0x5 >> 1)
1262 };
1263 
TEST(GeneratedPacketTest,testBitFieldAfterUnsizedArrayPacket)1264 TEST(GeneratedPacketTest, testBitFieldAfterUnsizedArrayPacket) {
1265   std::vector<uint8_t> count_array;
1266   for (uint8_t i = 1; i < 5; i++) {
1267     count_array.push_back(i);
1268   }
1269   BitField bit_field;
1270   bit_field.seven_bits_ = 0x77;
1271   bit_field.straddle_ = 0x5;
1272   bit_field.five_bits_ = 0x15;
1273 
1274   auto packet = BitFieldAfterUnsizedArrayPacketBuilder::Create(count_array, bit_field);
1275   ASSERT_EQ(bit_field_after_unsized_array_packet.size(), packet->size());
1276 
1277   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
1278   BitInserter it(*packet_bytes);
1279   packet->Serialize(it);
1280 
1281   ASSERT_EQ(bit_field_after_unsized_array_packet.size(), packet_bytes->size());
1282   for (size_t i = 0; i < bit_field_after_unsized_array_packet.size(); i++) {
1283     ASSERT_EQ(bit_field_after_unsized_array_packet[i], packet_bytes->at(i));
1284   }
1285 
1286   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
1287   auto payload_view = BitFieldAfterPayloadPacketView::Create(packet_bytes_view);
1288   ASSERT_TRUE(payload_view.IsValid());
1289   BitField parent_bf = payload_view.GetBitField();
1290   ASSERT_EQ(parent_bf.seven_bits_, bit_field.seven_bits_);
1291   ASSERT_EQ(parent_bf.straddle_, bit_field.straddle_);
1292   ASSERT_EQ(parent_bf.five_bits_, bit_field.five_bits_);
1293 
1294   auto view = BitFieldAfterUnsizedArrayPacketView::Create(payload_view);
1295   ASSERT_TRUE(view.IsValid());
1296   auto array = view.GetArray();
1297   ASSERT_EQ(count_array.size(), array.size());
1298   for (size_t i = 0; i < count_array.size(); i++) {
1299     ASSERT_EQ(array[i], count_array[i]);
1300   }
1301   BitField bf = view.GetBitField();
1302   ASSERT_EQ(bf.seven_bits_, bit_field.seven_bits_);
1303   ASSERT_EQ(bf.straddle_, bit_field.straddle_);
1304   ASSERT_EQ(bf.five_bits_, bit_field.five_bits_);
1305 }
1306 
1307 vector<uint8_t> bit_field_array_packet{
1308     0x06,  // _size_(array)
1309     // seven_bits_ = 0x77, straddle_ = 0x5, five_bits_ = 0x15
1310     0xf7,  // 0x77 | (0x5 & 0x1) << 7
1311     0xaa,  //  0x15 << 3 | (0x5 >> 1)
1312 
1313     // seven_bits_ = 0x78, straddle_ = 0x6, five_bits_ = 0x16
1314     0x78,  // 0x78 | (0x6 & 0x1) << 7
1315     0xb3,  //  0x16 << 3 | (0x6 >> 1)
1316 
1317     // seven_bits_ = 0x79, straddle_ = 0x7, five_bits_ = 0x17
1318     0xf9,  // 0x79 | (0x7 & 0x1) << 7
1319     0xbb,  //  0x17 << 3 | (0x7 >> 1)
1320 };
1321 
TEST(GeneratedPacketTest,testBitFieldArrayPacket)1322 TEST(GeneratedPacketTest, testBitFieldArrayPacket) {
1323   std::vector<BitField> count_array;
1324   for (size_t i = 0; i < 3; i++) {
1325     BitField bf;
1326     bf.seven_bits_ = 0x77 + i;
1327     bf.straddle_ = 0x5 + i;
1328     bf.five_bits_ = 0x15 + i;
1329     count_array.push_back(bf);
1330   }
1331 
1332   auto packet = BitFieldArrayPacketBuilder::Create(count_array);
1333   ASSERT_EQ(bit_field_array_packet.size(), packet->size());
1334 
1335   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
1336   BitInserter it(*packet_bytes);
1337   packet->Serialize(it);
1338 
1339   ASSERT_EQ(bit_field_array_packet.size(), packet_bytes->size());
1340   for (size_t i = 0; i < bit_field_array_packet.size(); i++) {
1341     ASSERT_EQ(bit_field_array_packet[i], packet_bytes->at(i));
1342   }
1343 
1344   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
1345   auto view = BitFieldArrayPacketView::Create(packet_bytes_view);
1346   ASSERT_TRUE(view.IsValid());
1347   auto array = view.GetArray();
1348   ASSERT_EQ(count_array.size(), array.size());
1349   for (size_t i = 0; i < count_array.size(); i++) {
1350     ASSERT_EQ(array[i].seven_bits_, count_array[i].seven_bits_);
1351     ASSERT_EQ(array[i].straddle_, count_array[i].straddle_);
1352     ASSERT_EQ(array[i].five_bits_, count_array[i].five_bits_);
1353   }
1354 }
1355 
TEST(GeneratedPacketTest,testNewBitFieldArrayPacket)1356 TEST(GeneratedPacketTest, testNewBitFieldArrayPacket) {
1357   PacketView<kLittleEndian> packet_bytes_view(std::make_shared<std::vector<uint8_t>>(bit_field_array_packet));
1358   auto view = BitFieldArrayPacketView::Create(packet_bytes_view);
1359   ASSERT_TRUE(view.IsValid());
1360 
1361   auto packet = BitFieldArrayPacketBuilder::Create(view.GetArray());
1362   ASSERT_EQ(bit_field_array_packet.size(), packet->size());
1363 
1364   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
1365   BitInserter it(*packet_bytes);
1366   packet->Serialize(it);
1367 
1368   ASSERT_EQ(*packet_bytes, bit_field_array_packet);
1369 }
1370 
1371 std::vector<uint8_t> child_two_two_two_ = {0x20, 0x02};
1372 std::vector<uint8_t> child_two_two_three_ = {0x20, 0x03};
1373 std::vector<uint8_t> child_two_two_four_ = {0x20, 0x04};
1374 
1375 DEFINE_AND_INSTANTIATE_ParentTwoReflectionTest(child_two_two_two_, child_two_two_three_, child_two_two_four_);
1376 
1377 DEFINE_AND_INSTANTIATE_ChildTwoTwoReflectionTest(child_two_two_two_, child_two_two_three_, child_two_two_four_);
1378 
1379 DEFINE_AND_INSTANTIATE_ChildTwoTwoThreeReflectionTest(child_two_two_three_);
1380 
1381 std::vector<uint8_t> one_versionless_struct_packet = {0x01};
1382 std::vector<uint8_t> one_versioned_struct_packet = {0x02, 0x03 /* version */, 0x04, 0x05, 0x06};
1383 std::vector<uint8_t> one_version_one_struct_packet = {0x03, 0x01 /* version */, 0x02};
1384 std::vector<uint8_t> one_version_two_struct_packet = {0x03, 0x02 /* version */, 0x03, 0x04};
1385 DEFINE_AND_INSTANTIATE_OneVersionlessStructPacketReflectionTest(one_versionless_struct_packet,
1386                                                                 one_versioned_struct_packet,
1387                                                                 one_version_one_struct_packet,
1388                                                                 one_version_two_struct_packet);
1389 DEFINE_AND_INSTANTIATE_OneVersionedStructPacketReflectionTest(one_versioned_struct_packet,
1390                                                               one_version_one_struct_packet,
1391                                                               one_version_two_struct_packet);
1392 DEFINE_AND_INSTANTIATE_OneVersionOneStructPacketReflectionTest(one_version_one_struct_packet);
1393 DEFINE_AND_INSTANTIATE_OneVersionTwoStructPacketReflectionTest(one_version_two_struct_packet);
1394 
1395 vector<uint8_t> one_struct_be{
1396     0x01, 0x02, 0x03,  // id = 0x01, count = 0x0203
1397 };
1398 
TEST(GeneratedPacketTest,testOneStructBe)1399 TEST(GeneratedPacketTest, testOneStructBe) {
1400   TwoRelatedNumbersBe trn;
1401   trn.id_ = 1;
1402   trn.count_ = 0x0203;
1403 
1404   auto packet = OneStructBeBuilder::Create(trn);
1405   ASSERT_EQ(one_struct_be.size(), packet->size());
1406 
1407   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
1408   BitInserter it(*packet_bytes);
1409   packet->Serialize(it);
1410 
1411   ASSERT_EQ(one_struct_be.size(), packet_bytes->size());
1412   for (size_t i = 0; i < one_struct_be.size(); i++) {
1413     ASSERT_EQ(one_struct_be[i], packet_bytes->at(i));
1414   }
1415 
1416   PacketView<!kLittleEndian> packet_bytes_view(packet_bytes);
1417   auto view = OneStructBeView::Create(packet_bytes_view);
1418   ASSERT_TRUE(view.IsValid());
1419   auto one = view.GetOne();
1420   ASSERT_EQ(one.id_, trn.id_);
1421   ASSERT_EQ(one.count_, trn.count_);
1422 }
1423 
1424 vector<uint8_t> two_structs_be{
1425     0x01, 0x01, 0x02,  // id, id * 0x0102
1426     0x02, 0x02, 0x04,
1427 };
1428 
TEST(GeneratedPacketTest,testTwoStructsBe)1429 TEST(GeneratedPacketTest, testTwoStructsBe) {
1430   std::vector<TwoRelatedNumbersBe> count_array;
1431   for (uint8_t i = 1; i < 3; i++) {
1432     TwoRelatedNumbersBe trn;
1433     trn.id_ = i;
1434     trn.count_ = 0x0102 * i;
1435     count_array.push_back(trn);
1436   }
1437 
1438   auto packet = TwoStructsBeBuilder::Create(count_array[0], count_array[1]);
1439   ASSERT_EQ(two_structs_be.size(), packet->size());
1440 
1441   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
1442   BitInserter it(*packet_bytes);
1443   packet->Serialize(it);
1444 
1445   ASSERT_EQ(two_structs_be.size(), packet_bytes->size());
1446   for (size_t i = 0; i < two_structs_be.size(); i++) {
1447     ASSERT_EQ(two_structs_be[i], packet_bytes->at(i));
1448   }
1449 
1450   PacketView<!kLittleEndian> packet_bytes_view(packet_bytes);
1451   auto view = TwoStructsBeView::Create(packet_bytes_view);
1452   ASSERT_TRUE(view.IsValid());
1453   auto one = view.GetOne();
1454   ASSERT_EQ(one.id_, count_array[0].id_);
1455   ASSERT_EQ(one.count_, count_array[0].count_);
1456   auto two = view.GetTwo();
1457   ASSERT_EQ(two.id_, count_array[1].id_);
1458   ASSERT_EQ(two.count_, count_array[1].count_);
1459 }
1460 
1461 vector<uint8_t> array_of_struct_be{
1462     0x04,              // _count_
1463     0x01, 0x01, 0x02,  // id, id * 0x0102
1464     0x02, 0x02, 0x04, 0x03, 0x03, 0x06, 0x04, 0x04, 0x08,
1465 };
1466 
TEST(GeneratedPacketTest,testArrayOfStructBe)1467 TEST(GeneratedPacketTest, testArrayOfStructBe) {
1468   std::vector<TwoRelatedNumbersBe> count_array;
1469   for (uint8_t i = 1; i < 5; i++) {
1470     TwoRelatedNumbersBe trn;
1471     trn.id_ = i;
1472     trn.count_ = 0x0102 * i;
1473     count_array.push_back(trn);
1474   }
1475 
1476   auto packet = ArrayOfStructBeBuilder::Create(count_array);
1477 
1478   ASSERT_EQ(array_of_struct_be.size(), packet->size());
1479 
1480   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
1481   BitInserter it(*packet_bytes);
1482   packet->Serialize(it);
1483 
1484   ASSERT_EQ(array_of_struct_be.size(), packet_bytes->size());
1485   for (size_t i = 0; i < array_of_struct_be.size(); i++) {
1486     ASSERT_EQ(array_of_struct_be[i], packet_bytes->at(i));
1487   }
1488 
1489   PacketView<!kLittleEndian> packet_bytes_view(packet_bytes);
1490   auto view = ArrayOfStructBeView::Create(packet_bytes_view);
1491   ASSERT_TRUE(view.IsValid());
1492   auto array = view.GetArray();
1493   ASSERT_EQ(count_array.size(), array.size());
1494   for (size_t i = 0; i < count_array.size(); i++) {
1495     ASSERT_EQ(array[i].id_, count_array[i].id_);
1496     ASSERT_EQ(array[i].count_, count_array[i].count_);
1497   }
1498 }
1499 
1500 vector<uint8_t> one_four_byte_struct{
1501     0x04,                    // struct_type_ = FourByte
1502     0xd1, 0xd2, 0xd3, 0xd4,  // four_bytes_
1503 };
1504 
TEST(GeneratedPacketTest,testOneFourByteStruct)1505 TEST(GeneratedPacketTest, testOneFourByteStruct) {
1506   FourByteStruct four_byte_struct(0xd4d3d2d1);
1507 
1508   auto packet = OneFourByteStructBuilder::Create(four_byte_struct);
1509   ASSERT_EQ(one_four_byte_struct.size(), packet->size());
1510 
1511   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
1512   BitInserter it(*packet_bytes);
1513   packet->Serialize(it);
1514 
1515   ASSERT_EQ(one_four_byte_struct.size(), packet_bytes->size());
1516   for (size_t i = 0; i < one_four_byte_struct.size(); i++) {
1517     ASSERT_EQ(one_four_byte_struct[i], packet_bytes->at(i));
1518   }
1519 
1520   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
1521   auto view = OneFourByteStructView::Create(packet_bytes_view);
1522   ASSERT_TRUE(view.IsValid());
1523   ASSERT_EQ(StructType::FOUR_BYTE, view.GetOneStruct().struct_type_);
1524   ASSERT_EQ(four_byte_struct.four_bytes_, view.GetOneStruct().four_bytes_);
1525 }
1526 
1527 vector<uint8_t> generic_struct_two{
1528     0x02,        // struct_type_ = TwoByte
1529     0x01, 0x02,  // two_bytes_
1530 };
1531 
TEST(GeneratedPacketTest,testOneGenericStructTwo)1532 TEST(GeneratedPacketTest, testOneGenericStructTwo) {
1533   TwoByteStruct two_byte_struct(0x0201);
1534   std::unique_ptr<TwoByteStruct> two_byte_struct_ptr = std::make_unique<TwoByteStruct>(two_byte_struct);
1535 
1536   auto packet = OneGenericStructBuilder::Create(std::move(two_byte_struct_ptr));
1537   ASSERT_EQ(generic_struct_two.size(), packet->size());
1538 
1539   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
1540   BitInserter it(*packet_bytes);
1541   packet->Serialize(it);
1542 
1543   ASSERT_EQ(generic_struct_two.size(), packet_bytes->size());
1544   for (size_t i = 0; i < generic_struct_two.size(); i++) {
1545     ASSERT_EQ(generic_struct_two[i], packet_bytes->at(i));
1546   }
1547 
1548   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
1549   auto view = OneGenericStructView::Create(packet_bytes_view);
1550   ASSERT_TRUE(view.IsValid());
1551   auto base_struct = view.GetBaseStruct();
1552   ASSERT_NE(nullptr, base_struct);
1553   ASSERT_TRUE(TwoByteStruct::IsInstance(*base_struct));
1554   TwoByteStruct* two_byte = static_cast<TwoByteStruct*>(base_struct.get());
1555   ASSERT_NE(nullptr, two_byte);
1556   ASSERT_TRUE(TwoByteStruct::IsInstance(*two_byte));
1557   ASSERT_EQ(two_byte_struct.two_bytes_, 0x0201);
1558   uint16_t val = two_byte->two_bytes_;
1559   ASSERT_EQ(val, 0x0201);
1560   ASSERT_EQ(two_byte_struct.two_bytes_, ((TwoByteStruct*)base_struct.get())->two_bytes_);
1561 }
1562 
1563 vector<uint8_t> generic_struct_four{
1564     0x04,                    // struct_type_ = FourByte
1565     0x01, 0x02, 0x03, 0x04,  // four_bytes_
1566 };
1567 
TEST(GeneratedPacketTest,testOneGenericStructFour)1568 TEST(GeneratedPacketTest, testOneGenericStructFour) {
1569   FourByteStruct four_byte_struct(0x04030201);
1570   std::unique_ptr<FourByteStruct> four_byte_struct_p = std::make_unique<FourByteStruct>(four_byte_struct);
1571   ASSERT_EQ(four_byte_struct.four_bytes_, four_byte_struct_p->four_bytes_);
1572 
1573   auto packet = OneGenericStructBuilder::Create(std::move(four_byte_struct_p));
1574   ASSERT_EQ(generic_struct_four.size(), packet->size());
1575 
1576   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
1577   BitInserter it(*packet_bytes);
1578   packet->Serialize(it);
1579 
1580   ASSERT_EQ(generic_struct_four.size(), packet_bytes->size());
1581   for (size_t i = 0; i < generic_struct_four.size(); i++) {
1582     ASSERT_EQ(generic_struct_four[i], packet_bytes->at(i));
1583   }
1584 
1585   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
1586   auto view = OneGenericStructView::Create(packet_bytes_view);
1587   ASSERT_TRUE(view.IsValid());
1588   auto base_struct = view.GetBaseStruct();
1589   ASSERT_NE(nullptr, base_struct);
1590   ASSERT_EQ(StructType::FOUR_BYTE, base_struct->struct_type_);
1591   ASSERT_EQ(four_byte_struct.four_bytes_, ((FourByteStruct*)base_struct.get())->four_bytes_);
1592 }
1593 
1594 vector<uint8_t> one_struct_array{
1595     0x04,                    // struct_type_ = FourByte
1596     0xa1, 0xa2, 0xa3, 0xa4,  // four_bytes_
1597     0x04,                    // struct_type_ = FourByte
1598     0xb2, 0xb2, 0xb3, 0xb4,  // four_bytes_
1599     0x02,                    // struct_type_ = TwoByte
1600     0xc3, 0xc2,              // two_bytes_
1601     0x04,                    // struct_type_ = TwoByte
1602     0xd4, 0xd2, 0xd3, 0xd4,  // four_bytes_
1603 };
1604 
TEST(GeneratedPacketTest,testOneGenericStructArray)1605 TEST(GeneratedPacketTest, testOneGenericStructArray) {
1606   std::vector<std::unique_ptr<UnusedParentStruct>> parent_vector;
1607   std::unique_ptr<FourByteStruct> fbs;
1608   std::unique_ptr<TwoByteStruct> tbs;
1609   fbs = std::make_unique<FourByteStruct>(0xa4a3a2a1);
1610   parent_vector.push_back(std::move(fbs));
1611   fbs = std::make_unique<FourByteStruct>(0xb4b3b2b2);
1612   parent_vector.push_back(std::move(fbs));
1613   tbs = std::make_unique<TwoByteStruct>(0xc2c3);
1614   parent_vector.push_back(std::move(tbs));
1615   fbs = std::make_unique<FourByteStruct>(0xd4d3d2d4);
1616   parent_vector.push_back(std::move(fbs));
1617 
1618   std::vector<std::unique_ptr<UnusedParentStruct>> vector_copy;
1619   for (auto& s : parent_vector) {
1620     if (s->struct_type_ == StructType::TWO_BYTE) {
1621       vector_copy.push_back(std::make_unique<TwoByteStruct>(*(TwoByteStruct*)s.get()));
1622     }
1623     if (s->struct_type_ == StructType::FOUR_BYTE) {
1624       vector_copy.push_back(std::make_unique<FourByteStruct>(*(FourByteStruct*)s.get()));
1625     }
1626   }
1627 
1628   auto packet = OneGenericStructArrayBuilder::Create(std::move(parent_vector));
1629   ASSERT_EQ(one_struct_array.size(), packet->size());
1630 
1631   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
1632   BitInserter it(*packet_bytes);
1633   packet->Serialize(it);
1634 
1635   ASSERT_EQ(one_struct_array.size(), packet_bytes->size());
1636   for (size_t i = 0; i < one_struct_array.size(); i++) {
1637     ASSERT_EQ(one_struct_array[i], packet_bytes->at(i));
1638   }
1639 
1640   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
1641   auto view = OneGenericStructArrayView::Create(packet_bytes_view);
1642   ASSERT_TRUE(view.IsValid());
1643   auto an_array = view.GetAnArray();
1644   ASSERT_EQ(vector_copy.size(), an_array.size());
1645   for (size_t i = 0; i < vector_copy.size(); i++) {
1646     ASSERT_NE(nullptr, an_array[i]);
1647     ASSERT_EQ(vector_copy[i]->struct_type_, an_array[i]->struct_type_);
1648     if (vector_copy[i]->struct_type_ == StructType::FOUR_BYTE) {
1649       ASSERT_EQ(FourByteStruct::Specialize(vector_copy[i].get())->four_bytes_,
1650                 FourByteStruct::Specialize(an_array[i].get())->four_bytes_);
1651     } else {
1652       ASSERT_EQ(TwoByteStruct::Specialize(vector_copy[i].get())->two_bytes_,
1653                 TwoByteStruct::Specialize(an_array[i].get())->two_bytes_);
1654     }
1655   }
1656 }
1657 
TEST(GeneratedPacketTest,testOneGenericStructFourArray)1658 TEST(GeneratedPacketTest, testOneGenericStructFourArray) {
1659   std::array<std::unique_ptr<UnusedParentStruct>, 4> parent_vector;
1660   std::unique_ptr<FourByteStruct> fbs;
1661   std::unique_ptr<TwoByteStruct> tbs;
1662   fbs = std::make_unique<FourByteStruct>(0xa4a3a2a1);
1663   parent_vector[0] = std::move(fbs);
1664   fbs = std::make_unique<FourByteStruct>(0xb4b3b2b2);
1665   parent_vector[1] = std::move(fbs);
1666   tbs = std::make_unique<TwoByteStruct>(0xc2c3);
1667   parent_vector[2] = std::move(tbs);
1668   fbs = std::make_unique<FourByteStruct>(0xd4d3d2d4);
1669   parent_vector[3] = std::move(fbs);
1670 
1671   std::array<std::unique_ptr<UnusedParentStruct>, 4> vector_copy;
1672   size_t index = 0;
1673   for (auto& s : parent_vector) {
1674     if (s->struct_type_ == StructType::TWO_BYTE) {
1675       vector_copy[index] = std::make_unique<TwoByteStruct>(*(TwoByteStruct*)s.get());
1676     }
1677     if (s->struct_type_ == StructType::FOUR_BYTE) {
1678       vector_copy[index] = std::make_unique<FourByteStruct>(*(FourByteStruct*)s.get());
1679     }
1680     index++;
1681   }
1682 
1683   auto packet = OneGenericStructFourArrayBuilder::Create(std::move(parent_vector));
1684   ASSERT_EQ(one_struct_array.size(), packet->size());
1685 
1686   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
1687   BitInserter it(*packet_bytes);
1688   packet->Serialize(it);
1689 
1690   ASSERT_EQ(one_struct_array.size(), packet_bytes->size());
1691   for (size_t i = 0; i < one_struct_array.size(); i++) {
1692     ASSERT_EQ(one_struct_array[i], packet_bytes->at(i));
1693   }
1694 
1695   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
1696   auto view = OneGenericStructFourArrayView::Create(packet_bytes_view);
1697   ASSERT_TRUE(view.IsValid());
1698   auto an_array = view.GetAnArray();
1699   ASSERT_EQ(vector_copy.size(), an_array.size());
1700   for (size_t i = 0; i < vector_copy.size(); i++) {
1701     ASSERT_NE(nullptr, an_array[i]);
1702     ASSERT_EQ(vector_copy[i]->struct_type_, an_array[i]->struct_type_);
1703     if (vector_copy[i]->struct_type_ == StructType::FOUR_BYTE) {
1704       ASSERT_EQ(FourByteStruct::Specialize(vector_copy[i].get())->four_bytes_,
1705                 FourByteStruct::Specialize(an_array[i].get())->four_bytes_);
1706     } else {
1707       ASSERT_EQ(TwoByteStruct::Specialize(vector_copy[i].get())->two_bytes_,
1708                 TwoByteStruct::Specialize(an_array[i].get())->two_bytes_);
1709     }
1710   }
1711 }
1712 
1713 vector<uint8_t> one_struct_array_after_fixed{
1714     0x01, 0x02,              // two_bytes = 0x0201
1715     0x04,                    // struct_type_ = FourByte
1716     0xa1, 0xa2, 0xa3, 0xa4,  // four_bytes_
1717     0x04,                    // struct_type_ = FourByte
1718     0xb2, 0xb2, 0xb3, 0xb4,  // four_bytes_
1719     0x02,                    // struct_type_ = TwoByte
1720     0xc3, 0xc2,              // two_bytes_
1721     0x04,                    // struct_type_ = TwoByte
1722     0xd4, 0xd2, 0xd3, 0xd4,  // four_bytes_
1723 };
1724 
1725 DEFINE_AND_INSTANTIATE_OneGenericStructArrayAfterFixedReflectionTest(one_struct_array_after_fixed);
1726 
1727 vector<uint8_t> one_length_type_value_struct{
1728     // _size_(value):16 type value
1729     0x04, 0x00, 0x01, 'o', 'n', 'e',            // ONE
1730     0x04, 0x00, 0x02, 't', 'w', 'o',            // TWO
1731     0x06, 0x00, 0x03, 't', 'h', 'r', 'e', 'e',  // THREE
1732 };
1733 
1734 DEFINE_AND_INSTANTIATE_OneLengthTypeValueStructReflectionTest(one_length_type_value_struct);
1735 
TEST(GeneratedPacketTest,testOneLengthTypeValueStruct)1736 TEST(GeneratedPacketTest, testOneLengthTypeValueStruct) {
1737   std::shared_ptr<std::vector<uint8_t>> packet_bytes =
1738       std::make_shared<std::vector<uint8_t>>(one_length_type_value_struct);
1739 
1740   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
1741   auto view = OneLengthTypeValueStructView::Create(packet_bytes_view);
1742   ASSERT_TRUE(view.IsValid());
1743   auto one = view.GetOneArray();
1744   size_t entry_id = 0;
1745   for (const auto& entry : one) {
1746     switch (entry_id++) {
1747       case 0:
1748         ASSERT_EQ(entry.type_, DataType::ONE);
1749         ASSERT_EQ(entry.value_, std::vector<uint8_t>({'o', 'n', 'e'}));
1750         break;
1751       case 1:
1752         ASSERT_EQ(entry.type_, DataType::TWO);
1753         ASSERT_EQ(entry.value_, std::vector<uint8_t>({'t', 'w', 'o'}));
1754         break;
1755       case 2:
1756         ASSERT_EQ(entry.type_, DataType::THREE);
1757         ASSERT_EQ(entry.value_, std::vector<uint8_t>({'t', 'h', 'r', 'e', 'e'}));
1758         break;
1759       default:
1760         ASSERT_EQ(entry.type_, DataType::UNUSED);
1761     }
1762   }
1763 }
1764 
1765 vector<uint8_t> one_length_type_value_struct_padded_10{
1766     0x20,                                                        // _size_(payload),
1767     0x14,                                                        // valid bytes
1768     0x04, 0x00, 0x01, 'o',  'n',  'e',                           // ONE
1769     0x04, 0x00, 0x02, 't',  'w',  'o',                           // TWO
1770     0x06, 0x00, 0x03, 't',  'h',  'r',  'e',  'e',               // THREE
1771     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // padding to 30
1772     0x20,                                                        // after padding
1773 };
1774 
1775 vector<uint8_t> one_length_type_value_struct_padded_18{
1776     0x20,                                                        // _size_(payload),
1777     0x0C,                                                        // valid bytes
1778     0x04, 0x00, 0x01, 'o',  'n',  'e',                           // ONE
1779     0x04, 0x00, 0x02, 't',  'w',  'o',                           // TWO
1780     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,              // padding to 20
1781     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // padding to 30
1782     0x20,                                                        // after padding
1783 };
1784 
1785 // TODO: Revisit LTV parsing.  Right now, the padding bytes are parsed
1786 // DEFINE_AND_INSTANTIATE_OneLengthTypeValueStructPaddedReflectionTest(one_length_type_value_struct_padded_10,
1787 //                                                                     one_length_type_value_struct_padded_18);
1788 
TEST(GeneratedPacketTest,testOneLengthTypeValueStructPaddedGeneration)1789 TEST(GeneratedPacketTest, testOneLengthTypeValueStructPaddedGeneration) {
1790   std::vector<LengthTypeValueStruct> ltv_vector;
1791   LengthTypeValueStruct ltv;
1792   ltv.type_ = DataType::ONE;
1793   ltv.value_ = {
1794       'o',
1795       'n',
1796       'e',
1797   };
1798   ltv_vector.push_back(ltv);
1799   ltv.type_ = DataType::TWO;
1800   ltv.value_ = {
1801       't',
1802       'w',
1803       'o',
1804   };
1805   ltv_vector.push_back(ltv);
1806   uint8_t after_padding = 0x20;
1807 
1808   auto packet = OneLengthTypeValueStructPaddedBuilder::Create(12, ltv_vector, after_padding);
1809   ASSERT_EQ(one_length_type_value_struct_padded_18.size(), packet->size());
1810 
1811   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
1812   BitInserter it(*packet_bytes);
1813   packet->Serialize(it);
1814 
1815   ASSERT_EQ(one_length_type_value_struct_padded_18.size(), packet_bytes->size());
1816   for (size_t i = 0; i < one_length_type_value_struct_padded_18.size(); i++) {
1817     ASSERT_EQ(one_length_type_value_struct_padded_18[i], packet_bytes->at(i));
1818   }
1819 
1820   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
1821   auto view = OneLengthTypeValueStructPaddedView::Create(SizedParentView::Create(packet_bytes_view));
1822   ASSERT_TRUE(view.IsValid());
1823   auto an_array = view.GetOneArray();
1824   // TODO: Revisit LTV parsing.  Right now, the padding bytes are parsed
1825   ASSERT_LE(ltv_vector.size(), an_array.size());
1826   for (size_t i = 0; i < ltv_vector.size(); i++) {
1827     ASSERT_EQ(ltv_vector[i].type_, an_array[i].type_);
1828     ASSERT_EQ(ltv_vector[i].value_, an_array[i].value_);
1829   }
1830   ASSERT_EQ(after_padding, view.GetAfterPadding());
1831 }
1832 
1833 vector<uint8_t> byte_sized{
1834     0x11,                                            // 1
1835     0x21, 0x22,                                      // 2
1836     0x31, 0x32, 0x33,                                // 3
1837     0x41, 0x42, 0x43, 0x44,                          // 4
1838     0x51, 0x52, 0x53, 0x54, 0x55,                    // 5
1839     0x61, 0x62, 0x63, 0x64, 0x65, 0x66,              // 6
1840     0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,        // 7
1841     0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,  // 8
1842 };
1843 
TEST(GeneratedPacketTest,testByteSizedFields)1844 TEST(GeneratedPacketTest, testByteSizedFields) {
1845   uint64_t array[9]{
1846       0xbadbadbad,
1847       0x11,                // 1
1848       0x2221,              // 2
1849       0x333231,            // 3
1850       0x44434241,          // 4
1851       0x5554535251,        // 5
1852       0x666564636261,      // 6
1853       0x77767574737271,    // 7
1854       0x8887868584838281,  // 8
1855   };
1856   auto packet =
1857       ByteSizedFieldsBuilder::Create(array[1], array[2], array[3], array[4], array[5], array[6], array[7], array[8]);
1858   ASSERT_EQ(byte_sized.size(), packet->size());
1859 
1860   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
1861   BitInserter it(*packet_bytes);
1862   packet->Serialize(it);
1863 
1864   ASSERT_EQ(byte_sized.size(), packet_bytes->size());
1865   for (size_t i = 0; i < byte_sized.size(); i++) {
1866     ASSERT_EQ(byte_sized[i], packet_bytes->at(i));
1867   }
1868 
1869   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
1870   auto view = ByteSizedFieldsView::Create(packet_bytes_view);
1871   ASSERT_TRUE(view.IsValid());
1872   ASSERT_EQ(array[1], view.GetOne());
1873   ASSERT_EQ(array[2], view.GetTwo());
1874   ASSERT_EQ(array[3], view.GetThree());
1875   ASSERT_EQ(array[4], view.GetFour());
1876   ASSERT_EQ(array[5], view.GetFive());
1877   ASSERT_EQ(array[6], view.GetSix());
1878   ASSERT_EQ(array[7], view.GetSeven());
1879   ASSERT_EQ(array[8], view.GetEight());
1880 }
1881 
1882 DEFINE_AND_INSTANTIATE_ByteSizedFieldsReflectionTest(byte_sized);
1883 
TEST(GeneratedPacketTest,testOneGenericStructArrayNoZeroEmpty)1884 TEST(GeneratedPacketTest, testOneGenericStructArrayNoZeroEmpty) {
1885   auto too_few_bytes = std::make_shared<std::vector<uint8_t>>(0);
1886   auto view = OneGenericStructArrayNoZeroView::Create(PacketView<kLittleEndian>(too_few_bytes));
1887   for (size_t i = 0; i < 10; i++) {
1888     if (view.IsValid()) {
1889       view.GetAnArray().size();
1890     }
1891     too_few_bytes->push_back(0);
1892     view = OneGenericStructArrayNoZeroView::Create(PacketView<kLittleEndian>(too_few_bytes));
1893   }
1894 
1895   std::vector<uint8_t> a_two_byte_struct = {
1896       static_cast<uint8_t>(StructTypeNoZero::TWO_BYTE),
1897       0x01,
1898       0x02,
1899   };
1900   too_few_bytes = std::make_shared<std::vector<uint8_t>>(a_two_byte_struct);
1901   view = OneGenericStructArrayNoZeroView::Create(PacketView<kLittleEndian>(too_few_bytes));
1902   ASSERT_TRUE(view.IsValid());
1903   ASSERT_EQ(1ul, view.GetAnArray().size());
1904 }
1905 
TEST(GeneratedPacketTest,testToStringOutput)1906 TEST(GeneratedPacketTest, testToStringOutput) {
1907   std::vector<TwoRelatedNumbersBe> count_array;
1908   for (uint8_t i = 1; i < 5; i++) {
1909     TwoRelatedNumbersBe trn;
1910     trn.id_ = i;
1911     trn.count_ = 0x0102 * i;
1912     count_array.push_back(trn);
1913   }
1914 
1915   auto packet = ArrayOfStructBeBuilder::Create(count_array);
1916 
1917   ASSERT_EQ(array_of_struct_be.size(), packet->size());
1918 
1919   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
1920   BitInserter it(*packet_bytes);
1921   packet->Serialize(it);
1922 
1923   ASSERT_EQ(array_of_struct_be.size(), packet_bytes->size());
1924   for (size_t i = 0; i < array_of_struct_be.size(); i++) {
1925     ASSERT_EQ(array_of_struct_be[i], packet_bytes->at(i));
1926   }
1927 
1928   PacketView<!kLittleEndian> packet_bytes_view(packet_bytes);
1929   auto view = ArrayOfStructBeView::Create(packet_bytes_view);
1930   ASSERT_TRUE(view.IsValid());
1931 
1932   ASSERT_EQ(
1933       "ArrayOfStructBe { array_count = 0x4, array = VECTOR[TwoRelatedNumbersBe { id = 0x1, count = 0x102 }, "
1934       "TwoRelatedNumbersBe { id = 0x2, count = 0x204 }, TwoRelatedNumbersBe { id = 0x3, count = 0x306 }, "
1935       "TwoRelatedNumbersBe { id = 0x4, count = 0x408 }] }",
1936       view.ToString());
1937 }
1938 
TEST(GeneratedPacketTest,testToStringOneFixedTypesStruct)1939 TEST(GeneratedPacketTest, testToStringOneFixedTypesStruct) {
1940   StructWithFixedTypes swf;
1941   swf.four_bits_ = FourBits::FIVE;
1942   swf.id_ = 0x0d;
1943   swf.array_ = {{0x01, 0x02, 0x03}};
1944   swf.six_bytes_ = SixBytes{{0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6}};
1945 
1946   auto packet = OneFixedTypesStructBuilder::Create(swf);
1947   ASSERT_EQ(one_fixed_types_struct.size(), packet->size());
1948 
1949   std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
1950   BitInserter it(*packet_bytes);
1951   packet->Serialize(it);
1952 
1953   ASSERT_EQ(one_fixed_types_struct.size(), packet_bytes->size());
1954   for (size_t i = 0; i < one_fixed_types_struct.size(); i++) {
1955     ASSERT_EQ(one_fixed_types_struct[i], packet_bytes->at(i));
1956   }
1957 
1958   PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
1959   auto view = OneFixedTypesStructView::Create(packet_bytes_view);
1960   ASSERT_TRUE(view.IsValid());
1961 
1962   ASSERT_EQ(
1963       "OneFixedTypesStruct { one = StructWithFixedTypes { four_bits = FIVE, id = 0xd, array = ARRAY[0x1, 0x2, 0x3], "
1964       "example_checksum = CHECKSUM, six_bytes = SixBytes } }",
1965       view.ToString());
1966 }
1967 
1968 }  // namespace parser
1969 }  // namespace packet
1970 }  // namespace bluetooth
1971