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 
23 #include "packet/view.h"
24 
25 namespace bluetooth {
26 namespace packet {
27 
28 // Templated Iterator for endianness
29 template <bool little_endian>
30 class Iterator : public std::iterator<std::random_access_iterator_tag, uint8_t> {
31  public:
32   Iterator(std::forward_list<View> data, size_t offset);
33   Iterator(const Iterator& itr) = default;
34   virtual ~Iterator() = default;
35 
36   // All addition and subtraction operators are unbounded.
37   Iterator operator+(int offset);
38   Iterator& operator+=(int offset);
39   Iterator operator++(int);
40   Iterator& operator++();
41 
42   Iterator operator-(int offset);
43   int operator-(Iterator& itr);
44   Iterator& operator-=(int offset);
45   Iterator operator--(int);
46   Iterator& operator--();
47 
48   Iterator& operator=(const Iterator& itr);
49 
50   bool operator!=(const Iterator& itr) const;
51   bool operator==(const Iterator& itr) const;
52 
53   bool operator<(const Iterator& itr) const;
54   bool operator>(const Iterator& itr) const;
55 
56   bool operator<=(const Iterator& itr) const;
57   bool operator>=(const Iterator& itr) const;
58 
59   uint8_t operator*() const;
60   uint8_t operator->() const;
61 
62   size_t NumBytesRemaining() const;
63 
64   Iterator Subrange(size_t index, size_t length) const;
65 
66   // Get the next sizeof(FixedWidthPODType) bytes and return the filled type
67   template <typename FixedWidthPODType>
68   FixedWidthPODType extract() {
69     static_assert(std::is_pod<FixedWidthPODType>::value, "Iterator::extract requires a fixed-width type.");
70     FixedWidthPODType extracted_value;
71     uint8_t* value_ptr = (uint8_t*)&extracted_value;
72 
73     for (size_t i = 0; i < sizeof(FixedWidthPODType); i++) {
74       size_t index = (little_endian ? i : sizeof(FixedWidthPODType) - i - 1);
75       value_ptr[index] = *((*this)++);
76     }
77     return extracted_value;
78   }
79 
80  private:
81   std::forward_list<View> data_;
82   size_t index_;
83   size_t begin_;
84   size_t end_;
85 };
86 
87 }  // namespace packet
88 }  // namespace bluetooth
89