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 OHOS_RESTOOL_RESOURCE_TABLE_H 17 #define OHOS_RESTOOL_RESOURCE_TABLE_H 18 19 #include <fstream> 20 #include <map> 21 #include <memory> 22 #include <sstream> 23 #include <unordered_map> 24 25 #include "resource_item.h" 26 #include "restool_errors.h" 27 28 namespace OHOS { 29 namespace Global { 30 namespace Restool { 31 class ResourceTable { 32 public: 33 ResourceTable(bool isNewModule = false); 34 virtual ~ResourceTable(); 35 uint32_t CreateResourceTable(); 36 uint32_t CreateResourceTable(const std::map<int64_t, std::vector<std::shared_ptr<ResourceItem>>> &items); 37 static uint32_t LoadResTable(const std::string path, std::map<int64_t, std::vector<ResourceItem>> &resInfos); 38 static uint32_t LoadResTable(std::basic_istream<char> &in, std::map<int64_t, std::vector<ResourceItem>> &resInfos); 39 private: 40 struct TableData { 41 uint32_t id; 42 ResourceItem resourceItem; 43 }; 44 45 struct IndexHeader { 46 int8_t version[VERSION_MAX_LEN]; 47 uint32_t fileSize; 48 uint32_t limitKeyConfigSize; 49 }; 50 51 struct LimitKeyConfig { 52 int8_t keyTag[TAG_LEN] = {'K', 'E', 'Y', 'S'}; 53 uint32_t offset; // IdSet file address offset 54 uint32_t keyCount; // KeyParam count 55 std::vector<int32_t> data; 56 }; 57 58 struct IdSet { 59 int8_t idTag[TAG_LEN] = {'I', 'D', 'S', 'S'}; 60 uint32_t idCount; 61 std::map<uint32_t, uint32_t> data; // pair id and offset 62 }; 63 64 struct RecordItem { 65 uint32_t size; 66 int32_t resType; 67 uint32_t id; 68 }; 69 70 struct KeyConfig { 71 static const uint32_t KEY_CONFIG_HEADER_LEN = 12; 72 int8_t keyTag[TAG_LEN] = {'K', 'E', 'Y', 'S'}; 73 uint32_t configId = 0; 74 uint32_t keyCount = 0; 75 std::vector<KeyParam> configs; 76 }; 77 78 struct IndexHeaderV2 { 79 static const uint32_t INDEX_HEADER_LEN = VERSION_MAX_LEN + 12; 80 int8_t version[VERSION_MAX_LEN]; 81 uint32_t length = 0; 82 uint32_t keyCount = 0; 83 uint32_t dataBlockOffset = 0; 84 std::unordered_map<std::string, KeyConfig> keyConfigs; // <resConfig, KeyConfig> 85 std::unordered_map<uint32_t, KeyConfig> idKeyConfigs; // <configId, KeyConfig> 86 }; 87 88 struct ResIndex { 89 static const uint32_t RES_INDEX_LEN = 12; 90 uint32_t resId = 0; 91 uint32_t offset = 0; 92 uint32_t length = 0; 93 std::string name; 94 }; 95 96 struct ResTypeHeader { 97 static const uint32_t RES_TYPE_HEADER_LEN = 12; 98 ResType resType; 99 uint32_t length = 0; 100 uint32_t count = 0; 101 std::unordered_map<uint32_t, ResIndex> resIndexs; // <resId, resIndex> 102 }; 103 104 struct IdSetHeader { 105 static const uint32_t ID_SET_HEADER_LEN = 16; 106 int8_t idTag[TAG_LEN] = {'I', 'D', 'S', 'S'}; 107 uint32_t length = 0; 108 uint32_t typeCount = 0; 109 uint32_t idCount = 0; 110 std::unordered_map<ResType, ResTypeHeader> resTypes; // <resType, ResTypeHeader> 111 }; 112 113 struct ResInfo { 114 static const uint32_t RES_INFO_LEN = 12; 115 static const uint32_t DATA_OFFSET_LEN = 8; 116 uint32_t resId = 0; 117 uint32_t length = 0; 118 uint32_t valueCount = 0; 119 std::map<uint32_t, uint32_t> dataOffset; // <resConfigId, offset> 120 }; 121 122 struct DataHeader { 123 static const uint32_t DATA_HEADER_LEN = 12; 124 int8_t idTag[TAG_LEN] = {'D', 'A', 'T', 'A'}; 125 uint32_t length = 0; 126 uint32_t idCount = 0; 127 std::unordered_map<uint32_t, ResInfo> resInfos; // <resID, ResInfo> 128 }; 129 130 uint32_t SaveToResouorceIndex(const std::map<std::string, std::vector<TableData>> &configs) const; 131 uint32_t SaveToNewResouorceIndex(const std::map<std::string, std::vector<TableData>> &configs) const; 132 uint32_t CreateIdDefined(const std::map<int64_t, std::vector<ResourceItem>> &allResource) const; 133 bool InitIndexHeader(IndexHeader &indexHeader, uint32_t count) const; 134 bool Prepare(const std::map<std::string, std::vector<TableData>> &configs, 135 std::map<std::string, LimitKeyConfig> &limitKeyConfigs, 136 std::map<std::string, IdSet> &idSets, uint32_t &pos) const; 137 bool SaveRecordItem(const std::map<std::string, std::vector<TableData>> &configs, std::ostringstream &out, 138 std::map<std::string, IdSet> &idSets, uint32_t &pos) const; 139 void SaveHeader(const IndexHeader &indexHeader, std::ostringstream &out) const; 140 void SaveLimitKeyConfigs(const std::map<std::string, LimitKeyConfig> &limitKeyConfigs, 141 std::ostringstream &out) const; 142 void SaveIdSets(const std::map<std::string, IdSet> &idSets, std::ostringstream &out) const; 143 static bool ReadFileHeader(std::basic_istream<char> &in, IndexHeader &indexHeader, uint64_t &pos, uint64_t length); 144 static bool ReadLimitKeys(std::basic_istream<char> &in, std::map<int64_t, std::vector<KeyParam>> &limitKeys, 145 uint32_t count, uint64_t &pos, uint64_t length); 146 static bool ReadIdTables(std::basic_istream<char> &in, std::map<int64_t, std::pair<int64_t, int64_t>> &datas, 147 uint32_t count, uint64_t &pos, uint64_t length); 148 static bool ReadDataRecordPrepare(std::basic_istream<char> &in, RecordItem &record, 149 uint64_t &pos, uint64_t length); 150 static bool ReadDataRecordStart(std::basic_istream<char> &in, RecordItem &record, 151 const std::map<int64_t, std::vector<KeyParam>> &limitKeys, 152 const std::map<int64_t, std::pair<int64_t, int64_t>> &datas, 153 std::map<int64_t, std::vector<ResourceItem>> &resInfos); 154 static bool InitHeader(IndexHeaderV2 &indexHeader, IdSetHeader &idSetHeader, 155 DataHeader &dataHeader, uint32_t count); 156 static void PrepareKeyConfig(IndexHeaderV2 &indexHeader, const uint32_t configId, 157 const std::string &config, const std::vector<TableData> &data); 158 static void PrepareResIndex(IdSetHeader &idSetHeader, const TableData &tableData); 159 static void PrepareResInfo(DataHeader &dataHeader, const uint32_t resId, 160 const uint32_t configId, const uint32_t dataPoolLen); 161 static void WriteDataPool(std::ostringstream &dataPool, const ResourceItem &resourceItem, uint32_t &dataPoolLen); 162 static void WriteResInfo(std::ostringstream &dataBlock, const DataHeader &idSetHeader, 163 const uint32_t dataBlockOffset, std::unordered_map<uint32_t, uint32_t> &idOffsetMap); 164 static void WriteIdSet(std::ostringstream &idSetBlock, const IdSetHeader &idSetHeader, 165 const std::unordered_map<uint32_t, uint32_t> &idOffsetMap); 166 static void WriteResHeader(std::ostringstream &resHeaderBlock, const IndexHeaderV2 &indexHeader); 167 static void WriteToIndex(const IndexHeaderV2 &indexHeader, const IdSetHeader &idSetHeader, 168 const DataHeader &dataHeader, const std::ostringstream &dataPool, std::ofstream &out); 169 static bool IsNewModule(const IndexHeader &indexHeader); 170 static uint32_t LoadNewResTable(std::basic_istream<char> &in, 171 std::map<int64_t, std::vector<ResourceItem>> &resInfos); 172 static bool ReadNewFileHeader(std::basic_istream<char> &in, IndexHeaderV2 &indexHeader, 173 uint64_t &pos, uint64_t length); 174 static bool ReadIdSetHeader(std::basic_istream<char> &in, IdSetHeader &idSetHeader, 175 uint64_t &pos, uint64_t length); 176 static bool ReadResources(std::basic_istream<char> &in, const ResIndex &resIndex, 177 const ResTypeHeader &resTypeHeader, IndexHeaderV2 &indexHeader, uint64_t length, 178 std::map<int64_t, std::vector<ResourceItem>> &resInfos); 179 static bool ReadResInfo(std::basic_istream<char> &in, ResInfo &resInfo, uint32_t offset, uint64_t length); 180 static bool ReadResConfig(std::basic_istream<char> &in, uint32_t &resConfigId, uint32_t &dataOffset, 181 uint64_t &pos, uint64_t length); 182 static bool ReadResourceItem(std::basic_istream<char> &in, ResourceItem &resourceItem, uint32_t dataOffset, 183 uint64_t &pos, uint64_t length); 184 std::string indexFilePath_; 185 std::string idDefinedPath_; 186 bool newResIndex_ = false; 187 }; 188 } 189 } 190 } 191 #endif