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_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 ark::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 BIGINT = 0x06, 40 METHOD = 0x07, 41 GENERATORMETHOD = 0x08, 42 ACCESSOR = 0x09, 43 METHODAFFILIATE = 0x0a, 44 ARRAY_U1 = 0x0b, 45 ARRAY_U8 = 0x0c, 46 ARRAY_I8 = 0x0d, 47 ARRAY_U16 = 0x0e, 48 ARRAY_I16 = 0x0f, 49 ARRAY_U32 = 0x10, 50 ARRAY_I32 = 0x11, 51 ARRAY_U64 = 0x12, 52 ARRAY_I64 = 0x13, 53 ARRAY_F32 = 0x14, 54 ARRAY_F64 = 0x15, 55 ARRAY_STRING = 0x16, 56 ASYNCGENERATORMETHOD = 0x17, 57 ASYNCMETHOD = 0x18, 58 LITERALARRAY = 0x19, 59 NULLVALUE = 0xff 60 }; 61 62 class LiteralDataAccessor { 63 public: 64 LiteralDataAccessor(const File &pandaFile, File::EntityId literalDataId); 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(size_t index); 76 GetLiteralNum()77 uint32_t GetLiteralNum() const 78 { 79 return literalNum_; 80 } 81 GetPandaFile()82 const File &GetPandaFile() const 83 { 84 return pandaFile_; 85 } 86 GetLiteralDataId()87 File::EntityId GetLiteralDataId() const 88 { 89 return literalDataId_; 90 } 91 GetLiteralArrayId(size_t index)92 File::EntityId GetLiteralArrayId(size_t index) const 93 { 94 ASSERT(index < literalNum_); 95 auto lSp = literalDataSp_.SubSpan(index * ID_SIZE); 96 return File::EntityId(static_cast<uint32_t>(helpers::Read<sizeof(uint32_t)>(&lSp))); 97 } 98 ResolveLiteralArrayIndex(File::EntityId id)99 size_t ResolveLiteralArrayIndex(File::EntityId id) const 100 { 101 auto offset = id.GetOffset(); 102 103 size_t index = 0; 104 while (index < literalNum_) { 105 auto arrayOffset = helpers::Read<sizeof(uint32_t)>(literalDataSp_.SubSpan(index * ID_SIZE)); 106 if (arrayOffset == offset) { 107 break; 108 } 109 index++; 110 } 111 return index; 112 } 113 114 using LiteralValue = std::variant<bool, void *, uint8_t, uint16_t, uint32_t, uint64_t, float, double, StringData>; 115 116 private: 117 static constexpr size_t LEN_SIZE = sizeof(uint32_t); 118 119 const File &pandaFile_; 120 File::EntityId literalDataId_; 121 uint32_t literalNum_; 122 Span<const uint8_t> literalDataSp_ {nullptr, nullptr}; 123 }; 124 125 } // namespace ark::panda_file 126 127 #endif // LIBPANDAFILE_Literal_DATA_ACCESSOR_H_ 128