diff --git a/BUILD.gn b/BUILD.gn index 2a014a4dbbf981c35a7ae0a93d931d75ee282d3f..f508195bb5a4aa75ddd49248d553da341130c32c 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -19,11 +19,10 @@ ohos_executable("restool") { sources = [ "src/append_compiler.cpp", "src/binary_file_packer.cpp", - "src/cmd_parser.cpp", + "src/cmd/dump_parser.cpp", + "src/cmd/package_parser.cpp", "src/compression_parser.cpp", "src/config_parser.cpp", - "src/factory_resource_compiler.cpp", - "src/factory_resource_packer.cpp", "src/file_entry.cpp", "src/file_manager.cpp", "src/generic_compiler.cpp", @@ -39,12 +38,15 @@ ohos_executable("restool") { "src/resconfig_parser.cpp", "src/resource_append.cpp", "src/resource_check.cpp", + "src/resource_compiler_factory.cpp", "src/resource_directory.cpp", + "src/resource_dumper.cpp", "src/resource_item.cpp", "src/resource_merge.cpp", "src/resource_module.cpp", "src/resource_overlap.cpp", "src/resource_pack.cpp", + "src/resource_packer_factory.cpp", "src/resource_table.cpp", "src/resource_util.cpp", "src/restool.cpp", @@ -62,6 +64,7 @@ ohos_executable("restool") { "//third_party/bounds_checking_function:libsec_static", "//third_party/cJSON:cjson_static", "//third_party/libpng:libpng_static", + "//third_party/zlib:libz", ] cflags = [ "-std=c++17" ] diff --git a/bundle.json b/bundle.json index 01e4a5a4489d5e00d9498c84cae0c79dc7f0132a..e04267d2c27943240a4355691858ee9681f121c5 100644 --- a/bundle.json +++ b/bundle.json @@ -22,7 +22,8 @@ "third_party": [ "bounds_checking_function", "cJSON", - "libpng" + "libpng", + "zlib" ] }, "build": { diff --git a/include/binary_file_packer.h b/include/binary_file_packer.h index 38f9cf12fa0746a2840a636c1d58be15dc6ec757..79d14ce721fdb86eb0ee8e46674e3c6cfe4e7e50 100644 --- a/include/binary_file_packer.h +++ b/include/binary_file_packer.h @@ -16,7 +16,7 @@ #ifndef OHOS_RESTOOL_BINARY_FILE_PACKER_H #define OHOS_RESTOOL_BINARY_FILE_PACKER_H -#include "cmd_parser.h" +#include "cmd/package_parser.h" #include "resource_util.h" #include "thread_pool.h" diff --git a/include/cmd_parser.h b/include/cmd/cmd_parser.h similarity index 47% rename from include/cmd_parser.h rename to include/cmd/cmd_parser.h index 83ad3d23e722e4230155c251f682b915b96a5682..3bfa70a1435509e5e5ea6b186c48d0f6ffcbe0a0 100644 --- a/include/cmd_parser.h +++ b/include/cmd/cmd_parser.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2024 - 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -16,110 +16,31 @@ #ifndef OHOS_RESTOOL_CMD_PARSER_H #define OHOS_RESTOOL_CMD_PARSER_H -#include +#include +#include #include -#include -#include +#include +#include #include "singleton.h" -#include "resource_data.h" #include "restool_errors.h" namespace OHOS { namespace Global { namespace Restool { + class ICmdParser { public: virtual uint32_t Parse(int argc, char *argv[]) = 0; -}; - -class PackageParser : public ICmdParser { -public: - PackageParser() {}; - virtual ~PackageParser() = default; - uint32_t Parse(int argc, char *argv[]) override; - const std::vector &GetInputs() const; - const std::string &GetPackageName() const; - const std::string &GetOutput() const; - const std::vector &GetResourceHeaders() const; - bool GetForceWrite() const; - const std::vector &GetModuleNames() const; - const std::string &GetConfig() const; - const std::string &GetRestoolPath() const; - uint32_t GetStartId() const; - bool IsFileList() const; - const std::vector &GetAppend() const; - bool GetCombine() const; - const std::string &GetDependEntry() const; - const std::string &GetIdDefinedOutput() const; - const std::string &GetIdDefinedInputPath() const; - bool GetIconCheck() const; - const TargetConfig &GetTargetConfigValues() const; - bool IsTargetConfig() const; - const std::vector &GetSysIdDefinedPaths() const; - const std::string &GetCompressionPath() const; - bool IsOverlap() const; - -private: - void InitCommand(); - uint32_t ParseCommand(int argc, char *argv[]); - uint32_t CheckError(int argc, char *argv[], int c, int optIndex); - uint32_t AddInput(const std::string& argValue); - uint32_t AddPackageName(const std::string& argValue); - uint32_t AddOutput(const std::string& argValue); - uint32_t AddResourceHeader(const std::string& argValue); - uint32_t ForceWrite(); - uint32_t PrintVersion(); - uint32_t AddMoudleNames(const std::string& argValue); - uint32_t AddConfig(const std::string& argValue); - uint32_t AddStartId(const std::string& argValue); - void AdaptResourcesDirForInput(); - uint32_t CheckParam() const; - uint32_t HandleProcess(int c, const std::string& argValue); - uint32_t ParseFileList(const std::string& fileListPath); - uint32_t AddAppend(const std::string& argValue); - uint32_t SetCombine(); - uint32_t AddDependEntry(const std::string& argValue); - uint32_t ShowHelp() const; - uint32_t SetIdDefinedOutput(const std::string& argValue); - uint32_t SetIdDefinedInputPath(const std::string& argValue); - uint32_t AddSysIdDefined(const std::string& argValue); - bool IsAscii(const std::string& argValue) const; - bool IsLongOpt(int argc, char *argv[]) const; - uint32_t IconCheck(); - uint32_t ParseTargetConfig(const std::string& argValue); - uint32_t AddCompressionPath(const std::string& argValue); - - static const struct option CMD_OPTS[]; - static const std::string CMD_PARAMS; - using HandleArgValue = std::function; - std::map handles_; - std::vector inputs_; - std::string packageName_; - std::string output_; - std::vector resourceHeaderPaths_; - bool forceWrite_ = false; - std::vector moduleNames_; - std::string configPath_; - std::string restoolPath_; - uint32_t startId_ = 0; - bool isFileList_ = false; - std::vector append_; - bool combine_ = false; - std::string dependEntry_; - std::string idDefinedOutput_; - std::string idDefinedInputPath_; - bool isIconCheck_ = false; - TargetConfig targetConfig_; - bool isTtargetConfig_; - std::vector sysIdDefinedPaths_; - std::string compressionPath_; + virtual uint32_t ExecCommand() = 0; }; template class CmdParser : public Singleton> { + static_assert(std::is_base_of_v, "Template T must inherit ICmdParser."); public: T &GetCmdParser(); uint32_t Parse(int argc, char *argv[]); + uint32_t ExecCommand(); static void ShowUseage(); private: @@ -155,6 +76,7 @@ void CmdParser::ShowUseage() std::cout << " --icon-check Enable the PNG image verification function for icons and startwindows.\n"; std::cout << " --target-config When used with '-i', selective compilation is supported.\n"; std::cout << " --compressed-config opt-compression.json path.\n"; + std::cout << " dump [config] Dump rsource in hap to json. If with 'config', will only dump limit path.\n"; } template @@ -166,12 +88,15 @@ T &CmdParser::GetCmdParser() template uint32_t CmdParser::Parse(int argc, char *argv[]) { - if (cmdParser_.Parse(argc, argv) != RESTOOL_SUCCESS) { - return RESTOOL_ERROR; - } - return RESTOOL_SUCCESS; + return cmdParser_.Parse(argc, argv); } + +template +uint32_t CmdParser::ExecCommand() +{ + return cmdParser_.ExecCommand(); +}; } } } -#endif +#endif \ No newline at end of file diff --git a/include/cmd/dump_parser.h b/include/cmd/dump_parser.h new file mode 100644 index 0000000000000000000000000000000000000000..5003ed871cfe78278fe3438595819c8e6fac0856 --- /dev/null +++ b/include/cmd/dump_parser.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 - 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_RESTOOL_DUMP_PARSER_H +#define OHOS_RESTOOL_DUMP_PARSER_H + +#include "cmd_parser.h" +#include +#include + +namespace OHOS { +namespace Global { +namespace Restool { +class DumpParser : public ICmdParser { +public: + virtual ~DumpParser() = default; + uint32_t Parse(int argc, char *argv[]) override; + uint32_t ExecCommand() override; + const std::string &GetInputPath() const; + +private: + std::string inputPath_; + std::string type_; +}; +} // namespace Restool +} // namespace Global +} // namespace OHOS +#endif diff --git a/include/cmd/package_parser.h b/include/cmd/package_parser.h new file mode 100644 index 0000000000000000000000000000000000000000..1774d2ace2d4c853114ea9434a403d9d3ee2d436 --- /dev/null +++ b/include/cmd/package_parser.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2024 - 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_RESTOOL_PACKAGE_PARSER_H +#define OHOS_RESTOOL_PACKAGE_PARSER_H + +#include +#include +#include "cmd_parser.h" + +namespace OHOS { +namespace Global { +namespace Restool { +class PackageParser : public ICmdParser { +public: + PackageParser(){}; + virtual ~PackageParser() = default; + uint32_t Parse(int argc, char *argv[]) override; + uint32_t ExecCommand() override; + const std::vector &GetInputs() const; + const std::string &GetPackageName() const; + const std::string &GetOutput() const; + const std::vector &GetResourceHeaders() const; + bool GetForceWrite() const; + const std::vector &GetModuleNames() const; + const std::string &GetConfig() const; + const std::string &GetRestoolPath() const; + uint32_t GetStartId() const; + bool IsFileList() const; + const std::vector &GetAppend() const; + bool GetCombine() const; + const std::string &GetDependEntry() const; + const std::string &GetIdDefinedOutput() const; + const std::string &GetIdDefinedInputPath() const; + bool GetIconCheck() const; + const TargetConfig &GetTargetConfigValues() const; + bool IsTargetConfig() const; + const std::vector &GetSysIdDefinedPaths() const; + const std::string &GetCompressionPath() const; + bool IsOverlap() const; + +private: + void InitCommand(); + uint32_t ParseCommand(int argc, char *argv[]); + uint32_t CheckError(int argc, char *argv[], int c, int optIndex); + uint32_t AddInput(const std::string &argValue); + uint32_t AddPackageName(const std::string &argValue); + uint32_t AddOutput(const std::string &argValue); + uint32_t AddResourceHeader(const std::string &argValue); + uint32_t ForceWrite(); + uint32_t PrintVersion(); + uint32_t AddMoudleNames(const std::string &argValue); + uint32_t AddConfig(const std::string &argValue); + uint32_t AddStartId(const std::string &argValue); + void AdaptResourcesDirForInput(); + uint32_t CheckParam() const; + uint32_t HandleProcess(int c, const std::string &argValue); + uint32_t ParseFileList(const std::string &fileListPath); + uint32_t AddAppend(const std::string &argValue); + uint32_t SetCombine(); + uint32_t AddDependEntry(const std::string &argValue); + uint32_t ShowHelp() const; + uint32_t SetIdDefinedOutput(const std::string &argValue); + uint32_t SetIdDefinedInputPath(const std::string &argValue); + uint32_t AddSysIdDefined(const std::string &argValue); + bool IsAscii(const std::string &argValue) const; + bool IsLongOpt(int argc, char *argv[]) const; + uint32_t IconCheck(); + uint32_t ParseTargetConfig(const std::string &argValue); + uint32_t AddCompressionPath(const std::string &argValue); + + static const struct option CMD_OPTS[]; + static const std::string CMD_PARAMS; + using HandleArgValue = std::function; + std::map handles_; + std::vector inputs_; + std::string packageName_; + std::string output_; + std::vector resourceHeaderPaths_; + bool forceWrite_ = false; + std::vector moduleNames_; + std::string configPath_; + std::string restoolPath_; + uint32_t startId_ = 0; + bool isFileList_ = false; + std::vector append_; + bool combine_ = false; + std::string dependEntry_; + std::string idDefinedOutput_; + std::string idDefinedInputPath_; + bool isIconCheck_ = false; + TargetConfig targetConfig_; + bool isTtargetConfig_; + std::vector sysIdDefinedPaths_; + std::string compressionPath_; +}; +} // namespace Restool +} // namespace Global +} // namespace OHOS +#endif \ No newline at end of file diff --git a/include/id_defined_parser.h b/include/id_defined_parser.h index 0fa40d41af77ed6194ae080f4a0b083345fb486c..3bb7268d200b2a65c26a7dbb2c368cf0ab7a4a39 100755 --- a/include/id_defined_parser.h +++ b/include/id_defined_parser.h @@ -18,7 +18,7 @@ #include #include -#include "cmd_parser.h" +#include "cmd/package_parser.h" namespace OHOS { namespace Global { diff --git a/include/resource_append.h b/include/resource_append.h index 2261e5f36da77e1f1e49fa9773235975c2ea47e1..9c4b85c2a072c3c8c58acefea3fac790ab5840cc 100644 --- a/include/resource_append.h +++ b/include/resource_append.h @@ -17,8 +17,8 @@ #define OHOS_RESTOOL_RESOURCE_APPEND_H #include -#include "cmd_parser.h" -#include "factory_resource_compiler.h" +#include "cmd/package_parser.h" +#include "resource_compiler_factory.h" #include "file_entry.h" namespace OHOS { diff --git a/include/factory_resource_compiler.h b/include/resource_compiler_factory.h similarity index 97% rename from include/factory_resource_compiler.h rename to include/resource_compiler_factory.h index 7a55736a5212e248a4b47d3f2b7031c05d2bae49..7dd0d7a1fba4479725344387138e68a0f243315d 100644 --- a/include/factory_resource_compiler.h +++ b/include/resource_compiler_factory.h @@ -22,7 +22,7 @@ namespace OHOS { namespace Global { namespace Restool { -class FactoryResourceCompiler { +class ResourceCompilerFactory { public: static std::unique_ptr CreateCompiler(ResType type, const std::string &output, bool isHap); static std::unique_ptr CreateCompilerForAppend(ResType type, const std::string &output); diff --git a/include/resource_data.h b/include/resource_data.h index f51d640acbacfc54ace69a04e9bdb33a544176d2..2162dc9c53f30dba7e75b86ec8b11ec6af2dc873 100644 --- a/include/resource_data.h +++ b/include/resource_data.h @@ -49,7 +49,7 @@ const static std::string SOLUTIONS_ARROW = "> "; const static std::string LONG_PATH_HEAD = "\\\\?\\"; const static int32_t VERSION_MAX_LEN = 128; const static int32_t INT_TO_BYTES = sizeof(uint32_t); -static const int8_t RESTOOL_VERSION[VERSION_MAX_LEN] = { "Restool 5.1.0.002" }; +static const int8_t RESTOOL_VERSION[VERSION_MAX_LEN] = { "Restool 5.1.0.003" }; const static int32_t TAG_LEN = 4; static std::set g_resourceSet; static std::set g_hapResourceSet; @@ -251,6 +251,19 @@ const std::map g_contentClusterMap = { { "symbol", ResType::SYMBOL } }; +const std::map g_keyTypeToStrMap = { + {KeyType::MCC, "mcc"}, + {KeyType::MNC, "mnc"}, + {KeyType::LANGUAGE, "language"}, + {KeyType::SCRIPT, "script"}, + {KeyType::REGION, "region"}, + {KeyType::ORIENTATION, "orientation"}, + {KeyType::RESOLUTION, "density"}, + {KeyType::DEVICETYPE, "device"}, + {KeyType::NIGHTMODE, "colorMode"}, + {KeyType::INPUTDEVICE, "inputDevice"}, +}; + const std::map g_resTypeMap = { { static_cast(ResType::ELEMENT), ResType::ELEMENT}, { static_cast(ResType::RAW), ResType::RAW}, diff --git a/include/resource_dumper.h b/include/resource_dumper.h new file mode 100644 index 0000000000000000000000000000000000000000..7bf63d7db5fc194c3e33d50215415a9529779263 --- /dev/null +++ b/include/resource_dumper.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2024 - 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_RESTOOL_RESOURCE_DUMP_H +#define OHOS_RESTOOL_RESOURCE_DUMP_H + +#include +#include +#include +#include +#include +#include +#include "config_parser.h" +#include "unzip.h" +#include "cJSON.h" +#include "cmd/dump_parser.h" +#include "resource_data.h" +#include "resource_item.h" + + +namespace OHOS { +namespace Global { +namespace Restool { +class ResourceDumper { +public: + virtual ~ResourceDumper() = default; + virtual uint32_t Dump(const DumpParser &parser); +protected: + virtual uint32_t DumpRes(std::string &out) const = 0; + void ReadHapInfo(const std::unique_ptr &buffer, size_t len); + uint32_t LoadHap(); + uint32_t ReadFileFromZip(unzFile &zip, const char *fileName, std::unique_ptr &buffer, size_t &len); + + std::string inputPath_; + std::string bundleName_; + std::string moduleName_; + std::map> resInfos_; +}; + +class ConfigDumper : public ResourceDumper { +public: + virtual ~ConfigDumper() = default; + uint32_t DumpRes(std::string &out) const override; +}; + + +class CommonDumper : public ResourceDumper { +public: + virtual ~CommonDumper() = default; + uint32_t DumpRes(std::string &out) const override; + +private: + uint32_t AddValueToJson(const ResourceItem &item, cJSON *json) const; + uint32_t AddPairVauleToJson(const ResourceItem &item, cJSON *json) const; + uint32_t AddKeyParamsToJson(const std::vector &keyParams, cJSON *json) const; + uint32_t AddResourceToJson(int64_t id, const std::vector &items, cJSON *json) const; + uint32_t AddItemCommonPropToJson(int32_t resId, const ResourceItem &item, cJSON* json) const; +}; + +class ResourceDumperFactory { +public: + static std::unique_ptr CreateResourceDumper(const std::string &type); + static const std::set GetSupportDumpType(); +}; +} // namespace Restool +} // namespace Global +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/include/resource_item.h b/include/resource_item.h index 870f3ff0f89b3531263160f5559ca777c1e4d45b..08ec82cbb9a5dc9024abfd17765170baa3319e40 100644 --- a/include/resource_item.h +++ b/include/resource_item.h @@ -44,6 +44,9 @@ public: const std::string &GetFilePath() const; const std::string &GetLimitKey() const; bool IsCoverable() const; + const std::vector SplitValue() const; + bool IsArray() const; + bool IsPair() const; ResourceItem &operator=(const ResourceItem &other); private: diff --git a/include/resource_merge.h b/include/resource_merge.h index 7a2c3a034e9017f74cd2bb2f9ad69b47f5e11b04..e41cef919a7098be7af820b1a5f7400004176218 100644 --- a/include/resource_merge.h +++ b/include/resource_merge.h @@ -20,7 +20,7 @@ #include #include "config_parser.h" #include "restool_errors.h" -#include "cmd_parser.h" +#include "cmd/package_parser.h" namespace OHOS { namespace Global { diff --git a/include/resource_overlap.h b/include/resource_overlap.h index b0bba338b322a5a490e5552168f73299bdc41917..01f469d63f5f1179f5f1f925ade9310f8e7c5678 100644 --- a/include/resource_overlap.h +++ b/include/resource_overlap.h @@ -16,7 +16,7 @@ #ifndef OHOS_RESTOOL_RESOURCE_OVERLAP_H #define OHOS_RESTOOL_RESOURCE_OVERLAP_H -#include "cmd_parser.h" +#include "cmd/package_parser.h" #include "resource_pack.h" namespace OHOS { diff --git a/include/resource_pack.h b/include/resource_pack.h index 87a82ed1e7364566bd6837a3d42b02c78abbd8c6..04e8541557ea94e44b2bd764dd56f2952ee8b2fa 100644 --- a/include/resource_pack.h +++ b/include/resource_pack.h @@ -16,7 +16,6 @@ #ifndef OHOS_RESTOOL_RESOURCE_PACK_H #define OHOS_RESTOOL_RESOURCE_PACK_H -#include "cmd_parser.h" #include "config_parser.h" #include "resource_append.h" #include "resource_data.h" @@ -65,6 +64,8 @@ private: void CheckConfigJson(); void CheckConfigJsonForCombine(ResourceAppend &resourceAppend); bool CopyIcon(std::string &dataPath, const std::string &idName, std::string &fileName) const; + void ShowPackSuccess(); + using HeaderCreater = std::function; std::map headerCreaters_; PackType packType_ = PackType::NORMAL; diff --git a/include/factory_resource_packer.h b/include/resource_packer_factory.h similarity index 96% rename from include/factory_resource_packer.h rename to include/resource_packer_factory.h index c54ab28d5cc039d7f13960a5f52be2033785c56f..adcacbead2c26859a53ca23cbf518b9b2840dc88 100644 --- a/include/factory_resource_packer.h +++ b/include/resource_packer_factory.h @@ -22,7 +22,7 @@ namespace OHOS { namespace Global { namespace Restool { -class FactoryResourcePacker { +class ResourcePackerFactory { public: static std::unique_ptr CreatePacker(PackType type, const PackageParser &packageParser); }; diff --git a/include/resource_table.h b/include/resource_table.h index 3aa552075a35ec90313c39255521f092dff752af..2c1ad47a23d7a419439d6001c9cc3e2e961098b2 100644 --- a/include/resource_table.h +++ b/include/resource_table.h @@ -31,7 +31,8 @@ public: virtual ~ResourceTable(); uint32_t CreateResourceTable(); uint32_t CreateResourceTable(const std::map>> &items); - uint32_t LoadResTable(const std::string path, std::map> &resInfos); + static uint32_t LoadResTable(const std::string path, std::map> &resInfos); + static uint32_t LoadResTable(std::basic_istream &in, std::map> &resInfos); private: struct TableData { uint32_t id; @@ -74,16 +75,16 @@ private: void SaveLimitKeyConfigs(const std::map &limitKeyConfigs, std::ostringstream &out) const; void SaveIdSets(const std::map &idSets, std::ostringstream &out) const; - bool ReadFileHeader(std::ifstream &in, IndexHeader &indexHeader, uint64_t &pos, uint64_t length) const; - bool ReadLimitKeys(std::ifstream &in, std::map> &limitKeys, - uint32_t count, uint64_t &pos, uint64_t length) const; - bool ReadIdTables(std::ifstream &in, std::map> &datas, - uint32_t count, uint64_t &pos, uint64_t length) const; - bool ReadDataRecordPrepare(std::ifstream &in, RecordItem &record, uint64_t &pos, uint64_t length) const; - bool ReadDataRecordStart(std::ifstream &in, RecordItem &record, + static bool ReadFileHeader(std::basic_istream &in, IndexHeader &indexHeader, uint64_t &pos, uint64_t length); + static bool ReadLimitKeys(std::basic_istream &in, std::map> &limitKeys, + uint32_t count, uint64_t &pos, uint64_t length); + static bool ReadIdTables(std::basic_istream &in, std::map> &datas, + uint32_t count, uint64_t &pos, uint64_t length); + static bool ReadDataRecordPrepare(std::basic_istream &in, RecordItem &record, uint64_t &pos, uint64_t length); + static bool ReadDataRecordStart(std::basic_istream &in, RecordItem &record, const std::map> &limitKeys, const std::map> &datas, - std::map> &resInfos) const; + std::map> &resInfos); std::string indexFilePath_; std::string idDefinedPath_; }; diff --git a/include/resource_util.h b/include/resource_util.h index 245abd20606278340e74b3b4b1536e9d68346fda..0431c4102e6e5d02364142ad26b03b0b67618d86 100644 --- a/include/resource_util.h +++ b/include/resource_util.h @@ -247,6 +247,19 @@ public: */ static void PrintWarningMsg(std::vector> &noBaseResource); + /** + * @brief covert KeyParam to str by keytype + * @param keyParam: KeyParam + * @return limit value string + */ + static std::string GetKeyParamValue(const KeyParam &KeyParam); + + /** + * @brief keyType to string + * @param type: KeyType + * @return limit type string + */ + static std::string KeyTypeToStr(KeyType type); private: enum class IgnoreType { IGNORE_FILE, @@ -257,7 +270,6 @@ private: static std::string GetLocaleLimitkey(const KeyParam &KeyParam); static std::string GetDeviceTypeLimitkey(const KeyParam &KeyParam); static std::string GetResolutionLimitkey(const KeyParam &KeyParam); - static std::string GetKeyParamValue(const KeyParam &KeyParam); }; } } diff --git a/src/cmd/dump_parser.cpp b/src/cmd/dump_parser.cpp new file mode 100644 index 0000000000000000000000000000000000000000..57f100bc1d5a69528f714c1dcb6d86e544822a25 --- /dev/null +++ b/src/cmd/dump_parser.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2024 - 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cmd/dump_parser.h" +#include "resource_util.h" +#include "resource_dumper.h" + +namespace OHOS { +namespace Global { +namespace Restool { +using namespace std; +uint32_t DumpParser::Parse(int argc, char *argv[]) +{ + // argv[0] is restool path, argv[1] is 'dump' subcommand. + int currentIndex = 2; + if (currentIndex >= argc) { + cerr << "Error: missing input Hap path." << endl; + return RESTOOL_ERROR; + } + const set supportedDumpType = ResourceDumperFactory::GetSupportDumpType(); + if (supportedDumpType.count(argv[currentIndex]) != 0) { + type_ = argv[currentIndex]; + currentIndex++; + } + if (currentIndex >= argc) { + cerr << "Error: missing input Hap path." << endl; + return RESTOOL_ERROR; + } + inputPath_ = ResourceUtil::RealPath(argv[currentIndex]); + if (inputPath_.empty()) { + cerr << "Error: invalid input path: '" << argv[currentIndex] << "'" << endl; + return RESTOOL_ERROR; + } + return RESTOOL_SUCCESS; +} + +const string& DumpParser::GetInputPath() const +{ + return inputPath_; +} + +uint32_t DumpParser::ExecCommand() +{ + auto resourceDump = ResourceDumperFactory::CreateResourceDumper(type_); + if (resourceDump) { + return resourceDump->Dump(*this); + } + cerr << "Error: not support dump type '" << type_ << "'" << endl; + return RESTOOL_ERROR; +} +} // namespace Restool +} // namespace Global +} // namespace OHOS \ No newline at end of file diff --git a/src/cmd_parser.cpp b/src/cmd/package_parser.cpp similarity index 98% rename from src/cmd_parser.cpp rename to src/cmd/package_parser.cpp index d3888b743882a82036f94fc3b7da7df294ac5440..09c3d4d7c1232625764ae4d3c235fb79255e5334 100644 --- a/src/cmd_parser.cpp +++ b/src/cmd/package_parser.cpp @@ -13,12 +13,13 @@ * limitations under the License. */ -#include "cmd_parser.h" +#include "cmd/package_parser.h" #include #include "resconfig_parser.h" #include "resource_util.h" #include "select_compile_parse.h" #include "file_entry.h" +#include "resource_pack.h" namespace OHOS { namespace Global { @@ -469,7 +470,7 @@ void PackageParser::InitCommand() handles_.emplace(Option::FORCEWRITE, [this](const string &) -> uint32_t { return ForceWrite(); }); handles_.emplace(Option::VERSION, [this](const string &) -> uint32_t { return PrintVersion(); }); handles_.emplace(Option::MODULES, bind(&PackageParser::AddMoudleNames, this, _1)); - handles_.emplace(Option::JSON, bind(&PackageParser::AddConfig, this, _1)); + handles_.emplace(Option::JSON, bind(&PackageParser::AddConfig, this, _1)); handles_.emplace(Option::STARTID, bind(&PackageParser::AddStartId, this, _1)); handles_.emplace(Option::APPEND, bind(&PackageParser::AddAppend, this, _1)); handles_.emplace(Option::COMBINE, [this](const string &) -> uint32_t { return SetCombine(); }); @@ -543,7 +544,7 @@ uint32_t PackageParser::CheckError(int argc, char *argv[], int c, int optIndex) uint32_t PackageParser::ParseCommand(int argc, char *argv[]) { restoolPath_ = string(argv[0]); - while (true) { + while (optind <= argc) { int optIndex = -1; int c = getopt_long(argc, argv, CMD_PARAMS.c_str(), CMD_OPTS, &optIndex); if (CheckError(argc, argv, c, optIndex) != RESTOOL_SUCCESS) { @@ -584,6 +585,11 @@ bool PackageParser::IsLongOpt(int argc, char *argv[]) const } return false; } + +uint32_t PackageParser::ExecCommand() +{ + return ResourcePack(*this).Package(); +} } } } diff --git a/src/file_manager.cpp b/src/file_manager.cpp index 1141c35a42cff96e2ce2461a53f5ea89a6f7e191..e6a5190531aacc4b22b557f2b3acc8dbe291de58 100644 --- a/src/file_manager.cpp +++ b/src/file_manager.cpp @@ -17,7 +17,7 @@ #include #include "compression_parser.h" #include -#include "factory_resource_compiler.h" +#include "resource_compiler_factory.h" #include "file_entry.h" #include "key_parser.h" #include "reference_parser.h" diff --git a/src/id_worker.cpp b/src/id_worker.cpp index c97031cd6e819dc7f1b5522663061009a1f5f4a0..a9a62c917462bd4e6a48b6d6c32c007400f32977 100644 --- a/src/id_worker.cpp +++ b/src/id_worker.cpp @@ -16,7 +16,6 @@ #include "id_worker.h" #include #include -#include "cmd_parser.h" namespace OHOS { namespace Global { diff --git a/src/resource_append.cpp b/src/resource_append.cpp index fcba40922a696dc84d2e4c15b654c69f9291859d..d212e1958a01db6aaf35f61080fdfcad9cf8256d 100644 --- a/src/resource_append.cpp +++ b/src/resource_append.cpp @@ -267,7 +267,7 @@ bool ResourceAppend::ScanFile(const FileInfo &fileInfo, const string &outputPath } unique_ptr resourceCompiler = - FactoryResourceCompiler::CreateCompilerForAppend(fileInfo.dirType, outputPath); + ResourceCompilerFactory::CreateCompilerForAppend(fileInfo.dirType, outputPath); if (resourceCompiler == nullptr) { return true; } diff --git a/src/factory_resource_compiler.cpp b/src/resource_compiler_factory.cpp similarity index 89% rename from src/factory_resource_compiler.cpp rename to src/resource_compiler_factory.cpp index 3cd1d2b1dabfa1c5a7d5aeaa98e2843e03718557..5f782f5da103efcae67a55a68f05c1003b01b197 100644 --- a/src/factory_resource_compiler.cpp +++ b/src/resource_compiler_factory.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "factory_resource_compiler.h" +#include "resource_compiler_factory.h" #include "append_compiler.h" #include "generic_compiler.h" #include "json_compiler.h" @@ -23,7 +23,7 @@ namespace OHOS { namespace Global { namespace Restool { using namespace std; -unique_ptr FactoryResourceCompiler::CreateCompiler(ResType type, +unique_ptr ResourceCompilerFactory::CreateCompiler(ResType type, const string &output, bool isOverlap) { if (type == ResType::ELEMENT) { @@ -35,7 +35,7 @@ unique_ptr FactoryResourceCompiler::CreateCompiler(ResType ty } } -unique_ptr FactoryResourceCompiler::CreateCompilerForAppend(ResType type, const string &output) +unique_ptr ResourceCompilerFactory::CreateCompilerForAppend(ResType type, const string &output) { if (type == ResType::ELEMENT) { return make_unique(type, output); diff --git a/src/resource_dumper.cpp b/src/resource_dumper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bf1d08ce47162f91dd1e345315ae8437c0835c53 --- /dev/null +++ b/src/resource_dumper.cpp @@ -0,0 +1,408 @@ +/* + * Copyright (c) 2024 - 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "resource_dumper.h" + +#include +#include +#include +#include +#include +#include +#include +#include "cJSON.h" +#include "resource_item.h" +#include "resource_table.h" +#include "resource_util.h" +#include "restool_errors.h" + + +namespace OHOS { +namespace Global { +namespace Restool { + +constexpr int PAIR_SIZE = 2; + +static std::map()>> dumpMap_ = { + {"config", std::make_unique} +}; + +uint32_t ResourceDumper::Dump(const DumpParser &packageParser) +{ + inputPath_ = packageParser.GetInputPath(); + if (LoadHap() != RESTOOL_SUCCESS) { + return RESTOOL_ERROR; + } + std::string jsonStr; + if (DumpRes(jsonStr) != RESTOOL_SUCCESS) { + return RESTOOL_ERROR; + } + std::cout << jsonStr << std::endl; + return RESTOOL_SUCCESS; +} + +uint32_t ResourceDumper::LoadHap() +{ + unzFile zipFile = unzOpen64(inputPath_.c_str()); + if (!zipFile) { + std::cerr << "Error: Open file is failed. filename: " << inputPath_ << std::endl; + return RESTOOL_ERROR; + } + std::unique_ptr buffer; + size_t len; + if (ReadFileFromZip(zipFile, "module.json", buffer, len) == RESTOOL_SUCCESS) { + ReadHapInfo(buffer, len); + } + if (ReadFileFromZip(zipFile, "resources.index", buffer, len) != RESTOOL_SUCCESS) { + unzClose(zipFile); + return RESTOOL_ERROR; + } + unzClose(zipFile); + std::stringstream stream; + stream.write(buffer.get(), len); + if (ResourceTable::LoadResTable(stream, resInfos_) != RESTOOL_SUCCESS) { + return RESTOOL_ERROR; + } + return RESTOOL_SUCCESS; +} + +void ResourceDumper::ReadHapInfo(const std::unique_ptr &buffer, size_t len) +{ + cJSON *module = cJSON_Parse(buffer.get()); + if (!module) { + return; + } + cJSON *appConfig = cJSON_GetObjectItemCaseSensitive(module, "app"); + cJSON *moduleConfig = cJSON_GetObjectItemCaseSensitive(module, "module"); + if (appConfig) { + cJSON *bundleName = cJSON_GetObjectItemCaseSensitive(appConfig, "bundleName"); + if (cJSON_IsString(bundleName) && bundleName->valuestring) { + bundleName_ = bundleName->valuestring; + } + } + if (moduleConfig) { + cJSON *moduleName = cJSON_GetObjectItemCaseSensitive(moduleConfig, "name"); + if (cJSON_IsString(moduleName) && moduleName->valuestring) { + moduleName_ = moduleName->valuestring; + } + } + cJSON_Delete(module); +} + +uint32_t ResourceDumper::ReadFileFromZip( + unzFile &zipFile, const char *fileName, std::unique_ptr &buffer, size_t &len) +{ + unz_file_info fileInfo; + if (unzLocateFile2(zipFile, fileName, 1) != UNZ_OK) { + std::cerr << "Error: Not found filename: " << fileName << " in " << inputPath_ << std::endl; + return RESTOOL_ERROR; + } + char filenameInZip[256]; + int err = unzGetCurrentFileInfo(zipFile, &fileInfo, filenameInZip, sizeof(filenameInZip), nullptr, 0, nullptr, 0); + if (err != UNZ_OK) { + std::cerr << "Error: Get file info error. filename: " << fileName << " errorCode: " << err << std::endl; + return RESTOOL_ERROR; + } + + len = fileInfo.compressed_size; + buffer = std::make_unique(len); + if (!buffer) { + std::cerr << "Error: Allocating memory failed for buffer in ReadFileFromZip."<< std::endl; + return RESTOOL_ERROR; + } + + err = unzOpenCurrentFilePassword(zipFile, nullptr); + if (err != UNZ_OK) { + std::cerr << "Error: in unzOpenCurrentFilePassword. ErrorCode: " << err <> root(cJSON_CreateObject(), + [](cJSON* node) { cJSON_Delete(node); }); + if (!root) { + std::cerr << "Error: failed to create cJSON object for root object." << std::endl; + return RESTOOL_ERROR; + } + if (!bundleName_.empty() && !moduleName_.empty()) { + cJSON *bundleName = cJSON_CreateString(bundleName_.c_str()); + cJSON *moduleName = cJSON_CreateString(moduleName_.c_str()); + if (bundleName) { + cJSON_AddItemToObject(root.get(), "bundleName", bundleName); + } + if (moduleName) { + cJSON_AddItemToObject(root.get(), "moduleName", moduleName); + } + } + cJSON *resource = cJSON_CreateArray(); + if (!resource) { + std::cerr << "Error: failed to create cJSON object for resource array." << std::endl; + return RESTOOL_ERROR; + } + cJSON_AddItemToObject(root.get(), "resource", resource); + for (auto it = resInfos_.begin(); it != resInfos_.end(); it++) { + if (AddResourceToJson(it->first, it->second, resource)) { + return RESTOOL_ERROR; + } + } + char *rawStr = cJSON_Print(root.get()); + if (!rawStr) { + std::cerr << "Error: covert json object to str failed" << std::endl; + return RESTOOL_ERROR; + } + out = rawStr; + cJSON_free(rawStr); + rawStr = nullptr; + return RESTOOL_SUCCESS; +} + +uint32_t CommonDumper::AddKeyParamsToJson(const std::vector &keyParams, cJSON *json) const +{ + if (!json) { + std::cerr << "Error: Add keyParam to null json object." << std::endl; + return RESTOOL_ERROR; + } + for (const auto &keyParam : keyParams) { + std::string valueStr = ResourceUtil::GetKeyParamValue(keyParam); + cJSON *value = cJSON_CreateString(valueStr.c_str()); + if (!value) { + std::cerr << "Error: failed to create cJSON object for keyparam." << std::endl; + return RESTOOL_ERROR; + } + cJSON_AddItemToObject(json, ResourceUtil::KeyTypeToStr(keyParam.keyType).c_str(), value); + } + return RESTOOL_SUCCESS; +} + +uint32_t CommonDumper::AddItemCommonPropToJson(int32_t resId, const ResourceItem &item, cJSON* json) const +{ + if (!json) { + std::cerr << "Error: add item common property to null json object." << std::endl; + return RESTOOL_ERROR; + } + cJSON *id = cJSON_CreateNumber(resId); + if (!id) { + std::cerr << "Error: failed to create cJSON object for resource id." << std::endl; + return RESTOOL_ERROR; + } + cJSON_AddItemToObject(json, "id", id); + + cJSON *name = cJSON_CreateString(item.GetName().c_str()); + if (!name) { + std::cerr << "Error: failed to create cJSON object for resource name." << std::endl; + return RESTOOL_ERROR; + } + cJSON_AddItemToObject(json, "name", name); + + cJSON *type = cJSON_CreateString((ResourceUtil::ResTypeToString(item.GetResType())).c_str()); + if (!type) { + std::cerr << "Error: failed to create cJSON object for resource type." << std::endl; + return RESTOOL_ERROR; + } + cJSON_AddItemToObject(json, "type", type); + return RESTOOL_SUCCESS; +} + +uint32_t CommonDumper::AddResourceToJson(int64_t resId, const std::vector &items, cJSON *json) const +{ + if (items.empty()) { + std::cerr << "Error: reourceItem is empty." << std::endl; + return RESTOOL_ERROR; + } + if (!json) { + std::cerr << "Error: add Resource to null json object." << std::endl; + return RESTOOL_ERROR; + } + cJSON *resource = cJSON_CreateObject(); + if (!resource) { + std::cerr << "Error: failed to create cJSON object for resource item." << std::endl; + return RESTOOL_ERROR; + } + cJSON_AddItemToArray(json, resource); + if (AddItemCommonPropToJson(resId, items[0], resource) != RESTOOL_SUCCESS) { + return RESTOOL_ERROR; + }; + cJSON *entryCount = cJSON_CreateNumber(items.size()); + if (!entryCount) { + std::cerr << "Error: failed to create cJSON object for resource value count." << std::endl; + return RESTOOL_ERROR; + } + cJSON_AddItemToObject(resource, "entryCount", entryCount); + + cJSON *entryValues = cJSON_CreateArray(); + if (!resource) { + std::cerr << "Error: failed to create cJSON object for resource value array." << std::endl; + return RESTOOL_ERROR; + } + cJSON_AddItemToObject(resource, "entryValues", entryValues); + + for (const ResourceItem &item : items) { + cJSON *value = cJSON_CreateObject(); + if (!value) { + std::cerr << "Error: failed to create cJSON object for value item." << std::endl; + return RESTOOL_ERROR; + } + cJSON_AddItemToArray(entryValues, value); + if (AddValueToJson(item, value) != RESTOOL_SUCCESS) { + return RESTOOL_ERROR; + } + if (AddKeyParamsToJson(item.GetKeyParam(), value) != RESTOOL_SUCCESS) { + return RESTOOL_ERROR; + } + } + return RESTOOL_SUCCESS; +} + +uint32_t CommonDumper::AddPairVauleToJson(const ResourceItem &item, cJSON *json) const +{ + if (!json) { + std::cerr << "Error: add pair vaule to null json object." << std::endl; + return RESTOOL_ERROR; + } + cJSON *value = cJSON_CreateObject(); + if (!value) { + std::cerr << "Error: failed to create cJSON object for value object." << std::endl; + return RESTOOL_ERROR; + } + cJSON_AddItemToObject(json, "value", value); + const std::vector rawValues = item.SplitValue(); + uint32_t index = 1; + if (rawValues.size() % PAIR_SIZE != 0) { + cJSON *parent = cJSON_CreateString(rawValues[0].c_str()); + if (!parent) { + std::cerr << "Error: failed to create cJSON object for parent." << std::endl; + return RESTOOL_ERROR; + } + cJSON_AddItemToObject(json, "parent", parent); + index++; + } + for (; index < rawValues.size(); index += PAIR_SIZE) { + cJSON *item = cJSON_CreateString(rawValues[index].c_str()); + if (!item) { + std::cerr << "Error: failed to create cJSON object for value item." << std::endl; + return RESTOOL_ERROR; + } + cJSON_AddItemToObject(value, rawValues[index -1].c_str(), item); + } + return RESTOOL_SUCCESS; +} + +uint32_t CommonDumper::AddValueToJson(const ResourceItem &item, cJSON *json) const +{ + if (!json) { + std::cerr << "Error: add value to null json object." << std::endl; + return RESTOOL_ERROR; + } + if (item.IsArray()) { + cJSON *values = cJSON_CreateArray(); + if (!values) { + std::cerr << "Error: failed to create cJSON object for value array." << std::endl; + return RESTOOL_ERROR; + } + cJSON_AddItemToObject(json, "value", values); + const std::vector rawValues = item.SplitValue(); + for (const std::string &value : rawValues) { + cJSON *valueItem = cJSON_CreateString(value.c_str()); + if (!valueItem) { + std::cerr << "Error: failed to create cJSON object for value item." << std::endl; + return RESTOOL_ERROR; + } + cJSON_AddItemToArray(values, valueItem); + } + return RESTOOL_SUCCESS; + } + if (item.IsPair()) { + return AddPairVauleToJson(item, json); + } + std::string rawValue = std::string(reinterpret_cast(item.GetData()), item.GetDataLength()); + cJSON *value = cJSON_CreateString(rawValue.c_str()); + if (!value) { + std::cerr << "Error: failed to create cJSON object for value." << std::endl; + return RESTOOL_ERROR; + } + cJSON_AddItemToObject(json, "value", value); + return RESTOOL_SUCCESS; +} + +uint32_t ConfigDumper::DumpRes(std::string &out) const +{ + std::unique_ptr> root(cJSON_CreateObject(), + [](cJSON* node) { cJSON_Delete(node); }); + if (!root) { + std::cerr << "Error: failed to create cJSON object for root object." << std::endl; + return RESTOOL_ERROR; + } + cJSON *configs = cJSON_CreateArray(); + if (!configs) { + std::cerr << "Error: failed to create cJSON object for config array." << std::endl; + return RESTOOL_ERROR; + } + cJSON_AddItemToObject(root.get(), "config", configs); + + std::set configSet; + for (auto it = resInfos_.cbegin(); it != resInfos_.cend(); it++) { + for (const auto &item : it->second) { + const std::string &limitKey = item.GetLimitKey(); + if (configSet.count(limitKey) != 0) { + continue; + } + configSet.emplace(limitKey); + cJSON *config = cJSON_CreateString(limitKey.c_str()); + if (!config) { + std::cerr << "Error: failed to create cJSON object for limitkey." << std::endl; + return RESTOOL_ERROR; + } + cJSON_AddItemToArray(configs, config); + } + } + char *rawStr = cJSON_Print(root.get()); + if (!rawStr) { + std::cerr << "Error: covert config json object to str failed" << std::endl; + return RESTOOL_ERROR; + } + out = rawStr; + cJSON_free(rawStr); + rawStr = nullptr; + return RESTOOL_SUCCESS; +} + +std::unique_ptr ResourceDumperFactory::CreateResourceDumper(const std::string &type) +{ + auto it = dumpMap_.find(type); + if (it != dumpMap_.end()) { + return it->second(); + } + return std::make_unique(); +} + +const std::set ResourceDumperFactory::GetSupportDumpType() +{ + std::set dumpType; + for (auto &it : dumpMap_) { + dumpType.insert(it.first); + } + return dumpType; +} +} +} +} \ No newline at end of file diff --git a/src/resource_item.cpp b/src/resource_item.cpp index f059c3ac08a967f95e6703044d16a8d1de33bc79..2a1793e9900ebd09865efec35b087bf3cacd31a1 100644 --- a/src/resource_item.cpp +++ b/src/resource_item.cpp @@ -130,6 +130,36 @@ bool ResourceItem::IsCoverable() const return coverable_; } +bool ResourceItem::IsArray() const +{ + return type_ == ResType::STRARRAY || type_ == ResType::INTARRAY; +} + +bool ResourceItem::IsPair() const +{ + return type_ == ResType::THEME || type_ == ResType::PLURAL || type_ == ResType::PATTERN; +} + +const std::vector ResourceItem::SplitValue() const +{ + std::vector ret; + if (!(IsArray() || IsPair())) { + return ret; + } + char *buffer = reinterpret_cast(data_); + uint32_t index = 0; + while (index < dataLen_) { + uint16_t strLen = *reinterpret_cast(buffer + index); + index += sizeof(uint16_t); + if (index + strLen >= dataLen_) { + return ret; + } + ret.push_back(string(buffer+index, strLen)); + index = index + strLen + 1; + } + return ret; +} + ResourceItem &ResourceItem::operator=(const ResourceItem &other) { if (this == &other) { diff --git a/src/resource_module.cpp b/src/resource_module.cpp index 796fddb953db2e0c324f0e557a3470fd6fabc127..9f2b257ce5590e7090c2fe2b8279ccc78f67e0b4 100644 --- a/src/resource_module.cpp +++ b/src/resource_module.cpp @@ -16,7 +16,7 @@ #include "resource_module.h" #include #include -#include "factory_resource_compiler.h" +#include "resource_compiler_factory.h" #include "restool_errors.h" namespace OHOS { @@ -54,7 +54,7 @@ uint32_t ResourceModule::ScanResource(bool isHap) } unique_ptr resourceCompiler = - FactoryResourceCompiler::CreateCompiler(type, moduleOutput_, isHap); + ResourceCompilerFactory::CreateCompiler(type, moduleOutput_, isHap); resourceCompiler->SetModuleName(moduleName_); if (resourceCompiler->Compile(item->second) != RESTOOL_SUCCESS) { return RESTOOL_ERROR; diff --git a/src/resource_pack.cpp b/src/resource_pack.cpp index f0260ec1968208e42e14817d3ca463982373e00d..1d12a2def3229e03c4f2caf6189b3705dfccd322 100644 --- a/src/resource_pack.cpp +++ b/src/resource_pack.cpp @@ -15,6 +15,7 @@ #include "resource_pack.h" #include +#include #include #include "file_entry.h" #include "file_manager.h" @@ -24,33 +25,34 @@ #include "resource_table.h" #include "compression_parser.h" #include "binary_file_packer.h" -#include "factory_resource_packer.h" +#include "resource_packer_factory.h" namespace OHOS { namespace Global { namespace Restool { using namespace std; ResourcePack::ResourcePack(const PackageParser &packageParser):packageParser_(packageParser) -{ -} +{} uint32_t ResourcePack::Package() { + uint32_t errorCode = RESTOOL_SUCCESS; if (!packageParser_.GetAppend().empty()) { - return PackAppend(); - } - - if (packageParser_.GetCombine()) { - return PackCombine(); + errorCode = PackAppend(); + } else if (packageParser_.GetCombine()) { + errorCode = PackCombine(); + } else { + if (packageParser_.IsOverlap()) { + packType_ = PackType::OVERLAP; + } + unique_ptr resourcePacker = + ResourcePackerFactory::CreatePacker(packType_, packageParser_); + errorCode = resourcePacker->Pack(); } - - if (packageParser_.IsOverlap()) { - packType_ = PackType::OVERLAP; + if (errorCode == RESTOOL_SUCCESS) { + ShowPackSuccess(); } - - unique_ptr resourcePacker = - FactoryResourcePacker::CreatePacker(packType_, packageParser_); - return resourcePacker->Pack(); + return errorCode; } uint32_t ResourcePack::InitCompression() @@ -578,6 +580,14 @@ void ResourcePack::CheckConfigJsonForCombine(ResourceAppend &resourceAppend) ResourceCheck resourceCheck(configJson_.GetCheckNode(), make_shared(resourceAppend)); resourceCheck.CheckConfigJsonForCombine(); } + +void ResourcePack::ShowPackSuccess() +{ + cout << "Info: restool resources compile success." << endl; + if (CompressionParser::GetCompressionParser()->GetMediaSwitch()) { + cout << CompressionParser::GetCompressionParser()->PrintTransMessage() << endl; + } +} } } } diff --git a/src/factory_resource_packer.cpp b/src/resource_packer_factory.cpp similarity index 86% rename from src/factory_resource_packer.cpp rename to src/resource_packer_factory.cpp index 9204709d1e557ebf82f47f49feb5d5022f6c6c8e..2ce3824d430bcbf364f69e37458e3b47d03c316d 100644 --- a/src/factory_resource_packer.cpp +++ b/src/resource_packer_factory.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "factory_resource_packer.h" +#include "resource_packer_factory.h" #include "resource_overlap.h" namespace OHOS { @@ -21,14 +21,14 @@ namespace Global { namespace Restool { using namespace std; -unique_ptr FactoryResourcePacker::CreatePacker(PackType type, const PackageParser &packageParser) +unique_ptr ResourcePackerFactory::CreatePacker(PackType type, const PackageParser &packageParser) { if (type == PackType::NORMAL) { return make_unique(packageParser); } else if (type == PackType::OVERLAP) { return make_unique(packageParser); } else { - cerr << "Error: FactoryResourcePacker: Unknown input PackType." << endl; + cerr << "Error: ResourcePackerFactory: Unknown input PackType." << endl; return nullptr; } } diff --git a/src/resource_table.cpp b/src/resource_table.cpp index 24ae7afc51cb3edb1b84a2f5c9a3e66507cd02aa..7a555cf9bf2558b1201f1b3286ad4a142576484c 100644 --- a/src/resource_table.cpp +++ b/src/resource_table.cpp @@ -15,7 +15,8 @@ #include "resource_table.h" #include -#include "cmd_parser.h" +#include +#include "cmd/package_parser.h" #include "file_entry.h" #include "file_manager.h" #include "resource_util.h" @@ -115,23 +116,33 @@ uint32_t ResourceTable::LoadResTable(const string path, map &in, map> &resInfos) +{ + if (!in) { + cerr << "Error: istream state is bad. stateCode: " << in.rdstate() << endl; + return RESTOOL_ERROR; + } + in.seekg(0, ios::end); + int64_t length = in.tellg(); + in.seekg(0, ios::beg); uint64_t pos = 0; IndexHeader indexHeader; if (!ReadFileHeader(in, indexHeader, pos, static_cast(length))) { - in.close(); return RESTOOL_ERROR; } map> limitKeys; if (!ReadLimitKeys(in, limitKeys, indexHeader.limitKeyConfigSize, pos, static_cast(length))) { - in.close(); return RESTOOL_ERROR; } map> datas; if (!ReadIdTables(in, datas, indexHeader.limitKeyConfigSize, pos, static_cast(length))) { - in.close(); return RESTOOL_ERROR; } @@ -139,11 +150,9 @@ uint32_t ResourceTable::LoadResTable(const string path, map(length)) || !ReadDataRecordStart(in, record, limitKeys, datas, resInfos)) { - in.close(); return RESTOOL_ERROR; } } - in.close(); return RESTOOL_SUCCESS; } @@ -348,7 +357,7 @@ void ResourceTable::SaveIdSets(const map &idSets, ostringstream & } } -bool ResourceTable::ReadFileHeader(ifstream &in, IndexHeader &indexHeader, uint64_t &pos, uint64_t length) const +bool ResourceTable::ReadFileHeader(basic_istream &in, IndexHeader &indexHeader, uint64_t &pos, uint64_t length) { pos += sizeof(indexHeader); if (pos > length) { @@ -361,8 +370,8 @@ bool ResourceTable::ReadFileHeader(ifstream &in, IndexHeader &indexHeader, uint6 return true; } -bool ResourceTable::ReadLimitKeys(ifstream &in, map> &limitKeys, - uint32_t count, uint64_t &pos, uint64_t length) const +bool ResourceTable::ReadLimitKeys(basic_istream &in, map> &limitKeys, + uint32_t count, uint64_t &pos, uint64_t length) { for (uint32_t i = 0; i< count; i++) { pos = pos + TAG_LEN + INT_TO_BYTES + INT_TO_BYTES; @@ -397,8 +406,8 @@ bool ResourceTable::ReadLimitKeys(ifstream &in, map> & return true; } -bool ResourceTable::ReadIdTables(std::ifstream &in, std::map> &datas, - uint32_t count, uint64_t &pos, uint64_t length) const +bool ResourceTable::ReadIdTables(basic_istream &in, std::map> &datas, + uint32_t count, uint64_t &pos, uint64_t length) { for (uint32_t i = 0; i< count; i++) { pos = pos + TAG_LEN + INT_TO_BYTES; @@ -431,7 +440,7 @@ bool ResourceTable::ReadIdTables(std::ifstream &in, std::map &in, RecordItem &record, uint64_t &pos, uint64_t length) { pos = pos + INT_TO_BYTES; if (pos > length) { @@ -449,10 +458,10 @@ bool ResourceTable::ReadDataRecordPrepare(ifstream &in, RecordItem &record, uint return true; } -bool ResourceTable::ReadDataRecordStart(std::ifstream &in, RecordItem &record, - const std::map> &limitKeys, - const std::map> &datas, - std::map> &resInfos) const +bool ResourceTable::ReadDataRecordStart(basic_istream &in, RecordItem &record, + const map> &limitKeys, + const map> &datas, + map> &resInfos) { int64_t offset = in.tellg(); offset = offset - INT_TO_BYTES - INT_TO_BYTES - INT_TO_BYTES; diff --git a/src/resource_util.cpp b/src/resource_util.cpp index 1a59c9e52a3770257b0883405aedec76b6853cd9..efef4ccb58eba8985576f1e7e44f555691c4252d 100644 --- a/src/resource_util.cpp +++ b/src/resource_util.cpp @@ -328,6 +328,10 @@ string ResourceUtil::GetKeyParamValue(const KeyParam &KeyParam) case KeyType::REGION: val = GetLocaleLimitkey(KeyParam); break; + case KeyType::INPUTDEVICE: + val = KeyParam.value == static_cast(InputDevice::INPUTDEVICE_NOT_SET) ? + "not set" : "pointDevice"; + break; default: val = to_string(KeyParam.value); break; @@ -471,6 +475,18 @@ void ResourceUtil::PrintWarningMsg(vector> &noBaseResource cerr << " of '" << item.second << "' does not have a base resource." << endl; } } + +string ResourceUtil::KeyTypeToStr(KeyType type) +{ + string ret("unknown type: "); + auto it = g_keyTypeToStrMap.find(type); + if (it != g_keyTypeToStrMap.end()) { + ret = it->second; + } else { + ret += to_string(static_cast(type)); + } + return ret; +} } } } diff --git a/src/restool.cpp b/src/restool.cpp index 0e229f5e633026a94fd3f83dc86f3187464e3ddc..1dd3fea75e0e84876e642e0cd9766604106059c5 100644 --- a/src/restool.cpp +++ b/src/restool.cpp @@ -13,19 +13,16 @@ * limitations under the License. */ -#include "cmd_parser.h" +#include +#include "cmd/package_parser.h" +#include "cmd/dump_parser.h" #include "resource_pack.h" #include "compression_parser.h" using namespace std; using namespace OHOS::Global::Restool; -namespace { -uint32_t ProccssHap(PackageParser &packageParser) -{ - ResourcePack pack(packageParser); - return pack.Package(); -} -} + +constexpr int PARAM_MIN_NUM = 2; int main(int argc, char *argv[]) { @@ -33,19 +30,23 @@ int main(int argc, char *argv[]) cerr << "Error: argv null" << endl; return RESTOOL_ERROR; } - auto &parser = CmdParser::GetInstance(); - if (parser.Parse(argc, argv) != RESTOOL_SUCCESS) { - parser.ShowUseage(); + if (argc < PARAM_MIN_NUM) { + cerr << "Error: At least 1 parameters are required, but no parameter is passed in." << endl; return RESTOOL_ERROR; } - - auto &packageParser = parser.GetCmdParser(); - if (ProccssHap(packageParser) != RESTOOL_SUCCESS) { - return RESTOOL_ERROR; + if (strcmp(argv[1], "dump") == 0) { + auto &dumpParser = CmdParser::GetInstance(); + if (dumpParser.Parse(argc, argv) != RESTOOL_SUCCESS) { + dumpParser.ShowUseage(); + return RESTOOL_ERROR; + } + return dumpParser.ExecCommand(); } - cout << "Info: restool resources compile success." << endl; - if (CompressionParser::GetCompressionParser()->GetMediaSwitch()) { - cout << CompressionParser::GetCompressionParser()->PrintTransMessage() << endl; + auto &packParser = CmdParser::GetInstance(); + if (packParser.Parse(argc, argv) != RESTOOL_SUCCESS) { + packParser.ShowUseage(); + return RESTOOL_ERROR; } - return RESTOOL_SUCCESS; + + return packParser.ExecCommand(); } diff --git a/src/select_compile_parse.cpp b/src/select_compile_parse.cpp index 6f5e81deeb4f627bbd9eaeab17644ee86b2e7d5b..5ce5588f200de22a4a5e90cfc215e5119812af60 100644 --- a/src/select_compile_parse.cpp +++ b/src/select_compile_parse.cpp @@ -16,7 +16,7 @@ #include "select_compile_parse.h" #include #include "key_parser.h" -#include "cmd_parser.h" +#include "cmd/package_parser.h" #include "resource_util.h" namespace OHOS {