1 /** 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef LIBPANDAFILE_SHORTY_ITERATOR_H 17 #define LIBPANDAFILE_SHORTY_ITERATOR_H 18 19 #include <cstdint> 20 #include "file_items.h" 21 #include "libpandabase/macros.h" 22 23 namespace panda::panda_file { 24 class ShortyIterator { 25 public: 26 ShortyIterator() = default; 27 ShortyIterator(const uint16_t * shorty_ptr)28 explicit ShortyIterator(const uint16_t *shorty_ptr) : shorty_ptr_(shorty_ptr) 29 { 30 shorty_ = *shorty_ptr_++; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) 31 element_ = shorty_ & ELEMENT_MASK; 32 elem_idx_ = 0; 33 ASSERT(element_ != 0); 34 } 35 36 ~ShortyIterator() = default; 37 38 DEFAULT_COPY_SEMANTIC(ShortyIterator); 39 DEFAULT_MOVE_SEMANTIC(ShortyIterator); 40 41 Type operator*() const 42 { 43 return Type(static_cast<Type::TypeId>(element_)); 44 } 45 46 bool operator==(const ShortyIterator &it) const 47 { 48 return shorty_ptr_ == it.shorty_ptr_ && elem_idx_ == it.elem_idx_; 49 } 50 51 bool operator!=(const ShortyIterator &it) const 52 { 53 return !(*this == it); 54 } 55 56 ShortyIterator &operator++() 57 { 58 if (element_ == 0) { 59 return *this; 60 } 61 IncrementWithoutCheck(); 62 if (element_ == 0) { 63 *this = ShortyIterator(); 64 } 65 return *this; 66 } 67 68 ShortyIterator operator++(int) // NOLINT(cert-dcl21-cpp) 69 { 70 ShortyIterator prev = *this; 71 ++(*this); 72 return prev; 73 } 74 75 // Current method made for high performance iterator usage 76 // !!! Do not use it in general way !!! IncrementWithoutCheck()77 ALWAYS_INLINE inline void IncrementWithoutCheck() 78 { 79 ASSERT(element_ != 0); 80 81 ++elem_idx_; 82 if (elem_idx_ == NUM_ELEMENTS_PER_16BIT) { 83 shorty_ = *shorty_ptr_++; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) 84 elem_idx_ = 0; 85 } else { 86 shorty_ >>= NUM_BITS_PER_ELEMENT; 87 } 88 element_ = shorty_ & ELEMENT_MASK; 89 } 90 91 private: 92 static constexpr uint32_t NUM_ELEMENTS_PER_16BIT = 4; 93 static constexpr uint32_t NUM_BITS_PER_ELEMENT = 4; 94 static constexpr uint32_t ELEMENT_MASK = 0xF; 95 96 const uint16_t *shorty_ptr_ {nullptr}; 97 uint16_t shorty_ {0}; 98 uint16_t element_ {0}; 99 uint16_t elem_idx_ {0}; 100 }; 101 102 } // namespace panda::panda_file 103 104 #endif // LIBPANDAFILE_SHORTY_ITERATOR_H 105