1 /*
2  * Copyright (C) 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 #ifndef ART_LIBDEXFILE_DEX_CLASS_ITERATOR_H_
18 #define ART_LIBDEXFILE_DEX_CLASS_ITERATOR_H_
19 
20 #include <android-base/logging.h>
21 
22 namespace art {
23 
24 class ClassAccessor;
25 class ClassIterator;
26 class DexFile;
27 
28 // Holder class, used to construct ClassAccessors.
29 class ClassIteratorData {
30  public:
ClassIteratorData(const DexFile & dex_file,uint32_t class_def_idx)31   ClassIteratorData(const DexFile& dex_file, uint32_t class_def_idx)
32       : dex_file_(dex_file),
33         class_def_idx_(class_def_idx) {}
34 
35  private:
36   const DexFile& dex_file_;
37   uint32_t class_def_idx_ = 0u;
38 
39   friend class ClassAccessor;
40   friend class ClassIterator;
41 };
42 
43 // Iterator for visiting classes in a Dex file.
44 class ClassIterator : public std::iterator<std::forward_iterator_tag, ClassIteratorData> {
45  public:
46   using value_type = std::iterator<std::forward_iterator_tag, ClassIteratorData>::value_type;
47   using difference_type = std::iterator<std::forward_iterator_tag, value_type>::difference_type;
48 
ClassIterator(const DexFile & dex_file,uint32_t class_def_idx)49   ClassIterator(const DexFile& dex_file, uint32_t class_def_idx)
50       : data_(dex_file, class_def_idx) {}
51 
52   // Value after modification.
53   ClassIterator& operator++() {
54     ++data_.class_def_idx_;
55     return *this;
56   }
57 
58   // Value before modification.
59   ClassIterator operator++(int) {
60     ClassIterator temp = *this;
61     ++*this;
62     return temp;
63   }
64 
65   const value_type& operator*() const {
66     return data_;
67   }
68 
69   bool operator==(const ClassIterator& rhs) const {
70     DCHECK_EQ(&data_.dex_file_, &rhs.data_.dex_file_) << "Comparing different dex files.";
71     return data_.class_def_idx_ == rhs.data_.class_def_idx_;
72   }
73 
74   bool operator!=(const ClassIterator& rhs) const {
75     return !(*this == rhs);
76   }
77 
78   bool operator<(const ClassIterator& rhs) const {
79     DCHECK_EQ(&data_.dex_file_, &rhs.data_.dex_file_) << "Comparing different dex files.";
80     return data_.class_def_idx_ < rhs.data_.class_def_idx_;
81   }
82 
83   bool operator>(const ClassIterator& rhs) const {
84     return rhs < *this;
85   }
86 
87   bool operator<=(const ClassIterator& rhs) const {
88     return !(rhs < *this);
89   }
90 
91   bool operator>=(const ClassIterator& rhs) const {
92     return !(*this < rhs);
93   }
94 
95  protected:
96   ClassIteratorData data_;
97 };
98 
99 }  // namespace art
100 
101 #endif  // ART_LIBDEXFILE_DEX_CLASS_ITERATOR_H_
102