1 /** 2 * Copyright (c) 2021-2024 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 ark::panda_file { 29 30 class FieldDataAccessor { 31 public: 32 PANDA_PUBLIC_API FieldDataAccessor(const File &pandaFile, File::EntityId fieldId); 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 &pandaFile, File::EntityId fieldId); 41 42 static File::EntityId GetNameId(const File &pandaFile, File::EntityId fieldId); 43 IsExternal()44 bool IsExternal() const 45 { 46 return isExternal_; 47 } 48 GetClassId()49 File::EntityId GetClassId() const 50 { 51 return File::EntityId(classOff_); 52 } 53 GetNameId()54 File::EntityId GetNameId() const 55 { 56 return File::EntityId(nameOff_); 57 } 58 GetType()59 uint32_t GetType() const 60 { 61 return typeOff_; 62 } 63 GetAccessFlags()64 uint32_t GetAccessFlags() const 65 { 66 return accessFlags_; 67 } 68 IsStatic()69 bool IsStatic() const 70 { 71 return (accessFlags_ & ACC_STATIC) != 0; 72 } 73 IsVolatile()74 bool IsVolatile() const 75 { 76 return (accessFlags_ & ACC_VOLATILE) != 0; 77 } 78 IsPublic()79 bool IsPublic() const 80 { 81 return (accessFlags_ & ACC_PUBLIC) != 0; 82 } 83 IsPrivate()84 bool IsPrivate() const 85 { 86 return (accessFlags_ & ACC_PRIVATE) != 0; 87 } 88 IsProtected()89 bool IsProtected() const 90 { 91 return (accessFlags_ & ACC_PROTECTED) != 0; 92 } 93 IsFinal()94 bool IsFinal() const 95 { 96 return (accessFlags_ & ACC_FINAL) != 0; 97 } 98 IsReadonly()99 bool IsReadonly() const 100 { 101 return (accessFlags_ & ACC_READONLY) != 0; 102 } 103 IsTransient()104 bool IsTransient() const 105 { 106 return (accessFlags_ & ACC_TRANSIENT) != 0; 107 } 108 IsSynthetic()109 bool IsSynthetic() const 110 { 111 return (accessFlags_ & ACC_SYNTHETIC) != 0; 112 } 113 IsEnum()114 bool IsEnum() const 115 { 116 return (accessFlags_ & ACC_ENUM) != 0; 117 } 118 119 template <class T> 120 std::optional<T> GetValue(); 121 122 template <class Callback> 123 void EnumerateRuntimeAnnotations(const Callback &cb); 124 125 template <class Callback> 126 void EnumerateAnnotations(const Callback &cb); 127 128 template <class Callback> 129 void EnumerateRuntimeTypeAnnotations(const Callback &cb); 130 131 template <class Callback> 132 void EnumerateTypeAnnotations(const Callback &cb); 133 134 template <class Callback> 135 bool EnumerateRuntimeAnnotationsWithEarlyStop(const Callback &cb); 136 137 template <class Callback> 138 bool EnumerateAnnotationsWithEarlyStop(const Callback &cb); 139 GetSize()140 size_t GetSize() 141 { 142 if (size_ == 0) { 143 SkipTypeAnnotations(); 144 } 145 146 return size_; 147 } 148 GetPandaFile()149 const File &GetPandaFile() const 150 { 151 return pandaFile_; 152 } 153 GetFieldId()154 File::EntityId GetFieldId() const 155 { 156 return fieldId_; 157 } 158 159 uint32_t GetAnnotationsNumber(); 160 uint32_t GetRuntimeAnnotationsNumber(); 161 uint32_t GetRuntimeTypeAnnotationsNumber(); 162 uint32_t GetTypeAnnotationsNumber(); 163 164 private: 165 using FieldValue = std::variant<uint32_t, uint64_t>; 166 167 PANDA_PUBLIC_API std::optional<FieldValue> GetValueInternal(); 168 169 void SkipValue(); 170 171 void SkipRuntimeAnnotations(); 172 173 void SkipAnnotations(); 174 175 void SkipRuntimeTypeAnnotations(); 176 177 void SkipTypeAnnotations(); 178 179 template <class T> 180 inline T GetValueImpl(FieldValue &fieldValue); 181 182 template <class T> 183 inline T GetValueIntegral(FieldValue &fieldValue); 184 185 template <class T> 186 inline T GetValueNonIntegral(FieldValue &fieldValue); 187 188 const File &pandaFile_; 189 File::EntityId fieldId_; 190 191 bool isExternal_; 192 193 uint32_t classOff_; 194 uint32_t typeOff_; 195 uint32_t nameOff_; 196 uint32_t accessFlags_; 197 198 Span<const uint8_t> taggedValuesSp_ {nullptr, nullptr}; 199 Span<const uint8_t> runtimeAnnotationsSp_ {nullptr, nullptr}; 200 Span<const uint8_t> annotationsSp_ {nullptr, nullptr}; 201 Span<const uint8_t> runtimeTypeAnnotationsSp_ {nullptr, nullptr}; 202 Span<const uint8_t> typeAnnotationsSp_ {nullptr, nullptr}; 203 204 size_t size_; 205 }; 206 207 } // namespace ark::panda_file 208 209 #endif // LIBPANDAFILE_FIELD_DATA_ACCESSOR_H_ 210