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