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_FIELD_DATA_ACCESSOR_H 17 #define LIBPANDAFILE_FIELD_DATA_ACCESSOR_H 18 19 #include "file.h" 20 #include "file_items.h" 21 #include "modifiers.h" 22 #include "type.h" 23 24 #include <variant> 25 #include <vector> 26 #include <optional> 27 28 namespace panda::panda_file { 29 30 class FieldDataAccessor { 31 public: 32 FieldDataAccessor(const File &panda_file, File::EntityId field_id); 33 34 ~FieldDataAccessor() = default; 35 36 NO_COPY_SEMANTIC(FieldDataAccessor); 37 NO_MOVE_SEMANTIC(FieldDataAccessor); 38 39 // quick way to get type id 40 static File::EntityId GetTypeId(const File &panda_file, File::EntityId field_id); 41 42 static File::EntityId GetNameId(const File &panda_file, File::EntityId field_id); 43 IsExternal()44 bool IsExternal() const 45 { 46 return is_external_; 47 } 48 GetClassId()49 File::EntityId GetClassId() const 50 { 51 return File::EntityId(class_off_); 52 } 53 GetNameId()54 File::EntityId GetNameId() const 55 { 56 return File::EntityId(name_off_); 57 } 58 GetType()59 uint32_t GetType() const 60 { 61 return type_off_; 62 } 63 GetAccessFlags()64 uint32_t GetAccessFlags() const 65 { 66 return access_flags_; 67 } 68 IsStatic()69 bool IsStatic() const 70 { 71 return (access_flags_ & ACC_STATIC) != 0; 72 } 73 IsVolatile()74 bool IsVolatile() const 75 { 76 return (access_flags_ & ACC_VOLATILE) != 0; 77 } 78 IsPublic()79 bool IsPublic() const 80 { 81 return (access_flags_ & ACC_PUBLIC) != 0; 82 } 83 IsPrivate()84 bool IsPrivate() const 85 { 86 return (access_flags_ & ACC_PRIVATE) != 0; 87 } 88 IsProtected()89 bool IsProtected() const 90 { 91 return (access_flags_ & ACC_PROTECTED) != 0; 92 } 93 IsFinal()94 bool IsFinal() const 95 { 96 return (access_flags_ & ACC_FINAL) != 0; 97 } 98 IsTransient()99 bool IsTransient() const 100 { 101 return (access_flags_ & ACC_TRANSIENT) != 0; 102 } 103 IsSynthetic()104 bool IsSynthetic() const 105 { 106 return (access_flags_ & ACC_SYNTHETIC) != 0; 107 } 108 IsEnum()109 bool IsEnum() const 110 { 111 return (access_flags_ & ACC_ENUM) != 0; 112 } 113 114 template <class T> 115 std::optional<T> GetValue(); 116 117 template <class Callback> 118 void EnumerateRuntimeAnnotations(const Callback &cb); 119 120 template <class Callback> 121 void EnumerateAnnotations(const Callback &cb); 122 123 template <class Callback> 124 void EnumerateRuntimeTypeAnnotations(const Callback &cb); 125 126 template <class Callback> 127 void EnumerateTypeAnnotations(const Callback &cb); 128 129 template <class Callback> 130 bool EnumerateRuntimeAnnotationsWithEarlyStop(const Callback &cb); 131 132 template <class Callback> 133 bool EnumerateAnnotationsWithEarlyStop(const Callback &cb); 134 GetSize()135 size_t GetSize() 136 { 137 if (size_ == 0) { 138 SkipTypeAnnotations(); 139 } 140 141 return size_; 142 } 143 GetPandaFile()144 const File &GetPandaFile() const 145 { 146 return panda_file_; 147 } 148 GetFieldId()149 File::EntityId GetFieldId() const 150 { 151 return field_id_; 152 } 153 154 uint32_t GetAnnotationsNumber(); 155 uint32_t GetRuntimeAnnotationsNumber(); 156 uint32_t GetRuntimeTypeAnnotationsNumber(); 157 uint32_t GetTypeAnnotationsNumber(); 158 159 private: 160 using FieldValue = std::variant<uint32_t, uint64_t>; 161 162 std::optional<FieldValue> GetValueInternal(); 163 164 void SkipValue(); 165 166 void SkipRuntimeAnnotations(); 167 168 void SkipAnnotations(); 169 170 void SkipRuntimeTypeAnnotations(); 171 172 void SkipTypeAnnotations(); 173 174 const File &panda_file_; 175 File::EntityId field_id_; 176 177 bool is_external_; 178 179 uint32_t class_off_; 180 uint32_t type_off_; 181 uint32_t name_off_; 182 uint32_t access_flags_; 183 184 Span<const uint8_t> tagged_values_sp_ {nullptr, nullptr}; 185 Span<const uint8_t> runtime_annotations_sp_ {nullptr, nullptr}; 186 Span<const uint8_t> annotations_sp_ {nullptr, nullptr}; 187 Span<const uint8_t> runtime_type_annotations_sp_ {nullptr, nullptr}; 188 Span<const uint8_t> type_annotations_sp_ {nullptr, nullptr}; 189 190 size_t size_; 191 }; 192 193 } // namespace panda::panda_file 194 195 #endif // LIBPANDAFILE_FIELD_DATA_ACCESSOR_H 196