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 "packet/packet_view.h"
18 
19 #include <gtest/gtest.h>
20 
21 #include <forward_list>
22 #include <memory>
23 
24 #include "hci/address.h"
25 #include "packet/iterator.h"
26 
27 using bluetooth::hci::Address;
28 using bluetooth::packet::PacketView;
29 using bluetooth::packet::View;
30 using std::vector;
31 
32 namespace {
33 vector<uint8_t> count_all = {
34     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
35     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
36 };
37 
38 vector<uint8_t> count_1 = {
39     0x00,
40     0x01,
41     0x02,
42 };
43 
44 vector<uint8_t> count_2 = {
45     0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
46 };
47 
48 vector<uint8_t> count_3 = {
49     0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
50 };
51 }  // namespace
52 
53 namespace bluetooth {
54 namespace packet {
55 
56 template <typename T>
57 class IteratorTest : public ::testing::Test {
58  public:
59   IteratorTest() = default;
60   ~IteratorTest() override = default;
61 
SetUp()62   void SetUp() override {
63     packet = std::shared_ptr<T>(new T({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())}));
64   }
65 
TearDown()66   void TearDown() override {
67     packet.reset();
68   }
69 
70   std::shared_ptr<T> packet;
71 };
72 
73 using PacketViewTypes = ::testing::Types<PacketView<true>, PacketView<false>>;
74 TYPED_TEST_CASE(IteratorTest, PacketViewTypes);
75 
76 class IteratorExtractTest : public ::testing::Test {
77  public:
78   IteratorExtractTest() = default;
79   ~IteratorExtractTest() override = default;
80 };
81 
82 template <typename T>
83 class PacketViewTest : public IteratorTest<T> {
84  public:
85   PacketViewTest() = default;
86   ~PacketViewTest() = default;
87 };
88 
89 using PacketViewTypes = ::testing::Types<PacketView<true>, PacketView<false>>;
90 TYPED_TEST_CASE(PacketViewTest, PacketViewTypes);
91 
92 class PacketViewMultiViewTest : public ::testing::Test {
93  public:
94   PacketViewMultiViewTest() = default;
95   ~PacketViewMultiViewTest() override = default;
96 
97   const PacketView<true> single_view =
98       PacketView<true>({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
99   const PacketView<true> multi_view = PacketView<true>({
100       View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
101       View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
102       View(std::make_shared<const vector<uint8_t>>(count_3), 0, count_3.size()),
103   });
104 };
105 
106 class PacketViewMultiViewAppendTest : public ::testing::Test {
107  public:
108   PacketViewMultiViewAppendTest() = default;
109   ~PacketViewMultiViewAppendTest() override = default;
110 
111   class AppendedPacketView : public PacketView<true> {
112    public:
AppendedPacketView(PacketView<true> first,std::forward_list<PacketView<true>> to_append)113     AppendedPacketView(PacketView<true> first, std::forward_list<PacketView<true>> to_append)
114         : PacketView<true>(first) {
115       for (const auto& packet_view : to_append) {
116         Append(packet_view);
117       }
118     }
119   };
120   const PacketView<true> single_view =
121       PacketView<true>({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
122   const PacketView<true> multi_view = AppendedPacketView(
123       PacketView<true>({View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size())}),
124       {PacketView<true>({View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size())}),
125        PacketView<true>({View(std::make_shared<const vector<uint8_t>>(count_3), 0, count_3.size())})});
126 };
127 
128 class ViewTest : public ::testing::Test {
129  public:
130   ViewTest() = default;
131   ~ViewTest() override = default;
132 };
133 
TEST(IteratorExtractTest,extractLeTest)134 TEST(IteratorExtractTest, extractLeTest) {
135   PacketView<true> packet({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
136   auto general_case = packet.begin();
137 
138   ASSERT_EQ(0x00, general_case.extract<uint8_t>());
139   ASSERT_EQ(0x0201, general_case.extract<uint16_t>());
140   ASSERT_EQ(0x06050403u, general_case.extract<uint32_t>());
141   ASSERT_EQ(0x0e0d0c0b0a090807u, general_case.extract<uint64_t>());
142   ASSERT_EQ(0x0f, general_case.extract<uint8_t>());
143   Address raw({0x10, 0x11, 0x12, 0x13, 0x14, 0x15});
144   ASSERT_EQ(raw, general_case.extract<Address>());
145   ASSERT_EQ(0x16, general_case.extract<uint8_t>());
146 }
147 
TEST(IteratorExtractTest,extractBeTest)148 TEST(IteratorExtractTest, extractBeTest) {
149   PacketView<false> packet({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
150   auto general_case = packet.begin();
151 
152   ASSERT_EQ(0x00, general_case.extract<uint8_t>());
153   ASSERT_EQ(0x0102, general_case.extract<uint16_t>());
154   ASSERT_EQ(0x03040506u, general_case.extract<uint32_t>());
155   ASSERT_EQ(0x0708090a0b0c0d0eu, general_case.extract<uint64_t>());
156   ASSERT_EQ(0x0f, general_case.extract<uint8_t>());
157   Address raw({0x15, 0x14, 0x13, 0x12, 0x11, 0x10});
158   ASSERT_EQ(raw, general_case.extract<Address>());
159   ASSERT_EQ(0x16, general_case.extract<uint8_t>());
160 }
161 
TYPED_TEST(IteratorTest,extractBoundsDeathTest)162 TYPED_TEST(IteratorTest, extractBoundsDeathTest) {
163   auto bounds_test = this->packet->end();
164 
165   ASSERT_DEATH(bounds_test.template extract<uint8_t>(), "");
166   ASSERT_DEATH(bounds_test.template extract<uint16_t>(), "");
167   ASSERT_DEATH(bounds_test.template extract<uint32_t>(), "");
168   ASSERT_DEATH(bounds_test.template extract<uint64_t>(), "");
169 }
170 
TYPED_TEST(IteratorTest,dereferenceDeathTest)171 TYPED_TEST(IteratorTest, dereferenceDeathTest) {
172   auto dereference_test = this->packet->end();
173 
174   ASSERT_DEATH(*dereference_test, "");
175   ASSERT_EQ(0x1f, *(dereference_test - 1));
176 }
177 
TYPED_TEST(IteratorTest,plusEqTest)178 TYPED_TEST(IteratorTest, plusEqTest) {
179   auto plus_eq = this->packet->begin();
180   for (size_t i = 0; i < count_all.size(); i += 2) {
181     ASSERT_EQ(count_all[i], *plus_eq) << "+= test: Dereferenced iterator does not equal expected at index " << i;
182     plus_eq += 2;
183   }
184 }
185 
TYPED_TEST(IteratorTest,preIncrementTest)186 TYPED_TEST(IteratorTest, preIncrementTest) {
187   auto plus_plus = this->packet->begin();
188   for (size_t i = 0; i < count_all.size() - 1; i++) {
189     ASSERT_EQ(count_all[i + 1], *(++plus_plus)) << "Pre-increment test: Dereferenced iterator does not equal expected "
190                                                 << "at index " << i;
191   }
192 }
193 
TYPED_TEST(IteratorTest,postIncrementTest)194 TYPED_TEST(IteratorTest, postIncrementTest) {
195   auto plus_plus = this->packet->begin();
196   for (size_t i = 0; i < count_all.size(); i++) {
197     ASSERT_EQ(count_all[i], plus_plus.operator*())
198         << "Post-increment test: Dereferenced iterator does not equal expected "
199         << "at index " << i;
200     plus_plus.operator++();
201   }
202 }
203 
TYPED_TEST(IteratorTest,additionTest)204 TYPED_TEST(IteratorTest, additionTest) {
205   auto plus = this->packet->begin();
206   for (size_t i = 0; i < count_all.size(); i++) {
207     ASSERT_EQ(count_all[i], *plus) << "+ test: Dereferenced iterator does not equal expected at index " << i;
208     plus = plus + 1;
209   }
210 }
211 
TYPED_TEST(IteratorTest,minusEqTest)212 TYPED_TEST(IteratorTest, minusEqTest) {
213   auto minus_eq = this->packet->end();
214   minus_eq -= 1;
215   size_t index = count_all.size() - 1;
216   for (size_t i = 0; index > i; i++) {
217     ASSERT_EQ(count_all[index], *minus_eq)
218         << "-= test: Dereferenced iterator does not equal expected at index " << index;
219     index -= i;
220     minus_eq -= i;
221   }
222 }
223 
TYPED_TEST(IteratorTest,preDecrementTest)224 TYPED_TEST(IteratorTest, preDecrementTest) {
225   auto minus_minus = this->packet->end();
226   for (size_t i = count_all.size(); i > 0; i--) {
227     ASSERT_EQ(count_all[i - 1], *(--minus_minus))
228         << "Pre-decrement test: Dereferenced iterator does not equal expected "
229         << "at index " << i;
230   }
231 }
232 
TYPED_TEST(IteratorTest,postDecrementTest)233 TYPED_TEST(IteratorTest, postDecrementTest) {
234   auto minus_minus = this->packet->end();
235   minus_minus.operator--();
236   for (size_t i = count_all.size() - 1; i > 0; i--) {
237     ASSERT_EQ(count_all[i], minus_minus.operator*())
238         << "Post-decrement test: Dereferenced iterator does not equal expected "
239         << "at index " << i;
240     minus_minus.operator--();
241   }
242 }
243 
TYPED_TEST(IteratorTest,subtractionTest)244 TYPED_TEST(IteratorTest, subtractionTest) {
245   auto minus = this->packet->end();
246   minus = minus - 1;
247   for (size_t i = count_all.size() - 1; i > 0; i--) {
248     ASSERT_EQ(count_all[i], *minus) << "- test: Dereferenced iterator does not equal expected at index " << i;
249     minus = minus - 1;
250   }
251 }
252 
TYPED_TEST(IteratorTest,differenceTest)253 TYPED_TEST(IteratorTest, differenceTest) {
254   auto begin = this->packet->begin();
255   auto end = this->packet->end();
256   int difference = end - begin;
257   ASSERT_EQ(difference, static_cast<int>(count_all.size()));
258   int neg_difference = begin - end;
259   ASSERT_EQ(neg_difference, -static_cast<int>(count_all.size()));
260 }
261 
TYPED_TEST(IteratorTest,equalityTest)262 TYPED_TEST(IteratorTest, equalityTest) {
263   auto begin = this->packet->begin();
264   auto end = this->packet->end();
265   auto begin_copy = this->packet->begin();
266   auto end_copy = this->packet->end();
267   ASSERT_EQ(begin_copy, begin);
268   ASSERT_EQ(end_copy, end);
269 }
270 
TYPED_TEST(IteratorTest,comparisonsTest)271 TYPED_TEST(IteratorTest, comparisonsTest) {
272   auto begin = this->packet->begin();
273   auto end = this->packet->end();
274   auto begin_copy = this->packet->begin();
275   auto end_copy = this->packet->end();
276   ASSERT_EQ(begin_copy, begin);
277   ASSERT_EQ(end_copy, end);
278   ASSERT_NE(begin, end);
279   ASSERT_TRUE(begin < end);
280   ASSERT_FALSE(end < end);
281   ASSERT_FALSE(end < begin);
282   ASSERT_FALSE(begin > end);
283   ASSERT_FALSE(end > end);
284   ASSERT_TRUE(end > begin);
285   ASSERT_TRUE(begin <= end);
286   ASSERT_TRUE(end <= end);
287   ASSERT_FALSE(end <= begin);
288   ASSERT_FALSE(begin >= end);
289   ASSERT_TRUE(end >= end);
290   ASSERT_TRUE(end >= begin);
291 }
292 
TYPED_TEST(PacketViewTest,getLengthTest)293 TYPED_TEST(PacketViewTest, getLengthTest) {
294   size_t length = this->packet->size();
295   ASSERT_EQ(length, count_all.size());
296 }
297 
TYPED_TEST(PacketViewTest,getAtIndexTest)298 TYPED_TEST(PacketViewTest, getAtIndexTest) {
299   size_t past_end = this->packet->size();
300   ASSERT_DEATH(this->packet->at(past_end), "");
301   size_t working_index = 0x1f;
302   ASSERT_EQ(0x1f, this->packet->at(working_index));
303 }
304 
TYPED_TEST(PacketViewTest,arrayOperatorTest)305 TYPED_TEST(PacketViewTest, arrayOperatorTest) {
306   size_t past_end = this->packet->size();
307   ASSERT_DEATH((*(this->packet))[past_end], "");
308   size_t working_index = 0x1f;
309   ASSERT_EQ(0x1f, (*(this->packet))[working_index]);
310 }
311 
TYPED_TEST(IteratorTest,numBytesRemainingTest)312 TYPED_TEST(IteratorTest, numBytesRemainingTest) {
313   auto all = this->packet->begin();
314   size_t remaining = all.NumBytesRemaining();
315   for (size_t n = remaining; n > 0; n--) {
316     ASSERT_EQ(remaining, all.NumBytesRemaining());
317     all.operator++();
318     remaining--;
319   }
320   ASSERT_EQ(static_cast<size_t>(0), all.NumBytesRemaining());
321   all.operator++();
322   ASSERT_DEATH(all.operator*(), "");
323   all.operator++();
324   ASSERT_EQ(static_cast<size_t>(0), all.NumBytesRemaining());
325   all.operator++();
326   ASSERT_DEATH(all.operator*(), "");
327 }
328 
TYPED_TEST(IteratorTest,subrangeTest)329 TYPED_TEST(IteratorTest, subrangeTest) {
330   auto empty = this->packet->begin().Subrange(0, 0);
331   ASSERT_EQ(static_cast<size_t>(0), empty.NumBytesRemaining());
332   ASSERT_DEATH(*empty, "");
333 
334   empty = this->packet->begin().Subrange(this->packet->size(), 1);
335   ASSERT_EQ(static_cast<size_t>(0), empty.NumBytesRemaining());
336   ASSERT_DEATH(*empty, "");
337 
338   auto all = this->packet->begin();
339   auto fullrange = all.Subrange(0, all.NumBytesRemaining());
340   ASSERT_EQ(all.NumBytesRemaining(), fullrange.NumBytesRemaining());
341   ASSERT_EQ(*(all + 1), 1);
342 
343   fullrange = all.Subrange(0, all.NumBytesRemaining() + 1);
344   ASSERT_EQ(all.NumBytesRemaining(), fullrange.NumBytesRemaining());
345   ASSERT_EQ(*(all + 1), 1);
346 
347   fullrange = all.Subrange(0, all.NumBytesRemaining() + 10);
348   ASSERT_EQ(all.NumBytesRemaining(), fullrange.NumBytesRemaining());
349   ASSERT_EQ(*(all + 1), 1);
350 
351   auto subrange = all.Subrange(0, 1);
352   ASSERT_EQ(1ul, subrange.NumBytesRemaining());
353   ASSERT_EQ(*(subrange), 0);
354 
355   subrange = this->packet->begin().Subrange(0, 4);
356   ASSERT_EQ(4ul, subrange.NumBytesRemaining());
357   ASSERT_EQ(*(subrange + 1), 1);
358 
359   subrange = all.Subrange(0, 3);
360   ASSERT_EQ(3ul, subrange.NumBytesRemaining());
361   ASSERT_EQ(*(subrange + 1), 1);
362 
363   subrange = all.Subrange(0, all.NumBytesRemaining() - 1);
364   ASSERT_EQ(all.NumBytesRemaining() - 1, subrange.NumBytesRemaining());
365   ASSERT_EQ(*(subrange + 1), 1);
366 
367   subrange = all.Subrange(0, all.NumBytesRemaining() - 2);
368   ASSERT_EQ(all.NumBytesRemaining() - 2, subrange.NumBytesRemaining());
369   ASSERT_EQ(*(subrange + 1), 1);
370 
371   subrange = all.Subrange(1, all.NumBytesRemaining());
372   ASSERT_EQ(all.NumBytesRemaining() - 1, subrange.NumBytesRemaining());
373   ASSERT_EQ(*subrange, 1);
374 
375   subrange = all.Subrange(2, all.NumBytesRemaining());
376   ASSERT_EQ(all.NumBytesRemaining() - 2, subrange.NumBytesRemaining());
377   ASSERT_EQ(*subrange, 2);
378 
379   subrange = all.Subrange(1, all.NumBytesRemaining() - 1);
380   ASSERT_EQ(all.NumBytesRemaining() - 1, subrange.NumBytesRemaining());
381   ASSERT_EQ(*subrange, 1);
382 
383   subrange = all.Subrange(2, all.NumBytesRemaining() - 2);
384   ASSERT_EQ(all.NumBytesRemaining() - 2, subrange.NumBytesRemaining());
385   ASSERT_EQ(*subrange, 2);
386 
387   subrange = all.Subrange(1, 1);
388   ASSERT_EQ(1ul, subrange.NumBytesRemaining());
389   ASSERT_EQ(*(subrange), 1);
390 
391   subrange = all.Subrange(1, 2);
392   ASSERT_EQ(2ul, subrange.NumBytesRemaining());
393   ASSERT_EQ(*(subrange), 1);
394 
395   subrange = all.Subrange(2, 1);
396   ASSERT_EQ(1ul, subrange.NumBytesRemaining());
397   ASSERT_EQ(*(subrange), 2);
398 
399   subrange = this->packet->begin().Subrange(this->packet->size() - 1, 2);
400   ASSERT_EQ(static_cast<size_t>(1), subrange.NumBytesRemaining());
401   ASSERT_EQ(*(subrange), this->packet->size() - 1);
402 }
403 
TYPED_TEST(IteratorTest,constructor_from_shared_vector_test)404 TYPED_TEST(IteratorTest, constructor_from_shared_vector_test) {
405   auto iterator = this->packet->begin();
406   Iterator<kLittleEndian> another(std::make_shared<std::vector<uint8_t>>(count_all));
407   ASSERT_EQ(iterator.NumBytesRemaining(), another.NumBytesRemaining());
408   for (size_t i = 0; i < count_all.size(); i++) {
409     ASSERT_EQ(iterator.template extract<uint8_t>(), another.extract<uint8_t>());
410   }
411 }
412 
413 using SubviewTestParam = std::pair<size_t, size_t>;
414 class SubviewBaseTest : public ::testing::TestWithParam<SubviewTestParam> {
415  public:
416   class SubPacketView : public PacketView<true> {
417    public:
418     using PacketView<true>::PacketView;
Slice(size_t header,size_t tail)419     PacketView<true> Slice(size_t header, size_t tail) {
420       return PacketView<true>::GetLittleEndianSubview(header, tail);
421     }
422   };
423 };
424 
425 class SubviewPassTest : public SubviewBaseTest {};
426 
TEST_P(SubviewPassTest,subviewTest)427 TEST_P(SubviewPassTest, subviewTest) {
428   auto header = GetParam().first;
429   auto tail = GetParam().second;
430   SubPacketView single_view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
431   SubPacketView multi_view({
432       View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
433       View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
434       View(std::make_shared<const vector<uint8_t>>(count_3), 0, count_3.size()),
435   });
436 
437   auto single_slice = single_view.Slice(header, tail);
438   auto multi_slice = multi_view.Slice(header, tail);
439 
440   ASSERT_EQ(single_slice.size(), tail - header);
441   ASSERT_EQ(single_slice.size(), multi_slice.size());
442   for (size_t i = 0; i < single_slice.size(); i++) {
443     ASSERT_EQ(single_slice[i], multi_slice[i]);
444   }
445 }
446 
447 static const size_t boundary_1 = count_1.size();
448 static const size_t boundary_2 = count_1.size() + count_2.size();
449 
450 INSTANTIATE_TEST_CASE_P(
451     chopomatic, SubviewPassTest,
452     ::testing::Values(
453         // {begin, end} pairs for subsets into the PacketView
454         SubviewTestParam{0, 0}, SubviewTestParam{0, boundary_1}, SubviewTestParam{0, boundary_1 + 1},
455         SubviewTestParam{0, boundary_2}, SubviewTestParam{0, boundary_2 + 1}, SubviewTestParam{0, count_all.size()},
456         SubviewTestParam{boundary_1 - 1, boundary_1}, SubviewTestParam{boundary_1 - 1, boundary_1 + 1},
457         SubviewTestParam{boundary_1 - 1, boundary_2}, SubviewTestParam{boundary_1 - 1, boundary_2 + 1},
458         SubviewTestParam{boundary_1 - 1, count_all.size()}, SubviewTestParam{boundary_1, boundary_1},
459         SubviewTestParam{boundary_1, boundary_2}, SubviewTestParam{boundary_1, boundary_2 + 1},
460         SubviewTestParam{boundary_1, count_all.size()}, SubviewTestParam{boundary_2 - 1, boundary_2},
461         SubviewTestParam{boundary_2 - 1, boundary_2 + 1}, SubviewTestParam{boundary_2 - 1, count_all.size()},
462         SubviewTestParam{boundary_2, boundary_2}, SubviewTestParam{boundary_2, boundary_2 + 1},
463         SubviewTestParam{boundary_2, count_all.size()}, SubviewTestParam{count_all.size() - 1, count_all.size()},
464         SubviewTestParam{count_all.size(), count_all.size()}));
465 
466 class SubviewDeathTest : public SubviewBaseTest {};
467 
TEST_P(SubviewDeathTest,subviewDeathTest)468 TEST_P(SubviewDeathTest, subviewDeathTest) {
469   auto header = GetParam().first;
470   auto tail = GetParam().second;
471   SubPacketView single_view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
472   SubPacketView multi_view({
473       View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
474       View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
475       View(std::make_shared<const vector<uint8_t>>(count_3), 0, count_3.size()),
476   });
477 
478   ASSERT_DEATH(auto single_slice = single_view.Slice(header, tail), "");
479   ASSERT_DEATH(auto multi_slice = multi_view.Slice(header, tail), "");
480 }
481 
482 INSTANTIATE_TEST_CASE_P(chopomaticDeath, SubviewDeathTest,
483                         ::testing::Values(
484                             // {begin, end} pairs for subsets into the PacketView
485                             SubviewTestParam{1, 0}, SubviewTestParam{count_all.size(), count_all.size() - 1},
486                             SubviewTestParam{count_all.size(), count_all.size() + 1}));
487 
TEST(SubviewTest,simpleSubviewTest)488 TEST(SubviewTest, simpleSubviewTest) {
489   PacketView<true> view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
490   PacketView<true> sub_1_view = view.GetLittleEndianSubview(0, view.size());
491   PacketView<true> sub_2_view = sub_1_view.GetLittleEndianSubview(0, sub_1_view.size());
492   PacketView<true> sub_3_view = sub_2_view.GetLittleEndianSubview(0, sub_2_view.size());
493   PacketView<true> sub_4_view = sub_3_view.GetLittleEndianSubview(0, sub_3_view.size());
494   ASSERT_EQ(sub_1_view.size(), view.size());
495   ASSERT_EQ(sub_2_view.size(), view.size());
496   ASSERT_EQ(sub_3_view.size(), view.size());
497   ASSERT_EQ(sub_4_view.size(), view.size());
498 }
499 
TEST(SubviewTest,realSubviewTest)500 TEST(SubviewTest, realSubviewTest) {
501   PacketView<true> view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
502   std::vector<PacketView<true>> sub_views{view};
503   for (size_t i = 1; i < 6; i++) {
504     size_t parent_size = sub_views[i - 1].size();
505     sub_views.push_back(sub_views[i - 1].GetLittleEndianSubview(1, parent_size - 1));
506     ASSERT_EQ(sub_views[i][0], i);
507     ASSERT_EQ(sub_views[i].size(), parent_size - 2);
508   }
509 }
510 
TEST(SubviewTest,subSubviewTest)511 TEST(SubviewTest, subSubviewTest) {
512   PacketView<true> single_view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
513   PacketView<true> multi_view({
514       View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
515       View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
516       View(std::make_shared<const vector<uint8_t>>(count_3), 0, count_3.size()),
517   });
518   ASSERT_EQ(single_view.size(), multi_view.size());
519   for (size_t i = 0; i < count_all.size() / 2; i++) {
520     PacketView<true> sub_single_view = single_view.GetLittleEndianSubview(i, count_all.size() - i);
521     PacketView<true> sub_multi_view = multi_view.GetLittleEndianSubview(i, count_all.size() - i);
522     ASSERT_EQ(count_all.size() - 2 * i, sub_single_view.size());
523     ASSERT_EQ(sub_single_view.size(), sub_multi_view.size());
524     for (size_t j = 0; j < sub_single_view.size() / 2; j++) {
525       PacketView<true> sub_sub_single_view = sub_single_view.GetLittleEndianSubview(j, sub_single_view.size() - j);
526       PacketView<true> sub_sub_multi_view = sub_multi_view.GetLittleEndianSubview(j, sub_multi_view.size() - j);
527       ASSERT_EQ(sub_single_view.size() - 2 * j, sub_sub_single_view.size());
528       ASSERT_EQ(sub_sub_single_view.size(), sub_sub_multi_view.size());
529     }
530   }
531 }
532 
TEST_F(PacketViewMultiViewTest,sizeTest)533 TEST_F(PacketViewMultiViewTest, sizeTest) {
534   ASSERT_EQ(single_view.size(), multi_view.size());
535 }
536 
TEST_F(PacketViewMultiViewTest,dereferenceTestLittleEndian)537 TEST_F(PacketViewMultiViewTest, dereferenceTestLittleEndian) {
538   auto single_itr = single_view.begin();
539   auto multi_itr = multi_view.begin();
540   for (size_t i = 0; i < single_view.size(); i++) {
541     ASSERT_EQ(single_itr.operator*(), multi_itr.operator*());
542     single_itr.operator++();
543     multi_itr.operator++();
544   }
545   ASSERT_DEATH(*multi_itr, "");
546 }
547 
TEST_F(PacketViewMultiViewTest,dereferenceTestBigEndian)548 TEST_F(PacketViewMultiViewTest, dereferenceTestBigEndian) {
549   auto single_itr = single_view.begin();
550   auto multi_itr = multi_view.begin();
551   for (size_t i = 0; i < single_view.size(); i++) {
552     ASSERT_EQ(single_itr.operator*(), multi_itr.operator*());
553     single_itr.operator++();
554     multi_itr.operator++();
555   }
556   ASSERT_DEATH(*multi_itr, "");
557 }
558 
TEST_F(PacketViewMultiViewTest,arrayOperatorTest)559 TEST_F(PacketViewMultiViewTest, arrayOperatorTest) {
560   for (size_t i = 0; i < single_view.size(); i++) {
561     ASSERT_EQ(single_view[i], multi_view[i]);
562   }
563   ASSERT_DEATH(multi_view[single_view.size()], "");
564 }
565 
TEST_F(PacketViewMultiViewAppendTest,sizeTestAppend)566 TEST_F(PacketViewMultiViewAppendTest, sizeTestAppend) {
567   ASSERT_EQ(single_view.size(), multi_view.size());
568 }
569 
TEST_F(PacketViewMultiViewAppendTest,dereferenceTestLittleEndianAppend)570 TEST_F(PacketViewMultiViewAppendTest, dereferenceTestLittleEndianAppend) {
571   auto single_itr = single_view.begin();
572   auto multi_itr = multi_view.begin();
573   for (size_t i = 0; i < single_view.size(); i++) {
574     ASSERT_EQ(single_itr.operator*(), multi_itr.operator*());
575     single_itr.operator++();
576     multi_itr.operator++();
577   }
578   ASSERT_DEATH(*multi_itr, "");
579 }
580 
TEST_F(PacketViewMultiViewAppendTest,dereferenceTestBigEndianAppend)581 TEST_F(PacketViewMultiViewAppendTest, dereferenceTestBigEndianAppend) {
582   auto single_itr = single_view.begin();
583   auto multi_itr = multi_view.begin();
584   for (size_t i = 0; i < single_view.size(); i++) {
585     ASSERT_EQ(single_itr.operator*(), multi_itr.operator*());
586     single_itr.operator++();
587     multi_itr.operator++();
588   }
589   ASSERT_DEATH(*multi_itr, "");
590 }
591 
TEST_F(PacketViewMultiViewAppendTest,arrayOperatorTestAppend)592 TEST_F(PacketViewMultiViewAppendTest, arrayOperatorTestAppend) {
593   for (size_t i = 0; i < single_view.size(); i++) {
594     ASSERT_EQ(single_view[i], multi_view[i]);
595   }
596   ASSERT_DEATH(multi_view[single_view.size()], "");
597 }
598 
TEST(ViewTest,arrayOperatorTest)599 TEST(ViewTest, arrayOperatorTest) {
600   View view_all(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size());
601   size_t past_end = view_all.size();
602   for (size_t i = 0; i < past_end; i++) {
603     ASSERT_EQ(view_all[i], count_all[i]);
604   }
605   ASSERT_DEATH(view_all[past_end], "");
606 
607   size_t header_size = 2;
608   size_t tail_size = 3;
609   View view_subset(std::make_shared<const vector<uint8_t>>(count_all), header_size, count_all.size() - tail_size);
610   View view_subset2(view_all, header_size, count_all.size() - tail_size);
611   size_t subset_length = view_subset.size();
612   for (size_t i = 0; i < subset_length; i++) {
613     ASSERT_EQ(view_subset[i], count_all[header_size + i]);
614     ASSERT_EQ(view_subset[i], view_subset2[i]);
615   }
616   ASSERT_DEATH(view_subset[subset_length + 1], "");
617   ASSERT_DEATH(view_subset2[subset_length + 1], "");
618 }
619 
TEST(ViewTest,earlySubSubviewTest)620 TEST(ViewTest, earlySubSubviewTest) {
621   View view(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size());
622   View sub_1_view(view, view.size() - 3, view.size() - 1);
623   View sub_2_view(sub_1_view, 1, 2);
624   ASSERT_EQ(sub_1_view.size(), 2u);
625   ASSERT_EQ(sub_2_view.size(), 1u);
626 }
627 
TEST(ViewTest,subSubviewTest)628 TEST(ViewTest, subSubviewTest) {
629   View view(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size());
630   std::vector<View> sub_views{view};
631   for (size_t i = 1; i < 6; i++) {
632     size_t parent_size = sub_views[i - 1].size();
633     sub_views.push_back({View(sub_views[i - 1], 1, parent_size - 1)});
634     ASSERT_EQ(sub_views[i][0], i);
635     ASSERT_EQ(sub_views[i].size(), parent_size - 2);
636   }
637 }
638 
TEST(ViewTest,zeroSubviewTest)639 TEST(ViewTest, zeroSubviewTest) {
640   View view(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size());
641   View subview(view, view.size(), view.size() + 1);
642   ASSERT_EQ(subview.size(), 0u);
643 }
644 }  // namespace packet
645 }  // namespace bluetooth
646