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 : public std::iterator<std::random_access_iterator_tag, uint8_t> {}; 39 #endif 40 41 // Iterator is a custom iterator class for Packets. 42 class Iterator : public IteratorTraits { 43 public: 44 Iterator(std::shared_ptr<const Packet> packet, size_t i); 45 Iterator(const Iterator& itr); 46 47 // All addition and subtraction operators are bounded from 0 to the length of 48 // the packet. 49 Iterator operator+(size_t offset); 50 Iterator& operator+=(size_t offset); 51 Iterator operator++(int); 52 Iterator& operator++(); 53 54 Iterator operator-(size_t offset); 55 int operator-(const Iterator& itr); 56 Iterator& operator-=(size_t offset); 57 Iterator operator--(int); 58 Iterator& operator--(); 59 60 Iterator& operator=(const Iterator& itr); 61 62 bool operator!=(const Iterator& itr) const; 63 bool operator==(const Iterator& itr) const; 64 65 bool operator<(const Iterator& itr) const; 66 bool operator>(const Iterator& itr) const; 67 68 bool operator<=(const Iterator& itr) const; 69 bool operator>=(const Iterator& itr) const; 70 71 uint8_t operator*() const; 72 73 template <typename FixedWidthIntegerType> extract()74 FixedWidthIntegerType extract() { 75 static_assert(std::is_integral<FixedWidthIntegerType>::value, 76 "Iterator::extract requires an integral type."); 77 78 FixedWidthIntegerType extracted_value = 0; 79 for (size_t i = 0; i < sizeof(FixedWidthIntegerType); i++) { 80 extracted_value |= static_cast<FixedWidthIntegerType>(**this) << i * 8; 81 (*this)++; 82 } 83 84 return extracted_value; 85 } 86 87 // Extract in Little Endian Format 88 template <typename FixedWidthIntegerType> extractBE()89 FixedWidthIntegerType extractBE() { 90 static_assert(std::is_integral<FixedWidthIntegerType>::value, 91 "Iterator::extract requires an integral type."); 92 93 FixedWidthIntegerType extracted_value = 0; 94 for (size_t i = 0; i < sizeof(FixedWidthIntegerType); i++) { 95 extracted_value |= static_cast<FixedWidthIntegerType>(**this) 96 << (sizeof(FixedWidthIntegerType) - 1 - i) * 8; 97 (*this)++; 98 } 99 100 return extracted_value; 101 } 102 extract8()103 uint8_t extract8() { return extract<uint8_t>(); } extract16()104 uint16_t extract16() { return extract<uint16_t>(); } extract32()105 uint32_t extract32() { return extract<uint32_t>(); } extract64()106 uint64_t extract64() { return extract<uint64_t>(); } 107 108 private: 109 std::shared_ptr<const Packet> packet_; 110 size_t index_; 111 }; // Iterator 112 113 } // namespace bluetooth 114