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_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 NULLVALUE = 0xff 64 }; 65 66 class LiteralDataAccessor { 67 public: 68 LiteralDataAccessor(const File &panda_file, File::EntityId literal_data_id); 69 70 template <class Callback> 71 void EnumerateObjectLiterals(size_t index, const Callback &cb); 72 73 template <class Callback> 74 void EnumerateLiteralVals(size_t index, const Callback &cb); 75 76 template <class Callback> 77 void EnumerateLiteralVals(File::EntityId id, const Callback &cb); 78 79 size_t GetLiteralValsNum(File::EntityId id) const; 80 size_t GetLiteralValsNum(size_t index) const; 81 GetLiteralNum()82 uint32_t GetLiteralNum() const 83 { 84 return literal_num_; 85 } 86 GetPandaFile()87 const File &GetPandaFile() const 88 { 89 return panda_file_; 90 } 91 GetLiteralDataId()92 File::EntityId GetLiteralDataId() const 93 { 94 return literal_data_id_; 95 } 96 GetLiteralArrayId(size_t index)97 File::EntityId GetLiteralArrayId(size_t index) const 98 { 99 if (literal_num_ == INVALID_INDEX) { 100 return File::EntityId(INVALID_INDEX); 101 } 102 103 ASSERT(index < literal_num_); 104 auto l_sp = literal_data_sp_.SubSpan(index * ID_SIZE); 105 return File::EntityId(static_cast<uint32_t>(helpers::Read<sizeof(uint32_t)>(&l_sp))); 106 } 107 ResolveLiteralArrayIndex(File::EntityId id)108 size_t ResolveLiteralArrayIndex(File::EntityId id) const 109 { 110 auto offset = id.GetOffset(); 111 112 size_t index = 0; 113 while (index < literal_num_) { 114 auto array_offset = helpers::Read<sizeof(uint32_t)>(literal_data_sp_.SubSpan(index * ID_SIZE)); 115 if (array_offset == offset) { 116 break; 117 } 118 index++; 119 } 120 return index; 121 } 122 123 using LiteralValue = std::variant<bool, void *, uint8_t, uint16_t, uint32_t, uint64_t, float, double, StringData>; 124 125 private: 126 static constexpr size_t LEN_SIZE = sizeof(uint32_t); 127 128 const File &panda_file_; 129 File::EntityId literal_data_id_; 130 uint32_t literal_num_; 131 Span<const uint8_t> literal_data_sp_ {nullptr, nullptr}; 132 }; 133 134 } // namespace panda::panda_file 135 136 #endif // LIBPANDAFILE_LITERAL_DATA_ACCESSOR_H 137