From ec486b34df40c0f197cca4da876a7099cd5dc57e Mon Sep 17 00:00:00 2001 From: HanSY Date: Mon, 9 Dec 2024 11:38:19 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: HanSY --- BUILD.gn | 4 + include/binary_file_packer.h | 19 ++--- include/cmd_parser.h | 2 +- include/factory_resource_compiler.h | 2 +- include/factory_resource_packer.h | 32 ++++++++ include/file_manager.h | 1 - include/generic_compiler.h | 12 +-- include/i_resource_compiler.h | 5 +- include/json_compiler.h | 2 +- include/overlap_binary_file_packer.h | 35 +++++++++ include/overlap_compiler.h | 34 +++++++++ include/resource_data.h | 7 +- include/resource_item.h | 6 +- include/resource_overlap.h | 39 ++++++++++ include/resource_pack.h | 22 +++--- src/binary_file_packer.cpp | 85 ++++++++------------- src/cmd_parser.cpp | 20 ++--- src/factory_resource_compiler.cpp | 10 ++- src/factory_resource_packer.cpp | 37 +++++++++ src/file_manager.cpp | 12 --- src/generic_compiler.cpp | 23 +++--- src/i_resource_compiler.cpp | 10 +-- src/json_compiler.cpp | 8 +- src/overlap_binary_file_packer.cpp | 57 ++++++++++++++ src/overlap_compiler.cpp | 41 ++++++++++ src/resource_item.cpp | 10 +-- src/resource_module.cpp | 7 +- src/resource_overlap.cpp | 110 +++++++++++++++++++++++++++ src/resource_pack.cpp | 61 +++------------ src/resource_table.cpp | 2 + 30 files changed, 516 insertions(+), 199 deletions(-) create mode 100644 include/factory_resource_packer.h create mode 100644 include/overlap_binary_file_packer.h create mode 100644 include/overlap_compiler.h create mode 100644 include/resource_overlap.h create mode 100644 src/factory_resource_packer.cpp create mode 100644 src/overlap_binary_file_packer.cpp create mode 100644 src/overlap_compiler.cpp create mode 100644 src/resource_overlap.cpp diff --git a/BUILD.gn b/BUILD.gn index a2d9fa6..2a014a4 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -23,6 +23,7 @@ ohos_executable("restool") { "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", @@ -32,6 +33,8 @@ ohos_executable("restool") { "src/id_worker.cpp", "src/json_compiler.cpp", "src/key_parser.cpp", + "src/overlap_binary_file_packer.cpp", + "src/overlap_compiler.cpp", "src/reference_parser.cpp", "src/resconfig_parser.cpp", "src/resource_append.cpp", @@ -40,6 +43,7 @@ ohos_executable("restool") { "src/resource_item.cpp", "src/resource_merge.cpp", "src/resource_module.cpp", + "src/resource_overlap.cpp", "src/resource_pack.cpp", "src/resource_table.cpp", "src/resource_util.cpp", diff --git a/include/binary_file_packer.h b/include/binary_file_packer.h index e241ac6..38f9cf1 100644 --- a/include/binary_file_packer.h +++ b/include/binary_file_packer.h @@ -29,22 +29,23 @@ public: ~BinaryFilePacker(); std::future CopyBinaryFileAsync(const std::vector &inputs); void StopCopy(); - void SetCopyHap(bool state); -private: - uint32_t CopyBinaryFile(const std::vector &inputs); - uint32_t CopyBinaryFile(const std::string &filePath, const std::string &fileType); - uint32_t CopyBinaryFileImpl(const std::string &src, const std::string &dst); - uint32_t CopySingleFile(const std::string &path, std::string &subPath); - uint32_t CopyBinaryFileWithHap(const std::vector &inputs); - bool IsDefinedFile(const std::unique_ptr &entry, std::string subPath); +protected: + virtual uint32_t CopyBinaryFile(const std::vector &inputs); + uint32_t CheckCopyResults(); + uint32_t CopyBinaryFile(const std::string &input); + virtual bool IsDuplicated(const std::unique_ptr &entry, std::string subPath); PackageParser packageParser_; std::string moduleName_; ThreadPool threadPool_; std::vector> copyResults_; std::atomic stopCopy_{false}; - bool copyHap_{false}; std::mutex mutex_; + +private: + uint32_t CopyBinaryFile(const std::string &filePath, const std::string &fileType); + uint32_t CopyBinaryFileImpl(const std::string &src, const std::string &dst); + uint32_t CopySingleFile(const std::string &path, std::string &subPath); }; } // namespace Restool } // namespace Global diff --git a/include/cmd_parser.h b/include/cmd_parser.h index 3e90ab7..83ad3d2 100644 --- a/include/cmd_parser.h +++ b/include/cmd_parser.h @@ -57,7 +57,7 @@ public: bool IsTargetConfig() const; const std::vector &GetSysIdDefinedPaths() const; const std::string &GetCompressionPath() const; - bool ExistHapInput(); + bool IsOverlap() const; private: void InitCommand(); diff --git a/include/factory_resource_compiler.h b/include/factory_resource_compiler.h index 638a429..7a55736 100644 --- a/include/factory_resource_compiler.h +++ b/include/factory_resource_compiler.h @@ -24,7 +24,7 @@ namespace Global { namespace Restool { class FactoryResourceCompiler { public: - static std::unique_ptr CreateCompiler(ResType type, const std::string &output); + 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/factory_resource_packer.h b/include/factory_resource_packer.h new file mode 100644 index 0000000..c54ab28 --- /dev/null +++ b/include/factory_resource_packer.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021-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_FACTORY_RESOURCE_PACKER_H +#define OHOS_RESTOOL_FACTORY_RESOURCE_PACKER_H + +#include +#include "resource_pack.h" + +namespace OHOS { +namespace Global { +namespace Restool { +class FactoryResourcePacker { +public: + static std::unique_ptr CreatePacker(PackType type, const PackageParser &packageParser); +}; +} +} +} +#endif \ No newline at end of file diff --git a/include/file_manager.h b/include/file_manager.h index aa4a0c6..655dfdf 100644 --- a/include/file_manager.h +++ b/include/file_manager.h @@ -35,7 +35,6 @@ public: { moduleName_ = moduleName; }; - void MarkItemsAsHap(); uint32_t MergeResourceItem(const std::map> &resourceInfos); bool ScaleIcons(const std::string &output, const std::map> &iconMap); void SetScanHap(bool state); diff --git a/include/generic_compiler.h b/include/generic_compiler.h index 1476143..d5a6af3 100644 --- a/include/generic_compiler.h +++ b/include/generic_compiler.h @@ -24,17 +24,19 @@ namespace Global { namespace Restool { class GenericCompiler : public IResourceCompiler { public: - GenericCompiler(ResType type, const std::string &output); + GenericCompiler(ResType type, const std::string &output, bool isOverlap = false); virtual ~GenericCompiler(); + protected: + std::string GetOutputFilePath(const FileInfo &fileInfo) const; + virtual bool IsIgnore(const FileInfo &fileInfo); uint32_t CompileSingleFile(const FileInfo &fileInfo) override; uint32_t CompileFiles(const std::vector &fileInfos) override; bool PostMediaFile(const FileInfo &fileInfo, const std::string &output); -private: - std::string GetOutputFilePath(const FileInfo &fileInfo) const; - bool IsIgnore(const FileInfo &fileInfo); - bool CopyMediaFile(const FileInfo &fileInfo, std::string &output); std::mutex mutex_; + +private: + bool CopyMediaFile(const FileInfo &fileInfo, std::string &output); }; } } diff --git a/include/i_resource_compiler.h b/include/i_resource_compiler.h index 0a3f5df..be9842b 100644 --- a/include/i_resource_compiler.h +++ b/include/i_resource_compiler.h @@ -25,7 +25,7 @@ namespace Global { namespace Restool { class IResourceCompiler { public: - IResourceCompiler(ResType type, const std::string &output); + IResourceCompiler(ResType type, const std::string &output, bool isOverlap = false); virtual ~IResourceCompiler(); uint32_t Compile(const std::vector &directoryInfos); const std::map> &GetResult() const; @@ -33,7 +33,6 @@ public: void SetModuleName(const std::string &moduleName); uint32_t CompileForAppend(const FileInfo &fileInfo); const std::map, std::vector> &GetResourceItems() const; - void SetHapRes(bool state); protected: virtual uint32_t CompileSingleFile(const FileInfo &fileInfo); @@ -43,7 +42,7 @@ protected: ResType type_; std::string output_; std::string moduleName_; - bool hapRes_ = false; + bool isOverlap_; // id, resource items std::map> resourceInfos_; diff --git a/include/json_compiler.h b/include/json_compiler.h index f14ad9f..5b6d77f 100644 --- a/include/json_compiler.h +++ b/include/json_compiler.h @@ -26,7 +26,7 @@ namespace Global { namespace Restool { class JsonCompiler : public IResourceCompiler { public: - JsonCompiler(ResType type, const std::string &output); + JsonCompiler(ResType type, const std::string &output, bool isOverlap = false); virtual ~JsonCompiler(); protected: uint32_t CompileSingleFile(const FileInfo &fileInfo) override; diff --git a/include/overlap_binary_file_packer.h b/include/overlap_binary_file_packer.h new file mode 100644 index 0000000..8a99b87 --- /dev/null +++ b/include/overlap_binary_file_packer.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021-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_OVERLAP_BINARY_FILE_PACKER_H +#define OHOS_RESTOOL_OVERLAP_BINARY_FILE_PACKER_H + +#include "binary_file_packer.h" + +namespace OHOS { +namespace Global { +namespace Restool { +class OverlapBinaryFilePacker : public BinaryFilePacker { +public: + OverlapBinaryFilePacker(const PackageParser &packageParser, const std::string &moduleName); + +protected: + uint32_t CopyBinaryFile(const std::vector &inputs); + bool IsDuplicated(const std::unique_ptr &entry, std::string subPath); +}; +} +} +} +#endif diff --git a/include/overlap_compiler.h b/include/overlap_compiler.h new file mode 100644 index 0000000..63b3ec1 --- /dev/null +++ b/include/overlap_compiler.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021-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_OVERLAP_COMPILER_H +#define OHOS_RESTOOL_OVERLAP_COMPILER_H + +#include "generic_compiler.h" + +namespace OHOS { +namespace Global { +namespace Restool { +class OverlapCompiler : public GenericCompiler { +public: + OverlapCompiler(ResType type, const std::string &output, bool isOverlap = false); + +protected: + bool IsIgnore(const FileInfo &fileInfo); +}; +} +} +} +#endif \ No newline at end of file diff --git a/include/resource_data.h b/include/resource_data.h index fe80c45..f51d640 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.012" }; +static const int8_t RESTOOL_VERSION[VERSION_MAX_LEN] = { "Restool 5.1.0.002" }; const static int32_t TAG_LEN = 4; static std::set g_resourceSet; static std::set g_hapResourceSet; @@ -93,6 +93,11 @@ enum class ResType { INVALID_RES_TYPE = -1, }; +enum class PackType { + NORMAL = 1, + OVERLAP +}; + enum class OrientationType { VERTICAL = 0, HORIZONTAL = 1, diff --git a/include/resource_item.h b/include/resource_item.h index c23133e..870f3ff 100644 --- a/include/resource_item.h +++ b/include/resource_item.h @@ -34,7 +34,7 @@ public: void SetFilePath(const std::string &filePath); void SetLimitKey(const std::string &limitKey); void SetName(const std::string &name); - void MarkHapRes(); + void MarkCoverable(); const int8_t *GetData() const; uint32_t GetDataLength() const; @@ -43,7 +43,7 @@ public: const std::vector &GetKeyParam() const; const std::string &GetFilePath() const; const std::string &GetLimitKey() const; - bool IsHapRes() const; + bool IsCoverable() const; ResourceItem &operator=(const ResourceItem &other); private: @@ -56,7 +56,7 @@ private: ResType type_; std::string filePath_; std::string limitKey_; - bool hapRes_ = false; + bool coverable_ = false; }; } } diff --git a/include/resource_overlap.h b/include/resource_overlap.h new file mode 100644 index 0000000..b0bba33 --- /dev/null +++ b/include/resource_overlap.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021-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_OVERLAP_H +#define OHOS_RESTOOL_RESOURCE_OVERLAP_H + +#include "cmd_parser.h" +#include "resource_pack.h" + +namespace OHOS { +namespace Global { +namespace Restool { +class ResourceOverlap : public ResourcePack { +public: + ResourceOverlap(const PackageParser &packageParser); + uint32_t Pack(); + +protected: + uint32_t ScanResources(const std::vector &inputs, const std::string &output); + +private: + uint32_t LoadHapResources(); +}; +} +} +} +#endif \ No newline at end of file diff --git a/include/resource_pack.h b/include/resource_pack.h index bf76eaa..87a82ed 100644 --- a/include/resource_pack.h +++ b/include/resource_pack.h @@ -27,19 +27,22 @@ namespace OHOS { namespace Global { namespace Restool { -enum class PackType { - NORMAL = 1, - OVERLAP -}; - class ResourcePack { public: explicit ResourcePack(const PackageParser &packageParser); virtual ~ResourcePack() = default; uint32_t Package(); + virtual uint32_t Pack(); + +protected: + uint32_t InitResourcePack(); + uint32_t PackResources(const ResourceMerge &resourceMerge); + virtual uint32_t ScanResources(const std::vector &inputs, const std::string &output); + PackageParser packageParser_; + std::string moduleName_; + ConfigParser configJson_; private: - uint32_t InitResourcePack(); uint32_t InitModule(); void InitHeaderCreater(); uint32_t InitOutput() const; @@ -50,10 +53,6 @@ private: uint32_t GenerateCplusHeader(const std::string &headerPath) const; uint32_t GenerateJsHeader(const std::string &headerPath) const; uint32_t GenerateConfigJson(); - uint32_t ScanResources(const std::vector &inputs, const std::string &output); - uint32_t Pack(); - uint32_t PackResources(const ResourceMerge &resourceMerge); - uint32_t LoadHapResources(); uint32_t PackPreview(); uint32_t PackAppend(); uint32_t PackCombine(); @@ -66,11 +65,8 @@ private: void CheckConfigJson(); void CheckConfigJsonForCombine(ResourceAppend &resourceAppend); bool CopyIcon(std::string &dataPath, const std::string &idName, std::string &fileName) const; - PackageParser packageParser_; - std::string moduleName_; using HeaderCreater = std::function; std::map headerCreaters_; - ConfigParser configJson_; PackType packType_ = PackType::NORMAL; }; } diff --git a/src/binary_file_packer.cpp b/src/binary_file_packer.cpp index 791fd13..dc4c3a1 100644 --- a/src/binary_file_packer.cpp +++ b/src/binary_file_packer.cpp @@ -39,62 +39,35 @@ void BinaryFilePacker::StopCopy() stopCopy_.store(true); } -void BinaryFilePacker::SetCopyHap(bool state) -{ - copyHap_ = state; -} - std::future BinaryFilePacker::CopyBinaryFileAsync(const std::vector &inputs) { - if (copyHap_) { - auto func = [this](const vector &inputs) { return this->CopyBinaryFileWithHap(inputs); }; - future res = threadPool_.Enqueue(func, inputs); - return res; - } auto func = [this](const vector &inputs) { return this->CopyBinaryFile(inputs); }; std::future res = threadPool_.Enqueue(func, inputs); return res; } -uint32_t BinaryFilePacker::CopyBinaryFileWithHap(const vector &inputs) +uint32_t BinaryFilePacker::CopyBinaryFile(const vector &inputs) { - vector hapResource{inputs[0]}; - if (CopyBinaryFile(hapResource) != RESTOOL_SUCCESS) { - return RESTOOL_ERROR; + for (const auto &input : inputs) { + CopyBinaryFile(input); } - copyResults_.clear(); - SetCopyHap(false); - - vector resource(inputs.begin() + 1, inputs.end()); - if (CopyBinaryFile(resource) != RESTOOL_SUCCESS) { + if (CheckCopyResults() != RESTOOL_SUCCESS) { return RESTOOL_ERROR; } return RESTOOL_SUCCESS; } -uint32_t BinaryFilePacker::CopyBinaryFile(const vector &inputs) +uint32_t BinaryFilePacker::CopyBinaryFile(const string &input) { - for (const auto &input : inputs) { - string rawfilePath = FileEntry::FilePath(input).Append(RAW_FILE_DIR).GetPath(); - if (CopyBinaryFile(rawfilePath, RAW_FILE_DIR) == RESTOOL_ERROR) { - cerr << "Error: copy raw file failed." << NEW_LINE_PATH << rawfilePath << endl; - return RESTOOL_ERROR; - } - string resfilePath = FileEntry::FilePath(input).Append(RES_FILE_DIR).GetPath(); - if (CopyBinaryFile(resfilePath, RES_FILE_DIR) == RESTOOL_ERROR) { - cerr << "Error: copy res file failed." << NEW_LINE_PATH << resfilePath << endl; - return RESTOOL_ERROR; - } + string rawfilePath = FileEntry::FilePath(input).Append(RAW_FILE_DIR).GetPath(); + if (CopyBinaryFile(rawfilePath, RAW_FILE_DIR) == RESTOOL_ERROR) { + cerr << "Error: copy raw file failed." << NEW_LINE_PATH << rawfilePath << endl; + return RESTOOL_ERROR; } - for (auto &res : copyResults_) { - if (stopCopy_.load()) { - cout << "Info: CopyBinaryFile: stop copy binary file." << endl; - return RESTOOL_ERROR; - } - uint32_t ret = res.get(); - if (ret != RESTOOL_SUCCESS) { - return RESTOOL_ERROR; - } + string resfilePath = FileEntry::FilePath(input).Append(RES_FILE_DIR).GetPath(); + if (CopyBinaryFile(resfilePath, RES_FILE_DIR) == RESTOOL_ERROR) { + cerr << "Error: copy res file failed." << NEW_LINE_PATH << resfilePath << endl; + return RESTOOL_ERROR; } return RESTOOL_SUCCESS; } @@ -142,7 +115,7 @@ uint32_t BinaryFilePacker::CopyBinaryFileImpl(const string &src, const string &d continue; } - if (IsDefinedFile(entry, subPath)) { + if (IsDuplicated(entry, subPath)) { continue; } @@ -159,20 +132,12 @@ uint32_t BinaryFilePacker::CopyBinaryFileImpl(const string &src, const string &d return RESTOOL_SUCCESS; } -bool BinaryFilePacker::IsDefinedFile(const unique_ptr &entry, string subPath) +bool BinaryFilePacker::IsDuplicated(const unique_ptr &entry, string subPath) { lock_guard lock(mutex_); - bool resEmplaceSuccess = true; - if (copyHap_) { - g_hapResourceSet.emplace(subPath); - g_resourceSet.emplace(subPath); - } else if (g_hapResourceSet.count(subPath)) { + if (g_hapResourceSet.count(subPath)) { g_hapResourceSet.erase(subPath); - } else { - resEmplaceSuccess = g_resourceSet.emplace(subPath).second; - } - - if (!resEmplaceSuccess) { + } else if (!g_resourceSet.emplace(subPath).second) { cerr << "Warning: '" << entry->GetFilePath().GetPath() << "' is defined repeatedly." << endl; return true; } @@ -194,6 +159,22 @@ uint32_t BinaryFilePacker::CopySingleFile(const std::string &path, std::string & } return RESTOOL_SUCCESS; } + +uint32_t BinaryFilePacker::CheckCopyResults() +{ + for (auto &res : copyResults_) { + if (stopCopy_.load()) { + cout << "Info: CopyBinaryFile: stop copy binary file." << endl; + return RESTOOL_ERROR; + } + uint32_t ret = res.get(); + if (ret != RESTOOL_SUCCESS) { + cerr << "Error: copy binary file failed." << endl; + return RESTOOL_ERROR; + } + } + return RESTOOL_SUCCESS; +} } // namespace Restool } // namespace Global } // namespace OHOS diff --git a/src/cmd_parser.cpp b/src/cmd_parser.cpp index 7120a4e..d3888b7 100644 --- a/src/cmd_parser.cpp +++ b/src/cmd_parser.cpp @@ -135,7 +135,13 @@ uint32_t PackageParser::AddInput(const string& argValue) if (!IsAscii(inputPath)) { return RESTOOL_ERROR; } - inputs_.push_back(inputPath); + + string indexPath = ResourceUtil::GetMainPath(inputPath).Append(RESOURCE_INDEX_FILE).GetPath(); + if (ResourceUtil::FileExist(indexPath)) { + inputs_.emplace(inputs_.begin(), inputPath); + } else { + inputs_.push_back(inputPath); + } return RESTOOL_SUCCESS; } @@ -444,15 +450,11 @@ const std::string &PackageParser::GetCompressionPath() const return compressionPath_; } -bool PackageParser::ExistHapInput() +bool PackageParser::IsOverlap() const { - for (auto &input : inputs_) { - string indexPath = ResourceUtil::GetMainPath(input).Append(RESOURCE_INDEX_FILE).GetPath(); - if (ResourceUtil::FileExist(indexPath)) { - inputs_.erase(find(inputs_.begin(), inputs_.end(), input)); - inputs_.emplace(inputs_.begin(), input); - return true; - } + string indexPath = ResourceUtil::GetMainPath(inputs_[0]).Append(RESOURCE_INDEX_FILE).GetPath(); + if (ResourceUtil::FileExist(indexPath)) { + return true; } return false; } diff --git a/src/factory_resource_compiler.cpp b/src/factory_resource_compiler.cpp index e4e8fc5..3cd1d2b 100644 --- a/src/factory_resource_compiler.cpp +++ b/src/factory_resource_compiler.cpp @@ -17,17 +17,21 @@ #include "append_compiler.h" #include "generic_compiler.h" #include "json_compiler.h" +#include "overlap_compiler.h" namespace OHOS { namespace Global { namespace Restool { using namespace std; -unique_ptr FactoryResourceCompiler::CreateCompiler(ResType type, const string &output) +unique_ptr FactoryResourceCompiler::CreateCompiler(ResType type, + const string &output, bool isOverlap) { if (type == ResType::ELEMENT) { - return make_unique(type, output); + return make_unique(type, output, isOverlap); + } else if (isOverlap) { + return make_unique(type, output, isOverlap); } else { - return make_unique(type, output); + return make_unique(type, output, isOverlap); } } diff --git a/src/factory_resource_packer.cpp b/src/factory_resource_packer.cpp new file mode 100644 index 0000000..9204709 --- /dev/null +++ b/src/factory_resource_packer.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021-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 "factory_resource_packer.h" +#include "resource_overlap.h" + +namespace OHOS { +namespace Global { +namespace Restool { +using namespace std; + +unique_ptr FactoryResourcePacker::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; + return nullptr; + } +} +} +} +} \ No newline at end of file diff --git a/src/file_manager.cpp b/src/file_manager.cpp index 0db0edd..1141c35 100644 --- a/src/file_manager.cpp +++ b/src/file_manager.cpp @@ -42,21 +42,9 @@ uint32_t FileManager::ScanModules(const vector &inputs, const string &ou if (!noBaseResource.empty()) { ResourceUtil::PrintWarningMsg(noBaseResource); } - if (scanHap_) { - MarkItemsAsHap(); - } return isHar || scanHap_ ? RESTOOL_SUCCESS : ParseReference(output); } -void FileManager::MarkItemsAsHap() -{ - for (auto &item : items_) { - for (auto &resourceItem : item.second) { - resourceItem.MarkHapRes(); - } - } -} - uint32_t FileManager::MergeResourceItem(const map> &resourceInfos) { return ResourceModule::MergeResourceItem(items_, resourceInfos); diff --git a/src/generic_compiler.cpp b/src/generic_compiler.cpp index 9b4dea4..52056fa 100644 --- a/src/generic_compiler.cpp +++ b/src/generic_compiler.cpp @@ -25,8 +25,8 @@ namespace OHOS { namespace Global { namespace Restool { using namespace std; -GenericCompiler::GenericCompiler(ResType type, const string &output) - : IResourceCompiler(type, output) +GenericCompiler::GenericCompiler(ResType type, const string &output, bool isOverlap) + : IResourceCompiler(type, output, isOverlap) { } GenericCompiler::~GenericCompiler() @@ -87,6 +87,11 @@ bool GenericCompiler::PostMediaFile(const FileInfo &fileInfo, const std::string cerr << "Error: resource item set data fail, data: " << data << NEW_LINE_PATH << fileInfo.filePath << endl; return false; } + + if (isOverlap_) { + resourceItem.MarkCoverable(); + } + return MergeResourceItem(resourceItem); } @@ -99,19 +104,11 @@ string GenericCompiler::GetOutputFilePath(const FileInfo &fileInfo) const bool GenericCompiler::IsIgnore(const FileInfo &fileInfo) { - std::lock_guard lock(mutex_); + lock_guard lock(mutex_); string output = GetOutputFilePath(fileInfo); - bool resEmplaceSuccess = true; - if (hapRes_) { - g_hapResourceSet.emplace(output); - g_resourceSet.emplace(output); - } else if (g_hapResourceSet.count(output)) { + if (g_hapResourceSet.count(output)) { g_hapResourceSet.erase(output); - } else { - resEmplaceSuccess = g_resourceSet.emplace(output).second; - } - - if (!resEmplaceSuccess) { + } else if (!g_resourceSet.emplace(output).second) { cerr << "Warning: '" << fileInfo.filePath << "' is defined repeatedly." << endl; return true; } diff --git a/src/i_resource_compiler.cpp b/src/i_resource_compiler.cpp index 4984660..ac75925 100644 --- a/src/i_resource_compiler.cpp +++ b/src/i_resource_compiler.cpp @@ -25,8 +25,8 @@ namespace OHOS { namespace Global { namespace Restool { using namespace std; -IResourceCompiler::IResourceCompiler(ResType type, const string &output) - :type_(type), output_(output) +IResourceCompiler::IResourceCompiler(ResType type, const string &output, bool isOverlap) + :type_(type), output_(output), isOverlap_(isOverlap) { } @@ -104,11 +104,6 @@ const map, vector> &IResourceCompiler::GetRe return nameInfos_; } -void IResourceCompiler::SetHapRes(bool state) -{ - hapRes_ = state; -} - void IResourceCompiler::SetModuleName(const string &moduleName) { moduleName_ = moduleName; @@ -157,7 +152,6 @@ bool IResourceCompiler::MergeResourceItem(const ResourceItem &resourceItem) cerr << "but declare again." << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; return false; } - nameInfos_[make_pair(resourceItem.GetResType(), idName)].push_back(resourceItem); return true; } diff --git a/src/json_compiler.cpp b/src/json_compiler.cpp index c400815..046c266 100644 --- a/src/json_compiler.cpp +++ b/src/json_compiler.cpp @@ -31,8 +31,8 @@ const string TAG_QUANTITY = "quantity"; const vector QUANTITY_ATTRS = { "zero", "one", "two", "few", "many", "other" }; const vector TRANSLATION_TYPE = { "string", "strarray", "plural" }; -JsonCompiler::JsonCompiler(ResType type, const string &output) - : IResourceCompiler(type, output), isBaseString_(false), root_(nullptr) +JsonCompiler::JsonCompiler(ResType type, const string &output, bool isOverlap) + : IResourceCompiler(type, output, isOverlap), isBaseString_(false), root_(nullptr) { InitParser(); } @@ -157,6 +157,10 @@ bool JsonCompiler::ParseJsonObjectLevel(cJSON *objectNode, const FileInfo &fileI return false; } + if (isOverlap_) { + resourceItem.MarkCoverable(); + } + return MergeResourceItem(resourceItem); } diff --git a/src/overlap_binary_file_packer.cpp b/src/overlap_binary_file_packer.cpp new file mode 100644 index 0000000..e6f84e6 --- /dev/null +++ b/src/overlap_binary_file_packer.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021-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 "overlap_binary_file_packer.h" + +namespace OHOS { +namespace Global { +namespace Restool { +using namespace std; + +OverlapBinaryFilePacker::OverlapBinaryFilePacker(const PackageParser &packageParser, const std::string &moduleName) + : BinaryFilePacker(packageParser, moduleName) +{ +} + +uint32_t OverlapBinaryFilePacker::CopyBinaryFile(const vector &inputs) +{ + string hapPath = inputs[0]; + BinaryFilePacker::CopyBinaryFile(hapPath); + if (CheckCopyResults() != RESTOOL_SUCCESS) { + return RESTOOL_ERROR; + } + + vector resource(inputs.begin() + 1, inputs.end()); + BinaryFilePacker rawFilePacker(packageParser_, moduleName_); + std::future copyFuture = rawFilePacker.CopyBinaryFileAsync(resource); + if (copyFuture.get() != RESTOOL_SUCCESS) { + cerr << "Error: copy binary file failed." << endl; + return RESTOOL_ERROR; + } + return RESTOOL_SUCCESS; +} + +bool OverlapBinaryFilePacker::IsDuplicated(const unique_ptr &entry, string subPath) +{ + lock_guard lock(mutex_); + if (!g_hapResourceSet.emplace(subPath).second || !g_resourceSet.emplace(subPath).second) { + cerr << "Warning: '" << entry->GetFilePath().GetPath() << "' is defined repeatedly in hap." << endl; + return true; + } + return false; +} +} +} +} \ No newline at end of file diff --git a/src/overlap_compiler.cpp b/src/overlap_compiler.cpp new file mode 100644 index 0000000..6ed0c64 --- /dev/null +++ b/src/overlap_compiler.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021-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 "overlap_compiler.h" +#include + +namespace OHOS { +namespace Global { +namespace Restool { +using namespace std; + +OverlapCompiler::OverlapCompiler(ResType type, const std::string &output, bool isOverlap) + : GenericCompiler(type, output, isOverlap) +{ +} + +bool OverlapCompiler::IsIgnore(const FileInfo &fileInfo) +{ + lock_guard lock(mutex_); + string output = GetOutputFilePath(fileInfo); + if (!g_hapResourceSet.emplace(output).second || !g_resourceSet.emplace(output).second) { + cerr << "Warning: '" << fileInfo.filePath << "' is defined repeatedly." << endl; + return true; + } + return false; +} +} +} +} \ No newline at end of file diff --git a/src/resource_item.cpp b/src/resource_item.cpp index 0ce0b1b..f059c3a 100644 --- a/src/resource_item.cpp +++ b/src/resource_item.cpp @@ -85,9 +85,9 @@ void ResourceItem::SetName(const string &name) name_ = name; } -void ResourceItem::MarkHapRes() +void ResourceItem::MarkCoverable() { - hapRes_ = true; + coverable_ = true; } const int8_t *ResourceItem::GetData() const @@ -125,9 +125,9 @@ const string &ResourceItem::GetLimitKey() const return limitKey_; } -bool ResourceItem::IsHapRes() const +bool ResourceItem::IsCoverable() const { - return hapRes_; + return coverable_; } ResourceItem &ResourceItem::operator=(const ResourceItem &other) @@ -157,7 +157,7 @@ void ResourceItem::CopyFrom(const ResourceItem &other) dataLen_ = other.dataLen_; filePath_ = other.filePath_; limitKey_ = other.limitKey_; - hapRes_ = other.hapRes_; + coverable_ = other.coverable_; if (!SetData(other.data_, other.dataLen_)) { ReleaseData(); } diff --git a/src/resource_module.cpp b/src/resource_module.cpp index c86a264..796fddb 100644 --- a/src/resource_module.cpp +++ b/src/resource_module.cpp @@ -54,11 +54,8 @@ uint32_t ResourceModule::ScanResource(bool isHap) } unique_ptr resourceCompiler = - FactoryResourceCompiler::CreateCompiler(type, moduleOutput_); + FactoryResourceCompiler::CreateCompiler(type, moduleOutput_, isHap); resourceCompiler->SetModuleName(moduleName_); - if (isHap) { - resourceCompiler->SetHapRes(true); - } if (resourceCompiler->Compile(item->second) != RESTOOL_SUCCESS) { return RESTOOL_ERROR; } @@ -94,7 +91,7 @@ uint32_t ResourceModule::MergeResourceItem(map> &a result.first->second.push_back(resourceItem); continue; } - if (ret->IsHapRes()) { // overlap the hap resource by new resource + if (ret->IsCoverable()) { // overlap the hap resource by new resource *ret = resourceItem; continue; } diff --git a/src/resource_overlap.cpp b/src/resource_overlap.cpp new file mode 100644 index 0000000..108b2b2 --- /dev/null +++ b/src/resource_overlap.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2021-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 +#include "resource_overlap.h" +#include "overlap_binary_file_packer.h" +#include "file_manager.h" +#include "resource_table.h" +#include "id_worker.h" + +namespace OHOS { +namespace Global { +namespace Restool { +using namespace std; + +ResourceOverlap::ResourceOverlap(const PackageParser &packageParser) : ResourcePack(packageParser) +{ +} + +uint32_t ResourceOverlap::Pack() +{ + cout << "Info: Pack: overlap pack mode" << endl; + + if (InitResourcePack() != RESTOOL_SUCCESS) { + cerr << "Error: ResourcePack init failed." << endl; + return RESTOOL_ERROR; + } + + ResourceMerge resourceMerge; + if (resourceMerge.Init(packageParser_) != RESTOOL_SUCCESS) { + cerr << "Error: resourceMerge init failed." << endl; + return RESTOOL_ERROR; + } + + OverlapBinaryFilePacker rawFilePacker(packageParser_, moduleName_); + future copyFuture = rawFilePacker.CopyBinaryFileAsync(resourceMerge.GetInputs()); + + if (LoadHapResources() != RESTOOL_SUCCESS) { + rawFilePacker.StopCopy(); + cerr << "Error: load hap resources failed." << endl; + return RESTOOL_ERROR; + } + + if (PackResources(resourceMerge) != RESTOOL_SUCCESS) { + rawFilePacker.StopCopy(); + cerr << "Error: pack resources failed." << endl; + return RESTOOL_ERROR; + } + + if (copyFuture.get() != RESTOOL_SUCCESS) { + cerr << "Error: copy binary file failed." << endl; + return RESTOOL_ERROR; + } + return RESTOOL_SUCCESS; +} + +uint32_t ResourceOverlap::ScanResources(const std::vector &inputs, const std::string &output) +{ + auto &fileManager = FileManager::GetInstance(); + fileManager.SetModuleName(moduleName_); + vector hapResInput{inputs[0]}; + if (fileManager.ScanModules(hapResInput, output, configJson_.IsHar()) != RESTOOL_SUCCESS) { + cerr << "Error: scan hap error" << endl; + return RESTOOL_ERROR; + } + fileManager.SetScanHap(false); + + vector resInputs(inputs.begin() + 1, inputs.end()); + if (fileManager.ScanModules(resInputs, output, configJson_.IsHar()) != RESTOOL_SUCCESS) { + cerr << "Error: scan resources error" << endl; + return RESTOOL_ERROR; + } + return RESTOOL_SUCCESS; +} + +uint32_t ResourceOverlap::LoadHapResources() +{ + ResourceTable resourceTabel; + map> items; + string resourceIndexPath = + FileEntry::FilePath(packageParser_.GetInputs()[0]).GetParent().Append(RESOURCE_INDEX_FILE).GetPath(); + if (resourceTabel.LoadResTable(resourceIndexPath, items) != RESTOOL_SUCCESS) { + return RESTOOL_ERROR; + } + + IdWorker::GetInstance().LoadIdFromHap(items); + + FileManager &fileManager = FileManager::GetInstance(); + fileManager.SetModuleName(moduleName_); + if (fileManager.MergeResourceItem(items) != RESTOOL_SUCCESS) { + return RESTOOL_ERROR; + } + fileManager.SetScanHap(true); + return RESTOOL_SUCCESS; +} +} +} +} \ No newline at end of file diff --git a/src/resource_pack.cpp b/src/resource_pack.cpp index 8d3c123..f0260ec 100644 --- a/src/resource_pack.cpp +++ b/src/resource_pack.cpp @@ -24,6 +24,7 @@ #include "resource_table.h" #include "compression_parser.h" #include "binary_file_packer.h" +#include "factory_resource_packer.h" namespace OHOS { namespace Global { @@ -43,10 +44,13 @@ uint32_t ResourcePack::Package() return PackCombine(); } - if (packageParser_.ExistHapInput()) { + if (packageParser_.IsOverlap()) { packType_ = PackType::OVERLAP; } - return Pack(); + + unique_ptr resourcePacker = + FactoryResourcePacker::CreatePacker(packType_, packageParser_); + return resourcePacker->Pack(); } uint32_t ResourcePack::InitCompression() @@ -280,32 +284,15 @@ uint32_t ResourcePack::ScanResources(const vector &inputs, const string { auto &fileManager = FileManager::GetInstance(); fileManager.SetModuleName(moduleName_); - if (packType_ == PackType::OVERLAP) { - vector hapResInput{inputs[0]}; - if (fileManager.ScanModules(hapResInput, output, configJson_.IsHar()) != RESTOOL_SUCCESS) { - return RESTOOL_ERROR; - } - fileManager.SetScanHap(false); - - vector resInputs(inputs.begin() + 1, inputs.end()); - if (fileManager.ScanModules(resInputs, output, configJson_.IsHar()) != RESTOOL_SUCCESS) { - return RESTOOL_ERROR; - } - } else { - if (fileManager.ScanModules(inputs, output, configJson_.IsHar()) != RESTOOL_SUCCESS) { - return RESTOOL_ERROR; - } + if (fileManager.ScanModules(inputs, output, configJson_.IsHar()) != RESTOOL_SUCCESS) { + return RESTOOL_ERROR; } return RESTOOL_SUCCESS; } uint32_t ResourcePack::Pack() { - if (packType_ == PackType::NORMAL) { - cout << "Info: Pack: normal pack mode" << endl; - } else if (packType_ == PackType::OVERLAP) { - cout << "Info: Pack: overlap pack mode" << endl; - } + cout << "Info: Pack: normal pack mode" << endl; if (InitResourcePack() != RESTOOL_SUCCESS) { cerr << "Error: ResourcePack init failed." << endl; @@ -319,9 +306,6 @@ uint32_t ResourcePack::Pack() } BinaryFilePacker rawFilePacker(packageParser_, moduleName_); - if (packType_ == PackType::OVERLAP) { - rawFilePacker.SetCopyHap(true); - } std::future copyFuture = rawFilePacker.CopyBinaryFileAsync(resourceMerge.GetInputs()); if (PackResources(resourceMerge) != RESTOOL_SUCCESS) { @@ -339,10 +323,6 @@ uint32_t ResourcePack::Pack() uint32_t ResourcePack::PackResources(const ResourceMerge &resourceMerge) { - if (packType_ == PackType::OVERLAP && LoadHapResources() != RESTOOL_SUCCESS) { - return RESTOOL_ERROR; - } - if (ScanResources(resourceMerge.GetInputs(), packageParser_.GetOutput()) != RESTOOL_SUCCESS) { return RESTOOL_ERROR; } @@ -379,28 +359,6 @@ uint32_t ResourcePack::PackResources(const ResourceMerge &resourceMerge) return RESTOOL_SUCCESS; } -uint32_t ResourcePack::LoadHapResources() -{ - ResourceTable resourceTabel; - map> items; - string resourceIndexPath = - FileEntry::FilePath(packageParser_.GetInputs()[0]).GetParent().Append(RESOURCE_INDEX_FILE).GetPath(); - if (resourceTabel.LoadResTable(resourceIndexPath, items) != RESTOOL_SUCCESS) { - return RESTOOL_ERROR; - } - - IdWorker::GetInstance().LoadIdFromHap(items); - - FileManager &fileManager = FileManager::GetInstance(); - fileManager.SetModuleName(moduleName_); - if (fileManager.MergeResourceItem(items) != RESTOOL_SUCCESS) { - return RESTOOL_ERROR; - } - fileManager.MarkItemsAsHap(); - fileManager.SetScanHap(true); - return RESTOOL_SUCCESS; -} - uint32_t ResourcePack::HandleFeature() { string output = packageParser_.GetOutput(); @@ -620,7 +578,6 @@ void ResourcePack::CheckConfigJsonForCombine(ResourceAppend &resourceAppend) ResourceCheck resourceCheck(configJson_.GetCheckNode(), make_shared(resourceAppend)); resourceCheck.CheckConfigJsonForCombine(); } - } } } diff --git a/src/resource_table.cpp b/src/resource_table.cpp index 54dd4fb..24ae7af 100644 --- a/src/resource_table.cpp +++ b/src/resource_table.cpp @@ -111,6 +111,7 @@ uint32_t ResourceTable::LoadResTable(const string path, map