/** * Copyright (c) 2021-2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef LIBPANDAFILE_SHORTY_ITERATOR_H #define LIBPANDAFILE_SHORTY_ITERATOR_H #include #include "file_items.h" #include "libpandabase/macros.h" namespace panda::panda_file { class ShortyIterator { public: ShortyIterator() = default; explicit ShortyIterator(const uint16_t *shorty_ptr) : shorty_ptr_(shorty_ptr) { shorty_ = *shorty_ptr_++; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) element_ = shorty_ & ELEMENT_MASK; elem_idx_ = 0; ASSERT(element_ != 0); } ~ShortyIterator() = default; DEFAULT_COPY_SEMANTIC(ShortyIterator); DEFAULT_MOVE_SEMANTIC(ShortyIterator); Type operator*() const { return Type(static_cast(element_)); } bool operator==(const ShortyIterator &it) const { return shorty_ptr_ == it.shorty_ptr_ && elem_idx_ == it.elem_idx_; } bool operator!=(const ShortyIterator &it) const { return !(*this == it); } ShortyIterator &operator++() { if (element_ == 0) { return *this; } IncrementWithoutCheck(); if (element_ == 0) { *this = ShortyIterator(); } return *this; } ShortyIterator operator++(int) // NOLINT(cert-dcl21-cpp) { ShortyIterator prev = *this; ++(*this); return prev; } // Current method made for high performance iterator usage // !!! Do not use it in general way !!! ALWAYS_INLINE inline void IncrementWithoutCheck() { ASSERT(element_ != 0); ++elem_idx_; if (elem_idx_ == NUM_ELEMENTS_PER_16BIT) { shorty_ = *shorty_ptr_++; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) elem_idx_ = 0; } else { shorty_ >>= NUM_BITS_PER_ELEMENT; } element_ = shorty_ & ELEMENT_MASK; } private: static constexpr uint32_t NUM_ELEMENTS_PER_16BIT = 4; static constexpr uint32_t NUM_BITS_PER_ELEMENT = 4; static constexpr uint32_t ELEMENT_MASK = 0xF; const uint16_t *shorty_ptr_ {nullptr}; uint16_t shorty_ {0}; uint16_t element_ {0}; uint16_t elem_idx_ {0}; }; } // namespace panda::panda_file #endif // LIBPANDAFILE_SHORTY_ITERATOR_H