1 /* 2 * Copyright (c) 2021 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 PANDA_LIBPANDAFILE_FIELD_DATA_ACCESSOR_H_ 17 #define PANDA_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 IsExternal()39 bool IsExternal() const 40 { 41 return is_external_; 42 } 43 GetClassId()44 File::EntityId GetClassId() const 45 { 46 return File::EntityId(class_off_); 47 } 48 GetNameId()49 File::EntityId GetNameId() const 50 { 51 return File::EntityId(name_off_); 52 } 53 GetType()54 uint32_t GetType() const 55 { 56 return type_off_; 57 } 58 GetAccessFlags()59 uint32_t GetAccessFlags() const 60 { 61 return access_flags_; 62 } 63 IsStatic()64 bool IsStatic() const 65 { 66 return (access_flags_ & ACC_STATIC) != 0; 67 } 68 IsVolatile()69 bool IsVolatile() const 70 { 71 return (access_flags_ & ACC_VOLATILE) != 0; 72 } 73 IsPublic()74 bool IsPublic() const 75 { 76 return (access_flags_ & ACC_PUBLIC) != 0; 77 } 78 IsPrivate()79 bool IsPrivate() const 80 { 81 return (access_flags_ & ACC_PRIVATE) != 0; 82 } 83 IsProtected()84 bool IsProtected() const 85 { 86 return (access_flags_ & ACC_PROTECTED) != 0; 87 } 88 IsFinal()89 bool IsFinal() const 90 { 91 return (access_flags_ & ACC_FINAL) != 0; 92 } 93 IsTransient()94 bool IsTransient() const 95 { 96 return (access_flags_ & ACC_TRANSIENT) != 0; 97 } 98 IsSynthetic()99 bool IsSynthetic() const 100 { 101 return (access_flags_ & ACC_SYNTHETIC) != 0; 102 } 103 IsEnum()104 bool IsEnum() const 105 { 106 return (access_flags_ & ACC_ENUM) != 0; 107 } 108 109 template <class T> 110 std::optional<T> GetValue(); 111 112 template <class Callback> 113 void EnumerateRuntimeAnnotations(const Callback &cb); 114 115 template <class Callback> 116 void EnumerateAnnotations(const Callback &cb); 117 GetSize()118 size_t GetSize() 119 { 120 if (size_ == 0) { 121 SkipAnnotations(); 122 } 123 124 return size_; 125 } 126 GetPandaFile()127 const File &GetPandaFile() const 128 { 129 return panda_file_; 130 } 131 GetFieldId()132 File::EntityId GetFieldId() const 133 { 134 return field_id_; 135 } 136 137 uint32_t GetAnnotationsNumber(); 138 uint32_t GetRuntimeAnnotationsNumber(); 139 140 private: 141 using FieldValue = std::variant<uint32_t, uint64_t>; 142 143 std::optional<FieldValue> GetValueInternal(); 144 145 void SkipValue(); 146 147 void SkipRuntimeAnnotations(); 148 149 void SkipAnnotations(); 150 151 const File &panda_file_; 152 File::EntityId field_id_; 153 154 bool is_external_ {false}; 155 156 uint32_t class_off_ {0}; 157 uint32_t type_off_ {0}; 158 uint32_t name_off_ {0}; 159 uint32_t access_flags_ {0}; 160 161 Span<const uint8_t> tagged_values_sp_ {nullptr, nullptr}; 162 Span<const uint8_t> runtime_annotations_sp_ {nullptr, nullptr}; 163 Span<const uint8_t> annotations_sp_ {nullptr, nullptr}; 164 165 size_t size_ {0}; 166 }; 167 168 } // namespace panda::panda_file 169 170 #endif // PANDA_LIBPANDAFILE_FIELD_DATA_ACCESSOR_H_ 171