From af403ee76ce7a7c485f4a3f3655417570b8a412c Mon Sep 17 00:00:00 2001 From: sunjie Date: Fri, 13 Dec 2024 17:01:42 +0800 Subject: [PATCH] add restool dump command Signed-off-by: sunjie Change-Id: Ifd10f76345a87a40ac73f82486cdce54a4e94a53 --- BUILD.gn | 9 +- bundle.json | 3 +- include/binary_file_packer.h | 2 +- include/{ => cmd}/cmd_parser.h | 111 +---- include/cmd/dump_parser.h | 40 ++ include/cmd/package_parser.h | 112 +++++ include/id_defined_parser.h | 2 +- include/resource_append.h | 4 +- ...compiler.h => resource_compiler_factory.h} | 2 +- include/resource_data.h | 15 +- include/resource_dumper.h | 81 ++++ include/resource_item.h | 3 + include/resource_merge.h | 2 +- include/resource_overlap.h | 2 +- include/resource_pack.h | 3 +- ...rce_packer.h => resource_packer_factory.h} | 2 +- include/resource_table.h | 19 +- include/resource_util.h | 14 +- src/cmd/dump_parser.cpp | 65 +++ .../package_parser.cpp} | 12 +- src/file_manager.cpp | 2 +- src/id_worker.cpp | 1 - src/resource_append.cpp | 2 +- ...iler.cpp => resource_compiler_factory.cpp} | 6 +- src/resource_dumper.cpp | 408 ++++++++++++++++++ src/resource_item.cpp | 30 ++ src/resource_module.cpp | 4 +- src/resource_pack.cpp | 40 +- ...packer.cpp => resource_packer_factory.cpp} | 6 +- src/resource_table.cpp | 41 +- src/resource_util.cpp | 16 + src/restool.cpp | 39 +- src/select_compile_parse.cpp | 2 +- 33 files changed, 918 insertions(+), 182 deletions(-) rename include/{ => cmd}/cmd_parser.h (47%) create mode 100644 include/cmd/dump_parser.h create mode 100644 include/cmd/package_parser.h rename include/{factory_resource_compiler.h => resource_compiler_factory.h} (97%) create mode 100644 include/resource_dumper.h rename include/{factory_resource_packer.h => resource_packer_factory.h} (96%) create mode 100644 src/cmd/dump_parser.cpp rename src/{cmd_parser.cpp => cmd/package_parser.cpp} (98%) rename src/{factory_resource_compiler.cpp => resource_compiler_factory.cpp} (89%) create mode 100644 src/resource_dumper.cpp rename src/{factory_resource_packer.cpp => resource_packer_factory.cpp} (86%) diff --git a/BUILD.gn b/BUILD.gn index 2a014a4..f508195 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 01e4a5a..e04267d 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 38f9cf1..79d14ce 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 83ad3d2..3bfa70a 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 0000000..5003ed8 --- /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 0000000..1774d2a --- /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 0fa40d4..3bb7268 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 2261e5f..9c4b85c 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 7a55736..7dd0d7a 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 f51d640..2162dc9 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 0000000..7bf63d7 --- /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 870f3ff..08ec82c 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 7a2c3a0..e41cef9 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 b0bba33..01f469d 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 87a82ed..04e8541 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 c54ab28..adcacbe 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 3aa5520..2c1ad47 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 245abd2..0431c41 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 0000000..57f100b --- /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 d3888b7..09c3d4d 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 1141c35..e6a5190 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 c97031c..a9a62c9 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 fcba409..d212e19 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 3cd1d2b..5f782f5 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 0000000..bf1d08c --- /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 f059c3a..2a1793e 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 796fddb..9f2b257 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 f0260ec..1d12a2d 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 9204709..2ce3824 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 24ae7af..7a555cf 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 1a59c9e..efef4cc 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 0e229f5..1dd3fea 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 6f5e81d..5ce5588 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 { -- Gitee