• 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 #pragma once
18 
19 #include <cstdint>
20 #include <forward_list>
21 #include <memory>
22 #include <type_traits>
23 
24 #include "packet/custom_field_fixed_size_interface.h"
25 #include "packet/view.h"
26 
27 namespace bluetooth {
28 namespace packet {
29 
30 // std::iterator is deprecated in C++17 onwards. Instead, you must declare all
31 // 5 aliases that the iterator needs for the std library.
32 #if __cplusplus >= 201703L
33 struct IteratorTraits {
34   using iterator_category = std::random_access_iterator_tag;
35   using value_type = uint8_t;
36   using difference_type = std::ptrdiff_t;
37   using pointer = uint8_t*;
38   using reference = uint8_t&;
39 };
40 #else
41 struct IteratorTraits : public std::iterator<std::random_access_iterator_tag, uint8_t> {};
42 #endif
43 
44 // Templated Iterator for endianness
45 template <bool little_endian>
46 class Iterator : public IteratorTraits {
47  public:
48   Iterator(const std::forward_list<View>& data, size_t offset);
49   Iterator(const Iterator& itr) = default;
50   virtual ~Iterator() = default;
51 
52   // All addition and subtraction operators are unbounded.
53   Iterator operator+(int offset) const;
54   Iterator& operator+=(int offset);
55   Iterator& operator++();
56 
57   Iterator operator-(int offset) const;
58   int operator-(const Iterator& itr) const;
59   Iterator& operator-=(int offset);
60   Iterator& operator--();
61 
62   Iterator& operator=(const Iterator& itr);
63 
64   bool operator!=(const Iterator& itr) const;
65   bool operator==(const Iterator& itr) const;
66 
67   bool operator<(const Iterator& itr) const;
68   bool operator>(const Iterator& itr) const;
69 
70   bool operator<=(const Iterator& itr) const;
71   bool operator>=(const Iterator& itr) const;
72 
73   uint8_t operator*() const;
74 
75   size_t NumBytesRemaining() const;
76 
77   Iterator Subrange(size_t index, size_t length) const;
78 
79   // Get the next sizeof(FixedWidthPODType) bytes and return the filled type
80   template <typename FixedWidthPODType, typename std::enable_if<std::is_pod<FixedWidthPODType>::value, int>::type = 0>
extract()81   FixedWidthPODType extract() {
82     static_assert(std::is_pod<FixedWidthPODType>::value, "Iterator::extract requires a fixed-width type.");
83     FixedWidthPODType extracted_value{};
84     uint8_t* value_ptr = (uint8_t*)&extracted_value;
85 
86     for (size_t i = 0; i < sizeof(FixedWidthPODType); i++) {
87       size_t index = (little_endian ? i : sizeof(FixedWidthPODType) - i - 1);
88       value_ptr[index] = this->operator*();
89       this->operator++();
90     }
91     return extracted_value;
92   }
93 
94   template <typename T, typename std::enable_if<std::is_base_of_v<CustomFieldFixedSizeInterface<T>, T>, int>::type = 0>
extract()95   T extract() {
96     T extracted_value{};
97     for (size_t i = 0; i < CustomFieldFixedSizeInterface<T>::length(); i++) {
98       size_t index = (little_endian ? i : CustomFieldFixedSizeInterface<T>::length() - i - 1);
99       extracted_value.data()[index] = this->operator*();
100       this->operator++();
101     }
102     return extracted_value;
103   }
104 
105  private:
106   std::forward_list<View> data_;
107   size_t index_;
108   size_t begin_;
109   size_t end_;
110 };
111 
112 }  // namespace packet
113 }  // namespace bluetooth
114