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 INTEGER = 0x02, 36 FLOAT = 0x03, 37 DOUBLE = 0x04, 38 STRING = 0x05, 39 METHOD = 0x06, 40 GENERATORMETHOD = 0x07, 41 ACCESSOR = 0x08, 42 METHODAFFILIATE = 0x09, 43 ARRAY_U1 = 0x0a, 44 ARRAY_U8 = 0x0b, 45 ARRAY_I8 = 0x0c, 46 ARRAY_U16 = 0x0d, 47 ARRAY_I16 = 0x0e, 48 ARRAY_U32 = 0x0f, 49 ARRAY_I32 = 0x10, 50 ARRAY_U64 = 0x11, 51 ARRAY_I64 = 0x12, 52 ARRAY_F32 = 0x13, 53 ARRAY_F64 = 0x14, 54 ARRAY_STRING = 0x15, 55 ASYNCGENERATORMETHOD = 0x16, 56 LITERALBUFFERINDEX = 0x17, 57 LITERALARRAY = 0x18, 58 BUILTINTYPEINDEX = 0x19, 59 NULLVALUE = 0xff 60 }; 61 62 class LiteralDataAccessor { 63 public: 64 LiteralDataAccessor(const File &panda_file, File::EntityId literal_data_id); 65 66 template <class Callback> 67 void EnumerateObjectLiterals(size_t index, const Callback &cb); 68 69 template <class Callback> 70 void EnumerateLiteralVals(size_t index, const Callback &cb); 71 72 template <class Callback> 73 void EnumerateLiteralVals(File::EntityId id, const Callback &cb); 74 75 size_t GetLiteralValsNum(File::EntityId id) const; 76 size_t GetLiteralValsNum(size_t index) const; 77 GetLiteralNum()78 uint32_t GetLiteralNum() const 79 { 80 return literal_num_; 81 } 82 GetPandaFile()83 const File &GetPandaFile() const 84 { 85 return panda_file_; 86 } 87 GetLiteralDataId()88 File::EntityId GetLiteralDataId() const 89 { 90 return literal_data_id_; 91 } 92 GetLiteralArrayId(size_t index)93 File::EntityId GetLiteralArrayId(size_t index) const 94 { 95 ASSERT(index < literal_num_); 96 auto l_sp = literal_data_sp_.SubSpan(index * ID_SIZE); 97 return File::EntityId(static_cast<uint32_t>(helpers::Read<sizeof(uint32_t)>(&l_sp))); 98 } 99 ResolveLiteralArrayIndex(File::EntityId id)100 size_t ResolveLiteralArrayIndex(File::EntityId id) const 101 { 102 auto offset = id.GetOffset(); 103 104 size_t index = 0; 105 while (index < literal_num_) { 106 auto array_offset = helpers::Read<sizeof(uint32_t)>(literal_data_sp_.SubSpan(index * ID_SIZE)); 107 if (array_offset == offset) { 108 break; 109 } 110 index++; 111 } 112 return index; 113 } 114 115 using LiteralValue = std::variant<bool, void *, uint8_t, uint16_t, uint32_t, uint64_t, float, double, StringData>; 116 117 private: 118 static constexpr size_t LEN_SIZE = sizeof(uint32_t); 119 120 const File &panda_file_; 121 File::EntityId literal_data_id_; 122 uint32_t literal_num_; 123 Span<const uint8_t> literal_data_sp_ {nullptr, nullptr}; 124 }; 125 126 } // namespace panda::panda_file 127 128 #endif // LIBPANDAFILE_LITERAL_DATA_ACCESSOR_H 129