1 /* 2 * Copyright 2018 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 <iterator> 20 #include <memory> 21 22 namespace bluetooth { 23 24 // Forward declare Packet class 25 class Packet; 26 27 // std::iterator is deprecated in C++17 onwards. Instead, you must declare all 28 // 5 aliases that the iterator needs for the std library. 29 #if __cplusplus >= 201703L 30 struct IteratorTraits { 31 using iterator_category = std::random_access_iterator_tag; 32 using value_type = uint8_t; 33 using difference_type = std::ptrdiff_t; 34 using pointer = uint8_t*; 35 using reference = uint8_t&; 36 }; 37 #else 38 struct IteratorTraits 39 : public std::iterator<std::random_access_iterator_tag, uint8_t> {}; 40 #endif 41 42 // Iterator is a custom iterator class for Packets. 43 class Iterator : public IteratorTraits { 44 public: 45 Iterator(std::shared_ptr<const Packet> packet, size_t i); 46 Iterator(const Iterator& itr); 47 48 // All addition and subtraction operators are bounded from 0 to the length of 49 // the packet. 50 Iterator operator+(size_t offset); 51 Iterator& operator+=(size_t offset); 52 Iterator operator++(int); 53 Iterator& operator++(); 54 55 Iterator operator-(size_t offset); 56 int operator-(const Iterator& itr); 57 Iterator& operator-=(size_t offset); 58 Iterator operator--(int); 59 Iterator& operator--(); 60 61 Iterator& operator=(const Iterator& itr); 62 63 bool operator!=(const Iterator& itr) const; 64 bool operator==(const Iterator& itr) const; 65 66 bool operator<(const Iterator& itr) const; 67 bool operator>(const Iterator& itr) const; 68 69 bool operator<=(const Iterator& itr) const; 70 bool operator>=(const Iterator& itr) const; 71 72 uint8_t operator*() const; 73 74 template <typename FixedWidthIntegerType> extract()75 FixedWidthIntegerType extract() { 76 static_assert(std::is_integral<FixedWidthIntegerType>::value, 77 "Iterator::extract requires an integral type."); 78 79 FixedWidthIntegerType extracted_value = 0; 80 for (size_t i = 0; i < sizeof(FixedWidthIntegerType); i++) { 81 extracted_value |= static_cast<FixedWidthIntegerType>(**this) << i * 8; 82 (*this)++; 83 } 84 85 return extracted_value; 86 } 87 88 // Extract in Little Endian Format 89 template <typename FixedWidthIntegerType> extractBE()90 FixedWidthIntegerType extractBE() { 91 static_assert(std::is_integral<FixedWidthIntegerType>::value, 92 "Iterator::extract requires an integral type."); 93 94 FixedWidthIntegerType extracted_value = 0; 95 for (size_t i = 0; i < sizeof(FixedWidthIntegerType); i++) { 96 extracted_value |= static_cast<FixedWidthIntegerType>(**this) 97 << (sizeof(FixedWidthIntegerType) - 1 - i) * 8; 98 (*this)++; 99 } 100 101 return extracted_value; 102 } 103 extract8()104 uint8_t extract8() { return extract<uint8_t>(); } extract16()105 uint16_t extract16() { return extract<uint16_t>(); } extract32()106 uint32_t extract32() { return extract<uint32_t>(); } extract64()107 uint64_t extract64() { return extract<uint64_t>(); } 108 109 private: 110 std::shared_ptr<const Packet> packet_; 111 size_t index_; 112 }; // Iterator 113 114 } // namespace bluetooth 115