1 /** 2 * Copyright (c) 2021-2025 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_LITERAL_DATA_ACCESSOR_H 17 #define LIBPANDAFILE_LITERAL_DATA_ACCESSOR_H 18 19 #include "file.h" 20 #include "field_data_accessor.h" 21 #include "helpers.h" 22 23 #include "utils/span.h" 24 25 namespace panda::panda_file { 26 using StringData = File::StringData; 27 28 /* LiteralTag could be extended by different language 29 // For example, JAVA could use it to represent Array of Integer 30 // by adding `INTARRAY` in the future 31 */ 32 enum class LiteralTag : uint8_t { 33 TAGVALUE = 0x00, 34 BOOL = 0x01, 35 // int_8 and tagvalue have the same range for data representation. 36 INTEGER_8 = TAGVALUE, 37 INTEGER = 0x02, 38 FLOAT = 0x03, 39 DOUBLE = 0x04, 40 STRING = 0x05, 41 METHOD = 0x06, 42 GENERATORMETHOD = 0x07, 43 ACCESSOR = 0x08, 44 METHODAFFILIATE = 0x09, 45 ARRAY_U1 = 0x0a, 46 ARRAY_U8 = 0x0b, 47 ARRAY_I8 = 0x0c, 48 ARRAY_U16 = 0x0d, 49 ARRAY_I16 = 0x0e, 50 ARRAY_U32 = 0x0f, 51 ARRAY_I32 = 0x10, 52 ARRAY_U64 = 0x11, 53 ARRAY_I64 = 0x12, 54 ARRAY_F32 = 0x13, 55 ARRAY_F64 = 0x14, 56 ARRAY_STRING = 0x15, 57 ASYNCGENERATORMETHOD = 0x16, 58 LITERALBUFFERINDEX = 0x17, 59 LITERALARRAY = 0x18, 60 BUILTINTYPEINDEX = 0x19, 61 GETTER = 0x1a, 62 SETTER = 0x1b, 63 ETS_IMPLEMENTS = 0x1c, 64 NULLVALUE = 0xff 65 }; 66 67 class LiteralDataAccessor { 68 public: 69 LiteralDataAccessor(const File &panda_file, File::EntityId literal_data_id); 70 71 template <class Callback> 72 void EnumerateObjectLiterals(size_t index, const Callback &cb); 73 74 template <class Callback> 75 void EnumerateLiteralVals(size_t index, const Callback &cb); 76 77 template <class Callback> 78 void EnumerateLiteralVals(File::EntityId id, const Callback &cb); 79 80 size_t GetLiteralValsNum(File::EntityId id) const; 81 size_t GetLiteralValsNum(size_t index) const; 82 GetLiteralNum()83 uint32_t GetLiteralNum() const 84 { 85 return literal_num_; 86 } 87 GetPandaFile()88 const File &GetPandaFile() const 89 { 90 return panda_file_; 91 } 92 GetLiteralDataId()93 File::EntityId GetLiteralDataId() const 94 { 95 return literal_data_id_; 96 } 97 GetLiteralArrayId(size_t index)98 File::EntityId GetLiteralArrayId(size_t index) const 99 { 100 if (literal_num_ == INVALID_INDEX) { 101 return File::EntityId(INVALID_INDEX); 102 } 103 104 ASSERT(index < literal_num_); 105 auto l_sp = literal_data_sp_.SubSpan(index * ID_SIZE); 106 return File::EntityId(static_cast<uint32_t>(helpers::Read<sizeof(uint32_t)>(&l_sp))); 107 } 108 ResolveLiteralArrayIndex(File::EntityId id)109 size_t ResolveLiteralArrayIndex(File::EntityId id) const 110 { 111 auto offset = id.GetOffset(); 112 113 size_t index = 0; 114 while (index < literal_num_) { 115 auto array_offset = helpers::Read<sizeof(uint32_t)>(literal_data_sp_.SubSpan(index * ID_SIZE)); 116 if (array_offset == offset) { 117 break; 118 } 119 index++; 120 } 121 return index; 122 } 123 124 using LiteralValue = std::variant<bool, void *, uint8_t, uint16_t, uint32_t, uint64_t, float, double, StringData>; 125 126 private: 127 static constexpr size_t LEN_SIZE = sizeof(uint32_t); 128 129 const File &panda_file_; 130 File::EntityId literal_data_id_; 131 uint32_t literal_num_; 132 Span<const uint8_t> literal_data_sp_ {nullptr, nullptr}; 133 }; 134 135 } // namespace panda::panda_file 136 137 #endif // LIBPANDAFILE_LITERAL_DATA_ACCESSOR_H 138