mirror of
https://github.com/openharmony/developtools_global_resource_tool.git
synced 2026-07-20 22:47:00 -04:00
@@ -0,0 +1,37 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
project(restool)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
if (WIN32)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-static -s")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -fstack-protector -DLIBXML_STATIC -Wno-attributes")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -fstack-protector -Wno-attributes")
|
||||
elseif (APPLE)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-fPIE -pie -static-libgcc -static-libstdc++")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -fstack-protector -O2 -g -Wall")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -fstack-protector")
|
||||
else()
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-Wl,-z,relro,-z,now -fPIE -pie -Wl,-z,noexecstack -s -static-libgcc -static-libstdc++")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -fstack-protector -O2 -g -Wall")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -fstack-protector")
|
||||
endif()
|
||||
|
||||
set(jsoncpp_dir ${CMAKE_SOURCE_DIR}/../../third_party/jsoncpp)
|
||||
set(bound_checking_function_dir ${CMAKE_SOURCE_DIR}/../../third_party/bounds_checking_function)
|
||||
set(libxml2_dir ${CMAKE_SOURCE_DIR}/../../third_party/libxml2)
|
||||
set(sqlite3_dir ${CMAKE_SOURCE_DIR}/../../third_party/sqlite)
|
||||
include_directories(include)
|
||||
include_directories(${jsoncpp_dir}/include)
|
||||
include_directories(${bound_checking_function_dir}/include)
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/third_party/libxml2/libxml2/include)
|
||||
include_directories(${sqlite3_dir}/include)
|
||||
|
||||
aux_source_directory(src restool_source)
|
||||
aux_source_directory(src/xml restool_source)
|
||||
|
||||
add_executable(restool ${restool_source})
|
||||
target_link_libraries(restool myxml2 jsoncpp securec sqlite3)
|
||||
|
||||
add_subdirectory(third_party/libxml2)
|
||||
add_subdirectory(third_party/jsoncpp)
|
||||
add_subdirectory(third_party/bounds_checking_function)
|
||||
add_subdirectory(third_party/sqlite3)
|
||||
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
||||
+17
-8
@@ -1,22 +1,31 @@
|
||||
# global_resource_tool
|
||||
|
||||
#### Description
|
||||
{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**}
|
||||
OpenHarmony resource compile tool
|
||||
|
||||
#### Software Architecture
|
||||
Software architecture description
|
||||
>developtools/
|
||||
>>----global_resource_tool
|
||||
>>>----include
|
||||
>>>----src
|
||||
>>>----third_party denpence third patry lib make script
|
||||
>>>----CMakeLists.txt
|
||||
>>>----win32.cmake windows cross compile script
|
||||
|
||||
#### Installation
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
1. gcc/g++ version 9.3.0
|
||||
2. cmake version mini 3.15
|
||||
3. mkdir build
|
||||
4. cd build
|
||||
5. cmake ../restool_standard
|
||||
6. make
|
||||
7. compile result restool binary
|
||||
|
||||
#### Instructions
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
1. restool -v show version.
|
||||
2. restool show help.
|
||||
|
||||
#### Contribution
|
||||
|
||||
|
||||
@@ -1,25 +1,32 @@
|
||||
# global_resource_tool
|
||||
|
||||
#### 介绍
|
||||
{**以下是 Gitee 平台说明,您可以替换此简介**
|
||||
Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台
|
||||
无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
|
||||
OpenHarmony 资源编译编译工具
|
||||
|
||||
#### 软件架构
|
||||
软件架构说明
|
||||
>developtools/
|
||||
>>----global_resource_tool
|
||||
>>>----include
|
||||
>>>----src
|
||||
>>>----third_party 依赖三方库编译脚本
|
||||
>>>----CMakeLists.txt
|
||||
>>>----win32.cmake windows交叉编译脚本
|
||||
|
||||
|
||||
#### 安装教程
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
1. 编译环境gcc/g++ 9.3.0
|
||||
2. cmake 版本最低3.15
|
||||
3. 与global_resource_tool同级目录新建build
|
||||
4. cd build
|
||||
5. cmake ../global_resource_tool
|
||||
6. make
|
||||
7. 编译结果输出restool
|
||||
|
||||
#### 使用说明
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
1. restool -v 显示版本信息
|
||||
2. restool 显示帮助信息
|
||||
|
||||
#### 参与贡献
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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_CMD_LIST_H
|
||||
#define OHOS_RESTOOL_CMD_LIST_H
|
||||
|
||||
#include<functional>
|
||||
#include<string>
|
||||
#include "resource_util.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class CmdList {
|
||||
public:
|
||||
CmdList() {};
|
||||
virtual ~CmdList() {};
|
||||
using HandleBack = std::function<uint32_t(int c, const std::string &argValue)>;
|
||||
uint32_t Init(const std::string &filePath, HandleBack callback);
|
||||
private:
|
||||
uint32_t GetString(const Json::Value &node, int c, HandleBack callback);
|
||||
uint32_t GetArray(const Json::Value &node, int c, HandleBack callback);
|
||||
uint32_t GetModuleNames(const Json::Value &node, HandleBack callback);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_CMD_PARSER_H
|
||||
#define OHOS_RESTOOL_CMD_PARSER_H
|
||||
|
||||
#include<getopt.h>
|
||||
#include<iostream>
|
||||
#include<functional>
|
||||
#include<vector>
|
||||
#include "singleton_object.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() {};
|
||||
~PackageParser() = default;
|
||||
uint32_t Parse(int argc, char *argv[]) override;
|
||||
const std::vector<std::string> &GetInputs() const;
|
||||
const std::string &GetPackageName() const;
|
||||
const std::string &GetOutput() const;
|
||||
const std::vector<std::string> &GetResourceHeaders() const;
|
||||
bool GetForceWrite() const;
|
||||
const std::vector<std::string> &GetModuleNames() const;
|
||||
const std::string &GetConfig() const;
|
||||
const std::string &GetRestoolPath() const;
|
||||
int32_t GetStartId() const;
|
||||
const std::string &GetCachePath() const;
|
||||
bool IsFileList() const;
|
||||
bool GetPreviewMode() const;
|
||||
int32_t GetPriority() const;
|
||||
|
||||
private:
|
||||
void InitCommand();
|
||||
uint32_t ParseCommand(int argc, char *argv[]);
|
||||
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);
|
||||
uint32_t AddCachePath(const std::string& argValue);
|
||||
uint32_t CheckParam() const;
|
||||
uint32_t HandleProcess(int c, const std::string& argValue);
|
||||
uint32_t ParseFileList(const std::string& fileListPath);
|
||||
uint32_t SetPreviewMode();
|
||||
uint32_t SetPriority(const std::string& argValue);
|
||||
|
||||
static const struct option CMD_OPTS[];
|
||||
static const std::string CMD_PARAMS;
|
||||
using HandleArgValue = std::function<uint32_t(const std::string&)>;
|
||||
std::map<int32_t, HandleArgValue> handles_;
|
||||
std::vector<std::string> inputs_;
|
||||
std::string packageName_;
|
||||
std::string output_;
|
||||
std::vector<std::string> resourceHeaderPaths_;
|
||||
bool forceWrite_ = false;
|
||||
std::vector<std::string> moduleNames_;
|
||||
std::string configPath_;
|
||||
std::string restoolPath_;
|
||||
int32_t startId_ = 0;
|
||||
std::string cachePath_;
|
||||
bool isFileList_ = false;
|
||||
bool previewMode_ = false;
|
||||
int32_t priority_ = -1;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class CmdParser : public Singleton<CmdParser<T>> {
|
||||
public:
|
||||
T &GetCmdParser();
|
||||
uint32_t Parse(int argc, char *argv[]);
|
||||
static void ShowUseage();
|
||||
|
||||
private:
|
||||
T cmdParser_;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
void CmdParser<T>::ShowUseage()
|
||||
{
|
||||
std::cout << "This is an OHOS Packaging Tool.\n";
|
||||
std::cout << "Useage:\n";
|
||||
std::cout << TOOL_NAME << " [arguments] Package the OHOS resources.\n";
|
||||
std::cout << "[arguments]:\n";
|
||||
std::cout << " -i input resource path, can add more.\n";
|
||||
std::cout << " -p package name.\n";
|
||||
std::cout << " -o output path.\n";
|
||||
std::cout << " -r resource header file path(like ./ResourceTable.js, ./ResrouceTable.h).\n";
|
||||
std::cout << " -f if output path exists,force delete it.\n";
|
||||
std::cout << " -v print tool version.\n";
|
||||
std::cout << " -m module name, can add more, split by ','(like entry1,entry2,...).\n";
|
||||
std::cout << " -j config.json path.\n";
|
||||
std::cout << " -e start id mask, e.g 0x01000000, in [0x01000000, 0x06FFFFFF),[0x08000000, 0x41FFFFFF)\n";
|
||||
std::cout << " -c increment compile cache directory path.\n";
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T &CmdParser<T>::GetCmdParser()
|
||||
{
|
||||
return cmdParser_;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
uint32_t CmdParser<T>::Parse(int argc, char *argv[])
|
||||
{
|
||||
if (cmdParser_.Parse(argc, argv) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_CONFIG_PARSER_H
|
||||
#define OHOS_RESTOOL_CONFIG_PARSER_H
|
||||
|
||||
#include<functional>
|
||||
#include "resource_util.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class ConfigParser {
|
||||
public:
|
||||
enum class ModuleType {
|
||||
NONE = 0,
|
||||
HAR = 1,
|
||||
ENTRY = 2,
|
||||
FEATURE = 3,
|
||||
};
|
||||
|
||||
ConfigParser();
|
||||
explicit ConfigParser(const std::string &filePath);
|
||||
virtual ~ConfigParser();
|
||||
uint32_t Init();
|
||||
const std::string &GetPackageName() const;
|
||||
const std::string &GetModuleName() const;
|
||||
ModuleType GetModuleType() const;
|
||||
uint32_t ParseRefence();
|
||||
uint32_t Save(const std::string &filePath) const;
|
||||
static void SetUseModule() { useModule_ = true; };
|
||||
static std::string GetConfigName() { return useModule_ ? MODULE_JSON : CONFIG_JSON; };
|
||||
private:
|
||||
bool ParseModule(Json::Value &moduleNode);
|
||||
bool ParseDistro(Json::Value &distroNode);
|
||||
bool ParseRefImpl(Json::Value &parent, const std::string &key, Json::Value &node);
|
||||
bool ParseJsonArrayRef(Json::Value &parent, const std::string &key, Json::Value &node);
|
||||
bool ParseJsonStringRef(Json::Value &parent, const std::string &key, Json::Value &node);
|
||||
bool GetRefIdFromString(std::string &value, bool &update, const std::string &match) const;
|
||||
bool ParseModuleType(const std::string &type);
|
||||
std::string filePath_;
|
||||
std::string packageName_;
|
||||
std::string moduleName_;
|
||||
ModuleType moduleType_;
|
||||
Json::Value rootNode_;
|
||||
static const std::map<std::string, ModuleType> MODULE_TYPES;
|
||||
static const std::map<std::string, std::string> JSON_STRING_IDS;
|
||||
static const std::map<std::string, std::string> JSON_ARRAY_IDS;
|
||||
static bool useModule_;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_COMPILER_H
|
||||
#define OHOS_RESTOOL_FACTORY_RESOURCE_COMPILER_H
|
||||
|
||||
#include<memory>
|
||||
#include "i_resource_compiler.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class FactoryResourceCompiler {
|
||||
public:
|
||||
static std::unique_ptr<IResourceCompiler> CreateCompiler(ResType type, const std::string &output);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_FILE_MANAGER_H
|
||||
#define OHOS_RESTOOL_FILE_MANAGER_H
|
||||
|
||||
#include<vector>
|
||||
#include "resource_data.h"
|
||||
#include "resource_item.h"
|
||||
#include "increment_manager.h"
|
||||
#include "singleton_object.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class FileManager : public Singleton<FileManager> {
|
||||
public:
|
||||
uint32_t ScanModules(const std::vector<std::string> &inputs, const std::string &output);
|
||||
const std::map<int32_t, std::vector<ResourceItem>> &GetResources() const { return alls_; };
|
||||
void SetModuleName(const std::string &moduleName) { moduleName_ = moduleName; };
|
||||
uint32_t ScanIncrement(const std::string &output);
|
||||
|
||||
private:
|
||||
uint32_t ScanModule(const std::string &input, const std::string &output,
|
||||
std::map<ResType, std::vector<DirectoryInfo>> &resTypeOfDirs);
|
||||
uint32_t MergeResourceItem(const std::map<int32_t, std::vector<ResourceItem>> &resourceInfos);
|
||||
uint32_t ParseReference(const std::string &output, const std::vector<std::string> &sxmlFolders);
|
||||
bool NeedParseReferenceInSolidXml(ResType resType) const;
|
||||
void FilterRefSolidXml(const std::string &output, std::vector<std::string> &outputPaths,
|
||||
const std::map<ResType, std::vector<DirectoryInfo>> &resTypeOfDirs) const;
|
||||
|
||||
// id, resource items
|
||||
std::map<int32_t, std::vector<ResourceItem>> alls_;
|
||||
std::string moduleName_;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_GENERIC_COMPILER_H
|
||||
#define OHOS_RESTOOL_GENERIC_COMPILER_H
|
||||
|
||||
#include "i_resource_compiler.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class GenericCompiler : public IResourceCompiler {
|
||||
public:
|
||||
GenericCompiler(ResType type, const std::string &output);
|
||||
virtual ~GenericCompiler();
|
||||
protected:
|
||||
uint32_t CompileSingleFile(const FileInfo &fileInfo) override;
|
||||
bool PostFile(const FileInfo &fileInfo);
|
||||
private:
|
||||
std::string GetOutputFilePath(const FileInfo &fileInfo) const;
|
||||
bool IsIgnore(const FileInfo &fileInfo) const;
|
||||
bool CopyFile(const FileInfo &fileInfo) const;
|
||||
bool IsConvertToSolidXml(const FileInfo &fileInfo) const;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_HEADER_H
|
||||
#define OHOS_RESTOOL_HEADER_H
|
||||
|
||||
#include<functional>
|
||||
#include<sstream>
|
||||
#include<string>
|
||||
#include "id_worker.h"
|
||||
#include "restool_errors.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class Header {
|
||||
public:
|
||||
static const std::string LICENSE_HEADER;
|
||||
Header(const std::string &outputPath);
|
||||
virtual ~Header();
|
||||
using HandleHeaderTail = std::function<void(std::stringstream&)>;
|
||||
using HandleBody = std::function<void(std::stringstream&, const IdWorker::ResourceId&)>;
|
||||
uint32_t Create(HandleHeaderTail headerHandler, HandleBody bodyHander, HandleHeaderTail tailHander) const;
|
||||
private:
|
||||
const std::string &outputPath_;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_COMPILER_H
|
||||
#define OHOS_RESTOOL_RESOURCE_COMPILER_H
|
||||
|
||||
#include<vector>
|
||||
#include "increment_manager.h"
|
||||
#include "resource_data.h"
|
||||
#include "resource_item.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class IResourceCompiler {
|
||||
public:
|
||||
IResourceCompiler(ResType type, const std::string &output);
|
||||
virtual ~IResourceCompiler();
|
||||
uint32_t Compile(const std::vector<DirectoryInfo> &directoryInfos);
|
||||
const std::map<int32_t, std::vector<ResourceItem>> &GetResult() const;
|
||||
uint32_t Compile(const FileInfo &fileInfo);
|
||||
void SetModuleName(const std::string &moduleName);
|
||||
void SetPreviewMode(bool enable) { previewMode_ = enable; };
|
||||
|
||||
protected:
|
||||
virtual uint32_t CompileSingleFile(const FileInfo &fileInfo);
|
||||
bool MergeResourceItem(const ResourceItem &resourceItem);
|
||||
bool IsXmlFile(const FileInfo &fileInfo) const;
|
||||
bool HasConvertedToSolidXml(const FileInfo &fileInfo) const;
|
||||
bool NeedIfConvertToSolidXml() const;
|
||||
std::string GetOutputFolder(const DirectoryInfo &directoryInfo) const;
|
||||
ResType type_;
|
||||
std::string output_;
|
||||
std::string moduleName_;
|
||||
bool previewMode_ = false;
|
||||
|
||||
// id, resource items
|
||||
std::map<int32_t, std::vector<ResourceItem>> resourceInfos_;
|
||||
// ResType, name, resourceItems
|
||||
std::map<std::pair<ResType, std::string>, std::vector<ResourceItem>> nameInfos_;
|
||||
|
||||
private:
|
||||
uint32_t ConvertToSolidXml(const std::map<std::string, std::vector<FileInfo>> &setsByDirectory);
|
||||
uint32_t PostCommit();
|
||||
void ListXmlFile(const std::vector<FileInfo> &fileInfo, std::vector<std::string> &xmlPaths) const;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_ID_WORKER_H
|
||||
#define OHOS_RESTOOL_ID_WORKER_H
|
||||
|
||||
#include<functional>
|
||||
#include<vector>
|
||||
#include "singleton_object.h"
|
||||
#include "resource_data.h"
|
||||
#include "resource_util.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class IdWorker : public Singleton<IdWorker> {
|
||||
public:
|
||||
enum class ResourceIdCluster {
|
||||
RES_ID_APP = 0,
|
||||
RES_ID_SYS,
|
||||
RES_ID_TYPE_MAX,
|
||||
};
|
||||
|
||||
struct ResourceId {
|
||||
int32_t id;
|
||||
int32_t seq;
|
||||
std::string type;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
uint32_t Init(ResourceIdCluster type, int32_t start = 0x01000000);
|
||||
int32_t GenerateId(ResType resType, const std::string &name);
|
||||
std::vector<ResourceId> GetHeaderId() const;
|
||||
int32_t GetId(ResType resType, const std::string &name) const;
|
||||
int32_t GetSystemId(ResType resType, const std::string &name) const;
|
||||
bool IsValidName(const std::string &name) const;
|
||||
bool PushCache(ResType resType, const std::string &name, int32_t id);
|
||||
void PushDelId(int32_t id);
|
||||
|
||||
private:
|
||||
int32_t GenerateAppId(ResType resType, const std::string &name);
|
||||
int32_t GenerateSysId(ResType resType, const std::string &name);
|
||||
uint32_t InitIdDefined();
|
||||
uint32_t InitIdDefined(const std::string &filePath);
|
||||
using ParseFunction = std::function<bool(const Json::Value&, ResourceId&)>;
|
||||
void InitParser();
|
||||
bool ParseType(const Json::Value &type, ResourceId &resourceId);
|
||||
bool ParseName(const Json::Value &name, ResourceId &resourceId);
|
||||
bool ParseOrder(const Json::Value &order, ResourceId &resourceId);
|
||||
bool PushResourceId(const ResourceId &resourceId);
|
||||
bool IsValidSystemName(const std::string &name) const;
|
||||
int32_t GetStartId(const Json::Value &root) const;
|
||||
int32_t GetMaxId(int32_t startId) const;
|
||||
int32_t appId_;
|
||||
int32_t maxId_;
|
||||
ResourceIdCluster type_;
|
||||
std::map<std::pair<ResType, std::string>, int32_t> ids_;
|
||||
std::map<std::pair<ResType, std::string>, ResourceId> definedIds_;
|
||||
std::map<std::string, ParseFunction> handles_;
|
||||
std::vector<int32_t> delIds_;
|
||||
std::map<std::pair<ResType, std::string>, int32_t> cacheIds_;
|
||||
static const int32_t START_SYS_ID;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_INCREMENT_INDEX_H
|
||||
#define OHOS_RESTOOL_INCREMENT_INDEX_H
|
||||
|
||||
#include "resource_item.h"
|
||||
#include "resource_util.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class IncrementIndex {
|
||||
public:
|
||||
IncrementIndex(const std::string &indexPath, const std::vector<std::string> &folder);
|
||||
virtual ~IncrementIndex() {};
|
||||
bool Save(const std::map<int32_t, std::vector<ResourceItem>> &items) const;
|
||||
bool Load(std::map<int32_t, std::vector<ResourceItem>> &items) const;
|
||||
void SetSkipPaths(const std::vector<std::string> &skipPaths);
|
||||
|
||||
static const std::string INDEX_FILE;
|
||||
private:
|
||||
bool LoadIndex(const Json::Value &indexInfo, std::map<int32_t, std::vector<ResourceItem>> &items) const;
|
||||
bool ParseResourceItem(const Json::Value &item, const std::string &filePath, ResourceItem &resourceItem) const;
|
||||
bool GetResourceItemProp(const Json::Value &item, const std::string &key, std::string &value) const;
|
||||
bool PushResourceItem(const ResourceItem &resourceItem, int32_t id,
|
||||
std::map<int32_t, std::vector<ResourceItem>> &items) const;
|
||||
bool IsIgnore(const std::string &filePath) const;
|
||||
const std::string &indexPath_;
|
||||
const std::vector<std::string> &folder_;
|
||||
std::vector<std::string> skipPaths_;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_INCREMENT_LIST_H
|
||||
#define OHOS_RESTOOL_INCREMENT_LIST_H
|
||||
|
||||
#include<functional>
|
||||
#include<vector>
|
||||
#include "resource_data.h"
|
||||
#include "resource_util.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class IncrementList {
|
||||
public:
|
||||
struct FileIncrement : FileInfo {
|
||||
bool isDeleted;
|
||||
std::string rootPath;
|
||||
std::string relativePath;
|
||||
};
|
||||
IncrementList(const std::string &listPath, const std::vector<std::string> &folder);
|
||||
virtual ~IncrementList() {};
|
||||
bool Parse(std::vector<FileIncrement> &fileList) const;
|
||||
|
||||
static const std::string RESTOOL_LIST_FILE;
|
||||
private:
|
||||
bool GetFromPath(const std::string &filePath, FileIncrement &info) const;
|
||||
int32_t GetPriority(const std::string &filePath) const;
|
||||
bool ParseSegment(const std::string &filePath, std::vector<std::string> &segments) const;
|
||||
bool IteratorArray(const Json::Value &array, std::function<bool(const std::string &)> callback) const;
|
||||
bool ParseArray(const Json::Value &array, std::vector<FileIncrement> &fileList, bool isDeleted) const;
|
||||
const std::string &listPath_;
|
||||
const std::vector<std::string> &folder_;
|
||||
enum PathSegment {
|
||||
SEG_RESOURCE = 0,
|
||||
SEG_LIMIT_KEY = 1,
|
||||
SEG_FILE_CLUSTER = 2,
|
||||
SEG_FILE_NAME =3,
|
||||
SEG_MAX
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_INCREMENT_MANAGER_H
|
||||
#define OHOS_RESTOOL_INCREMENT_MANAGER_H
|
||||
|
||||
#include<string>
|
||||
#include "resource_util.h"
|
||||
#include "resource_item.h"
|
||||
#include "singleton_object.h"
|
||||
|
||||
#include "increment_list.h"
|
||||
#include "increment_index.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class IncrementManager : public Singleton<IncrementManager> {
|
||||
public:
|
||||
struct FileIncrement : FileInfo {
|
||||
std::string extension;
|
||||
std::string relativePath;
|
||||
std::string inputPath;
|
||||
int32_t priority;
|
||||
};
|
||||
|
||||
struct ModuleInfo {
|
||||
std::string rootPath;
|
||||
std::vector<IncrementList::FileIncrement> fileIncrements;
|
||||
};
|
||||
|
||||
virtual ~IncrementManager();
|
||||
uint32_t Init(const std::string &cachePath, const std::vector<std::string> &folder,
|
||||
const std::string &outputPath, const std::string &moduleName);
|
||||
const std::map<int32_t, std::vector<ResourceItem>> &GetResourceItems() const { return items_; };
|
||||
const std::map<ResType, std::vector<DirectoryInfo>> &GetScanDirs() const { return scanDirs_; };
|
||||
bool FirstIncrement() const { return firstIncrement_; };
|
||||
bool Enable() const { return enalbe_; };
|
||||
|
||||
static const std::string ID_JSON_FILE;
|
||||
private:
|
||||
bool InitIdJson();
|
||||
bool InitList(std::vector<IncrementList::FileIncrement> &dels) const;
|
||||
bool ScanModules(const std::vector<IncrementList::FileIncrement> &dels);
|
||||
void FlushId();
|
||||
bool SaveIdJson() const;
|
||||
bool LoadIdJson();
|
||||
void PushScanDir(const std::map<ResType, std::vector<DirectoryInfo>> &scanDirs);
|
||||
void DeleteRawFile(std::vector<IncrementList::FileIncrement> &dels) const;
|
||||
bool ClearSolidXml() const;
|
||||
std::string cachePath_;
|
||||
std::vector<std::string> folder_;
|
||||
std::string outputPath_;
|
||||
std::string moduleName_;
|
||||
std::map<int32_t, std::vector<ResourceItem>> items_;
|
||||
std::map<ResType, std::vector<DirectoryInfo>> scanDirs_;
|
||||
bool enalbe_ = false;
|
||||
bool firstIncrement_ = true;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_JSON_COMPILER_H
|
||||
#define OHOS_RESTOOL_JSON_COMPILER_H
|
||||
|
||||
#include <functional>
|
||||
#include "i_resource_compiler.h"
|
||||
#include "resource_util.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class JsonCompiler : public IResourceCompiler {
|
||||
public:
|
||||
JsonCompiler(ResType type, const std::string &output);
|
||||
virtual ~JsonCompiler();
|
||||
protected:
|
||||
uint32_t CompileSingleFile(const FileInfo &fileInfo) override;
|
||||
private:
|
||||
void InitParser();
|
||||
bool ParseJsonArrayLevel(const Json::Value &arrayNode, const FileInfo &fileInfo);
|
||||
bool ParseJsonObjectLevel(const Json::Value &objectNode, const FileInfo &fileInfo);
|
||||
|
||||
using HandleResource = std::function<bool(const Json::Value&, ResourceItem&)>;
|
||||
bool HandleString(const Json::Value &objectNode, ResourceItem &resourceItem) const;
|
||||
bool HandleInteger(const Json::Value &objectNode, ResourceItem &resourceItem) const;
|
||||
bool HandleBoolean(const Json::Value &objectNode, ResourceItem &resourceItem) const;
|
||||
bool HandleColor(const Json::Value &objectNode, ResourceItem &resourceItem) const;
|
||||
bool HandleFloat(const Json::Value &objectNode, ResourceItem &resourceItem) const;
|
||||
bool HandleStringArray(const Json::Value &objectNode, ResourceItem &resourceItem) const;
|
||||
bool HandleIntegerArray(const Json::Value &objectNode, ResourceItem &resourceItem) const;
|
||||
bool HandleTheme(const Json::Value &objectNode, ResourceItem &resourceItem) const;
|
||||
bool HandlePattern(const Json::Value &objectNode, ResourceItem &resourceItem) const;
|
||||
bool HandlePlural(const Json::Value &objectNode, ResourceItem &resourceItem) const;
|
||||
|
||||
bool PushString(const std::string &value, ResourceItem &resourceItem) const;
|
||||
bool CheckJsonStringValue(const Json::Value &valueNode, const ResourceItem &resourceItem) const;
|
||||
bool CheckJsonIntegerValue(const Json::Value &valueNode, const ResourceItem &resourceItem) const;
|
||||
using HandleValue = std::function<bool(const Json::Value&, const ResourceItem&, std::vector<std::string>&)>;
|
||||
bool ParseValueArray(const Json::Value &objectNode, ResourceItem &resourceItem,
|
||||
const std::vector<std::string> &extra, HandleValue callback) const;
|
||||
bool ParseParent(const Json::Value &objectNode, const ResourceItem &resourceItem,
|
||||
std::vector<std::string> &extra) const;
|
||||
bool ParseAttribute(const Json::Value &arrayItem, const ResourceItem &resourceItem,
|
||||
std::vector<std::string> &values) const;
|
||||
bool CheckPluralValue(const Json::Value &arrayItem, const ResourceItem &resourceItem) const;
|
||||
std::map<ResType, HandleResource> handles_;
|
||||
static const std::string TAG_NAME;
|
||||
static const std::string TAG_VALUE;
|
||||
static const std::string TAG_PARENT;
|
||||
static const std::string TAG_QUANTITY;
|
||||
static const std::vector<std::string> QUANTITY_ATTRS;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_KEY_MANAGER_H
|
||||
#define OHOS_RESTOOL_KEY_MANAGER_H
|
||||
|
||||
#include<memory>
|
||||
#include "xml_key_node.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class KeyManager {
|
||||
public:
|
||||
KeyManager();
|
||||
virtual ~KeyManager() {};
|
||||
bool LoadKey(const std::string &keysPath);
|
||||
bool SaveKey(const std::string &keysPath);
|
||||
std::map<XmlKeyNode::KeyType, std::shared_ptr<XmlKeyNode>> &GetKeys() { return keys_; };
|
||||
private:
|
||||
std::map<XmlKeyNode::KeyType, std::shared_ptr<XmlKeyNode>> keys_;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_KEY_PARSER_H
|
||||
#define OHOS_RESTOOL_KEY_PARSER_H
|
||||
|
||||
#include<vector>
|
||||
#include "resource_data.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class KeyParser {
|
||||
public:
|
||||
static bool Parse(const std::string &folderName, std::vector<KeyParam> &keyparams);
|
||||
|
||||
private:
|
||||
typedef bool (*parse_key_founction)(const std::string &folderName, std::vector<KeyParam> &keyparams);
|
||||
static bool ParseMatch(const std::vector<std::string> &keys, std::vector<KeyParam> &keyparams, const std::vector<parse_key_founction> &founctions);
|
||||
static bool ParseMatchBySeq(const std::vector<std::string> &keys, std::vector<KeyParam> &keyparams, const std::vector<parse_key_founction> &founctions);
|
||||
|
||||
static bool ParseMccMnc(const std::string &folderName, std::vector<KeyParam> &keyparams);
|
||||
static bool ParseMcc(const std::string &folderName, std::vector<KeyParam> &keyparams);
|
||||
static bool ParseMnc(const std::string &folderName, std::vector<KeyParam> &keyparams);
|
||||
static bool ParseLSR(const std::string &folderName, std::vector<KeyParam> &keyparams);
|
||||
static bool ParseLanguage(const std::string &folderName, std::vector<KeyParam> &keyparams);
|
||||
static bool ParseScript(const std::string &folderName, std::vector<KeyParam> &keyparams);
|
||||
static bool ParseRegion(const std::string &folderName, std::vector<KeyParam> &keyparams);
|
||||
static bool ParseOrientation(const std::string &folderName, std::vector<KeyParam> &keyparams);
|
||||
static bool ParseDeviceType(const std::string &folderName, std::vector<KeyParam> &keyparams);
|
||||
static bool ParseNightMode(const std::string &folderName, std::vector<KeyParam> &keyparams);
|
||||
static bool ParseResolution(const std::string &folderName, std::vector<KeyParam> &keyparams);
|
||||
|
||||
static void PushMccMnc(const std::string &folderName, KeyType type, std::vector<KeyParam> &keyparams);
|
||||
static void PushLSR(const std::string &folderName, KeyType type, std::vector<KeyParam> &keyparams);
|
||||
static void PushValue(uint32_t value, KeyType type, std::vector<KeyParam> &keyparams);
|
||||
static const int32_t MCC_MNC_KEY_LENGHT = 3;
|
||||
static const int32_t SCRIPT_LENGHT = 4;
|
||||
static const int32_t MIN_REGION_LENGHT = 2;
|
||||
static const int32_t MAX_REGION_LENGHT = 3;
|
||||
static std::map<std::string, std::vector<KeyParam>> caches_;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_FILE_COMBINE_H
|
||||
#define OHOS_RESTOOL_FILE_COMBINE_H
|
||||
|
||||
#include "resource_directory.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class ModuleCombine {
|
||||
public:
|
||||
ModuleCombine(const std::string &modulePath, const std::string &outputPath);
|
||||
virtual ~ModuleCombine() {};
|
||||
bool Combine();
|
||||
|
||||
private:
|
||||
bool CombineDirectory(const DirectoryInfo &directoryInfo);
|
||||
bool CombineSolidXml(const std::string &src, const std::string &dst,
|
||||
const std::map<std::string , std::string> &sxmlPaths);
|
||||
const std::string &modulePath_;
|
||||
const std::string &outputPath_;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_NOCOPYABLE_OBJECT_H
|
||||
#define OHOS_RESTOOL_NOCOPYABLE_OBJECT_H
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
#define DISALLOW_COPY_AND_MOVE(className) \
|
||||
DISALLOW_COPY(className); \
|
||||
DISALLOW_MOVE(className)
|
||||
|
||||
#define DISALLOW_COPY(className) \
|
||||
className(const className&) = delete; \
|
||||
className& operator=(const className&&) = delete
|
||||
|
||||
#define DISALLOW_MOVE(className) \
|
||||
className(className&&) = delete; \
|
||||
className& operator=(className&&) = delete
|
||||
|
||||
class NoCopyable {
|
||||
protected:
|
||||
NoCopyable() {};
|
||||
virtual ~NoCopyable() {};
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_MOVE(NoCopyable);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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_PREVIEW_MANAGER_H
|
||||
#define OHOS_RESTOOL_PREVIEW_MANAGER_H
|
||||
|
||||
#include<vector>
|
||||
#include<string>
|
||||
#include "restool_errors.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class PreviewManager {
|
||||
public:
|
||||
PreviewManager() {};
|
||||
virtual ~PreviewManager();
|
||||
uint32_t ScanModules(const std::vector<std::string> &modulePaths, const std::string &output);
|
||||
void SetPriority(int32_t priority) { priority_ = priority; };
|
||||
private:
|
||||
bool ScanFile(const std::string &filePath, int32_t priority);
|
||||
int32_t priority_ = -1;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_REFERENCE_PARSER_H
|
||||
#define OHOS_RESTOOL_REFERENCE_PARSER_H
|
||||
|
||||
#include "id_worker.h"
|
||||
#include "resource_item.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class ReferenceParser {
|
||||
public:
|
||||
ReferenceParser();
|
||||
virtual ~ReferenceParser();
|
||||
uint32_t ParseRefInSolidXml(const std::vector<std::string> &solidXmlFolders) const;
|
||||
uint32_t ParseRefInElement(std::map<int32_t, std::vector<ResourceItem>> &alls) const;
|
||||
uint32_t ParseRefInString(std::string &value, bool &update) const;
|
||||
uint32_t ParseRefInProfile(const std::string &output) const;
|
||||
uint32_t ParseRefInJson(const std::string &filePath) const;
|
||||
private:
|
||||
bool ParseRefResourceItem(ResourceItem &resourceItem) const;
|
||||
bool ParseRefResourceItemData(const ResourceItem &resourceItem, std::string &data, bool &update) const;
|
||||
bool IsStringOfResourceItem(ResType resType) const;
|
||||
bool IsArrayOfResourceItem(ResType resType) const;
|
||||
bool IsNotElement(ResType resType) const;
|
||||
bool ParseRefString(std::string &key) const;
|
||||
bool ParseRefString(std::string &key, bool &update) const;
|
||||
bool ParseRefImpl(std::string &key, const std::map<std::string, ResType> &refs, bool isSystem) const;
|
||||
bool ParseRefJsonImpl(Json::Value &root) const;
|
||||
const IdWorker &idWorker_;
|
||||
static const std::map<std::string, ResType> ID_REFS;
|
||||
static const std::map<std::string, ResType> ID_OHOS_REFS;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_DATA_H
|
||||
#define OHOS_RESTOOL_RESOURCE_DATA_H
|
||||
|
||||
#include<map>
|
||||
#include<stdint.h>
|
||||
#include<string>
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
const static std::string TOOL_NAME = "restool";
|
||||
const static std::string RESOURCES_DIR = "resources";
|
||||
const static std::string CONFIG_JSON = "config.json";
|
||||
const static std::string MODULE_JSON = "module.json";
|
||||
const static std::string RAW_FILE_DIR = "rawfile";
|
||||
const static std::string ID_DEFINED_FILE = "id_defined.json";
|
||||
const static std::string RESOURCE_INDEX_FILE = "resources.index";
|
||||
const static std::string SEPARATOR = "/";
|
||||
const static int32_t VERSION_MAX_LEN = 128;
|
||||
static const int8_t RESTOOL_VERSION[VERSION_MAX_LEN] = { "Restool 2.007" };
|
||||
const static int32_t TAG_LEN = 4;
|
||||
|
||||
enum class KeyType {
|
||||
LANGUAGE = 0,
|
||||
REGION = 1,
|
||||
RESOLUTION = 2,
|
||||
ORIENTATION = 3,
|
||||
DEVICETYPE = 4,
|
||||
SCRIPT = 5,
|
||||
NIGHTMODE = 6,
|
||||
MCC = 7,
|
||||
MNC = 8,
|
||||
KEY_TYPE_MAX,
|
||||
};
|
||||
|
||||
enum class ResType {
|
||||
ELEMENT = 0,
|
||||
ANIMATION = 1,
|
||||
LAYOUT = 3,
|
||||
RAW = 6,
|
||||
INTEGER = 8,
|
||||
STRING = 9,
|
||||
STRARRAY = 10,
|
||||
INTARRAY = 11,
|
||||
BOOLEAN = 12,
|
||||
COLOR = 14,
|
||||
ID = 15,
|
||||
THEME = 16,
|
||||
PLURAL = 17,
|
||||
FLOAT = 18,
|
||||
MEDIA = 19,
|
||||
PROF = 20,
|
||||
GRAPHIC = 21,
|
||||
PATTERN = 22,
|
||||
INVALID_RES_TYPE = -1,
|
||||
};
|
||||
|
||||
enum class OrientationType {
|
||||
VERTICAL = 0,
|
||||
HORIZONTAL = 1,
|
||||
};
|
||||
|
||||
const std::map<std::string, OrientationType> g_orientaionMap = {
|
||||
{ "vertical", OrientationType::VERTICAL },
|
||||
{ "horizontal", OrientationType::HORIZONTAL },
|
||||
};
|
||||
|
||||
enum class DeviceType {
|
||||
PHONE = 0,
|
||||
TABLET = 1,
|
||||
CAR = 2,
|
||||
// RESERVER 3
|
||||
TV = 4,
|
||||
WEARABLE = 6,
|
||||
};
|
||||
|
||||
const std::map<std::string, DeviceType> g_deviceMap = {
|
||||
{ "phone", DeviceType::PHONE },
|
||||
{ "tablet", DeviceType::TABLET },
|
||||
{ "car", DeviceType::CAR },
|
||||
{ "tv", DeviceType::TV },
|
||||
{ "wearable", DeviceType::WEARABLE },
|
||||
};
|
||||
|
||||
enum class ResolutionType {
|
||||
SDPI = 120,
|
||||
MDPI = 160,
|
||||
LDPI = 240,
|
||||
XLDPI = 320,
|
||||
XXLDPI = 480,
|
||||
XXXLDPI = 640,
|
||||
};
|
||||
|
||||
const std::map<std::string, ResolutionType> g_resolutionMap = {
|
||||
{ "sdpi", ResolutionType::SDPI },
|
||||
{ "mdpi", ResolutionType::MDPI },
|
||||
{ "ldpi", ResolutionType::LDPI },
|
||||
{ "xldpi", ResolutionType::XLDPI },
|
||||
{ "xxldpi", ResolutionType::XXLDPI },
|
||||
{ "xxxldpi", ResolutionType::XXXLDPI },
|
||||
};
|
||||
|
||||
enum class NightMode {
|
||||
DARK = 0,
|
||||
LIGHT = 1,
|
||||
};
|
||||
|
||||
const std::map<std::string, NightMode> g_nightModeMap = {
|
||||
{ "dark", NightMode::DARK },
|
||||
{ "light", NightMode::LIGHT },
|
||||
};
|
||||
|
||||
struct KeyParam {
|
||||
KeyType keyType;
|
||||
uint32_t value;
|
||||
};
|
||||
|
||||
const std::map<std::string, ResType> g_fileClusterMap = {
|
||||
{ "element", ResType::ELEMENT },
|
||||
{ "media", ResType::MEDIA },
|
||||
{ "profile", ResType::PROF },
|
||||
{ "animation", ResType::ANIMATION },
|
||||
{ "graphic", ResType::GRAPHIC },
|
||||
{ "layout", ResType::LAYOUT }
|
||||
};
|
||||
|
||||
const std::map<std::string, ResType> g_contentClusterMap = {
|
||||
{ "id", ResType::ID },
|
||||
{ "integer", ResType::INTEGER },
|
||||
{ "string", ResType::STRING },
|
||||
{ "strarray", ResType::STRARRAY },
|
||||
{ "intarray", ResType::INTARRAY },
|
||||
{ "color", ResType::COLOR },
|
||||
{ "plural", ResType::PLURAL },
|
||||
{ "boolean", ResType::BOOLEAN },
|
||||
{ "pattern", ResType::PATTERN },
|
||||
{ "theme", ResType::THEME },
|
||||
{ "float", ResType::FLOAT }
|
||||
};
|
||||
|
||||
struct DirectoryInfo {
|
||||
std::string limitKey;
|
||||
std::string fileCluster;
|
||||
std::string dirPath;
|
||||
std::vector<KeyParam> keyParams;
|
||||
ResType dirType;
|
||||
};
|
||||
|
||||
struct FileInfo : DirectoryInfo {
|
||||
std::string filePath;
|
||||
std::string filename;
|
||||
ResType fileType;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_DIRECTORY
|
||||
#define OHOS_RESTOOL_RESOURCE_DIRECTORY
|
||||
|
||||
#include<functional>
|
||||
#include<string>
|
||||
#include<map>
|
||||
#include "key_parser.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class ResourceDirectory {
|
||||
public:
|
||||
ResourceDirectory() {};
|
||||
virtual ~ResourceDirectory() {};
|
||||
bool ScanResources(const std::string &resourcesDir, std::function<bool(const DirectoryInfo&)> callback) const;
|
||||
private:
|
||||
bool ScanResourceLimitKeyDir(const std::string &resourceTypeDir, const std::string &limitKey,
|
||||
std::function<bool(const DirectoryInfo&)> callback) const;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_ITEM_H
|
||||
#define OHOS_RESTOOL_RESOURCE_ITEM_H
|
||||
|
||||
#include<vector>
|
||||
#include "resource_data.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class ResourceItem {
|
||||
public:
|
||||
ResourceItem();
|
||||
ResourceItem(const ResourceItem &other);
|
||||
ResourceItem(const std::string &name, const std::vector<KeyParam> &keyparams, ResType type);
|
||||
virtual ~ResourceItem();
|
||||
|
||||
bool SetData(const std::string &data);
|
||||
bool SetData(const int8_t *data, uint32_t length);
|
||||
void SetFilePath(const std::string &filePath);
|
||||
void SetLimitKey(const std::string &limitKey);
|
||||
|
||||
const int8_t *GetData() const;
|
||||
const uint32_t GetDataLength() const;
|
||||
const std::string &GetName() const;
|
||||
const ResType &GetResType() const;
|
||||
const std::vector<KeyParam> &GetKeyParam() const;
|
||||
const std::string &GetFilePath() const;
|
||||
const std::string &GetLimitKey() const;
|
||||
|
||||
ResourceItem &operator=(const ResourceItem &other);
|
||||
private:
|
||||
void ReleaseData();
|
||||
void CopyFrom(const ResourceItem &other);
|
||||
int8_t *data_ = nullptr;
|
||||
uint32_t dataLen_;
|
||||
std::string name_;
|
||||
std::vector<KeyParam> keyparams_;
|
||||
ResType type_;
|
||||
std::string filePath_;
|
||||
std::string limitKey_;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_MERGE_H
|
||||
#define OHOS_RESTOOL_RESOURCE_MERGE_H
|
||||
|
||||
#include<string>
|
||||
#include<vector>
|
||||
#include "config_parser.h"
|
||||
#include "restool_errors.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class ResourceMerge {
|
||||
public:
|
||||
ResourceMerge();
|
||||
virtual ~ResourceMerge();
|
||||
uint32_t Init();
|
||||
const std::vector<std::string> &GetInputs() const;
|
||||
private:
|
||||
std::vector<std::string> inputsOrder_;
|
||||
static const std::vector<ConfigParser::ModuleType> ORDERS;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_MODULE_H
|
||||
#define OHOS_RESTOOL_RESOURCE_MODULE_H
|
||||
|
||||
#include "resource_item.h"
|
||||
#include "resource_directory.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class ResourceModule {
|
||||
public:
|
||||
ResourceModule(const std::string &modulePath, const std::string &moduleOutput, const std::string &moduleName);
|
||||
virtual ~ResourceModule() {};
|
||||
uint32_t ScanResource();
|
||||
const std::map<int32_t, std::vector<ResourceItem>> &GetOwner() const;
|
||||
const std::map<ResType, std::vector<DirectoryInfo>> &GetScanDirectorys() const;
|
||||
static uint32_t MergeResourceItem(std::map<int32_t, std::vector<ResourceItem>> &alls,
|
||||
const std::map<int32_t, std::vector<ResourceItem>> &other, bool tipError = false);
|
||||
void SetPreviewMode(bool enable) { previewMode_ = enable; };
|
||||
|
||||
protected:
|
||||
const std::string &modulePath_;
|
||||
const std::string &moduleOutput_;
|
||||
const std::string &moduleName_;
|
||||
std::map<int32_t, std::vector<ResourceItem>> owner_;
|
||||
std::map<ResType, std::vector<DirectoryInfo>> scanDirs_;
|
||||
bool previewMode_ = false;
|
||||
private:
|
||||
void Push(const std::map<int32_t, std::vector<ResourceItem>> &other);
|
||||
static const std::vector<ResType> SCAN_SEQ;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_MODULE_INC_H
|
||||
#define OHOS_RESTOOL_RESOURCE_MODULE_INC_H
|
||||
|
||||
#include "increment_list.h"
|
||||
#include "resource_module.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class ResourceModuleInc : public ResourceModule {
|
||||
public:
|
||||
ResourceModuleInc(const std::string &modulePath, const std::string &moduleOutput, const std::string &moduleName, const std::vector<std::string> &folder);
|
||||
virtual ~ResourceModuleInc() {};
|
||||
uint32_t ScanResource(const std::vector<IncrementList::FileIncrement> &fileIncrements);
|
||||
uint32_t SaveIndex() const;
|
||||
private:
|
||||
const std::vector<std::string> &folder_;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_PACK_H
|
||||
#define OHOS_RESTOOL_RESOURCE_PACK_H
|
||||
|
||||
#include "cmd_parser.h"
|
||||
#include "config_parser.h"
|
||||
#include "resource_util.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class ResourcePack {
|
||||
public:
|
||||
explicit ResourcePack(const PackageParser &packageParser);
|
||||
virtual ~ResourcePack() = default;
|
||||
uint32_t Package();
|
||||
|
||||
private:
|
||||
uint32_t Init();
|
||||
uint32_t InitModule();
|
||||
void InitHeaderCreater();
|
||||
uint32_t InitOutput() const;
|
||||
uint32_t GenerateHeader() const;
|
||||
uint32_t InitConfigJson();
|
||||
uint32_t GenerateTextHeader(const std::string &headerPath) const;
|
||||
uint32_t GenerateCplusHeader(const std::string &headerPath) const;
|
||||
uint32_t GenerateJsHeader(const std::string &headerPath) const;
|
||||
uint32_t CopyRawFile(const std::vector<std::string> &inputs) const;
|
||||
uint32_t CopyRawFileImpl(const std::string &src, const std::string &dst) const;
|
||||
uint32_t GenerateConfigJson();
|
||||
uint32_t ScanResources(const std::vector<std::string> &inputs, const std::string &output);
|
||||
PackageParser packageParser_;
|
||||
std::string moduleName_;
|
||||
using HeaderCreater = std::function<uint32_t(const std::string&)>;
|
||||
std::map<std::string, HeaderCreater> headerCreaters_;
|
||||
ConfigParser configJson_;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_TABLE_H
|
||||
#define OHOS_RESTOOL_RESOURCE_TABLE_H
|
||||
|
||||
#include <fstream>
|
||||
#include "resource_item.h"
|
||||
#include "restool_errors.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class ResourceTable {
|
||||
public:
|
||||
ResourceTable();
|
||||
virtual ~ResourceTable();
|
||||
uint32_t CreateResourceTable();
|
||||
private:
|
||||
struct TableData {
|
||||
int32_t id;
|
||||
ResourceItem resourceItem;
|
||||
};
|
||||
|
||||
struct IndexHeader {
|
||||
int8_t version[VERSION_MAX_LEN];
|
||||
uint32_t fileSize;
|
||||
uint32_t limitKeyConfigSize;
|
||||
};
|
||||
|
||||
struct LimitKeyConfig {
|
||||
int8_t keyTag[TAG_LEN] = {'K', 'E', 'Y', 'S'};
|
||||
uint32_t offset; // IdSet file address offset
|
||||
uint32_t keyCount; // KeyParam count
|
||||
std::vector<int32_t> data;
|
||||
};
|
||||
|
||||
struct IdSet {
|
||||
int8_t idTag[TAG_LEN] = {'I', 'D', 'S', 'S'};
|
||||
uint32_t idCount;
|
||||
std::map<int32_t, uint32_t> data; // pair id and offset
|
||||
};
|
||||
|
||||
struct RecordItem {
|
||||
uint32_t size;
|
||||
int32_t resType;
|
||||
int32_t id;
|
||||
};
|
||||
uint32_t SaveToResouorceIndex(const std::map<std::string, std::vector<TableData>> &configs) const;
|
||||
bool InitIndexHeader(IndexHeader &indexHeader, uint32_t count) const;
|
||||
bool Prepare(const std::map<std::string, std::vector<TableData>> &configs,
|
||||
std::map<std::string, LimitKeyConfig> &limitKeyConfigs,
|
||||
std::map<std::string, IdSet> &idSets, uint32_t &pos) const;
|
||||
bool SaveRecordItem(const std::map<std::string, std::vector<TableData>> &configs, std::ofstream &out,
|
||||
std::map<std::string, IdSet> &idSets, uint32_t &pos) const;
|
||||
void SaveHeader(const IndexHeader &indexHeader, std::ofstream &out) const;
|
||||
void SaveLimitKeyConfigs(const std::map<std::string, LimitKeyConfig> &limitKeyConfigs, std::ofstream &out) const;
|
||||
void SaveIdSets(const std::map<std::string, IdSet> &idSets, std::ofstream &out) const;
|
||||
std::string indexFilePath_;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_UTIL_H
|
||||
#define OHOS_RESTOOL_RESOURCE_UTIL_H
|
||||
|
||||
#include<filesystem>
|
||||
#include<vector>
|
||||
#include "resource_data.h"
|
||||
#include "json/json.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
|
||||
class ResourceUtil {
|
||||
public:
|
||||
/**
|
||||
* @brief split the string with given splitter.
|
||||
* @param str: input string.
|
||||
* @param out: the array of strings computed by splitter.
|
||||
* @param splitter: the split string.
|
||||
*/
|
||||
static void Split(const std::string &str, std::vector<std::string> &out, const std::string &splitter);
|
||||
|
||||
/**
|
||||
* @brief check file exist.
|
||||
* @param path: file path.
|
||||
* @return true if exist, other false.
|
||||
*/
|
||||
static bool FileExist(const std::string &path);
|
||||
|
||||
/**
|
||||
* @brief remove all files in the directory.
|
||||
* @param path: input directory.
|
||||
* @return true if remove success, other false.
|
||||
*/
|
||||
static bool RmoveAllDir(const std::string &path);
|
||||
|
||||
/**
|
||||
* @brief open json file.
|
||||
* @param path: json file path.
|
||||
* @param root: json root node
|
||||
* @return true if open success, other false.
|
||||
*/
|
||||
static bool OpenJsonFile(const std::string &path, Json::Value &root);
|
||||
|
||||
/**
|
||||
* @brief save json file.
|
||||
* @param path: json file path.
|
||||
* @param root: json root node
|
||||
* @return true if save success, other false.
|
||||
*/
|
||||
static bool SaveToJsonFile(const std::string &path, const Json::Value &root);
|
||||
|
||||
/**
|
||||
* @brief get resource type from directory.
|
||||
* @param name: directory name.
|
||||
* @return resrouce type.
|
||||
*/
|
||||
static ResType GetResTypeByDir(const std::string &name);
|
||||
|
||||
/**
|
||||
* @brief ResType to string
|
||||
* @param type: ResType
|
||||
* @return resrouce type string.
|
||||
*/
|
||||
static std::string ResTypeToString(ResType type);
|
||||
|
||||
/**
|
||||
* @brief get id name
|
||||
* @param name; id name or file name
|
||||
* @param type: ResType
|
||||
* @return return id name.
|
||||
*/
|
||||
static std::string GetIdName(const std::string &name, ResType type);
|
||||
|
||||
/**
|
||||
* @brief compose multi strings to string
|
||||
* @param contents: multi strings
|
||||
* @param addNull: if true, string length contains '\0'.
|
||||
* @return return string, empty if error
|
||||
*/
|
||||
static std::string ComposeStrings(const std::vector<std::string> &contents, bool addNull = false);
|
||||
|
||||
/**
|
||||
* @brief decompose string to multi strings
|
||||
* @param content: string
|
||||
* @return return string vector, empty if error
|
||||
*/
|
||||
static std::vector<std::string> DecomposeStrings(const std::string &content);
|
||||
|
||||
/**
|
||||
* @brief string to ResType
|
||||
* @param type: string
|
||||
* @return return ResType
|
||||
*/
|
||||
static ResType GetResTypeFromString(const std::string &type);
|
||||
|
||||
/**
|
||||
* @brief copy file
|
||||
* @param src: source file path
|
||||
* @param dst: destination file path
|
||||
* @return true if success, other false
|
||||
*/
|
||||
static bool CopyFleInner(const std::string &src, const std::string &dst);
|
||||
|
||||
/**
|
||||
* @brief create directorys
|
||||
* @param filePath: directory path
|
||||
* @return true if success, other false
|
||||
*/
|
||||
static bool CreateDirs(const std::string &filePath);
|
||||
|
||||
/**
|
||||
* @brief ignore file or directory
|
||||
* @param filename: file or directory name
|
||||
* @return true if ignore, other false
|
||||
*/
|
||||
static bool IsIgnoreFile(const std::string &filename, std::filesystem::file_type type);
|
||||
|
||||
/**
|
||||
* @brief need convert to solid xml
|
||||
* @param resType: ResType
|
||||
* @return true if need, other false
|
||||
*/
|
||||
static bool NeedConverToSolidXml(ResType resType);
|
||||
|
||||
/**
|
||||
* @brief generate hash string
|
||||
* @param key: string
|
||||
* @return hash string
|
||||
*/
|
||||
static std::string GenerateHash(const std::string key);
|
||||
private:
|
||||
enum class IgnoreType {
|
||||
IGNORE_FILE,
|
||||
IGNORE_DIR,
|
||||
IGNORE_ALL
|
||||
};
|
||||
static const std::map<std::string, IgnoreType> IGNORE_FILE_REGEX;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_ERRORS_H
|
||||
#define OHOS_RESTOOL_ERRORS_H
|
||||
|
||||
#include<stdint.h>
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
constexpr uint32_t RESTOOL_SUCCESS = 0;
|
||||
constexpr uint32_t RESTOOL_ERROR = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_SINGLETON_OBJECT_H
|
||||
#define OHOS_RESTOOL_SINGLETON_OBJECT_H
|
||||
|
||||
#include "nocopyable_object.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
template<typename T>
|
||||
class Singleton : public NoCopyable {
|
||||
public:
|
||||
static T &GetInstance()
|
||||
{
|
||||
return instance_;
|
||||
}
|
||||
|
||||
private:
|
||||
static T instance_;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
T Singleton<T>::instance_;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_SOLID_XML_H
|
||||
#define OHOS_RESTOOL_SOLID_XML_H
|
||||
|
||||
#include<fstream>
|
||||
#include<memory>
|
||||
#include<string>
|
||||
#include<vector>
|
||||
#include "libxml/parser.h"
|
||||
#include "xml_key_node.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class SolidXml {
|
||||
public:
|
||||
explicit SolidXml(const std::string &xmlPath, std::map<XmlKeyNode::KeyType, std::shared_ptr<XmlKeyNode>> &keys);
|
||||
virtual ~SolidXml();
|
||||
bool GenerateSolidXml(const std::string &filePath);
|
||||
bool FlushNodeKeys(const std::string &filePath,
|
||||
std::map<XmlKeyNode::KeyType, std::shared_ptr<XmlKeyNode>> &newKeys);
|
||||
private:
|
||||
class Node {
|
||||
public:
|
||||
Node(): name_(-1), value_(-1), nameSpace_(-1) {};
|
||||
virtual ~Node() {};
|
||||
virtual void RawData(std::ofstream &out) const;
|
||||
virtual bool LoadFrom(std::ifstream &in);
|
||||
virtual bool FlushIndex(const std::map<XmlKeyNode::KeyType, std::shared_ptr<XmlKeyNode>> &oldKeys,
|
||||
std::map<XmlKeyNode::KeyType, std::shared_ptr<XmlKeyNode>> &newKeys);
|
||||
void SetName(int32_t index) { name_ = index; };
|
||||
void SetValue(int32_t index) { value_ = index; };
|
||||
void SetNameSpace(int32_t index) { nameSpace_ = index; };
|
||||
protected:
|
||||
int32_t name_;
|
||||
int32_t value_;
|
||||
int32_t nameSpace_;
|
||||
};
|
||||
|
||||
class XmlNode : public Node {
|
||||
public:
|
||||
XmlNode() : child_(-1), brother_(-1) {};
|
||||
virtual ~XmlNode() {};
|
||||
void RawData(std::ofstream &out) const override;
|
||||
bool LoadFrom(std::ifstream &in) override;
|
||||
bool FlushIndex(const std::map<XmlKeyNode::KeyType, std::shared_ptr<XmlKeyNode>> &oldKeys,
|
||||
std::map<XmlKeyNode::KeyType, std::shared_ptr<XmlKeyNode>> &newKeys) override;
|
||||
void SetChild(int32_t index) { child_ = index; };
|
||||
void SetBrother(int32_t index) { brother_ = index; };
|
||||
void AddAttribute(int32_t index) { attributes_.push_back(index); };
|
||||
private:
|
||||
int32_t child_;
|
||||
int32_t brother_;
|
||||
std::vector<int32_t> attributes_;
|
||||
};
|
||||
|
||||
void Compile(const xmlNodePtr nodePtr, std::shared_ptr<XmlNode> &node);
|
||||
void CompileAttr(const xmlAttrPtr attrPtr, std::shared_ptr<XmlNode> &node);
|
||||
void CompileNameSpace(const xmlNodePtr nodePtr, std::shared_ptr<XmlNode> &node);
|
||||
void AddNampeSpaceDef(int32_t nameSpace, int32_t href);
|
||||
bool SaveToFile(const std::string &filePath) const;
|
||||
void PretreatmentAttr(std::string &value) const;
|
||||
bool LoadFromFile(const std::string &sxmlPath);
|
||||
static bool ChangeToNewKey(const std::map<XmlKeyNode::KeyType, std::shared_ptr<XmlKeyNode>> &oldKeys,
|
||||
std::map<XmlKeyNode::KeyType, std::shared_ptr<XmlKeyNode>> &newKeys,
|
||||
XmlKeyNode::KeyType keyType, int32_t &keyId);
|
||||
bool FlushXmlnsKey(std::map<XmlKeyNode::KeyType, std::shared_ptr<XmlKeyNode>> &newKeys);
|
||||
const std::string &xmlPath_;
|
||||
std::map<XmlKeyNode::KeyType, std::shared_ptr<XmlKeyNode>> &keys_;
|
||||
std::vector<std::shared_ptr<Node>> attributes_;
|
||||
std::vector<std::shared_ptr<XmlNode>> nodes_;
|
||||
std::vector<int32_t> nameSpaces_;
|
||||
std::vector<int32_t> hrefs_;
|
||||
|
||||
static const uint8_t SOLID_XML_MAGIC[];
|
||||
static const uint32_t SOLID_XML_MAGIC_LENGTH;
|
||||
#define CHECK_IO(stream) \
|
||||
if (!stream) { \
|
||||
return false; \
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_SOLID_XML_COMPILER_H
|
||||
#define OHOS_RESTOOL_SOLID_XML_COMPILER_H
|
||||
|
||||
#include "generic_compiler.h"
|
||||
#include "libxml/parser.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class SolidXmlCompiler : public GenericCompiler {
|
||||
public:
|
||||
SolidXmlCompiler(ResType type, const std::string &output);
|
||||
virtual ~SolidXmlCompiler();
|
||||
protected:
|
||||
uint32_t CompileSingleFile(const FileInfo &fileInfo) override;
|
||||
private:
|
||||
bool ParseXml(const FileInfo &fileInfo);
|
||||
bool ParseNodeId(const FileInfo &fileInfo, const xmlNodePtr &node, std::vector<std::string> &ids);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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_SQLITE_DATABASE_H
|
||||
#define OHOS_RESTOOL_SQLITE_DATABASE_H
|
||||
|
||||
#include<string>
|
||||
#include "resource_item.h"
|
||||
#include "singleton_object.h"
|
||||
#include "sqlite3.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class SqliteDatabase : public Singleton<SqliteDatabase> {
|
||||
public:
|
||||
void Init(const std::string &dbPath);
|
||||
bool OpenDatabase();
|
||||
void CloseDatabase();
|
||||
bool Insert(const ResourceItem &resourceItem);
|
||||
void SetPriority(int32_t priority) { priority_ = priority; };
|
||||
private:
|
||||
bool Query(const ResourceItem &resourceItem, int32_t &id);
|
||||
bool FindMaxId();
|
||||
bool CreateTable();
|
||||
std::string GetValue(const ResourceItem &resourceItem) const;
|
||||
std::string dbPath_;
|
||||
sqlite3 * db_ = nullptr;
|
||||
static int32_t id_;
|
||||
int32_t priority_ = 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_TASK_HANDLE_H
|
||||
#define OHOS_RESTOOL_TASK_HANDLE_H
|
||||
|
||||
#include "cmd_parser.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
|
||||
class TaskHandle {
|
||||
public:
|
||||
TaskHandle() {};
|
||||
~TaskHandle() {};
|
||||
uint32_t HandlePackage(const PackageParser &packageParser);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_XML_CONVERTER_H
|
||||
#define OHOS_RESTOOL_XML_CONVERTER_H
|
||||
|
||||
#include<memory>
|
||||
#include<vector>
|
||||
#include<string>
|
||||
#include "key_manager.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class XmlConverter {
|
||||
public:
|
||||
XmlConverter(const std::vector<std::string> &xmlPaths, const std::string &outputPath);
|
||||
virtual ~XmlConverter();
|
||||
bool GenerateSolidXml();
|
||||
bool GenerateKey();
|
||||
private:
|
||||
bool LoadKeys(const std::string &folderPath);
|
||||
const std::vector<std::string> &xmlPaths_;
|
||||
const std::string &outputPath_;
|
||||
KeyManager keyManager;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_XML_KEY_NODE_H
|
||||
#define OHOS_RESTOOL_XML_KEY_NODE_H
|
||||
|
||||
#include<functional>
|
||||
#include<map>
|
||||
#include<stdint.h>
|
||||
#include<string>
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
class XmlKeyNode {
|
||||
public:
|
||||
XmlKeyNode();
|
||||
virtual ~XmlKeyNode();
|
||||
int32_t PushKey(const std::string &name);
|
||||
bool SaveToFile(const std::string &filePath) const;
|
||||
bool LoadFromFile(const std::string &filePath);
|
||||
using RefParser = std::function<bool(std::string&)>;
|
||||
bool LoadFromFile(const std::string &filePath, RefParser parser);
|
||||
bool GetKeyValue(int32_t keyId, std::string &value) const;
|
||||
|
||||
enum class KeyType {
|
||||
NODE = 0,
|
||||
ATTRIBUTE,
|
||||
CONSTANT,
|
||||
CONTENT,
|
||||
END
|
||||
};
|
||||
static const std::map<KeyType, std::string> KEY_TO_FILE_NAME;
|
||||
private:
|
||||
int32_t keyId_;
|
||||
std::map<std::string, int32_t> keyMap_;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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_list.h"
|
||||
#include "restool_errors.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
uint32_t CmdList::Init(const string &filePath, function<uint32_t(int c, const string &argValue)> callback)
|
||||
{
|
||||
Json::Value root;
|
||||
if (!ResourceUtil::OpenJsonFile(filePath, root)) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (!callback) {
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
if (GetString(root["configPath"], 'j', callback) != RESTOOL_SUCCESS ||
|
||||
GetString(root["packageName"], 'p', callback) != RESTOOL_SUCCESS ||
|
||||
GetString(root["output"], 'o', callback) != RESTOOL_SUCCESS ||
|
||||
GetString(root["startId"], 'e', callback) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (GetModuleNames(root["moduleNames"], callback) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (GetArray(root["ResourceTable"], 'r', callback) != RESTOOL_SUCCESS ||
|
||||
GetString(root["applicationResource"], 'i', callback) != RESTOOL_SUCCESS ||
|
||||
GetArray(root["moduleResources"], 'i', callback) != RESTOOL_SUCCESS ||
|
||||
GetArray(root["dependencies"], 'i', callback) != RESTOOL_SUCCESS ) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
callback('f', "");
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
// below private
|
||||
uint32_t CmdList::GetString(const Json::Value &node, int c, HandleBack callback)
|
||||
{
|
||||
if (!node.isString()) {
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
if (callback(c, node.asString()) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t CmdList::GetArray(const Json::Value &node, int c, HandleBack callback)
|
||||
{
|
||||
if (!node.isArray()) {
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
for (Json::ArrayIndex i = 0; i < node.size(); i++) {
|
||||
if (!node[i].isString()) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
if (callback(c, node[i].asString()) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t CmdList::GetModuleNames(const Json::Value &node, HandleBack callback)
|
||||
{
|
||||
string moduleNames;
|
||||
if (GetArray(node, 'm', [&moduleNames](int c, const string &argValue) {
|
||||
if (!moduleNames.empty()) {
|
||||
moduleNames.append(",");
|
||||
}
|
||||
moduleNames.append(argValue);
|
||||
return RESTOOL_SUCCESS;
|
||||
}) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (!moduleNames.empty() && callback('m', moduleNames) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,322 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_parser.h"
|
||||
#include<algorithm>
|
||||
#include "resource_util.h"
|
||||
|
||||
#include "cmd_list.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
const struct option PackageParser::CMD_OPTS[] = {
|
||||
{ "inputPath", required_argument, nullptr, 'i' },
|
||||
{ "packageName", required_argument, nullptr, 'p' },
|
||||
{ "outputPath", required_argument, nullptr, 'o' },
|
||||
{ "resHeader", required_argument, nullptr, 'r' },
|
||||
{ "forceWrite", no_argument, nullptr, 'f' },
|
||||
{ "version", no_argument, nullptr, 'v'},
|
||||
{ "modules", optional_argument, nullptr, 'm' },
|
||||
{ "json", optional_argument, nullptr, 'j' },
|
||||
{ "startId", optional_argument, nullptr, 'e' },
|
||||
{ "cache", optional_argument, nullptr, 'c' },
|
||||
{ "fileList", required_argument, nullptr, 'l' },
|
||||
{ "preview", no_argument, nullptr, 'a' },
|
||||
{ "priority", required_argument, nullptr, 'g' },
|
||||
};
|
||||
|
||||
const string PackageParser::CMD_PARAMS = "i:p:o:r:m:j:e:c:l:g:afv";
|
||||
|
||||
uint32_t PackageParser::Parse(int argc, char *argv[])
|
||||
{
|
||||
InitCommand();
|
||||
if (ParseCommand(argc, argv) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
return CheckParam();
|
||||
}
|
||||
|
||||
const vector<string> &PackageParser::GetInputs() const
|
||||
{
|
||||
return inputs_;
|
||||
}
|
||||
|
||||
const string &PackageParser::GetPackageName() const
|
||||
{
|
||||
return packageName_;
|
||||
}
|
||||
|
||||
const string &PackageParser::GetOutput() const
|
||||
{
|
||||
return output_;
|
||||
}
|
||||
|
||||
const vector<string> &PackageParser::GetResourceHeaders() const
|
||||
{
|
||||
return resourceHeaderPaths_;
|
||||
}
|
||||
|
||||
bool PackageParser::GetForceWrite() const
|
||||
{
|
||||
return forceWrite_;
|
||||
}
|
||||
|
||||
const vector<string> &PackageParser::GetModuleNames() const
|
||||
{
|
||||
return moduleNames_;
|
||||
}
|
||||
|
||||
const string &PackageParser::GetConfig() const
|
||||
{
|
||||
return configPath_;
|
||||
}
|
||||
|
||||
const string &PackageParser::GetRestoolPath() const
|
||||
{
|
||||
return restoolPath_;
|
||||
}
|
||||
|
||||
int32_t PackageParser::GetStartId() const
|
||||
{
|
||||
return startId_;
|
||||
}
|
||||
|
||||
const string &PackageParser::GetCachePath() const
|
||||
{
|
||||
return cachePath_;
|
||||
}
|
||||
|
||||
uint32_t PackageParser::AddInput(const string& argValue)
|
||||
{
|
||||
auto ret = find_if(inputs_.begin(), inputs_.end(), [argValue](auto iter) {return argValue == iter;});
|
||||
if (ret != inputs_.end()) {
|
||||
cerr << "Error: repeat input '" << argValue << "'" << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
inputs_.push_back(argValue);
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t PackageParser::AddPackageName(const string& argValue)
|
||||
{
|
||||
if (!packageName_.empty()) {
|
||||
cerr << "Error: double package name " << packageName_ << " vs " << argValue << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
packageName_ = argValue;
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t PackageParser::AddOutput(const string& argValue)
|
||||
{
|
||||
if (!output_.empty()) {
|
||||
cerr << "Error: double output " << output_ << " vs " << argValue << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
output_ = argValue;
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t PackageParser::AddResourceHeader(const string& argValue)
|
||||
{
|
||||
if (find(resourceHeaderPaths_.begin(), resourceHeaderPaths_.end(), argValue) != resourceHeaderPaths_.end()) {
|
||||
cerr << "Error: '" << argValue << "' input duplicated." << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
resourceHeaderPaths_.push_back(argValue);
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t PackageParser::ForceWrite()
|
||||
{
|
||||
forceWrite_ = true;
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t PackageParser::PrintVersion()
|
||||
{
|
||||
cout << "Info: Restool version= " << RESTOOL_VERSION << endl;
|
||||
cout << "time = (" << __DATE__ << " " << __TIME__ << ")" << endl;
|
||||
exit(RESTOOL_SUCCESS);
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t PackageParser::AddMoudleNames(const string& argValue)
|
||||
{
|
||||
if (!moduleNames_.empty()) {
|
||||
cerr << "Error: -m double module name '" << argValue << "'" << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
ResourceUtil::Split(argValue, moduleNames_, ",");
|
||||
for (auto it = moduleNames_.begin(); it != moduleNames_.end(); it++) {
|
||||
auto ret = find_if(moduleNames_.begin(), moduleNames_.end(), [it](auto iter) {return *it == iter;});
|
||||
if (ret != it) {
|
||||
cerr << "Error: double module name '" << *it << "'" << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t PackageParser::AddConfig(const string& argValue)
|
||||
{
|
||||
if (!configPath_.empty()) {
|
||||
cerr << "Error: double config.json " << configPath_ << " vs " << argValue << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
configPath_ = argValue;
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t PackageParser::AddStartId(const string& argValue)
|
||||
{
|
||||
startId_ = strtol(argValue.c_str(), nullptr, 16);
|
||||
if ((startId_ >= 0x01000000 && startId_ < 0x06ffffff) || (startId_ >= 0x08000000 && startId_ < 0x41ffffff)) {
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
cerr << "Error: invalid start id " << argValue << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
uint32_t PackageParser::AddCachePath(const string& argValue)
|
||||
{
|
||||
cachePath_ = argValue;
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t PackageParser::CheckParam() const
|
||||
{
|
||||
|
||||
if (inputs_.empty()) {
|
||||
cerr << "Error: input path empty." << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (output_.empty()) {
|
||||
cerr << "Error: output path empty." << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (previewMode_) {
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
if (packageName_.empty()) {
|
||||
cerr << "Error: package name empty." << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (resourceHeaderPaths_.empty()) {
|
||||
cerr << "Error: resource header path empty." << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
bool PackageParser::IsFileList() const
|
||||
{
|
||||
return isFileList_;
|
||||
}
|
||||
|
||||
uint32_t PackageParser::SetPreviewMode()
|
||||
{
|
||||
previewMode_ = true;
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
bool PackageParser::GetPreviewMode() const
|
||||
{
|
||||
return previewMode_;
|
||||
}
|
||||
|
||||
int32_t PackageParser::GetPriority() const
|
||||
{
|
||||
return priority_;
|
||||
}
|
||||
|
||||
uint32_t PackageParser::SetPriority(const string& argValue)
|
||||
{
|
||||
priority_ = atoi(argValue.c_str());
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
void PackageParser::InitCommand()
|
||||
{
|
||||
using namespace placeholders;
|
||||
handles_.emplace('i', bind(&PackageParser::AddInput, this, _1));
|
||||
handles_.emplace('p', bind(&PackageParser::AddPackageName, this, _1));
|
||||
handles_.emplace('o', bind(&PackageParser::AddOutput, this, _1));
|
||||
handles_.emplace('r', bind(&PackageParser::AddResourceHeader, this, _1));
|
||||
handles_.emplace('f', [this](const string &) -> uint32_t { return ForceWrite(); });
|
||||
handles_.emplace('v', [this](const string &) -> uint32_t { return PrintVersion(); });
|
||||
handles_.emplace('m', bind(&PackageParser::AddMoudleNames, this, _1));
|
||||
handles_.emplace('j', bind(&PackageParser::AddConfig, this, _1));
|
||||
handles_.emplace('e', bind(&PackageParser::AddStartId, this, _1));
|
||||
handles_.emplace('c', bind(&PackageParser::AddCachePath, this, _1));
|
||||
handles_.emplace('a', [this](const string &) -> uint32_t { return SetPreviewMode(); });
|
||||
handles_.emplace('g', bind(&PackageParser::SetPriority, this, _1));
|
||||
}
|
||||
|
||||
uint32_t PackageParser::HandleProcess(int c, const string& argValue)
|
||||
{
|
||||
auto handler = handles_.find(c);
|
||||
if (handler == handles_.end()) {
|
||||
cout << "Warning: unsupport " << c << endl;
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
return handler->second(argValue);
|
||||
}
|
||||
|
||||
uint32_t PackageParser::ParseFileList(const string& fileListPath)
|
||||
{
|
||||
isFileList_ = true;
|
||||
CmdList cmdList;
|
||||
if (cmdList.Init(fileListPath, [this](int c, const string &argValue) -> int32_t {
|
||||
return HandleProcess(c, argValue);
|
||||
}) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t PackageParser::ParseCommand(int argc, char *argv[])
|
||||
{
|
||||
restoolPath_ = string(argv[0]);
|
||||
while (true) {
|
||||
int optIndex = 0;
|
||||
int c = getopt_long(argc, argv, CMD_PARAMS.c_str(), CMD_OPTS,&optIndex);
|
||||
if (c == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
string argValue = (optarg != nullptr) ? optarg : "";
|
||||
if (c == 'l') {
|
||||
return ParseFileList(argValue);
|
||||
}
|
||||
if (HandleProcess(c, argValue) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,266 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 "config_parser.h"
|
||||
#include<iostream>
|
||||
#include<regex>
|
||||
#include "reference_parser.h"
|
||||
#include "restool_errors.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
const map<string, ConfigParser::ModuleType> ConfigParser::MODULE_TYPES = {
|
||||
{ "har", ModuleType::HAR, },
|
||||
{ "entry", ModuleType::ENTRY },
|
||||
{ "feature", ModuleType::FEATURE }
|
||||
};
|
||||
|
||||
const map<string, string> ConfigParser::JSON_STRING_IDS = {
|
||||
{ "icon", "^\\$media:" },
|
||||
{ "label", "^\\$string:" },
|
||||
{ "description", "^\\$string:" },
|
||||
{ "theme", "^\\$theme:" },
|
||||
{ "reason", "^\\$string:" }
|
||||
};
|
||||
|
||||
const map<string, string> ConfigParser::JSON_ARRAY_IDS = {
|
||||
{ "landscapeLayouts", "^\\$layout:" },
|
||||
{ "portraitLayouts", "^\\$layout:" }
|
||||
};
|
||||
|
||||
bool ConfigParser::useModule_ = false;
|
||||
|
||||
ConfigParser::ConfigParser()
|
||||
: filePath_("") ,packageName_("") ,moduleName_(""), moduleType_(ModuleType::NONE)
|
||||
{
|
||||
}
|
||||
|
||||
ConfigParser::ConfigParser(const string &filePath)
|
||||
: filePath_(filePath) ,packageName_("") ,moduleName_(""), moduleType_(ModuleType::NONE)
|
||||
{
|
||||
}
|
||||
|
||||
ConfigParser::~ConfigParser()
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t ConfigParser::Init()
|
||||
{
|
||||
if (!ResourceUtil::OpenJsonFile(filePath_, rootNode_)) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (!rootNode_.isObject()) {
|
||||
cerr << "Error: root node not obeject in " << filePath_ << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (!ParseModule(rootNode_["module"])) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
const string &ConfigParser::GetPackageName() const
|
||||
{
|
||||
return packageName_;
|
||||
}
|
||||
|
||||
const string &ConfigParser::GetModuleName() const
|
||||
{
|
||||
return moduleName_;
|
||||
}
|
||||
|
||||
ConfigParser::ModuleType ConfigParser::GetModuleType() const
|
||||
{
|
||||
return moduleType_;
|
||||
}
|
||||
|
||||
uint32_t ConfigParser::ParseRefence()
|
||||
{
|
||||
if (ParseRefImpl(rootNode_, "", rootNode_)) {
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
uint32_t ConfigParser::Save(const string &filePath) const
|
||||
{
|
||||
if (ResourceUtil::SaveToJsonFile(filePath, rootNode_)) {
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
// below private
|
||||
bool ConfigParser::ParseModule(Json::Value &moduleNode)
|
||||
{
|
||||
if (!moduleNode.isObject()) {
|
||||
cerr << "Error: 'module' not object in " << filePath_ << endl;
|
||||
return false;
|
||||
}
|
||||
if (moduleNode.empty()) {
|
||||
cerr << "Error: 'module' empty in " << filePath_ << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!useModule_) {
|
||||
if (moduleNode["package"].isString()) {
|
||||
packageName_ = moduleNode["package"].asString();
|
||||
}
|
||||
return ParseDistro(moduleNode["distro"]);
|
||||
}
|
||||
|
||||
if (moduleNode["name"].isString()) {
|
||||
moduleName_ = moduleNode["name"].asString();
|
||||
}
|
||||
|
||||
if (moduleName_.empty()) {
|
||||
cerr << "Error: 'name' don't found in 'module', " << filePath_ << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (moduleNode["type"].isString() && !ParseModuleType(moduleNode["type"].asString())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConfigParser::ParseDistro(Json::Value &distroNode)
|
||||
{
|
||||
if (!distroNode.isObject()) {
|
||||
cerr << "Error: 'distro' not object in " << filePath_ << endl;
|
||||
return false;
|
||||
}
|
||||
if (distroNode.empty()) {
|
||||
cerr << "Error: 'distro' empty in " << filePath_ << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (distroNode["moduleName"].isString()) {
|
||||
moduleName_ = distroNode["moduleName"].asString();
|
||||
}
|
||||
|
||||
if (moduleName_.empty()) {
|
||||
cerr << "Error: 'moduleName' don't found in 'distro', " << filePath_ << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (distroNode["moduleType"].isString() && !ParseModuleType(distroNode["moduleType"].asString())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConfigParser::ParseRefImpl(Json::Value &parent, const std::string &key, Json::Value &node)
|
||||
{
|
||||
if (node.isArray()) {
|
||||
const auto &result = JSON_ARRAY_IDS.find(key);
|
||||
if (result != JSON_ARRAY_IDS.end()) {
|
||||
return ParseJsonArrayRef(parent, key, node);
|
||||
}
|
||||
for (Json::ArrayIndex index = 0; index < node.size(); index++) {
|
||||
if (!ParseRefImpl(node, "", node[index])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if (node.isObject()) {
|
||||
const auto members = node.getMemberNames();
|
||||
for (const auto &member : members) {
|
||||
if (!ParseRefImpl(node, member, node[member])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if (!key.empty() && node.isString()) {
|
||||
return ParseJsonStringRef(parent, key, node);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConfigParser::ParseJsonArrayRef(Json::Value &parent, const string &key, Json::Value &node)
|
||||
{
|
||||
Json::ArrayIndex size = node.size();
|
||||
Json::Value array(Json::arrayValue);
|
||||
for (Json::ArrayIndex index = 0; index < size; index++) {
|
||||
if (!node[index].isString()) {
|
||||
cerr << "Error: '" << key << "' invalid value. " << filePath_ << endl;
|
||||
return false;
|
||||
}
|
||||
string value = node[index].asString();
|
||||
bool update = false;
|
||||
if (!GetRefIdFromString(value, update, JSON_ARRAY_IDS.at(key))) {
|
||||
cerr << "Error: '" << key << "' value " << node[index] << " invalid. " << filePath_ << endl;
|
||||
return false;
|
||||
}
|
||||
if (update) {
|
||||
array.append(atoi(value.c_str()));
|
||||
}
|
||||
}
|
||||
parent[key + "Id"] = array;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConfigParser::ParseJsonStringRef(Json::Value &parent, const string &key, Json::Value &node)
|
||||
{
|
||||
const auto &result = JSON_STRING_IDS.find(key);
|
||||
if (result == JSON_STRING_IDS.end()) {
|
||||
return true;
|
||||
}
|
||||
string value = node.asString();
|
||||
bool update = false;
|
||||
if (!GetRefIdFromString(value, update, JSON_STRING_IDS.at(key))) {
|
||||
cerr << "Error: '" << key << "' value " << node << " invalid value. " << filePath_ << endl;
|
||||
return false;
|
||||
}
|
||||
if (update) {
|
||||
parent[key + "Id"] = atoi(value.c_str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConfigParser::GetRefIdFromString(string &value, bool &update, const string &match) const
|
||||
{
|
||||
ReferenceParser refParser;
|
||||
string error = "Error: '" + value + "' must start with '" + match.substr(match.find("\\") + 1) + "'";
|
||||
if (refParser.ParseRefInString(value, update) != RESTOOL_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
if (!update) {
|
||||
return true;
|
||||
}
|
||||
smatch result;
|
||||
if (regex_search(value, result, regex(match))) {
|
||||
value = value.substr(result[0].str().length());
|
||||
return true;
|
||||
}
|
||||
cerr << error << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ConfigParser::ParseModuleType(const string &type)
|
||||
{
|
||||
const auto &result = MODULE_TYPES.find(type);
|
||||
if (result == MODULE_TYPES.end()) {
|
||||
cerr << "Error: moduleType='" << type << "' invalid value in " << filePath_ << endl;
|
||||
return false;
|
||||
}
|
||||
moduleType_ = result->second;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_compiler.h"
|
||||
#include "generic_compiler.h"
|
||||
#include "json_compiler.h"
|
||||
#include "solid_xml_compiler.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
unique_ptr<IResourceCompiler> FactoryResourceCompiler::CreateCompiler(ResType type, const string &output)
|
||||
{
|
||||
if (type == ResType::ELEMENT) {
|
||||
return make_unique<JsonCompiler>(type, output);
|
||||
} else if (type == ResType::LAYOUT || type == ResType::ANIMATION || type == ResType::GRAPHIC) {
|
||||
return make_unique<SolidXmlCompiler>(type, output);
|
||||
} else {
|
||||
return make_unique<GenericCompiler>(type, output);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 "file_manager.h"
|
||||
#include<algorithm>
|
||||
#include<filesystem>
|
||||
#include<iostream>
|
||||
#include "factory_resource_compiler.h"
|
||||
#include "key_parser.h"
|
||||
#include "reference_parser.h"
|
||||
#include "resource_directory.h"
|
||||
#include "resource_util.h"
|
||||
#include "restool_errors.h"
|
||||
|
||||
#include "resource_module.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
uint32_t FileManager::ScanModules(const vector<string> &inputs, const string &output)
|
||||
{
|
||||
vector<string> sxmlFolders;
|
||||
for (auto input : inputs) {
|
||||
map<ResType, vector<DirectoryInfo>> resTypeOfDirs;
|
||||
if(ScanModule(input, output, resTypeOfDirs) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
FilterRefSolidXml(output, sxmlFolders, resTypeOfDirs);
|
||||
}
|
||||
return ParseReference(output, sxmlFolders);
|
||||
}
|
||||
|
||||
uint32_t FileManager::ScanIncrement(const string &output)
|
||||
{
|
||||
auto &incrementManager = IncrementManager::GetInstance();
|
||||
alls_ = incrementManager.GetResourceItems();
|
||||
vector<string> sxmlFolders;
|
||||
FilterRefSolidXml(output, sxmlFolders, incrementManager.GetScanDirs());
|
||||
return ParseReference(output, sxmlFolders);
|
||||
}
|
||||
|
||||
//below private founction
|
||||
uint32_t FileManager::ScanModule(const string &input, const string &output,
|
||||
map<ResType, vector<DirectoryInfo>> &resTypeOfDirs)
|
||||
{
|
||||
ResourceModule resourceModule(input, output, moduleName_);
|
||||
if (resourceModule.ScanResource() != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
resTypeOfDirs = resourceModule.GetScanDirectorys();
|
||||
MergeResourceItem(resourceModule.GetOwner());
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t FileManager::MergeResourceItem(const map<int32_t, vector<ResourceItem>> &resourceInfos)
|
||||
{
|
||||
return ResourceModule::MergeResourceItem(alls_, resourceInfos);
|
||||
}
|
||||
|
||||
uint32_t FileManager::ParseReference(const string &output, const vector<string> &sxmlFolders)
|
||||
{
|
||||
ReferenceParser referenceParser;
|
||||
if (referenceParser.ParseRefInSolidXml(sxmlFolders) != RESTOOL_SUCCESS ||
|
||||
referenceParser.ParseRefInElement(alls_) != RESTOOL_SUCCESS ||
|
||||
referenceParser.ParseRefInProfile(output) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
bool FileManager::NeedParseReferenceInSolidXml(ResType resType) const
|
||||
{
|
||||
if (resType == ResType::LAYOUT || resType == ResType::ANIMATION || resType == ResType::GRAPHIC) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void FileManager::FilterRefSolidXml(const string &output, vector<string> &outputPaths,
|
||||
const map<ResType, vector<DirectoryInfo>> &resTypeOfDirs) const
|
||||
{
|
||||
for (const auto &iter : resTypeOfDirs) {
|
||||
if (!NeedParseReferenceInSolidXml(iter.first)) {
|
||||
continue;
|
||||
}
|
||||
for (const auto &resourceDir : iter.second) {
|
||||
string outputPath = filesystem::path(output).append(RESOURCES_DIR).append(resourceDir.limitKey)
|
||||
.append(resourceDir.fileCluster).string();
|
||||
if (find(outputPaths.begin(), outputPaths.end(), outputPath) == outputPaths.end()) {
|
||||
outputPaths.push_back(outputPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 "generic_compiler.h"
|
||||
#include<filesystem>
|
||||
#include<iostream>
|
||||
#include "restool_errors.h"
|
||||
#include "resource_util.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
GenericCompiler::GenericCompiler(ResType type, const string &output)
|
||||
: IResourceCompiler(type, output)
|
||||
{
|
||||
}
|
||||
GenericCompiler::~GenericCompiler()
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t GenericCompiler::CompileSingleFile(const FileInfo &fileInfo)
|
||||
{
|
||||
if (IsIgnore(fileInfo)) {
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
if (!CopyFile(fileInfo)) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (!PostFile(fileInfo)) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
bool GenericCompiler::PostFile(const FileInfo &fileInfo)
|
||||
{
|
||||
ResourceItem resourceItem(fileInfo.filename, fileInfo.keyParams, type_);
|
||||
resourceItem.SetFilePath(fileInfo.filePath);
|
||||
resourceItem.SetLimitKey(fileInfo.limitKey);
|
||||
|
||||
string data = fileInfo.filename;
|
||||
if (IsConvertToSolidXml(fileInfo)) {
|
||||
data = filesystem::path(data).replace_extension(".sxml").string();
|
||||
}
|
||||
data = moduleName_ + SEPARATOR + RESOURCES_DIR + SEPARATOR + \
|
||||
fileInfo.limitKey + SEPARATOR + fileInfo.fileCluster + SEPARATOR + data;
|
||||
if (!resourceItem.SetData(reinterpret_cast<const int8_t *>(data.c_str()), data.length())) {
|
||||
cerr << "Error: resource item set data fail, " << fileInfo.filePath << endl;
|
||||
return false;
|
||||
}
|
||||
return MergeResourceItem(resourceItem);
|
||||
}
|
||||
|
||||
string GenericCompiler::GetOutputFilePath(const FileInfo &fileInfo) const
|
||||
{
|
||||
string outputFolder = GetOutputFolder(fileInfo);
|
||||
string outputFilePath = filesystem::path(outputFolder).append(fileInfo.filename).string();
|
||||
return outputFilePath;
|
||||
}
|
||||
|
||||
bool GenericCompiler::IsIgnore(const FileInfo &fileInfo) const
|
||||
{
|
||||
if (IsConvertToSolidXml(fileInfo)) {
|
||||
if (HasConvertedToSolidXml(fileInfo)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return ResourceUtil::FileExist(GetOutputFilePath(fileInfo));
|
||||
}
|
||||
|
||||
bool GenericCompiler::CopyFile(const FileInfo &fileInfo) const
|
||||
{
|
||||
if (previewMode_) {
|
||||
return true;
|
||||
}
|
||||
if (IsConvertToSolidXml(fileInfo)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
string outputFolder = GetOutputFolder(fileInfo);
|
||||
if (!ResourceUtil::CreateDirs(outputFolder)) {
|
||||
return false;
|
||||
}
|
||||
return ResourceUtil::CopyFleInner(fileInfo.filePath, GetOutputFilePath(fileInfo));
|
||||
}
|
||||
|
||||
bool GenericCompiler::IsConvertToSolidXml(const FileInfo &fileInfo) const
|
||||
{
|
||||
if (NeedIfConvertToSolidXml() && IsXmlFile(fileInfo)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 "header.h"
|
||||
#include<algorithm>
|
||||
#include<fstream>
|
||||
#include<iostream>
|
||||
#include<iomanip>
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
const std::string Header::LICENSE_HEADER = "/*\n\
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.\n\
|
||||
* Licensed under the Apache License, Version 2.0 (the \"License\");\n\
|
||||
* you may not use this file except in compliance with the License.\n\
|
||||
* You may obtain a copy of the License at\n\
|
||||
*\n\
|
||||
* http://www.apache.org/licenses/LICENSE-2.0\n\
|
||||
*\n\
|
||||
* Unless required by applicable law or agreed to in writing, software\n\
|
||||
* distributed under the License is distributed on an \"AS IS\" BASIS,\n\
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\
|
||||
* See the License for the specific language governing permissions and\n\
|
||||
* limitations under the License.\n\
|
||||
*/\n";
|
||||
|
||||
Header::Header(const string &outputPath) : outputPath_(outputPath)
|
||||
{
|
||||
}
|
||||
|
||||
Header::~Header()
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t Header::Create(HandleHeaderTail headerHandler, HandleBody bodyHandler, HandleHeaderTail tailHandler) const
|
||||
{
|
||||
IdWorker &idWorker = IdWorker::GetInstance();
|
||||
vector<IdWorker::ResourceId> resourceIds = idWorker.GetHeaderId();
|
||||
|
||||
ofstream out(outputPath_, ofstream::out | ofstream::binary);
|
||||
if (!out.is_open()) {
|
||||
cerr << "Error: open fail '" << outputPath_ << "'" << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
stringstream buffer;
|
||||
headerHandler(buffer);
|
||||
for (const auto &resourceId : resourceIds) {
|
||||
bodyHandler(buffer, resourceId);
|
||||
}
|
||||
tailHandler(buffer);
|
||||
out << buffer.rdbuf();
|
||||
out.close();
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 "i_resource_compiler.h"
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include "id_worker.h"
|
||||
#include "resource_util.h"
|
||||
#include "restool_errors.h"
|
||||
#include "sqlite_database.h"
|
||||
#include "xml_converter.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
IResourceCompiler::IResourceCompiler(ResType type, const string &output)
|
||||
:type_(type), output_(output)
|
||||
{
|
||||
}
|
||||
|
||||
IResourceCompiler::~IResourceCompiler()
|
||||
{
|
||||
nameInfos_.clear();
|
||||
resourceInfos_.clear();
|
||||
}
|
||||
|
||||
uint32_t IResourceCompiler::Compile(const vector<DirectoryInfo> &directoryInfos)
|
||||
{
|
||||
vector<FileInfo> fileInfos;
|
||||
map<string, vector<FileInfo>> setsByDirectory;
|
||||
for (const auto &directoryInfo : directoryInfos) {
|
||||
string outputFolder = GetOutputFolder(directoryInfo);
|
||||
for (const auto &it : filesystem::directory_iterator(directoryInfo.dirPath)) {
|
||||
if (ResourceUtil::IsIgnoreFile(it.path().filename().string(), it.status().type())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (it.is_directory()) {
|
||||
cout << "Error: '" << it.path().string() << "' not regular." << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
FileInfo fileInfo = { directoryInfo, it.path().string(), it.path().filename().string() };
|
||||
fileInfos.push_back(fileInfo);
|
||||
setsByDirectory[outputFolder].push_back(fileInfo);
|
||||
}
|
||||
}
|
||||
|
||||
sort(fileInfos.begin(), fileInfos.end(), [](const auto &a, const auto &b) {
|
||||
return a.filePath < b.filePath;
|
||||
});
|
||||
for (const auto &fileInfo : fileInfos) {
|
||||
if (CompileSingleFile(fileInfo) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (previewMode_) {
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
if (NeedIfConvertToSolidXml() && ConvertToSolidXml(setsByDirectory) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
return PostCommit();
|
||||
}
|
||||
|
||||
const map<int32_t, vector<ResourceItem>> &IResourceCompiler::GetResult() const
|
||||
{
|
||||
return resourceInfos_;
|
||||
}
|
||||
|
||||
uint32_t IResourceCompiler::Compile(const FileInfo &fileInfo)
|
||||
{
|
||||
if (CompileSingleFile(fileInfo) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (previewMode_) {
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
map<string, vector<FileInfo>> setsByDirectory;
|
||||
if (NeedIfConvertToSolidXml()) {
|
||||
string outputFolder = filesystem::path(output_).append(RESOURCES_DIR)
|
||||
.append(fileInfo.limitKey).append(fileInfo.fileCluster).string();
|
||||
setsByDirectory[outputFolder].push_back(fileInfo);
|
||||
}
|
||||
|
||||
if (ConvertToSolidXml(setsByDirectory) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
return PostCommit();
|
||||
}
|
||||
|
||||
void IResourceCompiler::SetModuleName(const string &moduleName)
|
||||
{
|
||||
moduleName_ = moduleName;
|
||||
}
|
||||
|
||||
uint32_t IResourceCompiler::ConvertToSolidXml(const map<string, vector<FileInfo>> &setsByDirectory)
|
||||
{
|
||||
for (const auto &iter : setsByDirectory) {
|
||||
vector<string> xmlPaths;
|
||||
ListXmlFile(iter.second, xmlPaths);
|
||||
if (xmlPaths.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
string xmlOutPath = iter.first;
|
||||
if (!ResourceUtil::CreateDirs(xmlOutPath)) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
sort(xmlPaths.begin(), xmlPaths.end());
|
||||
XmlConverter xmlConverter(xmlPaths, xmlOutPath);
|
||||
if (!xmlConverter.GenerateSolidXml()) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (!xmlConverter.GenerateKey()) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t IResourceCompiler::CompileSingleFile(const FileInfo &fileInfo)
|
||||
{
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t IResourceCompiler::PostCommit()
|
||||
{
|
||||
IdWorker &idWorker = IdWorker::GetInstance();
|
||||
for (const auto &nameInfo : nameInfos_) {
|
||||
int32_t id = idWorker.GenerateId(nameInfo.first.first, nameInfo.first.second);
|
||||
if (id < 0) {
|
||||
cerr << "Error: restype='" << ResourceUtil::ResTypeToString(nameInfo.first.first) << "' name='";
|
||||
cerr << nameInfo.first.second << "' id not be defined." << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
resourceInfos_.emplace(id, nameInfo.second);
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
bool IResourceCompiler::MergeResourceItem(const ResourceItem &resourceItem)
|
||||
{
|
||||
if (previewMode_) {
|
||||
return SqliteDatabase::GetInstance().Insert(resourceItem);
|
||||
}
|
||||
string idName = ResourceUtil::GetIdName(resourceItem.GetName(), resourceItem.GetResType());
|
||||
if (!IdWorker::GetInstance().IsValidName(idName)) {
|
||||
cerr << "Error: in " << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
auto item = nameInfos_.find(make_pair(resourceItem.GetResType(), idName));
|
||||
if (item == nameInfos_.end()) {
|
||||
nameInfos_[make_pair(resourceItem.GetResType(), idName)].push_back(resourceItem);
|
||||
return true;
|
||||
}
|
||||
|
||||
auto ret = find_if(item->second.begin(), item->second.end(), [resourceItem](auto &iter) {
|
||||
return resourceItem.GetLimitKey() == iter.GetLimitKey();
|
||||
});
|
||||
if (ret != item->second.end()) {
|
||||
cerr << "Error: resource '" << idName << "' first declared in " << ret->GetFilePath();
|
||||
cerr << ", but declare again in " << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
nameInfos_[make_pair(resourceItem.GetResType(), idName)].push_back(resourceItem);
|
||||
return true;
|
||||
}
|
||||
|
||||
void IResourceCompiler::ListXmlFile(const vector<FileInfo> &fileInfos, vector<string> &xmlPaths) const
|
||||
{
|
||||
for (const auto &fileInfo : fileInfos) {
|
||||
if (!IsXmlFile(fileInfo)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (HasConvertedToSolidXml(fileInfo)) {
|
||||
continue;
|
||||
}
|
||||
xmlPaths.push_back(fileInfo.filePath);
|
||||
}
|
||||
}
|
||||
|
||||
bool IResourceCompiler::IsXmlFile(const FileInfo &fileInfo) const
|
||||
{
|
||||
if (filesystem::path(fileInfo.filePath).extension() != ".xml") {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IResourceCompiler::HasConvertedToSolidXml(const FileInfo &fileInfo) const
|
||||
{
|
||||
string solidXmlPath = filesystem::path(output_).append(RESOURCES_DIR).append(fileInfo.limitKey)
|
||||
.append(fileInfo.fileCluster).append(fileInfo.filename).replace_extension(".sxml").string();
|
||||
if (ResourceUtil::FileExist(solidXmlPath)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IResourceCompiler::NeedIfConvertToSolidXml() const
|
||||
{
|
||||
return ResourceUtil::NeedConverToSolidXml(type_);
|
||||
}
|
||||
|
||||
string IResourceCompiler::GetOutputFolder(const DirectoryInfo &directoryInfo) const
|
||||
{
|
||||
string outputFolder = filesystem::path(output_).append(RESOURCES_DIR)
|
||||
.append(directoryInfo.limitKey).append(directoryInfo.fileCluster).string();
|
||||
return outputFolder;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,349 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 "id_worker.h"
|
||||
#include<filesystem>
|
||||
#include<iostream>
|
||||
#include<regex>
|
||||
#include "cmd_parser.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
const int32_t IdWorker::START_SYS_ID = 0x07800000;
|
||||
uint32_t IdWorker::Init(ResourceIdCluster type, int32_t startId)
|
||||
{
|
||||
type_ = type;
|
||||
if (InitIdDefined() != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (type == ResourceIdCluster::RES_ID_APP) {
|
||||
appId_ = startId;
|
||||
maxId_ = GetMaxId(startId);
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t IdWorker::GenerateId(ResType resType, const string &name)
|
||||
{
|
||||
if (type_ == ResourceIdCluster::RES_ID_APP) {
|
||||
return GenerateAppId(resType, name);
|
||||
}
|
||||
return GenerateSysId(resType, name);
|
||||
}
|
||||
|
||||
vector<IdWorker::ResourceId> IdWorker::GetHeaderId() const
|
||||
{
|
||||
map<ResType, vector<ResourceId>> idClassify;
|
||||
for (const auto &it : ids_) {
|
||||
ResourceId resourceId;
|
||||
resourceId.id = it.second;
|
||||
resourceId.type = ResourceUtil::ResTypeToString(it.first.first);
|
||||
resourceId.name = it.first.second;
|
||||
idClassify[it.first.first].push_back(resourceId);
|
||||
}
|
||||
|
||||
vector<ResourceId> ids;
|
||||
for (const auto &item : idClassify) {
|
||||
ids.insert(ids.end(), item.second.begin(), item.second.end());
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
int32_t IdWorker::GetId(ResType resType, const string &name) const
|
||||
{
|
||||
auto result = ids_.find(make_pair(resType, name));
|
||||
if (result == ids_.end()) {
|
||||
return -1;
|
||||
}
|
||||
return result->second;
|
||||
}
|
||||
|
||||
int32_t IdWorker::GetSystemId(ResType resType, const string &name) const
|
||||
{
|
||||
auto result = definedIds_.find(make_pair(resType, name));
|
||||
if (result == definedIds_.end()) {
|
||||
return -1;
|
||||
}
|
||||
return result->second.id;
|
||||
}
|
||||
|
||||
bool IdWorker::IsValidName(const string &name) const
|
||||
{
|
||||
if (!regex_match(name, regex("[a-zA-z0-9_]+"))) {
|
||||
cerr << "Error: '" << name << "' only contain [a-zA-z0-9_]." << endl;
|
||||
return false;
|
||||
}
|
||||
if (type_ != ResourceIdCluster::RES_ID_SYS) {
|
||||
return true;
|
||||
}
|
||||
return IsValidSystemName(name);
|
||||
}
|
||||
|
||||
bool IdWorker::PushCache(ResType resType, const string &name, int32_t id)
|
||||
{
|
||||
auto result = cacheIds_.emplace(make_pair(resType, name), id);
|
||||
if (!result.second) {
|
||||
return false;
|
||||
}
|
||||
if (appId_ == id) {
|
||||
appId_ = id + 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (id < appId_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int32_t i = appId_; i < id; i++) {
|
||||
delIds_.push_back(i);
|
||||
}
|
||||
appId_ = id + 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
void IdWorker::PushDelId(int32_t id)
|
||||
{
|
||||
delIds_.push_back(id);
|
||||
}
|
||||
|
||||
int32_t IdWorker::GenerateAppId(ResType resType, const string &name)
|
||||
{
|
||||
auto result = ids_.find(make_pair(resType, name));
|
||||
if (result != ids_.end()) {
|
||||
return result->second;
|
||||
}
|
||||
|
||||
result = cacheIds_.find(make_pair(resType, name));
|
||||
if (result != cacheIds_.end()) {
|
||||
ids_.emplace(make_pair(resType, name), result->second);
|
||||
return result->second;
|
||||
}
|
||||
|
||||
if (appId_ > maxId_) {
|
||||
cerr << "Error: id count exceed " << appId_ << ">" << maxId_ << endl;
|
||||
return -1;
|
||||
}
|
||||
int32_t id = 0;
|
||||
if (!delIds_.empty()) {
|
||||
id = delIds_.front();
|
||||
delIds_.erase(delIds_.begin());
|
||||
} else {
|
||||
id = appId_;
|
||||
appId_++;
|
||||
}
|
||||
ids_.emplace(make_pair(resType, name), id);
|
||||
return id;
|
||||
}
|
||||
|
||||
int32_t IdWorker::GenerateSysId(ResType resType, const string &name)
|
||||
{
|
||||
auto result = ids_.find(make_pair(resType, name));
|
||||
if (result != ids_.end()) {
|
||||
return result->second;
|
||||
}
|
||||
|
||||
auto defined = definedIds_.find(make_pair(resType, name));
|
||||
if (defined != definedIds_.end()) {
|
||||
ids_.emplace(make_pair(resType, name), defined->second.id);
|
||||
return defined->second.id;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t IdWorker::InitIdDefined()
|
||||
{
|
||||
InitParser();
|
||||
CmdParser<PackageParser> &parser = CmdParser<PackageParser>::GetInstance();
|
||||
PackageParser &packageParser = parser.GetCmdParser();
|
||||
string idDefinedPath;
|
||||
if (type_ == ResourceIdCluster::RES_ID_SYS) {
|
||||
for (const auto &inputPath : packageParser.GetInputs()) {
|
||||
idDefinedPath = filesystem::path(inputPath).append(RESOURCES_DIR)
|
||||
.append("base").append("element").append(ID_DEFINED_FILE).string();
|
||||
if (InitIdDefined(idDefinedPath) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
idDefinedPath = filesystem::path(packageParser.GetRestoolPath()).parent_path().append(ID_DEFINED_FILE).string();
|
||||
if (InitIdDefined(idDefinedPath) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t IdWorker::InitIdDefined(const std::string &filePath)
|
||||
{
|
||||
if (!ResourceUtil::FileExist(filePath)) {
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
Json::Value root;
|
||||
if (!ResourceUtil::OpenJsonFile(filePath, root)) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
int32_t startSysId = GetStartId(root);
|
||||
if (startSysId < 0) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
auto record = root["record"];
|
||||
if (record.empty()) {
|
||||
cerr << "Error: id_defined.json record empty." << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
if (!record.isArray()) {
|
||||
cerr << "Error: id_defined.json record not array." << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
for (Json::ArrayIndex index = 0; index < record.size(); index++) {
|
||||
auto arrayItem = record[index];
|
||||
ResourceId resourceId;
|
||||
resourceId.seq = index;
|
||||
resourceId.id = startSysId;
|
||||
if (!arrayItem.isObject()) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
for (const auto &handle : handles_) {
|
||||
if (!handle.second(arrayItem[handle.first], resourceId)) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
}
|
||||
if (!PushResourceId(resourceId)) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
void IdWorker::InitParser()
|
||||
{
|
||||
using namespace placeholders;
|
||||
handles_.emplace("type", bind(&IdWorker::ParseType, this, _1, _2));
|
||||
handles_.emplace("name", bind(&IdWorker::ParseName, this, _1, _2));
|
||||
handles_.emplace("order", bind(&IdWorker::ParseOrder, this, _1, _2));
|
||||
}
|
||||
|
||||
bool IdWorker::ParseType(const Json::Value &type, ResourceId &resourceId)
|
||||
{
|
||||
if (type.empty()) {
|
||||
cerr << "Error: id_defined.json seq=" << resourceId.seq << " type empty." << endl;
|
||||
return false;
|
||||
}
|
||||
if (!type.isString()) {
|
||||
cerr << "Error: id_defined.json seq=" << resourceId.seq << " type not string." << endl;
|
||||
return false;
|
||||
}
|
||||
if (ResourceUtil::GetResTypeFromString(type.asString()) == ResType::INVALID_RES_TYPE) {
|
||||
cerr << "Error: id_defined.json seq=" << resourceId.seq << " type '";
|
||||
cerr << type.asString() << "' invalid." << endl;
|
||||
return false;
|
||||
}
|
||||
resourceId.type = type.asString();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IdWorker::ParseName(const Json::Value &name, ResourceId &resourceId)
|
||||
{
|
||||
if (name.empty()) {
|
||||
cerr << "Error: id_defined.json seq=" << resourceId.seq << " name empty." << endl;
|
||||
return false;
|
||||
}
|
||||
if (!name.isString()) {
|
||||
cerr << "Error: id_defined.json seq=" << resourceId.seq << " name not string." << endl;
|
||||
return false;
|
||||
}
|
||||
resourceId.name = name.asString();
|
||||
if ((resourceId.id & START_SYS_ID) == START_SYS_ID && !IsValidSystemName(resourceId.name)) {
|
||||
cerr << "Error: id_defined.json."<< endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IdWorker::ParseOrder(const Json::Value &order, ResourceId &resourceId)
|
||||
{
|
||||
if (order.empty()) {
|
||||
cerr << "Error: id_defined.json seq=" << resourceId.seq << " order empty." << endl;
|
||||
return false;
|
||||
}
|
||||
if (!order.isInt()) {
|
||||
cerr << "Error: id_defined.json seq=" << resourceId.seq << " order not int." << endl;
|
||||
return false;
|
||||
}
|
||||
if (order.asInt() != resourceId.seq) {
|
||||
cerr << "Error: id_defined.json seq=" << resourceId.seq << " order value ";
|
||||
cerr << order.asInt() << " vs expect " << resourceId.seq << endl;
|
||||
return false;
|
||||
}
|
||||
resourceId.id = resourceId.id + order.asInt();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IdWorker::PushResourceId(const ResourceId &resourceId)
|
||||
{
|
||||
ResType resType = ResourceUtil::GetResTypeFromString(resourceId.type);
|
||||
auto result = definedIds_.emplace(make_pair(resType, resourceId.name), resourceId);
|
||||
if (!result.second) {
|
||||
cerr << "Error: '" << resourceId.type << "' '" << resourceId.name << "' duplicated." << endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IdWorker::IsValidSystemName(const string &name) const
|
||||
{
|
||||
if (regex_match(name, regex("^ohos.+"))) {
|
||||
return true;
|
||||
}
|
||||
cerr << "Error: '" << name << "' must start with 'ohos'" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t IdWorker::GetStartId(const Json::Value &root) const
|
||||
{
|
||||
auto startId = root["startId"];
|
||||
if (startId.empty()) {
|
||||
cerr << "Error: id_defined.json 'startId' empty." << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!startId.isString()) {
|
||||
cerr << "Error: id_defined.json 'startId' not string." << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t id = strtol(startId.asString().c_str(), nullptr, 16);
|
||||
return id;
|
||||
}
|
||||
|
||||
int32_t IdWorker::GetMaxId(int32_t startId) const
|
||||
{
|
||||
int32_t flag = 1;
|
||||
while ((flag & startId) == 0) {
|
||||
flag = flag << 1;
|
||||
}
|
||||
return (startId + flag - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 "increment_index.h"
|
||||
#include<algorithm>
|
||||
#include<iostream>
|
||||
#include "key_parser.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
const string IncrementIndex::INDEX_FILE = "index.json";
|
||||
IncrementIndex::IncrementIndex(const string &indexPath, const vector<string> &folder)
|
||||
: indexPath_(indexPath), folder_(folder)
|
||||
{
|
||||
}
|
||||
|
||||
bool IncrementIndex::Save(const map<int32_t, vector<ResourceItem>> &items) const
|
||||
{
|
||||
Json::Value root;
|
||||
root["header"] = Json::Value(Json::ValueType::objectValue);
|
||||
root["header"]["folder"] = Json::Value(Json::ValueType::arrayValue);
|
||||
for (const auto &folder : folder_) {
|
||||
root["header"]["folder"].append(folder);
|
||||
}
|
||||
|
||||
root["index"] = Json::Value(Json::ValueType::objectValue);
|
||||
for (const auto &item : items) {
|
||||
string id = to_string(item.first);
|
||||
root["index"][id] = Json::Value(Json::ValueType::objectValue);
|
||||
for (const auto &resourceItem : item.second) {
|
||||
root["index"][id][resourceItem.GetFilePath()] = Json::Value(Json::ValueType::objectValue);
|
||||
auto &record = root["index"][id][resourceItem.GetFilePath()];
|
||||
string data(reinterpret_cast<const char *>(resourceItem.GetData()), resourceItem.GetDataLength());
|
||||
record["data"] = data;
|
||||
record["name"] = resourceItem.GetName();
|
||||
record["limitkey"] = resourceItem.GetLimitKey();
|
||||
record["type"] = ResourceUtil::ResTypeToString(resourceItem.GetResType());
|
||||
}
|
||||
}
|
||||
|
||||
if (!ResourceUtil::SaveToJsonFile(indexPath_, root)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IncrementIndex::Load(map<int32_t, vector<ResourceItem>> &items) const
|
||||
{
|
||||
Json::Value indexJson;
|
||||
if (!ResourceUtil::OpenJsonFile(indexPath_, indexJson)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto headerInfo = indexJson["header"];
|
||||
if (headerInfo.empty() || !headerInfo.isObject()) {
|
||||
cerr << "Error: " << indexPath_ << " header info." << endl;
|
||||
return true;
|
||||
}
|
||||
auto folderInfo = headerInfo["folder"];
|
||||
if (folderInfo.empty() || !folderInfo.isArray()) {
|
||||
cerr << "Error: " << indexPath_ << " folder info." << endl;
|
||||
return false;
|
||||
}
|
||||
if (folder_.size() != folderInfo.size()) {
|
||||
cerr << "Error: add/delete dependency, don't support increment compile." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < folder_.size(); i++) {
|
||||
if (folder_[i] != folderInfo[static_cast<int>(i)].asString()) {
|
||||
cerr << "Error: dependency change, don't support increment compile." << endl;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!LoadIndex(indexJson["index"], items)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void IncrementIndex::SetSkipPaths(const vector<string> &skipPaths)
|
||||
{
|
||||
skipPaths_ = skipPaths;
|
||||
}
|
||||
|
||||
// below private
|
||||
bool IncrementIndex::LoadIndex(const Json::Value &indexInfo, map<int32_t, vector<ResourceItem>> &items) const
|
||||
{
|
||||
if (indexInfo.empty() || !indexInfo.isObject()) {
|
||||
cerr << "Error: " << indexPath_ << " index info." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto &idMember : indexInfo.getMemberNames()) {
|
||||
int32_t id = strtol(idMember.c_str(), nullptr, 10);
|
||||
if (id < 0) {
|
||||
cerr << "Error: " << indexPath_ << " '" << idMember << "' not integer string." << endl;
|
||||
return false;
|
||||
}
|
||||
if (items.count(id) != 0) {
|
||||
cerr << "Error: " << indexPath_ << " '" << idMember << "' duplicated." << endl;
|
||||
return false;
|
||||
}
|
||||
if (!indexInfo[idMember].isObject()) {
|
||||
cerr << "Error: " << indexPath_ << " '" << idMember << "' not object." << endl;
|
||||
return false;
|
||||
}
|
||||
for (const auto &pathMember : indexInfo[idMember].getMemberNames()) {
|
||||
if (IsIgnore(pathMember)) {
|
||||
continue;
|
||||
}
|
||||
auto item = indexInfo[idMember][pathMember];
|
||||
if (!item.isObject()) {
|
||||
cerr << "Error: " << indexPath_ << " [" << idMember << "][" << pathMember<<"] not object." << endl;
|
||||
return false;
|
||||
}
|
||||
ResourceItem resourceItem;
|
||||
if (!ParseResourceItem(item, pathMember, resourceItem)) {
|
||||
cerr << "Error: " << indexPath_ << " [" << idMember << "][" << pathMember<<"]." << endl;
|
||||
return false;
|
||||
}
|
||||
if (!PushResourceItem(resourceItem, id, items)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IncrementIndex::ParseResourceItem(const Json::Value &item, const string &filePath,
|
||||
ResourceItem &resourceItem) const
|
||||
{
|
||||
string name;
|
||||
string type;
|
||||
string limitKey;
|
||||
string data;
|
||||
if (!GetResourceItemProp(item, "name", name) || !GetResourceItemProp(item, "type", type) ||
|
||||
!GetResourceItemProp(item, "limitkey", limitKey) || !GetResourceItemProp(item, "data", data)) {
|
||||
cerr << "Error: 'name' 'type' 'limitkey' 'data' invalid." << endl;
|
||||
return false;
|
||||
}
|
||||
ResType resType = ResourceUtil::GetResTypeFromString(type);
|
||||
if (resType == ResType::INVALID_RES_TYPE) {
|
||||
cerr << "Error: " << indexPath_ << " invaid ResType '" << type << "'" << endl;
|
||||
return false;
|
||||
}
|
||||
vector<KeyParam> keyParams;
|
||||
if (!KeyParser::Parse(limitKey, keyParams)) {
|
||||
return false;
|
||||
}
|
||||
ResourceItem temp(name, keyParams, resType);
|
||||
if (resType != ResType::ID && !temp.SetData(reinterpret_cast<const int8_t *>(data.c_str()), data.length())) {
|
||||
cerr << "Error: resource set data fail." << endl;
|
||||
return false;
|
||||
}
|
||||
temp.SetFilePath(filePath);
|
||||
temp.SetLimitKey(limitKey);
|
||||
resourceItem = temp;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IncrementIndex::GetResourceItemProp(const Json::Value &item, const string &key, string &value) const
|
||||
{
|
||||
if (item[key].empty() || !item[key].isString()) {
|
||||
return false;
|
||||
}
|
||||
value = item[key].asString();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IncrementIndex::PushResourceItem(const ResourceItem &resourceItem, int32_t id,
|
||||
map<int32_t, vector<ResourceItem>> &items) const
|
||||
{
|
||||
if (items.find(id) == items.end()) {
|
||||
items[id].push_back(resourceItem);
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto &first = items[id].begin();
|
||||
if (resourceItem.GetName() != first->GetName()) {
|
||||
cerr << "Error: " << indexPath_ << " '" << resourceItem.GetName();
|
||||
cerr << "', expect '" << first->GetName() << "'"<< endl;
|
||||
return false;
|
||||
}
|
||||
if (resourceItem.GetResType() != first->GetResType()) {
|
||||
cerr << "Error: " << indexPath_ << " '" << ResourceUtil::ResTypeToString(resourceItem.GetResType());
|
||||
cerr << "', expect '" << ResourceUtil::ResTypeToString(first->GetResType()) << "'"<< endl;
|
||||
return false;
|
||||
}
|
||||
auto result = find_if(items[id].begin(), items[id].end(), [&resourceItem](const auto &iter) {
|
||||
return resourceItem.GetLimitKey() == iter.GetLimitKey();
|
||||
});
|
||||
if (result != items[id].end()) {
|
||||
cerr << "Error: " << indexPath_ << " '" << resourceItem.GetLimitKey() << "' conflict." << endl;
|
||||
return false;
|
||||
}
|
||||
items[id].push_back(resourceItem);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IncrementIndex::IsIgnore(const string &filePath) const
|
||||
{
|
||||
if (skipPaths_.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (find(skipPaths_.begin(), skipPaths_.end(), filePath) != skipPaths_.end()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 "increment_list.h"
|
||||
#include<algorithm>
|
||||
#include<filesystem>
|
||||
#include<iostream>
|
||||
#include "key_parser.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
const string IncrementList::RESTOOL_LIST_FILE = "restool_list.json";
|
||||
IncrementList::IncrementList(const string &listPath, const vector<string> &folder)
|
||||
: listPath_(listPath), folder_(folder)
|
||||
{
|
||||
}
|
||||
|
||||
bool IncrementList::Parse(std::vector<FileIncrement> &fileList) const
|
||||
{
|
||||
Json::Value listJson;
|
||||
if (!ResourceUtil::OpenJsonFile(listPath_, listJson)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ParseArray(listJson["del"], fileList, true) &&
|
||||
ParseArray(listJson["fix"], fileList, false)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// below private
|
||||
bool IncrementList::GetFromPath(const string &filePath, FileIncrement &info) const
|
||||
{
|
||||
int32_t priority = GetPriority(filePath);
|
||||
if (priority < 0) {
|
||||
cerr << "Error: " << RESTOOL_LIST_FILE << " '" << filePath << "' invalid." << endl;
|
||||
return false;
|
||||
}
|
||||
info.rootPath = folder_[priority];
|
||||
string rootPath = filesystem::path(info.rootPath).append("").string();
|
||||
info.relativePath = filePath.substr(rootPath.length());
|
||||
vector<string> segments;
|
||||
if (!ParseSegment(info.relativePath, segments)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
info.dirPath = filesystem::path(filePath).parent_path().string();
|
||||
info.filePath = filePath;
|
||||
info.limitKey = segments[SEG_LIMIT_KEY];
|
||||
if (info.limitKey == RAW_FILE_DIR) {
|
||||
info.dirType = ResType::INVALID_RES_TYPE;
|
||||
return true;
|
||||
}
|
||||
if (!KeyParser::Parse(info.limitKey, info.keyParams)) {
|
||||
cerr << "Error: '" << filePath << "' '" << info.limitKey << "' invalid limit key." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
info.fileCluster = segments[SEG_FILE_CLUSTER];
|
||||
info.dirType = ResourceUtil::GetResTypeByDir(info.fileCluster);
|
||||
if (info.dirType == ResType::INVALID_RES_TYPE) {
|
||||
cerr << "Error: '" << filePath << "' '" << info.fileCluster << "' invalid ResType." << endl;
|
||||
return false;
|
||||
}
|
||||
info.filename = segments[SEG_FILE_NAME];
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t IncrementList::GetPriority(const string &filePath) const
|
||||
{
|
||||
auto result = find_if(folder_.begin(), folder_.end(), [&filePath](auto &iter) {
|
||||
string rootPath = filesystem::path(iter).append("").string();
|
||||
if (filePath.length() <= rootPath.length()) {
|
||||
return false;
|
||||
}
|
||||
if (filePath.compare(0, rootPath.length(), rootPath.c_str()) == 0) {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
if (result == folder_.end()) {
|
||||
return -1;
|
||||
}
|
||||
return (result - folder_.begin());
|
||||
}
|
||||
|
||||
bool IncrementList::ParseSegment(const string &filePath, vector<string> &segments) const
|
||||
{
|
||||
for (const auto &it : filesystem::path(filePath)) {
|
||||
segments.push_back(it.string());
|
||||
}
|
||||
|
||||
if (segments.size() >= (SEG_RESOURCE + 1) && segments[SEG_RESOURCE] != RESOURCES_DIR) {
|
||||
cerr << "Error: '" << filePath << "' don't contain '" << RESOURCES_DIR << "'" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (segments.size() >= (SEG_LIMIT_KEY + 1) && segments[SEG_LIMIT_KEY] == RAW_FILE_DIR) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (segments.size() != SEG_MAX) {
|
||||
cerr << "Error: '" << filePath << "' segments != " << SEG_MAX << endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IncrementList::IteratorArray(const Json::Value &array, function<bool(const string &)> callback) const
|
||||
{
|
||||
if (array.empty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!array.isArray()) {
|
||||
cerr << "Error: "<< RESTOOL_LIST_FILE << ",not array." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (Json::ArrayIndex i = 0; i < array.size(); i++) {
|
||||
if (!array[i].isString()) {
|
||||
cerr << "Error: " << RESTOOL_LIST_FILE << ",not string." << endl;
|
||||
return false;
|
||||
}
|
||||
if (callback && !callback(array[i].asString())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IncrementList::ParseArray(const Json::Value &array, vector<FileIncrement> &fileList, bool isDeleted) const
|
||||
{
|
||||
return IteratorArray(array, [this, &fileList, &isDeleted](const string &filePath) {
|
||||
FileIncrement info;
|
||||
info.isDeleted = isDeleted;
|
||||
if (!GetFromPath(filePath, info)) {
|
||||
return false;
|
||||
}
|
||||
fileList.push_back(info);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,308 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 "increment_manager.h"
|
||||
#include<algorithm>
|
||||
#include<iostream>
|
||||
#include "id_worker.h"
|
||||
#include "key_parser.h"
|
||||
#include "restool_errors.h"
|
||||
#include "xml_key_node.h"
|
||||
|
||||
#include "resource_module_inc.h"
|
||||
#include "module_combine.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
const string IncrementManager::ID_JSON_FILE = "ids.json";
|
||||
IncrementManager::~IncrementManager()
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t IncrementManager::Init(const string &cachePath, const vector<std::string> &folder,
|
||||
const string &outputPath, const string &moduleName)
|
||||
{
|
||||
cachePath_ = cachePath;
|
||||
folder_ = folder;
|
||||
outputPath_ = outputPath;
|
||||
moduleName_ = moduleName;
|
||||
|
||||
if (!InitIdJson()) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (!ClearSolidXml()) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
vector<IncrementList::FileIncrement> dels;
|
||||
if (!InitList(dels)) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
DeleteRawFile(dels);
|
||||
if (!ScanModules(dels)) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
enalbe_= true;
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
// below private
|
||||
bool IncrementManager::InitIdJson()
|
||||
{
|
||||
string idJsonPath = filesystem::path(cachePath_).append(ID_JSON_FILE).string();
|
||||
if (!ResourceUtil::FileExist(idJsonPath)) {
|
||||
return true;
|
||||
}
|
||||
if (!LoadIdJson()) {
|
||||
return false;
|
||||
}
|
||||
firstIncrement_ = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IncrementManager::ScanModules(const vector<IncrementList::FileIncrement> &dels)
|
||||
{
|
||||
vector<ModuleInfo> moduleInfos;
|
||||
for (const auto &folder : folder_) {
|
||||
ModuleInfo moduleInfo;
|
||||
moduleInfo.rootPath = folder;
|
||||
for_each(dels.begin(), dels.end(), [&moduleInfo](const auto &iter) {
|
||||
if (moduleInfo.rootPath != iter.rootPath) {
|
||||
return;
|
||||
}
|
||||
moduleInfo.fileIncrements.push_back(iter);
|
||||
});
|
||||
moduleInfos.push_back(moduleInfo);
|
||||
}
|
||||
|
||||
for (auto &iter : moduleInfos) {
|
||||
string pathHash = ResourceUtil::GenerateHash(iter.rootPath);
|
||||
string moduleCachePath = filesystem::path(cachePath_).append(pathHash).string();
|
||||
ResourceModuleInc resourceModuleInc(iter.rootPath, moduleCachePath, moduleName_, folder_);
|
||||
if (FirstIncrement()) {
|
||||
if (resourceModuleInc.ResourceModule::ScanResource() != RESTOOL_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (resourceModuleInc.ScanResource(iter.fileIncrements) != RESTOOL_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
PushScanDir(resourceModuleInc.GetScanDirectorys());
|
||||
if (ResourceModule::MergeResourceItem(items_, resourceModuleInc.GetOwner()) != RESTOOL_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
if (resourceModuleInc.SaveIndex() != RESTOOL_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ModuleCombine moduleCombine(moduleCachePath, outputPath_);
|
||||
if (!moduleCombine.Combine()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
FlushId();
|
||||
SaveIdJson();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IncrementManager::InitList(vector<IncrementList::FileIncrement> &dels) const
|
||||
{
|
||||
string listPath = filesystem::path(cachePath_).append(IncrementList::RESTOOL_LIST_FILE).string();
|
||||
if (!ResourceUtil::FileExist(listPath)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
IncrementList incrementList(listPath, folder_);
|
||||
if (!incrementList.Parse(dels)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void IncrementManager::FlushId()
|
||||
{
|
||||
for_each(items_.begin(), items_.end(), [](const auto &iter) {
|
||||
auto &idWorker = IdWorker::GetInstance();
|
||||
ResType resType = iter.second.begin()->GetResType();
|
||||
string name = ResourceUtil::GetIdName(iter.second.begin()->GetName(), resType);
|
||||
idWorker.GenerateId(resType, name);
|
||||
});
|
||||
}
|
||||
|
||||
bool IncrementManager::SaveIdJson() const
|
||||
{
|
||||
Json::Value root;
|
||||
for (const auto &iter : items_) {
|
||||
Json::Value node;
|
||||
ResType resType = iter.second.begin()->GetResType();
|
||||
node["name"] = ResourceUtil::GetIdName(iter.second.begin()->GetName(), resType);
|
||||
node["type"] = ResourceUtil::ResTypeToString(resType);
|
||||
root[to_string(iter.first)] = node;
|
||||
}
|
||||
|
||||
string idJsonPath = filesystem::path(cachePath_).append(ID_JSON_FILE).string();
|
||||
if (!ResourceUtil::SaveToJsonFile(idJsonPath, root)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IncrementManager::LoadIdJson()
|
||||
{
|
||||
Json::Value root;
|
||||
string idJsonPath = filesystem::path(cachePath_).append(ID_JSON_FILE).string();
|
||||
if (!ResourceUtil::OpenJsonFile(idJsonPath, root)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!root.isObject()) {
|
||||
cerr << "Error: '" << idJsonPath << "' invalid, not object." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto &idWorker = IdWorker::GetInstance();
|
||||
for (const auto &member : root.getMemberNames()) {
|
||||
int32_t id = strtol(member.c_str(), nullptr, 10);
|
||||
if (id < 0) {
|
||||
cerr << "Error: '" << idJsonPath << "' invalid '" << member << "'" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto &node = root[member];
|
||||
if (!node.isObject()) {
|
||||
cerr << "Error: '" << idJsonPath << "' '" << member << "' not object." << endl;
|
||||
return false;
|
||||
}
|
||||
if (!node["name"].isString()) {
|
||||
cerr << "Error: '" << idJsonPath << "' '" << member << "' name not string." << endl;
|
||||
return false;
|
||||
}
|
||||
string name = node["name"].asString();
|
||||
|
||||
if (!node["type"].isString()) {
|
||||
cerr << "Error: '" << idJsonPath << "' '" << member << "' type not string." << endl;
|
||||
return false;
|
||||
}
|
||||
ResType resType = ResourceUtil::GetResTypeFromString(node["type"].asString());
|
||||
if (resType == ResType::INVALID_RES_TYPE) {
|
||||
cerr << "Error: '" << idJsonPath << "' '" << member << "' '" << node["type"] << "' invalid." << endl;
|
||||
return false;
|
||||
}
|
||||
if (!idWorker.PushCache(resType, name, id)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void IncrementManager::PushScanDir(const map<ResType, vector<DirectoryInfo>> &scanDirs)
|
||||
{
|
||||
for (const auto &iter : scanDirs) {
|
||||
for (const auto &directoryInfo : iter.second) {
|
||||
scanDirs_[iter.first].push_back(directoryInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IncrementManager::DeleteRawFile(vector<IncrementList::FileIncrement> &dels) const
|
||||
{
|
||||
for (auto it = dels.begin(); it != dels.end();) {
|
||||
if (it->dirType != ResType::INVALID_RES_TYPE) {
|
||||
it++;
|
||||
continue;
|
||||
}
|
||||
string rawFilePath = filesystem::path(outputPath_).append(it->relativePath).string();
|
||||
filesystem::remove(rawFilePath);
|
||||
it = dels.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
bool IncrementManager::ClearSolidXml() const
|
||||
{
|
||||
string resourceDir = filesystem::path(outputPath_).append(RESOURCES_DIR).string();
|
||||
if (!ResourceUtil::FileExist(resourceDir)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ResourceDirectory resourceDirectory;
|
||||
if (!resourceDirectory.ScanResources(resourceDir, [](const DirectoryInfo &info) {
|
||||
if (!ResourceUtil::NeedConverToSolidXml(info.dirType)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (const auto &entry : filesystem::directory_iterator(info.dirPath)) {
|
||||
if (entry.is_directory()) {
|
||||
cerr << "Error: '" << entry.path().string() << "' is directroy." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
string extension = entry.path().extension().string();
|
||||
if (extension != ".sxml" && extension != ".key" && extension != ".json") {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!filesystem::remove(entry.path().string())) {
|
||||
cerr << "Error: remove '" << entry.path().string() << "' fail." << endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
})) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
{
|
||||
"0x01000000":
|
||||
{
|
||||
"name":"xxxxx",
|
||||
"type":"string"
|
||||
}
|
||||
}
|
||||
{
|
||||
"header":{
|
||||
"folder":["xxxx", "xxxx", "xxxx", "xxxx"]
|
||||
},
|
||||
"index":{
|
||||
"0x01000000":{
|
||||
"filepath":{
|
||||
"data":"xxxx",
|
||||
"name":"xxxx",
|
||||
"type":"xxxx",
|
||||
"limitkey":"xxxx"
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
"del":[
|
||||
"xx/xx/xx/xxx"
|
||||
],
|
||||
"fix":[
|
||||
"xxx/xxx/xx"
|
||||
]
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,469 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 "json_compiler.h"
|
||||
#include <iostream>
|
||||
#include <regex>
|
||||
#include "restool_errors.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
const string JsonCompiler::TAG_NAME = "name";
|
||||
const string JsonCompiler::TAG_VALUE = "value";
|
||||
const string JsonCompiler::TAG_PARENT = "parent";
|
||||
const string JsonCompiler::TAG_QUANTITY = "quantity";
|
||||
const vector<string> JsonCompiler::QUANTITY_ATTRS = { "zero", "one", "two", "few", "many", "other" };
|
||||
|
||||
JsonCompiler::JsonCompiler(ResType type, const string &output)
|
||||
: IResourceCompiler(type, output)
|
||||
{
|
||||
InitParser();
|
||||
}
|
||||
|
||||
JsonCompiler::~JsonCompiler()
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t JsonCompiler::CompileSingleFile(const FileInfo &fileInfo)
|
||||
{
|
||||
if (fileInfo.limitKey == "base" &&
|
||||
fileInfo.fileCluster == "element" &&
|
||||
fileInfo.filename == ID_DEFINED_FILE) {
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
Json::Value root;
|
||||
if (!ResourceUtil::OpenJsonFile(fileInfo.filePath, root)) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (!root.isObject()) {
|
||||
cerr << "Error: root node must object," << fileInfo.filePath << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (root.getMemberNames().size() != 1) {
|
||||
cerr << "Error: root node must only one member," << fileInfo.filePath << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
string tag = root.getMemberNames()[0];
|
||||
auto ret = g_contentClusterMap.find(tag);
|
||||
if (ret == g_contentClusterMap.end()) {
|
||||
cerr << "Error: invalid tag name '" << tag << "'," << fileInfo.filePath << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
FileInfo copy = fileInfo;
|
||||
copy.fileType = ret->second;
|
||||
if (!ParseJsonArrayLevel(root[tag], copy)) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
//below private
|
||||
void JsonCompiler::InitParser()
|
||||
{
|
||||
using namespace placeholders;
|
||||
handles_.emplace(ResType::STRING, bind(&JsonCompiler::HandleString, this, _1, _2));
|
||||
handles_.emplace(ResType::INTEGER, bind(&JsonCompiler::HandleInteger, this, _1, _2));
|
||||
handles_.emplace(ResType::BOOLEAN, bind(&JsonCompiler::HandleBoolean, this, _1, _2));
|
||||
handles_.emplace(ResType::COLOR, bind(&JsonCompiler::HandleColor, this, _1, _2));
|
||||
handles_.emplace(ResType::FLOAT, bind(&JsonCompiler::HandleFloat, this, _1, _2));
|
||||
handles_.emplace(ResType::STRARRAY, bind(&JsonCompiler::HandleStringArray, this, _1, _2));
|
||||
handles_.emplace(ResType::INTARRAY, bind(&JsonCompiler::HandleIntegerArray, this, _1, _2));
|
||||
handles_.emplace(ResType::THEME, bind(&JsonCompiler::HandleTheme, this, _1, _2));
|
||||
handles_.emplace(ResType::PATTERN, bind(&JsonCompiler::HandlePattern, this, _1, _2));
|
||||
handles_.emplace(ResType::PLURAL, bind(&JsonCompiler::HandlePlural, this, _1, _2));
|
||||
}
|
||||
|
||||
bool JsonCompiler::ParseJsonArrayLevel(const Json::Value &arrayNode, const FileInfo &fileInfo)
|
||||
{
|
||||
if (!arrayNode.isArray()) {
|
||||
cerr << "Error: '" << ResourceUtil::ResTypeToString(fileInfo.fileType) << "' must be array,";
|
||||
cerr << fileInfo.filePath << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (arrayNode.empty()) {
|
||||
cerr << "Error: '" << ResourceUtil::ResTypeToString(fileInfo.fileType) << "' empty,";
|
||||
cerr << fileInfo.filePath << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (Json::ArrayIndex index = 0; index < arrayNode.size(); index++) {
|
||||
if (!arrayNode[index].isObject()) {
|
||||
cerr << "Error: the seq=" << index << " item must be object," << fileInfo.filePath << endl;
|
||||
return false;
|
||||
}
|
||||
if (!ParseJsonObjectLevel(arrayNode[index], fileInfo)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JsonCompiler::ParseJsonObjectLevel(const Json::Value &objectNode, const FileInfo &fileInfo)
|
||||
{
|
||||
auto nameNode = objectNode[TAG_NAME];
|
||||
if (nameNode.empty()) {
|
||||
cerr << "Error: name empty," << fileInfo.filePath << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!nameNode.isString()) {
|
||||
cerr << "Error: name must string," << fileInfo.filePath << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
ResourceItem resourceItem(nameNode.asString(), fileInfo.keyParams, fileInfo.fileType);
|
||||
resourceItem.SetFilePath(fileInfo.filePath);
|
||||
resourceItem.SetLimitKey(fileInfo.limitKey);
|
||||
auto ret = handles_.find(fileInfo.fileType);
|
||||
if (ret == handles_.end()) {
|
||||
cerr << "Error: json parser don't support " << ResourceUtil::ResTypeToString(fileInfo.fileType) << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ret->second(objectNode, resourceItem)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return MergeResourceItem(resourceItem);
|
||||
}
|
||||
|
||||
bool JsonCompiler::HandleString(const Json::Value &objectNode, ResourceItem &resourceItem) const
|
||||
{
|
||||
Json::Value valueNode = objectNode[TAG_VALUE];
|
||||
if (!CheckJsonStringValue(valueNode, resourceItem)) {
|
||||
return false;
|
||||
}
|
||||
return PushString(valueNode.asString(), resourceItem);
|
||||
}
|
||||
|
||||
bool JsonCompiler::HandleInteger(const Json::Value &objectNode, ResourceItem &resourceItem) const
|
||||
{
|
||||
Json::Value valueNode = objectNode[TAG_VALUE];
|
||||
if (!CheckJsonIntegerValue(valueNode, resourceItem)) {
|
||||
return false;
|
||||
}
|
||||
return PushString(valueNode.asString(), resourceItem);
|
||||
}
|
||||
|
||||
bool JsonCompiler::HandleBoolean(const Json::Value &objectNode, ResourceItem &resourceItem) const
|
||||
{
|
||||
Json::Value valueNode = objectNode[TAG_VALUE];
|
||||
if (valueNode.isString()) {
|
||||
regex ref("^\\$boolean:.*");
|
||||
if (!regex_match(valueNode.asString(), ref)) {
|
||||
cerr << "Error: '" << valueNode.asString() << "' only refer '$boolean:xxx',";
|
||||
cerr << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
} else if (!valueNode.isBool()) {
|
||||
cerr << "Error: '" << resourceItem.GetName() << "' value not boolean," << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
return PushString(valueNode.asString(), resourceItem);
|
||||
}
|
||||
|
||||
bool JsonCompiler::HandleColor(const Json::Value &objectNode, ResourceItem &resourceItem) const
|
||||
{
|
||||
return HandleString(objectNode, resourceItem);
|
||||
}
|
||||
|
||||
bool JsonCompiler::HandleFloat(const Json::Value &objectNode, ResourceItem &resourceItem) const
|
||||
{
|
||||
return HandleString(objectNode, resourceItem);
|
||||
}
|
||||
|
||||
bool JsonCompiler::HandleStringArray(const Json::Value &objectNode, ResourceItem &resourceItem) const
|
||||
{
|
||||
vector<string> extra;
|
||||
return ParseValueArray(objectNode, resourceItem, extra,
|
||||
[this](const Json::Value &arrayItem, const ResourceItem &resourceItem, vector<string> &values) -> bool {
|
||||
if (!arrayItem.isObject()) {
|
||||
cerr << "Error: '" << resourceItem.GetName() << "' value array item not object,";
|
||||
cerr << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
auto value = arrayItem[TAG_VALUE];
|
||||
if (!CheckJsonStringValue(value, resourceItem)) {
|
||||
return false;
|
||||
}
|
||||
values.push_back(value.asString());
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
bool JsonCompiler::HandleIntegerArray(const Json::Value &objectNode, ResourceItem &resourceItem) const
|
||||
{
|
||||
vector<string> extra;
|
||||
return ParseValueArray(objectNode, resourceItem, extra,
|
||||
[this](const Json::Value &arrayItem, const ResourceItem &resourceItem, vector<string> &values) -> bool {
|
||||
if (!CheckJsonIntegerValue(arrayItem, resourceItem)) {
|
||||
return false;
|
||||
}
|
||||
values.push_back(arrayItem.asString());
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
bool JsonCompiler::HandleTheme(const Json::Value &objectNode, ResourceItem &resourceItem) const
|
||||
{
|
||||
vector<string> extra;
|
||||
if (!ParseParent(objectNode, resourceItem, extra)) {
|
||||
return false;
|
||||
}
|
||||
return ParseValueArray(objectNode, resourceItem, extra,
|
||||
[this](const Json::Value &arrayItem, const ResourceItem &resourceItem, vector<string> &values) {
|
||||
return ParseAttribute(arrayItem, resourceItem, values);
|
||||
});
|
||||
}
|
||||
|
||||
bool JsonCompiler::HandlePattern(const Json::Value &objectNode, ResourceItem &resourceItem) const
|
||||
{
|
||||
return HandleTheme(objectNode, resourceItem);
|
||||
}
|
||||
|
||||
bool JsonCompiler::HandlePlural(const Json::Value &objectNode, ResourceItem &resourceItem) const
|
||||
{
|
||||
vector<string> extra;
|
||||
vector<string> attrs;
|
||||
bool result = ParseValueArray(objectNode, resourceItem, extra,
|
||||
[&attrs, this](const Json::Value &arrayItem, const ResourceItem &resourceItem, vector<string> &values) {
|
||||
if (!CheckPluralValue(arrayItem, resourceItem)) {
|
||||
return false;
|
||||
}
|
||||
string quantityValue = arrayItem[TAG_QUANTITY].asString();
|
||||
if (find(attrs.begin(), attrs.end(), quantityValue) != attrs.end()) {
|
||||
cerr << "Error: Plural '" << resourceItem.GetName() << "' quantity '" << quantityValue;
|
||||
cerr << "' duplicated," << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
attrs.push_back(quantityValue);
|
||||
values.push_back(quantityValue);
|
||||
values.push_back(arrayItem[TAG_VALUE].asString());
|
||||
return true;
|
||||
});
|
||||
if (!result) {
|
||||
return false;
|
||||
}
|
||||
if (find(attrs.begin(), attrs.end(), "other") == attrs.end()) {
|
||||
cerr << "Error: Plural '" << resourceItem.GetName() << "' quantity must contains 'other',";
|
||||
cerr << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JsonCompiler::PushString(const string &value, ResourceItem &resourceItem) const
|
||||
{
|
||||
if (!resourceItem.SetData(reinterpret_cast<const int8_t *>(value.c_str()), value.length())) {
|
||||
cerr << "Error: resourceItem setdata fail,'" << resourceItem.GetName() << "',";
|
||||
cerr << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JsonCompiler::CheckJsonStringValue(const Json::Value &valueNode, const ResourceItem &resourceItem) const
|
||||
{
|
||||
if (!valueNode.isString()) {
|
||||
cerr << "Error: '" << resourceItem.GetName() << "' value not string," << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
const map<ResType, string> REFS = {
|
||||
{ ResType::STRING, "$string:" },
|
||||
{ ResType::STRARRAY, "$string:" },
|
||||
{ ResType::COLOR, "$color:" },
|
||||
{ ResType::FLOAT, "$float:" }
|
||||
};
|
||||
|
||||
string value = valueNode.asString();
|
||||
ResType type = resourceItem.GetResType();
|
||||
regex ref("^\\$.+:");
|
||||
smatch result;
|
||||
if (regex_search(value, result, ref) && result[0] != REFS.at(type)) {
|
||||
cerr << "Error: '" << value << "' only refer '"<< REFS.at(type) << "xxx',";
|
||||
cerr << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JsonCompiler::CheckJsonIntegerValue(const Json::Value &valueNode, const ResourceItem &resourceItem) const
|
||||
{
|
||||
if (valueNode.isString()) {
|
||||
regex ref("^\\$integer:.*");
|
||||
if (!regex_match(valueNode.asString(), ref)) {
|
||||
cerr << "Error: '" << valueNode.asString() << "' only refer '$integer:xxx',";
|
||||
cerr << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
} else if (!valueNode.isInt()) {
|
||||
cerr << "Error: '" << resourceItem.GetName() << "' value not integer," << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JsonCompiler::ParseValueArray(const Json::Value &objectNode, ResourceItem &resourceItem,
|
||||
const vector<string> &extra, HandleValue callback) const
|
||||
{
|
||||
Json::Value arrayNode = objectNode[TAG_VALUE];
|
||||
if (!arrayNode.isArray()) {
|
||||
cerr << "Error: '" << resourceItem.GetName() << "' value not array," << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (arrayNode.empty()) {
|
||||
cerr << "Error: '" << resourceItem.GetName() << "' value empty," << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
vector<string> contents;
|
||||
if (!extra.empty()) {
|
||||
contents.assign(extra.begin(), extra.end());
|
||||
}
|
||||
for (Json::ArrayIndex index = 0; index < arrayNode.size(); index++) {
|
||||
vector<string> values;
|
||||
if (!callback(arrayNode[index], resourceItem, values)) {
|
||||
return false;
|
||||
}
|
||||
contents.insert(contents.end(), values.begin(), values.end());
|
||||
}
|
||||
|
||||
string data = ResourceUtil::ComposeStrings(contents);
|
||||
if (data.empty()) {
|
||||
cerr << "Error: '" << resourceItem.GetName() << "' array too large,"<< resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
return PushString(data, resourceItem);
|
||||
}
|
||||
|
||||
bool JsonCompiler::ParseParent(const Json::Value &objectNode, const ResourceItem &resourceItem,
|
||||
vector<string> &extra) const
|
||||
{
|
||||
auto parent = objectNode[TAG_PARENT];
|
||||
string type = ResourceUtil::ResTypeToString(resourceItem.GetResType());
|
||||
if (!parent.isNull()) {
|
||||
if (!parent.isString()) {
|
||||
cerr << "Error: " << type << " '" << resourceItem.GetName() << "' parent not string,";
|
||||
cerr << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
if (parent.empty()) {
|
||||
cerr << "Error: " << type << " '"<< resourceItem.GetName() << "' parent empty,";
|
||||
cerr << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
string parentValue = parent.asString();
|
||||
if (regex_match(parentValue, regex("^ohos:" + type + ":.+"))) {
|
||||
parentValue = "$" + parentValue;
|
||||
} else {
|
||||
parentValue = "$" + type + ":" + parentValue;
|
||||
}
|
||||
extra.push_back(parentValue);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JsonCompiler::ParseAttribute(const Json::Value &arrayItem, const ResourceItem &resourceItem,
|
||||
vector<string> &values) const
|
||||
{
|
||||
string type = ResourceUtil::ResTypeToString(resourceItem.GetResType());
|
||||
if (!arrayItem.isObject()) {
|
||||
cerr << "Error: " << type << " '" << resourceItem.GetName() << "' attribute not object,";
|
||||
cerr << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
auto name = arrayItem[TAG_NAME];
|
||||
if (name.empty()) {
|
||||
cerr << "Error: " << type << " '" << resourceItem.GetName() << "' attribute name empty,";
|
||||
cerr << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
if (!name.isString()) {
|
||||
cerr << "Error: " << type << " '" << resourceItem.GetName() << "' attribute name not string,";
|
||||
cerr << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
values.push_back(name.asString());
|
||||
|
||||
auto value = arrayItem[TAG_VALUE];
|
||||
if (value.isNull()) {
|
||||
cerr << "Error: " << type << " '" << resourceItem.GetName() << "' attribute '" << name.asString();
|
||||
cerr << "' value empty," << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
if (!value.isString()) {
|
||||
cerr << "Error: " << type << " '" << resourceItem.GetName() << "' attribute '" << name.asString();
|
||||
cerr << "' value not string," << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
values.push_back(value.asString());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JsonCompiler::CheckPluralValue(const Json::Value &arrayItem, const ResourceItem &resourceItem) const
|
||||
{
|
||||
if (!arrayItem.isObject()) {
|
||||
cerr << "Error: Plural '" << resourceItem.GetName() << "' array item not object,";
|
||||
cerr << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
auto quantity = arrayItem[TAG_QUANTITY];
|
||||
if (quantity.empty()) {
|
||||
cerr << "Error: Plural '" << resourceItem.GetName() << "' quantity empty,";
|
||||
cerr << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
if (!quantity.isString()) {
|
||||
cerr << "Error: Plural '" << resourceItem.GetName() << "' quantity not string,";
|
||||
cerr << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
string quantityValue = quantity.asString();
|
||||
if (find(QUANTITY_ATTRS.begin(), QUANTITY_ATTRS.end(), quantityValue) == QUANTITY_ATTRS.end()) {
|
||||
string buffer(" ");
|
||||
for_each(QUANTITY_ATTRS.begin(), QUANTITY_ATTRS.end(), [&buffer](auto iter) {
|
||||
buffer.append(iter).append(" ");
|
||||
});
|
||||
cerr << "Error: Plural '" << resourceItem.GetName() << "' quantity '" << quantityValue;
|
||||
cerr << "' not in [" << buffer << "]," << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto value = arrayItem[TAG_VALUE];
|
||||
if (value.isNull()) {
|
||||
cerr << "Error: Plural '" << resourceItem.GetName() << "' quantity '" << quantityValue;
|
||||
cerr << "' value empty" << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
if (!value.isString()) {
|
||||
cerr << "Error: Plural '" << resourceItem.GetName() << "' quantity '" << quantityValue;
|
||||
cerr << "' value not string" << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 "key_parser.h"
|
||||
#include<regex>
|
||||
#include "resource_util.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
map<string, vector<KeyParam>> KeyParser::caches_ = {};
|
||||
bool KeyParser::Parse(const string &folderName, vector<KeyParam> &keyparams)
|
||||
{
|
||||
if (folderName == "base") {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (caches_.count(folderName) != 0) {
|
||||
keyparams = caches_[folderName];
|
||||
return true;
|
||||
}
|
||||
vector<string> keyParts;
|
||||
ResourceUtil::Split(folderName, keyParts, "-");
|
||||
|
||||
vector<parse_key_founction> founctions = {
|
||||
ParseMccMnc,
|
||||
ParseLSR,
|
||||
ParseOrientation,
|
||||
ParseDeviceType,
|
||||
ParseNightMode,
|
||||
ParseResolution,
|
||||
};
|
||||
|
||||
if (!ParseMatch(keyParts, keyparams, founctions)) {
|
||||
return false;
|
||||
}
|
||||
caches_.emplace(folderName, keyparams);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KeyParser::ParseMatch(const vector<string> &keys, vector<KeyParam> &keyparams, const vector<parse_key_founction> &founctions)
|
||||
{
|
||||
size_t next = 0;
|
||||
for (const auto &key : keys) {
|
||||
bool parseMatch = false;
|
||||
for (size_t i = next; i < founctions.size(); i++) {
|
||||
if (founctions[i](key, keyparams)) {
|
||||
parseMatch = true;
|
||||
next = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!parseMatch) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KeyParser::ParseMatchBySeq(const vector<string> &keys, vector<KeyParam> &keyparams, const vector<parse_key_founction> &founctions)
|
||||
{
|
||||
for (size_t i = 0; i < keys.size(); i++) {
|
||||
if (!founctions[i](keys[i], keyparams)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KeyParser::ParseMccMnc(const string &folderName, vector<KeyParam> &keyparams)
|
||||
{
|
||||
vector<parse_key_founction> founctions = {
|
||||
ParseMcc,
|
||||
ParseMnc,
|
||||
};
|
||||
|
||||
vector<string> keyParts;
|
||||
ResourceUtil::Split(folderName, keyParts, "_");
|
||||
if (keyParts.size() > founctions.size()) {
|
||||
return false;
|
||||
}
|
||||
return ParseMatchBySeq(keyParts, keyparams, founctions);
|
||||
}
|
||||
|
||||
bool KeyParser::ParseMcc(const string &folderName, vector<KeyParam> &keyparams)
|
||||
{
|
||||
regex mcc("mcc(\\d{3})");
|
||||
if (!regex_match(folderName, mcc)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PushMccMnc(folderName, KeyType::MCC, keyparams);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KeyParser::ParseMnc(const string &folderName, vector<KeyParam> &keyparams)
|
||||
{
|
||||
regex mcc("mnc(\\d{2,3})");
|
||||
if (!regex_match(folderName, mcc)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PushMccMnc(folderName, KeyType::MNC, keyparams);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KeyParser::ParseLSR(const string &folderName, vector<KeyParam> &keyparams)
|
||||
{
|
||||
map<string, vector<parse_key_founction>> founctionModels = {
|
||||
{ "all", { ParseLanguage, ParseScript, ParseRegion } },
|
||||
{ "language script", { ParseLanguage, ParseScript} },
|
||||
{ "language region", { ParseLanguage, ParseRegion } },
|
||||
};
|
||||
|
||||
vector<string> keyParts;
|
||||
ResourceUtil::Split(folderName, keyParts, "_");
|
||||
if (keyParts.size() > founctionModels["all"].size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto model : founctionModels) {
|
||||
vector<KeyParam> tmp;
|
||||
if (ParseMatchBySeq(keyParts, tmp, model.second)) {
|
||||
keyparams.insert(keyparams.end(), tmp.begin(), tmp.end());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool KeyParser::ParseLanguage(const string &folderName, vector<KeyParam> &keyparams)
|
||||
{
|
||||
if (g_deviceMap.find(folderName) != g_deviceMap.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
regex language("[a-z]{2,3}");
|
||||
if (!regex_match(folderName, language)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PushLSR(folderName, KeyType::LANGUAGE, keyparams);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KeyParser::ParseScript(const string &folderName, vector<KeyParam> &keyparams)
|
||||
{
|
||||
if (folderName.length() != SCRIPT_LENGHT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
regex script("^[A-Z][a-z]{3}");
|
||||
if (!regex_match(folderName, script)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PushLSR(folderName, KeyType::SCRIPT, keyparams);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KeyParser::ParseRegion(const string &folderName, vector<KeyParam> &keyparams)
|
||||
{
|
||||
if (folderName.length() < MIN_REGION_LENGHT || folderName.length() > MAX_REGION_LENGHT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
regex regionOfNumber("[0-9]{3}");
|
||||
regex regionOfSupper("[A-Z]{2,3}");
|
||||
|
||||
if (!regex_match(folderName, regionOfNumber) && !regex_match(folderName, regionOfSupper)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PushLSR(folderName, KeyType::REGION, keyparams);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KeyParser::ParseOrientation(const string &folderName, vector<KeyParam> &keyparams)
|
||||
{
|
||||
auto it = g_orientaionMap.find(folderName);
|
||||
if (it == g_orientaionMap.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PushValue(static_cast<uint32_t>(it->second), KeyType::ORIENTATION, keyparams);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KeyParser::ParseDeviceType(const string &folderName, vector<KeyParam> &keyparams)
|
||||
{
|
||||
auto it = g_deviceMap.find(folderName);
|
||||
if (it == g_deviceMap.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PushValue(static_cast<uint32_t>(it->second), KeyType::DEVICETYPE, keyparams);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KeyParser::ParseNightMode(const string &folderName, vector<KeyParam> &keyparams)
|
||||
{
|
||||
auto it = g_nightModeMap.find(folderName);
|
||||
if (it == g_nightModeMap.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PushValue(static_cast<uint32_t>(it->second), KeyType::NIGHTMODE, keyparams);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KeyParser::ParseResolution(const string &folderName, vector<KeyParam> &keyparams)
|
||||
{
|
||||
auto it = g_resolutionMap.find(folderName);
|
||||
if (it == g_resolutionMap.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PushValue(static_cast<uint32_t>(it->second), KeyType::RESOLUTION, keyparams);
|
||||
return true;
|
||||
}
|
||||
|
||||
void KeyParser::PushMccMnc(const string &folderName, KeyType type, vector<KeyParam> &keyparams)
|
||||
{
|
||||
KeyParam keyParam;
|
||||
keyParam.keyType = type;
|
||||
keyParam.value = atoi(folderName.substr(MCC_MNC_KEY_LENGHT).c_str());
|
||||
keyparams.push_back(keyParam);
|
||||
}
|
||||
|
||||
void KeyParser::PushLSR(const string &folderName, KeyType type, vector<KeyParam> &keyparams)
|
||||
{
|
||||
KeyParam keyParam;
|
||||
keyParam.keyType = type;
|
||||
keyParam.value = 0;
|
||||
for (size_t i = 0; i < folderName.size(); i++) {
|
||||
keyParam.value = (keyParam.value << 8) | (folderName[i] & 0xff);
|
||||
}
|
||||
keyparams.push_back(keyParam);
|
||||
}
|
||||
|
||||
void KeyParser::PushValue(uint32_t value, KeyType type, vector<KeyParam> &keyparams)
|
||||
{
|
||||
KeyParam keyParam;
|
||||
keyParam.keyType = type;
|
||||
keyParam.value = value;
|
||||
keyparams.push_back(keyParam);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 "module_combine.h"
|
||||
#include<algorithm>
|
||||
#include<filesystem>
|
||||
#include<iostream>
|
||||
#include "key_manager.h"
|
||||
#include "resource_util.h"
|
||||
#include "solid_xml.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
ModuleCombine::ModuleCombine(const string &modulePath, const string &outputPath)
|
||||
: modulePath_(modulePath), outputPath_(outputPath)
|
||||
{
|
||||
}
|
||||
|
||||
bool ModuleCombine::Combine()
|
||||
{
|
||||
string resourceDir = filesystem::path(modulePath_).append(RESOURCES_DIR).string();
|
||||
ResourceDirectory resourceDirectory;
|
||||
if (!resourceDirectory.ScanResources(resourceDir, [this](const DirectoryInfo &info) -> bool {
|
||||
return CombineDirectory(info);
|
||||
})) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// below private
|
||||
bool ModuleCombine::CombineDirectory(const DirectoryInfo &directoryInfo)
|
||||
{
|
||||
string outputFolder = filesystem::path(outputPath_).append(RESOURCES_DIR)
|
||||
.append(directoryInfo.limitKey).append(directoryInfo.fileCluster).string();
|
||||
if (!ResourceUtil::CreateDirs(outputFolder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
map<string, string> sxmlPaths;
|
||||
for (const auto &entry : filesystem::directory_iterator(directoryInfo.dirPath)) {
|
||||
string src = entry.path().string();
|
||||
if (entry.is_directory()) {
|
||||
cerr << "Error: " << src << " is directory." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
string filename = entry.path().filename().string();
|
||||
string dst = filesystem::path(outputFolder).append(filename).string();
|
||||
if (ResourceUtil::FileExist(dst)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry.path().extension().string() == ".sxml") {
|
||||
sxmlPaths.emplace(src, dst);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto result = find_if (XmlKeyNode::KEY_TO_FILE_NAME.begin(), XmlKeyNode::KEY_TO_FILE_NAME.end(),
|
||||
[&filename](const auto &iter) {
|
||||
return filename == iter.second;
|
||||
});
|
||||
if (result != XmlKeyNode::KEY_TO_FILE_NAME.end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ResourceUtil::CopyFleInner(src, dst)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return CombineSolidXml(directoryInfo.dirPath, outputFolder, sxmlPaths);
|
||||
}
|
||||
|
||||
bool ModuleCombine::CombineSolidXml(const string &src, const string &dst, const map<string , string> &sxmlPaths)
|
||||
{
|
||||
if (sxmlPaths.empty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
KeyManager oldKeyManager;
|
||||
if (!oldKeyManager.LoadKey(src)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
KeyManager newKeyManager;
|
||||
if (!newKeyManager.LoadKey(dst)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto &sxmlPath : sxmlPaths) {
|
||||
SolidXml solidXml(sxmlPath.first, oldKeyManager.GetKeys());
|
||||
if (!solidXml.FlushNodeKeys(sxmlPath.second, newKeyManager.GetKeys())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!newKeyManager.SaveKey(dst)) {
|
||||
cerr << "Error: GenerateToOther " << modulePath_ << " fail." << endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 "preview_manager.h"
|
||||
#include<filesystem>
|
||||
#include<iostream>
|
||||
#include "factory_resource_compiler.h"
|
||||
#include "key_parser.h"
|
||||
#include "resource_module.h"
|
||||
#include "resource_util.h"
|
||||
#include "sqlite_database.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
PreviewManager::~PreviewManager()
|
||||
{
|
||||
SqliteDatabase &database = SqliteDatabase::GetInstance();
|
||||
database.CloseDatabase();
|
||||
}
|
||||
|
||||
uint32_t PreviewManager::ScanModules(const vector<string> &modulePaths, const string &output)
|
||||
{
|
||||
|
||||
SqliteDatabase &database = SqliteDatabase::GetInstance();
|
||||
string dbPath = filesystem::path(output).append("resources.db").string();
|
||||
database.Init(dbPath);
|
||||
if(!database.OpenDatabase()) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
int32_t priority = 0;
|
||||
if (priority_ >= 0) {
|
||||
priority = priority_;
|
||||
}
|
||||
|
||||
for (const auto &iter : modulePaths) {
|
||||
if (filesystem::is_directory(iter)) {
|
||||
ResourceModule resourceMoudle(iter, output, "");
|
||||
resourceMoudle.SetPreviewMode(true);
|
||||
database.SetPriority(priority);
|
||||
if (resourceMoudle.ScanResource() != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
} else if (!ScanFile(iter, priority)) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
if (priority_ >= 0) {
|
||||
continue;
|
||||
}
|
||||
priority++;
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
bool PreviewManager::ScanFile(const string &filePath, int32_t priority)
|
||||
{
|
||||
if (!ResourceUtil::FileExist(filePath)) {
|
||||
cerr << "Error: " << filePath << " non't exist." << endl;
|
||||
return false;
|
||||
}
|
||||
FileInfo fileInfo;
|
||||
fileInfo.filePath = filePath;
|
||||
fileInfo.filename = filesystem::path(filePath).filename().string();
|
||||
fileInfo.dirPath = filesystem::path(filePath).parent_path().string();
|
||||
fileInfo.fileCluster = filesystem::path(fileInfo.dirPath).filename().string();
|
||||
fileInfo.limitKey = filesystem::path(fileInfo.dirPath).parent_path().filename().string();
|
||||
|
||||
fileInfo.dirType = ResourceUtil::GetResTypeByDir(fileInfo.fileCluster);
|
||||
if (fileInfo.dirType == ResType::INVALID_RES_TYPE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!KeyParser::Parse(fileInfo.limitKey, fileInfo.keyParams)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unique_ptr<IResourceCompiler> resourceCompiler =
|
||||
FactoryResourceCompiler::CreateCompiler(fileInfo.dirType, "");
|
||||
resourceCompiler->SetPreviewMode(true);
|
||||
resourceCompiler->SetModuleName("");
|
||||
if (resourceCompiler->Compile(fileInfo) != RESTOOL_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,321 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 "reference_parser.h"
|
||||
#include<iostream>
|
||||
#include<regex>
|
||||
#include "restool_errors.h"
|
||||
#include "xml_key_node.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
const map<string, ResType> ReferenceParser::ID_REFS = {
|
||||
{ "^\\$id:", ResType::ID },
|
||||
{ "^\\$boolean:", ResType::BOOLEAN },
|
||||
{ "^\\$color:", ResType::COLOR },
|
||||
{ "^\\$float:", ResType::FLOAT },
|
||||
{ "^\\$media:", ResType::MEDIA },
|
||||
{ "^\\$profile:", ResType::PROF },
|
||||
{ "^\\$integer:", ResType::INTEGER },
|
||||
{ "^\\$string:", ResType::STRING },
|
||||
{ "^\\$layout:", ResType::LAYOUT },
|
||||
{ "^\\$pattern:", ResType::PATTERN },
|
||||
{ "^\\$plural:", ResType::PLURAL },
|
||||
{ "^\\$graphic:", ResType::GRAPHIC },
|
||||
{ "^\\$theme:", ResType::THEME }
|
||||
};
|
||||
|
||||
const map<string, ResType> ReferenceParser::ID_OHOS_REFS = {
|
||||
{ "^\\$ohos:id:", ResType::ID },
|
||||
{ "^\\$ohos:boolean:", ResType::BOOLEAN },
|
||||
{ "^\\$ohos:color:", ResType::COLOR },
|
||||
{ "^\\$ohos:float:", ResType::FLOAT },
|
||||
{ "^\\$ohos:media:", ResType::MEDIA },
|
||||
{ "^\\$ohos:profile:", ResType::PROF },
|
||||
{ "^\\$ohos:integer:", ResType::INTEGER },
|
||||
{ "^\\$ohos:string:", ResType::STRING },
|
||||
{ "^\\$ohos:layout:", ResType::LAYOUT },
|
||||
{ "^\\$ohos:pattern:", ResType::PATTERN },
|
||||
{ "^\\$ohos:plural:", ResType::PLURAL },
|
||||
{ "^\\$ohos:graphic:", ResType::GRAPHIC },
|
||||
{ "^\\$ohos:theme:", ResType::THEME }
|
||||
};
|
||||
|
||||
ReferenceParser::ReferenceParser() : idWorker_(IdWorker::GetInstance())
|
||||
{
|
||||
}
|
||||
|
||||
ReferenceParser::~ReferenceParser()
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t ReferenceParser::ParseRefInSolidXml(const vector<string> &solidXmlFolders) const
|
||||
{
|
||||
for (const auto &solidXmlFolder : solidXmlFolders) {
|
||||
string filePath = filesystem::path(solidXmlFolder)
|
||||
.append(XmlKeyNode::KEY_TO_FILE_NAME.at(XmlKeyNode::KeyType::CONSTANT)).string();
|
||||
if (!ResourceUtil::FileExist(filePath)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
XmlKeyNode xmlKeyNode;
|
||||
if (!xmlKeyNode.LoadFromFile(filePath, [this](auto &key) -> bool {
|
||||
return ParseRefString(key);
|
||||
})) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (!xmlKeyNode.SaveToFile(filePath)) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t ReferenceParser::ParseRefInElement(map<int32_t, vector<ResourceItem>> &alls) const
|
||||
{
|
||||
for (auto &iter : alls) {
|
||||
for (auto &resourceItem : iter.second) {
|
||||
if (IsNotElement(resourceItem.GetResType())) {
|
||||
break;
|
||||
}
|
||||
if (!ParseRefResourceItem(resourceItem)) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t ReferenceParser::ParseRefInString(string &value, bool &update) const
|
||||
{
|
||||
if (ParseRefString(value, update)) {
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
uint32_t ReferenceParser::ParseRefInProfile(const string &output) const
|
||||
{
|
||||
string profileFolder = filesystem::path(output).append(RESOURCES_DIR).append("base").append("profile").string();
|
||||
if (!ResourceUtil::FileExist(profileFolder)) {
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
for (const auto &entry : filesystem::directory_iterator(profileFolder)) {
|
||||
if (entry.is_directory()) {
|
||||
cerr << "Error: '" << entry.path().string() << "' is directory." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (entry.path().extension() != ".json" ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ParseRefInJson(entry.path().string()) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t ReferenceParser::ParseRefInJson(const string &filePath) const
|
||||
{
|
||||
Json::Value root;
|
||||
if (!ResourceUtil::OpenJsonFile(filePath, root)) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (!ParseRefJsonImpl(root)) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (!ResourceUtil::SaveToJsonFile(filePath, root)) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
bool ReferenceParser::ParseRefResourceItem(ResourceItem &resourceItem) const
|
||||
{
|
||||
ResType resType = resourceItem.GetResType();
|
||||
string data;
|
||||
bool update = false;
|
||||
if (IsStringOfResourceItem(resType)) {
|
||||
data= string(reinterpret_cast<const char *>(resourceItem.GetData()), resourceItem.GetDataLength());
|
||||
if (!ParseRefString(data, update)) {
|
||||
cerr << "Error: in " << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
if (!update) {
|
||||
return true;
|
||||
}
|
||||
} else if (IsArrayOfResourceItem(resType)) {
|
||||
if (!ParseRefResourceItemData(resourceItem, data, update)) {
|
||||
return false;
|
||||
}
|
||||
if (!update) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (update && !resourceItem.SetData(reinterpret_cast<const int8_t *>(data.c_str()), data.length())) {
|
||||
cerr << "Error: set data fail '" << resourceItem.GetName() << "' in " << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReferenceParser::ParseRefResourceItemData(const ResourceItem &resourceItem, string &data, bool &update) const
|
||||
{
|
||||
data = string(reinterpret_cast<const char *>(resourceItem.GetData()), resourceItem.GetDataLength());
|
||||
vector<string> contents = ResourceUtil::DecomposeStrings(data);
|
||||
if (contents.empty()) {
|
||||
cerr << "Error: DecomposeStrings fail '" << resourceItem.GetName() << "' in ";
|
||||
cerr << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto &content : contents) {
|
||||
bool flag = false;
|
||||
if (!ParseRefString(content, flag)) {
|
||||
cerr << "Error: in " << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
update = (update || flag);
|
||||
}
|
||||
|
||||
if (!update) {
|
||||
return true;
|
||||
}
|
||||
|
||||
data = ResourceUtil::ComposeStrings(contents);
|
||||
if (data.empty()) {
|
||||
cerr << "Error: ComposeStrings fail '" << resourceItem.GetName() << "' in ";
|
||||
cerr << resourceItem.GetFilePath() << endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReferenceParser::IsStringOfResourceItem(ResType resType) const
|
||||
{
|
||||
if (resType == ResType::STRING ||
|
||||
resType == ResType::INTEGER ||
|
||||
resType == ResType::BOOLEAN ||
|
||||
resType == ResType::COLOR ||
|
||||
resType == ResType::FLOAT) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ReferenceParser::IsArrayOfResourceItem(ResType resType) const
|
||||
{
|
||||
if (resType == ResType::STRARRAY ||
|
||||
resType == ResType::INTARRAY ||
|
||||
resType == ResType::PLURAL ||
|
||||
resType == ResType::THEME ||
|
||||
resType == ResType::PATTERN) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ReferenceParser::IsNotElement(ResType resType) const
|
||||
{
|
||||
auto result = find_if(g_contentClusterMap.begin(), g_contentClusterMap.end(), [resType](const auto &iter) {
|
||||
return resType == iter.second;
|
||||
});
|
||||
if (result == g_contentClusterMap.end()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ReferenceParser::ParseRefString(string &key) const
|
||||
{
|
||||
bool update = false;
|
||||
return ParseRefString(key, update);
|
||||
}
|
||||
|
||||
bool ReferenceParser::ParseRefString(std::string &key, bool &update) const
|
||||
{
|
||||
update = false;
|
||||
if (regex_match(key, regex("^\\$ohos:[a-z]+:.+"))) {
|
||||
update = true;
|
||||
return ParseRefImpl(key, ID_OHOS_REFS, true);
|
||||
} else if (regex_match(key, regex("^\\$[a-z]+:.+"))) {
|
||||
update = true;
|
||||
return ParseRefImpl(key, ID_REFS, false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReferenceParser::ParseRefImpl(string &key, const map<string, ResType> &refs, bool isSystem) const
|
||||
{
|
||||
for (const auto &ref : refs) {
|
||||
smatch result;
|
||||
if (regex_search(key, result, regex(ref.first))) {
|
||||
string name = key.substr(result[0].str().length());
|
||||
int32_t id = idWorker_.GetId(ref.second, name);
|
||||
if (isSystem) {
|
||||
id = idWorker_.GetSystemId(ref.second, name);
|
||||
} else {
|
||||
id = idWorker_.GetId(ref.second, name);
|
||||
}
|
||||
if (id < 0) {
|
||||
cerr << "Error: ref '" << key << "' don't be defined." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
key = to_string(id);
|
||||
if (ref.second != ResType::ID) {
|
||||
key = key = "$" + ResourceUtil::ResTypeToString(ref.second) + ":" + to_string(id);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
cerr << "Error: reference '" << key << "' invalid." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ReferenceParser::ParseRefJsonImpl(Json::Value &node) const
|
||||
{
|
||||
if (node.isObject()) {
|
||||
for (const auto &member : node.getMemberNames()) {
|
||||
if (!ParseRefJsonImpl(node[member])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if (node.isArray()) {
|
||||
for (Json::ArrayIndex i = 0; i < node.size(); i++) {
|
||||
if (!ParseRefJsonImpl(node[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if (node.isString()) {
|
||||
string value = node.asString();
|
||||
if (!ParseRefString(value)) {
|
||||
return false;
|
||||
}
|
||||
node = value;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_directory.h"
|
||||
#include<iostream>
|
||||
#include "resource_util.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
bool ResourceDirectory::ScanResources(const string &resourcesDir, function<bool(const DirectoryInfo&)> callback) const
|
||||
{
|
||||
for (auto &it : filesystem::directory_iterator(resourcesDir)) {
|
||||
string limitKey = it.path().filename().string();
|
||||
if (ResourceUtil::IsIgnoreFile(limitKey, it.status().type())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!it.is_directory()) {
|
||||
cerr << "Error: '" << it.path().string() << "' not directory." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (limitKey == RAW_FILE_DIR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ScanResourceLimitKeyDir(it.path().string(), limitKey, callback)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// below private
|
||||
bool ResourceDirectory::ScanResourceLimitKeyDir(const string &resourceTypeDir, const string &limitKey,
|
||||
function<bool(const DirectoryInfo&)> callback) const
|
||||
{
|
||||
vector<KeyParam> keyParams;
|
||||
if (!KeyParser::Parse(limitKey, keyParams)) {
|
||||
cerr << "Error: " << resourceTypeDir << ",invalid limit key '" << limitKey << "'" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto &it : filesystem::directory_iterator(resourceTypeDir)) {
|
||||
string dirPath = it.path().string();
|
||||
string fileCluster = it.path().filename().string();
|
||||
if (ResourceUtil::IsIgnoreFile(fileCluster, it.status().type())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!it.is_directory()) {
|
||||
cerr << "Error: '" << dirPath << "' not directory." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
ResType type = ResourceUtil::GetResTypeByDir(fileCluster);
|
||||
if (type == ResType::INVALID_RES_TYPE) {
|
||||
string array("[ ");
|
||||
for (auto item : g_fileClusterMap) {
|
||||
array.append("'" + item.first + "' ");
|
||||
}
|
||||
array.append("]");
|
||||
cerr << "Error: " << dirPath << " ,invalid directory name '";
|
||||
cerr << fileCluster << "', must in " << array << endl;
|
||||
return false;
|
||||
}
|
||||
DirectoryInfo info = { limitKey, fileCluster, dirPath, keyParams, type };
|
||||
if (callback && !callback(info)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_item.h"
|
||||
#include <iostream>
|
||||
#include "securec.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
ResourceItem::ResourceItem()
|
||||
{
|
||||
}
|
||||
|
||||
ResourceItem::ResourceItem(const ResourceItem &other)
|
||||
{
|
||||
CopyFrom(other);
|
||||
}
|
||||
|
||||
ResourceItem::ResourceItem(const string &name, const vector<KeyParam> &keyparams, ResType type)
|
||||
:data_(nullptr), dataLen_(0), name_(name),keyparams_(keyparams), type_(type)
|
||||
{
|
||||
}
|
||||
|
||||
ResourceItem::~ResourceItem()
|
||||
{
|
||||
ReleaseData();
|
||||
}
|
||||
|
||||
bool ResourceItem::SetData(const string &data)
|
||||
{
|
||||
return SetData(reinterpret_cast<const int8_t *>(data.c_str()), data.length() + 1);
|
||||
}
|
||||
|
||||
bool ResourceItem::SetData(const int8_t *data, uint32_t length)
|
||||
{
|
||||
if (data == nullptr || length <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ReleaseData();
|
||||
int8_t *buffer = reinterpret_cast<int8_t *>(new (nothrow) int8_t[length]);
|
||||
if (buffer == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = (memset_s(buffer, length, 0, length) == EOK);
|
||||
result = result && (memcpy_s(buffer, length, data, length) == EOK);
|
||||
data_ = buffer;
|
||||
dataLen_ = length;
|
||||
return result;
|
||||
}
|
||||
|
||||
void ResourceItem::SetFilePath(const string &filePath)
|
||||
{
|
||||
filePath_ = filePath;
|
||||
}
|
||||
|
||||
void ResourceItem::SetLimitKey(const string &limitKey)
|
||||
{
|
||||
limitKey_ = limitKey;
|
||||
}
|
||||
|
||||
const int8_t *ResourceItem::GetData() const
|
||||
{
|
||||
return data_;
|
||||
}
|
||||
|
||||
const uint32_t ResourceItem::GetDataLength() const
|
||||
{
|
||||
return dataLen_;
|
||||
}
|
||||
|
||||
const string &ResourceItem::GetName() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
const ResType &ResourceItem::GetResType() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
const vector<KeyParam> &ResourceItem::GetKeyParam() const
|
||||
{
|
||||
return keyparams_;
|
||||
}
|
||||
|
||||
const string &ResourceItem::GetFilePath() const
|
||||
{
|
||||
return filePath_;
|
||||
}
|
||||
|
||||
const string &ResourceItem::GetLimitKey() const
|
||||
{
|
||||
return limitKey_;
|
||||
}
|
||||
|
||||
ResourceItem &ResourceItem::operator=(const ResourceItem &other)
|
||||
{
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
CopyFrom(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//below private founction
|
||||
void ResourceItem::ReleaseData()
|
||||
{
|
||||
if (data_ != nullptr) {
|
||||
delete[] data_;
|
||||
data_ = nullptr;
|
||||
dataLen_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ResourceItem::CopyFrom(const ResourceItem &other)
|
||||
{
|
||||
name_ = other.name_;
|
||||
keyparams_ = other.keyparams_;
|
||||
type_ = other.type_;
|
||||
dataLen_ = other.dataLen_;
|
||||
filePath_ = other.filePath_;
|
||||
limitKey_ = other.limitKey_;
|
||||
if (!SetData(other.data_, other.dataLen_)) {
|
||||
ReleaseData();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_merge.h"
|
||||
#include "cmd_parser.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
const vector<ConfigParser::ModuleType> ResourceMerge::ORDERS = {
|
||||
ConfigParser::ModuleType::NONE,
|
||||
ConfigParser::ModuleType::ENTRY,
|
||||
ConfigParser::ModuleType::FEATURE,
|
||||
ConfigParser::ModuleType::HAR
|
||||
};
|
||||
|
||||
ResourceMerge::ResourceMerge()
|
||||
{
|
||||
}
|
||||
|
||||
ResourceMerge::~ResourceMerge()
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t ResourceMerge::Init()
|
||||
{
|
||||
auto &cmdParser = CmdParser<PackageParser>::GetInstance().GetCmdParser();
|
||||
const vector<string> &inputs = cmdParser.GetInputs();
|
||||
if (cmdParser.IsFileList()) {
|
||||
inputsOrder_ = inputs;
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
map<ConfigParser::ModuleType, vector<string>> inputTypes;
|
||||
for (auto it = inputs.crbegin(); it != inputs.crend(); it++) {
|
||||
string filePath = filesystem::path(*it).append(ConfigParser::GetConfigName()).string();
|
||||
string resourceDir = filesystem::path(*it).append(RESOURCES_DIR).string();
|
||||
ConfigParser::ModuleType moduleType = ConfigParser::ModuleType::NONE;
|
||||
if (!ResourceUtil::FileExist(filePath)) {
|
||||
inputTypes[moduleType].push_back(resourceDir);
|
||||
continue;
|
||||
}
|
||||
ConfigParser configParser(filePath);
|
||||
if (configParser.Init() != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
moduleType = configParser.GetModuleType();
|
||||
inputTypes[moduleType].push_back(resourceDir);
|
||||
}
|
||||
|
||||
for (const auto &type : ORDERS) {
|
||||
if (inputTypes.find(type) == inputTypes.end()) {
|
||||
continue;
|
||||
}
|
||||
inputsOrder_.insert(inputsOrder_.end(), inputTypes[type].begin(), inputTypes[type].end());
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
const vector<string> &ResourceMerge::GetInputs() const
|
||||
{
|
||||
return inputsOrder_;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_module.h"
|
||||
#include<filesystem>
|
||||
#include<iostream>
|
||||
#include "factory_resource_compiler.h"
|
||||
#include "restool_errors.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
const vector<ResType> ResourceModule::SCAN_SEQ = {
|
||||
ResType::ELEMENT,
|
||||
ResType::MEDIA,
|
||||
ResType::PROF,
|
||||
ResType::ANIMATION,
|
||||
ResType::GRAPHIC,
|
||||
ResType::LAYOUT,
|
||||
};
|
||||
ResourceModule::ResourceModule(const string &modulePath, const string &moduleOutput, const string &moduleName)
|
||||
: modulePath_(modulePath), moduleOutput_(moduleOutput), moduleName_(moduleName)
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t ResourceModule::ScanResource()
|
||||
{
|
||||
if (!ResourceUtil::FileExist(modulePath_)) {
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
ResourceDirectory directory;
|
||||
if (!directory.ScanResources(modulePath_,[this](const DirectoryInfo &info) -> bool {
|
||||
scanDirs_[info.dirType].push_back(info);
|
||||
return true;
|
||||
})) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
for (const auto &type : SCAN_SEQ) {
|
||||
const auto &item = scanDirs_.find(type);
|
||||
if (item == scanDirs_.end() || item->second.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
unique_ptr<IResourceCompiler> resourceCompiler =
|
||||
FactoryResourceCompiler::CreateCompiler(type, moduleOutput_);
|
||||
resourceCompiler->SetModuleName(moduleName_);
|
||||
resourceCompiler->SetPreviewMode(previewMode_);
|
||||
if (resourceCompiler->Compile(item->second) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
Push(resourceCompiler->GetResult());
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
const map<int32_t, vector<ResourceItem>> &ResourceModule::GetOwner() const
|
||||
{
|
||||
return owner_;
|
||||
}
|
||||
|
||||
const map<ResType, vector<DirectoryInfo>> &ResourceModule::GetScanDirectorys() const
|
||||
{
|
||||
return scanDirs_;
|
||||
}
|
||||
|
||||
uint32_t ResourceModule::MergeResourceItem(map<int32_t, vector<ResourceItem>> &alls,
|
||||
const map<int32_t, vector<ResourceItem>> &other, bool tipError)
|
||||
{
|
||||
for (const auto &iter : other) {
|
||||
auto result = alls.emplace(iter.first, iter.second);
|
||||
if (result.second) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const auto &resourceItem : iter.second) {
|
||||
auto ret = find_if(result.first->second.begin(), result.first->second.end(), [&resourceItem](auto &iter) {
|
||||
return resourceItem.GetLimitKey() == iter.GetLimitKey();
|
||||
});
|
||||
if (ret == result.first->second.end()) {
|
||||
result.first->second.push_back(resourceItem);
|
||||
continue;
|
||||
}
|
||||
string error = resourceItem.GetName() + "' conflict, first declared in " + \
|
||||
ret->GetFilePath() + ", but declared again in " + resourceItem.GetFilePath();
|
||||
if (tipError) {
|
||||
cerr << "Error: " << error << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
cout << "Warning: " << error << endl;
|
||||
}
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
// below private
|
||||
void ResourceModule::Push(const map<int32_t, std::vector<ResourceItem>> &other)
|
||||
{
|
||||
if (previewMode_) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto &iter : other) {
|
||||
owner_.emplace(iter.first, iter.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_module_inc.h"
|
||||
#include<filesystem>
|
||||
#include<iostream>
|
||||
#include "factory_resource_compiler.h"
|
||||
#include "increment_index.h"
|
||||
#include "restool_errors.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
ResourceModuleInc::ResourceModuleInc(const string &modulePath, const string &moduleOutput,
|
||||
const string &moduleName, const vector<string> &folder)
|
||||
: ResourceModule(modulePath, moduleOutput, moduleName), folder_(folder)
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t ResourceModuleInc::ScanResource(const vector<IncrementList::FileIncrement> &fileIncrements)
|
||||
{
|
||||
vector<string> skips;
|
||||
for (const auto &fileIncrement : fileIncrements) {
|
||||
skips.push_back(fileIncrement.filePath);
|
||||
if (fileIncrement.dirType == ResType::ELEMENT) {
|
||||
continue;
|
||||
}
|
||||
string filePathDel = filesystem::path(moduleOutput_).append(RESOURCES_DIR)
|
||||
.append(fileIncrement.limitKey).append(fileIncrement.fileCluster).append(fileIncrement.filename).string();
|
||||
if (ResourceUtil::NeedConverToSolidXml(fileIncrement.dirType) &&
|
||||
filesystem::path(filePathDel).extension().string() == ".xml") {
|
||||
filePathDel = filesystem::path(filePathDel).replace_extension(".sxml").string();
|
||||
}
|
||||
if (!filesystem::remove(filePathDel)) {
|
||||
cerr << "Error: delete '" << filePathDel << "' fail" << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
string indexPath = filesystem::path(moduleOutput_).append(IncrementIndex::INDEX_FILE).string();
|
||||
IncrementIndex moduleIndex(indexPath, folder_);
|
||||
moduleIndex.SetSkipPaths(skips);
|
||||
if (!moduleIndex.Load(owner_)) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
for (const auto &fileIncrement : fileIncrements) {
|
||||
unique_ptr<IResourceCompiler> resourceCompiler =
|
||||
FactoryResourceCompiler::CreateCompiler(fileIncrement.dirType, moduleOutput_);
|
||||
resourceCompiler->SetModuleName(moduleName_);
|
||||
if (resourceCompiler->Compile(fileIncrement) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (MergeResourceItem(owner_, resourceCompiler->GetResult(), true) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t ResourceModuleInc::SaveIndex() const
|
||||
{
|
||||
string indexPath = filesystem::path(moduleOutput_).append(IncrementIndex::INDEX_FILE).string();
|
||||
IncrementIndex moduleIndex(indexPath, folder_);
|
||||
if (!moduleIndex.Save(owner_)) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,357 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_pack.h"
|
||||
#include<algorithm>
|
||||
#include<filesystem>
|
||||
#include "file_manager.h"
|
||||
#include "header.h"
|
||||
#include "increment_manager.h"
|
||||
#include "resource_merge.h"
|
||||
#include "resource_table.h"
|
||||
|
||||
#include "preview_manager.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
ResourcePack::ResourcePack(const PackageParser &packageParser):packageParser_(packageParser)
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t ResourcePack::Package()
|
||||
{
|
||||
if (packageParser_.GetPreviewMode()) {
|
||||
PreviewManager preview;
|
||||
preview.SetPriority(packageParser_.GetPriority());
|
||||
return preview.ScanModules(packageParser_.GetInputs(), packageParser_.GetOutput());
|
||||
}
|
||||
if (Init() != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
ResourceMerge resourceMerge;
|
||||
if (resourceMerge.Init() != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (ScanResources(resourceMerge.GetInputs(), packageParser_.GetOutput()) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (GenerateHeader() != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (CopyRawFile(resourceMerge.GetInputs()) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (GenerateConfigJson() != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
ResourceTable resourceTable;
|
||||
if (resourceTable.CreateResourceTable() != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
//below private founction
|
||||
uint32_t ResourcePack::Init()
|
||||
{
|
||||
InitHeaderCreater();
|
||||
if (InitOutput() != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (InitConfigJson() != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (InitModule() != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t ResourcePack::InitModule()
|
||||
{
|
||||
IdWorker::ResourceIdCluster hapType = IdWorker::ResourceIdCluster::RES_ID_APP;
|
||||
string packageName = packageParser_.GetPackageName();
|
||||
if (packageName == "ohos.global.systemres") {
|
||||
hapType = IdWorker::ResourceIdCluster::RES_ID_SYS;
|
||||
}
|
||||
|
||||
moduleName_ = configJson_.GetModuleName();
|
||||
vector<string> moduleNames = packageParser_.GetModuleNames();
|
||||
IdWorker &idWorker = IdWorker::GetInstance();
|
||||
int32_t startId = packageParser_.GetStartId();
|
||||
if (startId > 0) {
|
||||
return idWorker.Init(hapType, startId);
|
||||
}
|
||||
|
||||
if (moduleNames.empty()) {
|
||||
return idWorker.Init(hapType);
|
||||
} else {
|
||||
sort(moduleNames.begin(), moduleNames.end());
|
||||
auto it = find_if(moduleNames.begin(), moduleNames.end(), [this](auto iter) {
|
||||
return moduleName_ == iter;
|
||||
});
|
||||
if (it == moduleNames.end()) {
|
||||
string buffer(" ");
|
||||
for_each(moduleNames.begin(), moduleNames.end(), [&buffer](auto &iter) {
|
||||
buffer.append(" " + iter + " ");
|
||||
});
|
||||
cerr << "Error: module name '" << moduleName_ << "' not in [" << buffer << "]" << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
int32_t startId = ((it - moduleNames.begin()) + 1) * 0x01000000;
|
||||
if (startId == 0x07000000) {
|
||||
startId = startId + 0x01000000;
|
||||
}
|
||||
return idWorker.Init(hapType, startId);
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
void ResourcePack::InitHeaderCreater()
|
||||
{
|
||||
using namespace placeholders;
|
||||
headerCreaters_.emplace(".txt", bind(&ResourcePack::GenerateTextHeader, this, _1));
|
||||
headerCreaters_.emplace(".js", bind(&ResourcePack::GenerateJsHeader, this, _1));
|
||||
headerCreaters_.emplace(".h", bind(&ResourcePack::GenerateCplusHeader, this, _1));
|
||||
}
|
||||
|
||||
uint32_t ResourcePack::InitOutput() const
|
||||
{
|
||||
string cachePath = packageParser_.GetCachePath();
|
||||
string indexPath = filesystem::path(cachePath).append(IncrementManager::ID_JSON_FILE).string();
|
||||
if (!cachePath.empty() && ResourceUtil::FileExist(indexPath)) {
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
bool forceWrite = packageParser_.GetForceWrite();
|
||||
string output = packageParser_.GetOutput();
|
||||
string resourcesPath = filesystem::path(output).append(RESOURCES_DIR).string();
|
||||
if (ResourceUtil::FileExist(resourcesPath)) {
|
||||
if (!forceWrite) {
|
||||
cerr << "Error: output path '" << resourcesPath << "' exists." << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (!ResourceUtil::RmoveAllDir(resourcesPath)) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t ResourcePack::GenerateHeader() const
|
||||
{
|
||||
auto headerPaths = packageParser_.GetResourceHeaders();
|
||||
string textPath = filesystem::path(packageParser_.GetOutput()).append("ResourceTable.txt").string();
|
||||
headerPaths.push_back(textPath);
|
||||
for (const auto &headerPath : headerPaths) {
|
||||
string extension = filesystem::path(headerPath).extension().string();
|
||||
auto it = headerCreaters_.find(extension);
|
||||
if (it == headerCreaters_.end()) {
|
||||
cout << "Warning: don't support header file format '" << headerPath << "'" << endl;
|
||||
continue;
|
||||
}
|
||||
if (it->second(headerPath) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t ResourcePack::InitConfigJson()
|
||||
{
|
||||
string config = packageParser_.GetConfig();
|
||||
if (config.empty()) {
|
||||
if( packageParser_.GetInputs().size() > 1) {
|
||||
cerr << "Error: more input path, -j config.json empty" << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
config = filesystem::path(packageParser_.GetInputs()[0]).append(CONFIG_JSON).string();
|
||||
if (!ResourceUtil::FileExist(config)) {
|
||||
config = filesystem::path(packageParser_.GetInputs()[0]).append(MODULE_JSON).string();
|
||||
}
|
||||
}
|
||||
|
||||
if (filesystem::path(config).filename().string() == MODULE_JSON) {
|
||||
ConfigParser::SetUseModule();
|
||||
}
|
||||
configJson_ = ConfigParser(config);
|
||||
if (configJson_.Init() != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t ResourcePack::GenerateTextHeader(const string &headerPath) const
|
||||
{
|
||||
Header textHeader(headerPath);
|
||||
bool first = true;
|
||||
uint32_t result = textHeader.Create([](stringstream &buffer) {},
|
||||
[&first](stringstream &buffer, const IdWorker::ResourceId& resourceId) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
buffer << "\n";
|
||||
}
|
||||
buffer << resourceId.type << " " << resourceId.name;
|
||||
buffer << " 0x" << hex << setw(8) << setfill('0') << resourceId.id;
|
||||
}, [](stringstream &buffer) {});
|
||||
if (result != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t ResourcePack::GenerateCplusHeader(const string &headerPath) const
|
||||
{
|
||||
Header cplusHeader(headerPath);
|
||||
uint32_t result = cplusHeader.Create([](stringstream &buffer) {
|
||||
buffer << Header::LICENSE_HEADER << "\n";
|
||||
buffer << "#ifndef RESOURCE_TABLE_H\n";
|
||||
buffer << "#define RESOURCE_TABLE_H\n\n";
|
||||
buffer << "#include<stdint.h>\n\n";
|
||||
buffer << "namespace OHOS {\n";
|
||||
},
|
||||
[](stringstream &buffer, const IdWorker::ResourceId& resourceId) {
|
||||
string name = resourceId.type + "_" + resourceId.name;
|
||||
transform(name.begin(), name.end(), name.begin(), ::toupper);
|
||||
buffer << "const int32_t " << name << " = ";
|
||||
buffer << "0x" << hex << setw(8) << setfill('0') << resourceId.id << ";\n";
|
||||
}, [](stringstream &buffer){
|
||||
buffer << "}\n";
|
||||
buffer << "#endif";
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t ResourcePack::GenerateJsHeader(const std::string &headerPath) const
|
||||
{
|
||||
Header JsHeader(headerPath);
|
||||
string itemType;
|
||||
uint32_t result = JsHeader.Create([](stringstream &buffer) {
|
||||
buffer << Header::LICENSE_HEADER << "\n";
|
||||
buffer << "export default {\n";
|
||||
},
|
||||
[&itemType](stringstream &buffer, const IdWorker::ResourceId& resourceId) {
|
||||
if (itemType != resourceId.type) {
|
||||
if (!itemType.empty()) {
|
||||
buffer << "\n" << " " << "},\n";
|
||||
}
|
||||
buffer << " " << resourceId.type << " : {\n";
|
||||
itemType = resourceId.type;
|
||||
} else {
|
||||
buffer << ",\n";
|
||||
}
|
||||
buffer << " " << resourceId.name << " : " << resourceId.id;
|
||||
}, [](stringstream &buffer){
|
||||
buffer << "\n" << " " << "}\n";
|
||||
buffer << "}\n";
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t ResourcePack::CopyRawFile(const vector<string> &inputs) const
|
||||
{
|
||||
for (const auto &input : inputs) {
|
||||
string rawfilePath = filesystem::path(input).append(RAW_FILE_DIR).string();
|
||||
if (!ResourceUtil::FileExist(rawfilePath)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!filesystem::is_directory(rawfilePath)) {
|
||||
cerr << "Error: '" << rawfilePath << "' not directory." << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
string dst = filesystem::path(packageParser_.GetOutput()).append(RESOURCES_DIR).append(RAW_FILE_DIR).string();
|
||||
if (CopyRawFileImpl(rawfilePath, dst) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t ResourcePack::CopyRawFileImpl(const string &src, const string &dst) const
|
||||
{
|
||||
if (!ResourceUtil::CreateDirs(dst)) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
for (const auto &entry : filesystem::directory_iterator(src)) {
|
||||
string filename = entry.path().filename().string();
|
||||
if (ResourceUtil::IsIgnoreFile(filename, entry.status().type())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
string subPath = filesystem::path(dst).append(filename).string();
|
||||
if (entry.is_directory()) {
|
||||
if (CopyRawFileImpl(entry.path().string(), subPath) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
} else {
|
||||
if (ResourceUtil::FileExist(subPath)) {
|
||||
continue;
|
||||
}
|
||||
if (!ResourceUtil::CopyFleInner(entry.path().string(), subPath)) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t ResourcePack::GenerateConfigJson()
|
||||
{
|
||||
if (configJson_.ParseRefence() != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
string outputPath = filesystem::path(packageParser_.GetOutput()).append(ConfigParser::GetConfigName()).string();
|
||||
return configJson_.Save(outputPath);
|
||||
}
|
||||
|
||||
uint32_t ResourcePack::ScanResources(const vector<string> &inputs, const string &output)
|
||||
{
|
||||
auto &fileManager = FileManager::GetInstance();
|
||||
fileManager.SetModuleName(moduleName_);
|
||||
string cachePath = packageParser_.GetCachePath();
|
||||
if (cachePath.empty()) {
|
||||
if (fileManager.ScanModules(inputs, output) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
auto &incrementManager = IncrementManager::GetInstance();
|
||||
if (incrementManager.Init(cachePath, inputs, output, moduleName_) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
if (fileManager.ScanIncrement(output) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_table.h"
|
||||
#include <filesystem>
|
||||
#include "securec.h"
|
||||
#include "cmd_parser.h"
|
||||
#include "file_manager.h"
|
||||
#include "resource_util.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
ResourceTable::ResourceTable()
|
||||
{
|
||||
auto &parser =CmdParser<PackageParser>::GetInstance();
|
||||
auto &packageParser = parser.GetCmdParser();
|
||||
indexFilePath_ = filesystem::path(packageParser.GetOutput()).append(RESOURCE_INDEX_FILE).string();
|
||||
}
|
||||
|
||||
ResourceTable::~ResourceTable()
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t ResourceTable::CreateResourceTable()
|
||||
{
|
||||
FileManager &fileManager = FileManager::GetInstance();
|
||||
auto &allResource = fileManager.GetResources();
|
||||
map<string, vector<TableData>> configs;
|
||||
for (const auto &item : allResource) {
|
||||
for (const auto &resourceItem : item.second) {
|
||||
if (resourceItem.GetResType() == ResType::ID) {
|
||||
break;
|
||||
}
|
||||
TableData tableData;
|
||||
tableData.id = item.first;
|
||||
tableData.resourceItem = resourceItem;
|
||||
configs[resourceItem.GetLimitKey()].push_back(tableData);
|
||||
}
|
||||
}
|
||||
|
||||
if (SaveToResouorceIndex(configs) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
//below private
|
||||
uint32_t ResourceTable::SaveToResouorceIndex(const map<string, vector<TableData>> &configs) const
|
||||
{
|
||||
uint32_t pos = 0;
|
||||
IndexHeader indexHeader;
|
||||
if (!InitIndexHeader(indexHeader, configs.size())) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
pos += sizeof(IndexHeader);
|
||||
|
||||
map<string, LimitKeyConfig> limitKeyConfigs;
|
||||
map<string, IdSet> idSets;
|
||||
if (!Prepare(configs, limitKeyConfigs, idSets, pos)) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
ofstream out(indexFilePath_, ofstream::out | ofstream::binary);
|
||||
if (!out.is_open()) {
|
||||
cerr << "Error: open fail " << indexFilePath_ << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (!SaveRecordItem(configs, out, idSets, pos)) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
indexHeader.fileSize = pos;
|
||||
SaveHeader(indexHeader, out);
|
||||
SaveLimitKeyConfigs(limitKeyConfigs, out);
|
||||
SaveIdSets(idSets, out);
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
bool ResourceTable::InitIndexHeader(IndexHeader &indexHeader, uint32_t count) const
|
||||
{
|
||||
if (memcpy_s(indexHeader.version, VERSION_MAX_LEN, RESTOOL_VERSION, VERSION_MAX_LEN) != EOK) {
|
||||
cerr << "Error: InitIndexHeader memcpy_s fail." << endl;
|
||||
return false;
|
||||
}
|
||||
indexHeader.limitKeyConfigSize = count;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ResourceTable::Prepare(const map<string, vector<TableData>> &configs,
|
||||
map<string, LimitKeyConfig> &limitKeyConfigs,
|
||||
map<string, IdSet> &idSets, uint32_t &pos) const
|
||||
{
|
||||
for (const auto &config : configs) {
|
||||
LimitKeyConfig limitKeyConfig;
|
||||
const auto &keyParams = config.second.at(0).resourceItem.GetKeyParam();
|
||||
limitKeyConfig.keyCount = keyParams.size();
|
||||
pos += sizeof(limitKeyConfig.keyTag) + sizeof(limitKeyConfig.offset) + sizeof(limitKeyConfig.keyCount);
|
||||
for (const auto &keyParam : keyParams) {
|
||||
limitKeyConfig.data.push_back(static_cast<int32_t>(keyParam.keyType));
|
||||
limitKeyConfig.data.push_back(static_cast<int32_t>(keyParam.value));
|
||||
pos += sizeof(KeyParam);
|
||||
}
|
||||
limitKeyConfigs.emplace(config.first, limitKeyConfig);
|
||||
}
|
||||
|
||||
for (const auto &config : configs) {
|
||||
auto limitKeyConfig = limitKeyConfigs.find(config.first);
|
||||
if (limitKeyConfig == limitKeyConfigs.end()) {
|
||||
cerr << "Error: limit key config don't find '" << config.first << "'" << endl;
|
||||
return false;
|
||||
}
|
||||
limitKeyConfig->second.offset = pos;
|
||||
|
||||
IdSet idSet;
|
||||
idSet.idCount = config.second.size();
|
||||
pos += sizeof(idSet.idTag) + sizeof(idSet.idCount);
|
||||
for (const auto &tableData : config.second) {
|
||||
idSet.data.emplace(tableData.id, 0);
|
||||
pos += sizeof(uint32_t) + sizeof(uint32_t);
|
||||
}
|
||||
idSets.emplace(config.first, idSet);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ResourceTable::SaveRecordItem(const map<string, vector<TableData>> &configs,
|
||||
ofstream &out, map<string, IdSet> &idSets, uint32_t &pos) const
|
||||
{
|
||||
out.seekp(pos);
|
||||
for (const auto &config : configs) {
|
||||
auto idSet = idSets.find(config.first);
|
||||
if (idSet == idSets.end()) {
|
||||
cerr << "Error: id set don't find '" << config.first << "'" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto &tableData : config.second) {
|
||||
if (idSet->second.data.find(tableData.id) == idSet->second.data.end()) {
|
||||
cerr << "Error: resource table don't find id '" << tableData.id << "'" << endl;
|
||||
return false;
|
||||
}
|
||||
idSet->second.data[tableData.id] = pos;
|
||||
RecordItem recordItem;
|
||||
recordItem.id = tableData.id;
|
||||
recordItem.resType = static_cast<int32_t>(tableData.resourceItem.GetResType());
|
||||
vector<string> contents;
|
||||
string value(reinterpret_cast<const char *>(tableData.resourceItem.GetData()),
|
||||
tableData.resourceItem.GetDataLength());
|
||||
contents.push_back(value);
|
||||
string name = ResourceUtil::GetIdName(tableData.resourceItem.GetName(),
|
||||
tableData.resourceItem.GetResType());
|
||||
contents.push_back(name);
|
||||
string data = ResourceUtil::ComposeStrings(contents, true);
|
||||
recordItem.size = sizeof(RecordItem) + data.length() - sizeof(uint32_t);
|
||||
pos += recordItem.size + sizeof(uint32_t);
|
||||
|
||||
out.write(reinterpret_cast<const char *>(&recordItem.size), sizeof(uint32_t));
|
||||
out.write(reinterpret_cast<const char *>(&recordItem.resType), sizeof(uint32_t));
|
||||
out.write(reinterpret_cast<const char *>(&recordItem.id), sizeof(uint32_t));
|
||||
out.write(reinterpret_cast<const char *>(data.c_str()), data.length());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ResourceTable::SaveHeader(const IndexHeader &indexHeader, std::ofstream &out) const
|
||||
{
|
||||
out.seekp(0);
|
||||
out.write(reinterpret_cast<const char *>(&indexHeader.version), VERSION_MAX_LEN);
|
||||
out.write(reinterpret_cast<const char *>(&indexHeader.fileSize), sizeof(uint32_t));
|
||||
out.write(reinterpret_cast<const char *>(&indexHeader.limitKeyConfigSize), sizeof(uint32_t));
|
||||
}
|
||||
|
||||
void ResourceTable::SaveLimitKeyConfigs(const map<string, LimitKeyConfig> &limitKeyConfigs, ofstream &out) const
|
||||
{
|
||||
for (const auto &iter : limitKeyConfigs) {
|
||||
out.write(reinterpret_cast<const char *>(iter.second.keyTag), TAG_LEN);
|
||||
out.write(reinterpret_cast<const char *>(&iter.second.offset), sizeof(uint32_t));
|
||||
out.write(reinterpret_cast<const char *>(&iter.second.keyCount), sizeof(uint32_t));
|
||||
for (const auto &value : iter.second.data) {
|
||||
out.write(reinterpret_cast<const char *>(&value), sizeof(int32_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ResourceTable::SaveIdSets(const map<string, IdSet> &idSets, ofstream &out) const
|
||||
{
|
||||
for (const auto &iter : idSets) {
|
||||
out.write(reinterpret_cast<const char *>(iter.second.idTag), TAG_LEN);
|
||||
out.write(reinterpret_cast<const char *>(&iter.second.idCount), sizeof(uint32_t));
|
||||
for (const auto &keyValue : iter.second.data) {
|
||||
out.write(reinterpret_cast<const char *>(&keyValue.first), sizeof(uint32_t));
|
||||
out.write(reinterpret_cast<const char *>(&keyValue.second), sizeof(uint32_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_util.h"
|
||||
#include<algorithm>
|
||||
#include<fstream>
|
||||
#include<iostream>
|
||||
#include<regex>
|
||||
#ifdef __WIN32
|
||||
#include "windows.h"
|
||||
#endif
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
const map<string, ResourceUtil::IgnoreType> ResourceUtil::IGNORE_FILE_REGEX = {
|
||||
{ "\\.git", IgnoreType::IGNORE_ALL },
|
||||
{ "\\.svn", IgnoreType::IGNORE_ALL },
|
||||
{ ".+\\.scc", IgnoreType::IGNORE_ALL },
|
||||
{ "\\.ds_store", IgnoreType::IGNORE_ALL },
|
||||
{ "desktop\\.ini", IgnoreType::IGNORE_ALL },
|
||||
{ "picasa\\.ini", IgnoreType::IGNORE_ALL },
|
||||
{ "\\..+", IgnoreType::IGNORE_ALL },
|
||||
{ "_.+",IgnoreType::IGNORE_DIR },
|
||||
{ "cvs", IgnoreType::IGNORE_ALL },
|
||||
{ "thumbs\\.db", IgnoreType::IGNORE_ALL },
|
||||
{ ".+~", IgnoreType::IGNORE_ALL }
|
||||
};
|
||||
|
||||
void ResourceUtil::Split(const string &str, vector<string> &out, const string &splitter)
|
||||
{
|
||||
string::size_type len = str.size();
|
||||
string::size_type begin = 0;
|
||||
string::size_type end = str.find(splitter, begin);
|
||||
while (end != string::npos) {
|
||||
string sub = str.substr(begin, end - begin);
|
||||
out.push_back(sub);
|
||||
begin = end + splitter.size();
|
||||
if (begin >= len) {
|
||||
break;
|
||||
}
|
||||
end = str.find(splitter, begin);
|
||||
}
|
||||
|
||||
if (begin < len) {
|
||||
out.push_back(str.substr(begin));
|
||||
}
|
||||
}
|
||||
|
||||
bool ResourceUtil::FileExist(const string &path)
|
||||
{
|
||||
return filesystem::exists(path);
|
||||
}
|
||||
|
||||
bool ResourceUtil::RmoveAllDir(const string &path)
|
||||
{
|
||||
error_code err;
|
||||
filesystem::remove_all(path, err);
|
||||
if (err) {
|
||||
cerr << "Error: remove all " << path << " failed, msg :=" << err.message() << endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ResourceUtil::OpenJsonFile(const string &path, Json::Value &root)
|
||||
{
|
||||
ifstream ifs(path, ios::binary);
|
||||
if (!ifs) {
|
||||
cerr << "Error: open json faild '" << path << "'" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
Json::CharReaderBuilder readBuilder;
|
||||
readBuilder["collectComments"] = false;
|
||||
readBuilder["failIfExtra"] = true;
|
||||
JSONCPP_STRING errs;
|
||||
if(!parseFromStream(readBuilder, ifs, &root, &errs)) {
|
||||
cerr << "Error: parseFromStream '" << path;
|
||||
cerr << "\n" << errs << endl;
|
||||
ifs.close();
|
||||
return false;
|
||||
}
|
||||
ifs.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ResourceUtil::SaveToJsonFile(const string &path, const Json::Value &root)
|
||||
{
|
||||
Json::StreamWriterBuilder writerBuilder;
|
||||
writerBuilder["indentation"] = " ";
|
||||
writerBuilder["emitUTF8"] = true;
|
||||
unique_ptr<Json::StreamWriter> writer(writerBuilder.newStreamWriter());
|
||||
ofstream out(path, ofstream::out | ofstream::binary);
|
||||
if (!out.is_open()) {
|
||||
cerr << "Error: open fail " << path << endl;
|
||||
return false;
|
||||
}
|
||||
writer->write(root, &out);
|
||||
out.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
ResType ResourceUtil::GetResTypeByDir(const string &name)
|
||||
{
|
||||
auto ret = g_fileClusterMap.find(name);
|
||||
if (ret == g_fileClusterMap.end()) {
|
||||
return ResType::INVALID_RES_TYPE;
|
||||
}
|
||||
return ret->second;
|
||||
}
|
||||
|
||||
string ResourceUtil::ResTypeToString(ResType type)
|
||||
{
|
||||
auto ret = find_if(g_fileClusterMap.begin(), g_fileClusterMap.end(), [type](auto iter) {
|
||||
return iter.second == type;
|
||||
});
|
||||
if (ret != g_fileClusterMap.end()) {
|
||||
return ret->first;
|
||||
}
|
||||
|
||||
ret = find_if(g_contentClusterMap.begin(), g_contentClusterMap.end(), [type](auto iter) {
|
||||
return iter.second == type;
|
||||
});
|
||||
if (ret != g_contentClusterMap.end()) {
|
||||
return ret->first;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
string ResourceUtil::GetIdName(const string &name, ResType type)
|
||||
{
|
||||
if (type != ResType::MEDIA && type != ResType::LAYOUT && type != ResType::PROF &&
|
||||
type != ResType::ANIMATION && type != ResType::GRAPHIC ) {
|
||||
return name;
|
||||
}
|
||||
|
||||
string::size_type pos = name.find_last_of(".");
|
||||
if (pos != string::npos) {
|
||||
return name.substr(0, pos);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
string ResourceUtil::ComposeStrings(const vector<string> &contents, bool addNull)
|
||||
{
|
||||
string result;
|
||||
for (const auto &iter : contents) {
|
||||
if (iter.length() > UINT16_MAX) {
|
||||
return "";
|
||||
}
|
||||
|
||||
uint16_t size = iter.length();
|
||||
if (addNull) {
|
||||
size += sizeof(char);
|
||||
}
|
||||
result.append(sizeof(char), (size & 0xff));
|
||||
result.append(sizeof(char), (size >> 8));
|
||||
result.append(iter);
|
||||
result.append(sizeof(char), '\0');
|
||||
if (result.length() > UINT16_MAX) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
vector<string> ResourceUtil::DecomposeStrings(const string &content)
|
||||
{
|
||||
vector<string> result;
|
||||
size_t length = content.length();
|
||||
size_t pos = 0;
|
||||
const size_t HEAD_LENGTH = 2;
|
||||
while (pos < length) {
|
||||
if (pos + HEAD_LENGTH >= length) {
|
||||
result.clear();
|
||||
return result;
|
||||
}
|
||||
uint16_t size = (content[pos] & 0xff) | ((content[pos + 1] & 0xff) << 8);
|
||||
pos += HEAD_LENGTH;
|
||||
|
||||
if (pos + size >= length) {
|
||||
result.clear();
|
||||
return result;
|
||||
}
|
||||
string buffer = content.substr(pos, size);
|
||||
result.push_back(buffer);
|
||||
pos += size + sizeof(char);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ResType ResourceUtil::GetResTypeFromString(const string &type)
|
||||
{
|
||||
ResType resType = GetResTypeByDir(type);
|
||||
if (resType != ResType::INVALID_RES_TYPE) {
|
||||
return resType;
|
||||
}
|
||||
|
||||
auto ret = g_contentClusterMap.find(type);
|
||||
if (ret != g_contentClusterMap.end()) {
|
||||
return ret->second;
|
||||
}
|
||||
return ResType::INVALID_RES_TYPE;
|
||||
}
|
||||
|
||||
bool ResourceUtil::CopyFleInner(const string &src, const string &dst)
|
||||
{
|
||||
#ifdef __WIN32
|
||||
if (!CopyFileA(src.c_str(), dst.c_str(), false)) {
|
||||
cerr << "Error: copy file fail from '" << src << "' to '" << dst << "'" << endl;
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
error_code err;
|
||||
filesystem::path from(src);
|
||||
filesystem::path to(dst);
|
||||
if (!filesystem::copy_file(from, to, filesystem::copy_options::overwrite_existing, err)) {
|
||||
cerr << "Error: copy file fail from '" << src << "' to '" << dst << "'" << endl;
|
||||
cerr << err.message() << endl;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ResourceUtil::CreateDirs(const string &filePath)
|
||||
{
|
||||
if (FileExist(filePath)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
error_code err;
|
||||
if (!filesystem::create_directories(filePath, err)) {
|
||||
cerr << "Error: create directory fail '" << filePath << "'" << endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ResourceUtil::IsIgnoreFile(const string &filename, filesystem::file_type type)
|
||||
{
|
||||
string key = filename;
|
||||
transform(key.begin(), key.end(), key.begin(), ::tolower);
|
||||
for (const auto &iter : IGNORE_FILE_REGEX) {
|
||||
if ((iter.second == IgnoreType::IGNORE_FILE && type != filesystem::file_type::regular) ||
|
||||
(iter.second == IgnoreType::IGNORE_DIR && type != filesystem::file_type::directory)) {
|
||||
continue;
|
||||
}
|
||||
if (regex_match(key, regex(iter.first))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ResourceUtil::NeedConverToSolidXml(ResType resType)
|
||||
{
|
||||
if (resType == ResType::LAYOUT || resType == ResType::ANIMATION ||
|
||||
resType == ResType::GRAPHIC) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
string ResourceUtil::GenerateHash(const std::string key)
|
||||
{
|
||||
hash<string> hash_function;
|
||||
return to_string(hash_function(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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_parser.h"
|
||||
#include "task_handle.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace OHOS::Global::Restool;
|
||||
|
||||
uint32_t ProccssHap(PackageParser &packageParser) {
|
||||
TaskHandle taskHandle;
|
||||
return taskHandle.HandlePackage(packageParser);
|
||||
}
|
||||
|
||||
uint32_t PackCmdHandle(PackageParser &packageParser)
|
||||
{
|
||||
return ProccssHap(packageParser);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
auto &parser = CmdParser<PackageParser>::GetInstance();
|
||||
if (parser.Parse(argc, argv) != RESTOOL_SUCCESS) {
|
||||
parser.ShowUseage();
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
auto &packageParser = parser.GetCmdParser();
|
||||
if (PackCmdHandle(packageParser) != RESTOOL_SUCCESS) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
cout << "Info: restool resources compile success." << endl;
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 "solid_xml_compiler.h"
|
||||
#include<filesystem>
|
||||
#include<iostream>
|
||||
#include<regex>
|
||||
#include "restool_errors.h"
|
||||
#include "resource_util.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
SolidXmlCompiler::SolidXmlCompiler(ResType type, const string &output)
|
||||
: GenericCompiler(type, output)
|
||||
{
|
||||
}
|
||||
|
||||
SolidXmlCompiler::~SolidXmlCompiler()
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t SolidXmlCompiler::CompileSingleFile(const FileInfo &fileInfo)
|
||||
{
|
||||
if (!IsXmlFile(fileInfo)) {
|
||||
cerr << "Error: '" << fileInfo.filePath << "' should be xml file." << endl;
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (HasConvertedToSolidXml(fileInfo)) {
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
if (!PostFile(fileInfo)) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
|
||||
if (!ParseXml(fileInfo)) {
|
||||
return RESTOOL_ERROR;
|
||||
}
|
||||
return RESTOOL_SUCCESS;
|
||||
}
|
||||
|
||||
bool SolidXmlCompiler::ParseXml(const FileInfo &fileInfo)
|
||||
{
|
||||
xmlKeepBlanksDefault(0);
|
||||
xmlDocPtr doc = xmlParseFile(fileInfo.filePath.c_str());
|
||||
if (doc == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
vector<string> ids;
|
||||
bool result = ParseNodeId(fileInfo, xmlDocGetRootElement(doc), ids);
|
||||
xmlFreeDoc(doc);
|
||||
if (!result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto &id : ids) {
|
||||
ResourceItem resourceItem(id, fileInfo.keyParams, ResType::ID);
|
||||
resourceItem.SetFilePath(fileInfo.filePath);
|
||||
resourceItem.SetLimitKey(fileInfo.limitKey);
|
||||
if (!MergeResourceItem(resourceItem)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SolidXmlCompiler::ParseNodeId(const FileInfo &fileInfo, const xmlNodePtr &node, vector<string> &ids)
|
||||
{
|
||||
if (node == nullptr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (node->type == XML_COMMENT_NODE) {
|
||||
return ParseNodeId(fileInfo, node->next, ids);
|
||||
}
|
||||
|
||||
string idValue;
|
||||
xmlChar * xmlValue = xmlGetProp(node, BAD_CAST "id");
|
||||
if (xmlValue != nullptr) {
|
||||
idValue = string(reinterpret_cast<const char *>(xmlValue));
|
||||
xmlFree(xmlValue);
|
||||
}
|
||||
|
||||
regex ref("^\\$\\+id:");
|
||||
smatch result;
|
||||
if (regex_search(idValue, result, ref)) {
|
||||
string name = idValue.substr(result[0].str().size());
|
||||
if (find(ids.begin(), ids.end(), name) != ids.end()) {
|
||||
cerr << "Error: '" << idValue << "' duplicated in " << fileInfo.filePath << endl;
|
||||
return false;
|
||||
}
|
||||
ids.push_back(name);
|
||||
}
|
||||
|
||||
if (!ParseNodeId(fileInfo, node->children, ids)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ParseNodeId(fileInfo, node->next, ids)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 "sqlite_database.h"
|
||||
#include<iostream>
|
||||
|
||||
#include "resource_util.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
int32_t SqliteDatabase::id_ = 0;
|
||||
void SqliteDatabase::Init(const string &dbPath)
|
||||
{
|
||||
dbPath_ = dbPath;
|
||||
}
|
||||
|
||||
bool SqliteDatabase::OpenDatabase()
|
||||
{
|
||||
int result = sqlite3_open(dbPath_.c_str(), &db_);
|
||||
if (result) {
|
||||
cerr << "Can't open database: " << sqlite3_errmsg(db_) << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CreateTable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!FindMaxId()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SqliteDatabase::CloseDatabase()
|
||||
{
|
||||
if (db_ == nullptr) {
|
||||
return;
|
||||
}
|
||||
sqlite3_close(db_);
|
||||
db_ = nullptr;
|
||||
}
|
||||
|
||||
bool SqliteDatabase::Insert(const ResourceItem &resourceItem)
|
||||
{
|
||||
if (resourceItem.GetResType() == ResType::ID) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t id = -1;
|
||||
if (!Query(resourceItem, id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (id >= 0 ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
string data = GetValue(resourceItem);
|
||||
string sql = "insert into resource_index values(" + to_string(id_) + ",'" + resourceItem.GetName() + "','" + \
|
||||
data + "'," + \
|
||||
to_string((int32_t)resourceItem.GetResType()) + ",'" + resourceItem.GetFilePath() + \
|
||||
"','" + resourceItem.GetLimitKey() + "'," + to_string(priority_) + ")";
|
||||
auto callback = [](void *owner, int argc, char **argv, char **azColName) -> int {
|
||||
return 0;
|
||||
};
|
||||
|
||||
char *zErrMsg = 0;
|
||||
int result = sqlite3_exec(db_, sql.c_str(), callback, nullptr, &zErrMsg);
|
||||
if (result) {
|
||||
cerr << "insert sql error: " << zErrMsg << endl;
|
||||
sqlite3_free(zErrMsg);
|
||||
return false;
|
||||
}
|
||||
id_++;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SqliteDatabase::Query(const ResourceItem &resourceItem, int32_t &id)
|
||||
{
|
||||
string sql = "select id from resource_index where name='" + resourceItem.GetName() + \
|
||||
"' and type='" + to_string((int32_t)resourceItem.GetResType()) + \
|
||||
"' and limitkey='" + resourceItem.GetLimitKey() + \
|
||||
"' and priority=" + to_string(priority_);
|
||||
auto callback = [](void *id, int argc, char **argv, char **azColName) -> int {
|
||||
if (argc > 0 && id) {
|
||||
(*static_cast<int *>(id)) = atoi(argv[0]);
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
id = -1;
|
||||
char *zErrMsg = 0;
|
||||
int result = sqlite3_exec(db_, sql.c_str(), callback, &id, &zErrMsg);
|
||||
if (result) {
|
||||
cerr << "query sql error: " << zErrMsg << endl;
|
||||
sqlite3_free(zErrMsg);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (id < 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
sql = "update resource_index set value='" + GetValue(resourceItem) + \
|
||||
"', path='" + resourceItem.GetFilePath() + \
|
||||
"' where id = " + to_string(id);
|
||||
result = sqlite3_exec(db_, sql.c_str(), callback, nullptr, &zErrMsg);
|
||||
if (result) {
|
||||
cerr << "query sql error: " << zErrMsg << endl;
|
||||
sqlite3_free(zErrMsg);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SqliteDatabase::FindMaxId()
|
||||
{
|
||||
string sql = "select max(id) from resource_index";
|
||||
auto callback = [](void *owner, int argc, char **argv, char **azColName) -> int {
|
||||
if (argc > 0 && argv[0]) {
|
||||
id_ = atoi(argv[0]) + 1;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
char *zErrMsg = 0;
|
||||
int result = sqlite3_exec(db_, sql.c_str(), callback, nullptr, &zErrMsg);
|
||||
if (result) {
|
||||
cerr << "find max id sql error: " << zErrMsg << endl;
|
||||
sqlite3_free(zErrMsg);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SqliteDatabase::CreateTable()
|
||||
{
|
||||
string sql = "select * from sqlite_master where name = 'resource_index'";
|
||||
auto callback = [](void *find, int argc, char **argv, char **azColName) -> int {
|
||||
if (argc > 0 && find) {
|
||||
(*static_cast<bool *>(find)) = true;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
bool find = false;
|
||||
char *zErrMsg = 0;
|
||||
int result = sqlite3_exec(db_, sql.c_str(), callback, &find, &zErrMsg);
|
||||
if (result) {
|
||||
cerr << "search table error: " << zErrMsg << endl;
|
||||
sqlite3_free(zErrMsg);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (find) {
|
||||
return true;
|
||||
}
|
||||
|
||||
sql = "create table resource_index(id int, name, value image, type int, path, limitkey, priority int)";
|
||||
result = sqlite3_exec(db_, sql.c_str(), callback, nullptr, &zErrMsg);
|
||||
if (result) {
|
||||
cerr << "create table error: " << zErrMsg << endl;
|
||||
sqlite3_free(zErrMsg);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
string SqliteDatabase::GetValue(const ResourceItem &resourceItem) const
|
||||
{
|
||||
string data(reinterpret_cast<const char *>(resourceItem.GetData()), resourceItem.GetDataLength());
|
||||
if (resourceItem.GetResType() == ResType::STRARRAY || resourceItem.GetResType() == ResType::INTARRAY ||
|
||||
resourceItem.GetResType() == ResType::THEME || resourceItem.GetResType() == ResType::PATTERN ||
|
||||
resourceItem.GetResType() == ResType::PLURAL ) {
|
||||
vector<string> contents = ResourceUtil::DecomposeStrings(data);
|
||||
Json::Value array(Json::arrayValue);
|
||||
for (const auto &iter : contents) {
|
||||
array.append(iter);
|
||||
}
|
||||
data = array.toStyledString();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 "task_handle.h"
|
||||
|
||||
#include "resource_pack.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
uint32_t TaskHandle::HandlePackage(const PackageParser &packageParser)
|
||||
{
|
||||
ResourcePack pack(packageParser);
|
||||
return pack.Package();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 "key_manager.h"
|
||||
#include<filesystem>
|
||||
#include "resource_util.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
KeyManager::KeyManager()
|
||||
{
|
||||
keys_.emplace(XmlKeyNode::KeyType::NODE, make_shared<XmlKeyNode>());
|
||||
keys_.emplace(XmlKeyNode::KeyType::ATTRIBUTE, make_shared<XmlKeyNode>());
|
||||
keys_.emplace(XmlKeyNode::KeyType::CONSTANT, make_shared<XmlKeyNode>());
|
||||
keys_.emplace(XmlKeyNode::KeyType::CONTENT, make_shared<XmlKeyNode>());
|
||||
}
|
||||
|
||||
bool KeyManager::LoadKey(const string &keysPath)
|
||||
{
|
||||
for (auto &key : keys_) {
|
||||
string keyPath = filesystem::path(keysPath).append(XmlKeyNode::KEY_TO_FILE_NAME.at(key.first)).string();
|
||||
if (!ResourceUtil::FileExist(keyPath)) {
|
||||
continue;
|
||||
}
|
||||
if (!key.second->LoadFromFile(keyPath)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KeyManager::SaveKey(const string &keysPath)
|
||||
{
|
||||
for (const auto &iter : keys_) {
|
||||
string keyPath = filesystem::path(keysPath).append(XmlKeyNode::KEY_TO_FILE_NAME.at(iter.first)).string();
|
||||
if (!iter.second->SaveToFile(keyPath)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,380 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 "solid_xml.h"
|
||||
#include<iostream>
|
||||
#include<regex>
|
||||
#include "securec.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
const uint8_t SolidXml::SOLID_XML_MAGIC[] = "SolidXml";
|
||||
const uint32_t SolidXml::SOLID_XML_MAGIC_LENGTH =
|
||||
(sizeof(SolidXml::SOLID_XML_MAGIC) / sizeof(uint32_t) + 1) * sizeof(uint32_t);
|
||||
|
||||
SolidXml::SolidXml(const string &xmlPath, map<XmlKeyNode::KeyType, shared_ptr<XmlKeyNode>> &keys)
|
||||
: xmlPath_(xmlPath), keys_(keys)
|
||||
{
|
||||
}
|
||||
|
||||
SolidXml::~SolidXml()
|
||||
{
|
||||
}
|
||||
|
||||
bool SolidXml::GenerateSolidXml(const string &filePath)
|
||||
{
|
||||
xmlKeepBlanksDefault(0);
|
||||
xmlDocPtr doc = xmlParseFile(xmlPath_.c_str());
|
||||
if (doc == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto root = make_shared<XmlNode>();
|
||||
nodes_.push_back(root);
|
||||
Compile(xmlDocGetRootElement(doc), root);
|
||||
xmlFreeDoc(doc);
|
||||
return SaveToFile(filePath);
|
||||
}
|
||||
|
||||
bool SolidXml::FlushNodeKeys(const string &filePath, map<XmlKeyNode::KeyType, shared_ptr<XmlKeyNode>> &newKeys)
|
||||
{
|
||||
if (!LoadFromFile(xmlPath_)) {
|
||||
cerr << "Error: load " << xmlPath_ << " fail." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool firstNode = true;
|
||||
for (auto &node : nodes_) {
|
||||
if (!node->FlushIndex(keys_, newKeys)) {
|
||||
cerr << "Error: flush node key fail, '" << xmlPath_ << "'" << endl;
|
||||
return false;
|
||||
}
|
||||
if (firstNode && !FlushXmlnsKey(newKeys)) {
|
||||
return false;
|
||||
}
|
||||
firstNode = false;
|
||||
}
|
||||
|
||||
for (auto &attr : attributes_) {
|
||||
if (!attr->FlushIndex(keys_, newKeys)) {
|
||||
cerr << "Error: flush attibutes key fail, '" << xmlPath_ << "'" << endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return SaveToFile(filePath);
|
||||
}
|
||||
|
||||
//below private
|
||||
void SolidXml::Compile(const xmlNodePtr nodePtr, shared_ptr<XmlNode> &node)
|
||||
{
|
||||
if (nodePtr->type == XML_COMMENT_NODE) {
|
||||
if (nodePtr->next) {
|
||||
Compile(nodePtr->next, node);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
string name(reinterpret_cast<const char *>(nodePtr->name));
|
||||
node->SetName(keys_[XmlKeyNode::KeyType::NODE]->PushKey(name));
|
||||
CompileNameSpace(nodePtr, node);
|
||||
CompileAttr(nodePtr->properties, node);
|
||||
|
||||
if (nodePtr->children) {
|
||||
if (nodePtr->children->type == XML_TEXT_NODE) {
|
||||
string content(reinterpret_cast<const char *>(nodePtr->children->content));
|
||||
node->SetValue(keys_[XmlKeyNode::KeyType::CONTENT]->PushKey(content));
|
||||
} else {
|
||||
auto child = make_shared<XmlNode>();
|
||||
nodes_.push_back(child);
|
||||
node->SetChild(nodes_.size() - 1);
|
||||
Compile(nodePtr->children, child);
|
||||
}
|
||||
}
|
||||
|
||||
if (nodePtr->next) {
|
||||
auto brother = make_shared<XmlNode>();
|
||||
nodes_.push_back(brother);
|
||||
node->SetBrother(nodes_.size() - 1);
|
||||
Compile(nodePtr->next, brother);
|
||||
}
|
||||
}
|
||||
|
||||
void SolidXml::CompileAttr(const xmlAttrPtr attrPtr, shared_ptr<XmlNode> &node)
|
||||
{
|
||||
if (attrPtr == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
xmlChar * xmlValue = xmlNodeListGetString(attrPtr->doc, attrPtr->children, 1);
|
||||
string value(reinterpret_cast<const char *>(xmlValue));
|
||||
PretreatmentAttr(value);
|
||||
xmlFree(xmlValue);
|
||||
string name(reinterpret_cast<const char *>(attrPtr->name));
|
||||
auto attr = make_shared<Node>();
|
||||
attributes_.push_back(attr);
|
||||
attr->SetName(keys_[XmlKeyNode::KeyType::ATTRIBUTE]->PushKey(name));
|
||||
attr->SetValue(keys_[XmlKeyNode::KeyType::CONSTANT]->PushKey(value));
|
||||
if (attrPtr->ns != nullptr && attrPtr->ns->prefix != nullptr) {
|
||||
string nameSpace(reinterpret_cast<const char *>(attrPtr->ns->prefix));
|
||||
attr->SetNameSpace(keys_[XmlKeyNode::KeyType::NODE]->PushKey(nameSpace));
|
||||
}
|
||||
node->AddAttribute(attributes_.size() - 1);
|
||||
CompileAttr(attrPtr->next, node);
|
||||
}
|
||||
|
||||
void SolidXml::CompileNameSpace(const xmlNodePtr nodePtr, shared_ptr<XmlNode> &node)
|
||||
{
|
||||
if (nodePtr->ns && nodePtr->ns->prefix) {
|
||||
string nameSpace(reinterpret_cast<const char *>(nodePtr->ns->prefix));
|
||||
node->SetNameSpace(keys_[XmlKeyNode::KeyType::NODE]->PushKey(nameSpace));
|
||||
}
|
||||
|
||||
auto nsDef = nodePtr->nsDef;
|
||||
while (nsDef) {
|
||||
string nameSpace;
|
||||
string href;
|
||||
if (nsDef->prefix) {
|
||||
nameSpace = string(reinterpret_cast<const char *>(nsDef->prefix));
|
||||
}
|
||||
if (nsDef->href) {
|
||||
href = string(reinterpret_cast<const char *>(nsDef->href));
|
||||
}
|
||||
int32_t nameSpaceIndex = keys_[XmlKeyNode::KeyType::NODE]->PushKey(nameSpace);
|
||||
int32_t herfIndex = keys_[XmlKeyNode::KeyType::NODE]->PushKey(href);
|
||||
AddNampeSpaceDef(nameSpaceIndex, herfIndex);
|
||||
nsDef = nsDef->next;
|
||||
}
|
||||
}
|
||||
|
||||
void SolidXml::Node::RawData(ofstream &out) const
|
||||
{
|
||||
out.write(reinterpret_cast<const char *>(&nameSpace_), sizeof(int32_t));
|
||||
out.write(reinterpret_cast<const char *>(&name_), sizeof(int32_t));
|
||||
out.write(reinterpret_cast<const char *>(&value_), sizeof(int32_t));
|
||||
}
|
||||
|
||||
void SolidXml::XmlNode::RawData(ofstream &out) const
|
||||
{
|
||||
SolidXml::Node::RawData(out);
|
||||
out.write(reinterpret_cast<const char *>(&child_), sizeof(int32_t));
|
||||
out.write(reinterpret_cast<const char *>(&brother_), sizeof(int32_t));
|
||||
int32_t attrStart = attributes_.size();
|
||||
int32_t attrCount = attributes_.size();
|
||||
if (!attributes_.empty()) {
|
||||
attrStart = attributes_.at(0);
|
||||
}
|
||||
out.write(reinterpret_cast<const char *>(&attrStart), sizeof(int32_t));
|
||||
out.write(reinterpret_cast<const char *>(&attrCount), sizeof(int32_t));
|
||||
}
|
||||
|
||||
bool SolidXml::Node::LoadFrom(ifstream &in)
|
||||
{
|
||||
CHECK_IO(in.read(reinterpret_cast<char *>(&nameSpace_), sizeof(int32_t)))
|
||||
CHECK_IO(in.read(reinterpret_cast<char *>(&name_), sizeof(int32_t)));
|
||||
CHECK_IO(in.read(reinterpret_cast<char *>(&value_), sizeof(int32_t)));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SolidXml::XmlNode::LoadFrom(ifstream &in)
|
||||
{
|
||||
if (!SolidXml::Node::LoadFrom(in)) {
|
||||
return false;
|
||||
}
|
||||
CHECK_IO(in.read(reinterpret_cast<char *>(&child_), sizeof(int32_t)));
|
||||
CHECK_IO(in.read(reinterpret_cast<char *>(&brother_), sizeof(int32_t)));
|
||||
int32_t attrStart = 0;
|
||||
int32_t attrCount = 0;
|
||||
CHECK_IO(in.read(reinterpret_cast<char *>(&attrStart), sizeof(int32_t)));
|
||||
CHECK_IO(in.read(reinterpret_cast<char *>(&attrCount), sizeof(int32_t)));
|
||||
for (int32_t i = attrStart; i < attrStart + attrCount; i++) {
|
||||
attributes_.push_back(i);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SolidXml::Node::FlushIndex(const map<XmlKeyNode::KeyType, shared_ptr<XmlKeyNode>> &oldKeys,
|
||||
map<XmlKeyNode::KeyType, shared_ptr<XmlKeyNode>> &newKeys)
|
||||
{
|
||||
if (!ChangeToNewKey(oldKeys, newKeys, XmlKeyNode::KeyType::NODE, nameSpace_) ||
|
||||
!ChangeToNewKey(oldKeys, newKeys, XmlKeyNode::KeyType::ATTRIBUTE, name_) ||
|
||||
!ChangeToNewKey(oldKeys, newKeys, XmlKeyNode::KeyType::CONSTANT, value_)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SolidXml::XmlNode::FlushIndex(const map<XmlKeyNode::KeyType, shared_ptr<XmlKeyNode>> &oldKeys,
|
||||
map<XmlKeyNode::KeyType, shared_ptr<XmlKeyNode>> &newKeys)
|
||||
{
|
||||
if (!ChangeToNewKey(oldKeys, newKeys, XmlKeyNode::KeyType::NODE, nameSpace_) ||
|
||||
!ChangeToNewKey(oldKeys, newKeys, XmlKeyNode::KeyType::NODE, name_) ||
|
||||
!ChangeToNewKey(oldKeys, newKeys, XmlKeyNode::KeyType::CONTENT, value_)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SolidXml::AddNampeSpaceDef(int32_t nameSpace, int32_t href)
|
||||
{
|
||||
nameSpaces_.push_back(nameSpace);
|
||||
hrefs_.push_back(href);
|
||||
}
|
||||
|
||||
bool SolidXml::SaveToFile(const std::string &filePath) const
|
||||
{
|
||||
ofstream out(filePath, ofstream::out | ofstream::binary);
|
||||
if (!out.is_open()) {
|
||||
cerr << "Error: open fail," << filePath << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// write solid xml header
|
||||
uint8_t magic[SOLID_XML_MAGIC_LENGTH] = {0};
|
||||
if (memcpy_s(magic, SOLID_XML_MAGIC_LENGTH, SOLID_XML_MAGIC, sizeof(SOLID_XML_MAGIC)) != EOK) {
|
||||
cerr << "Error: SolidXml::SaveToFile memcpy_s fail." << endl;
|
||||
return false;
|
||||
}
|
||||
uint32_t version = 1;
|
||||
uint32_t numOfNodes = nodes_.size();
|
||||
uint32_t numOfAttributes = attributes_.size();
|
||||
uint32_t numOfNameSpaces = nameSpaces_.size();
|
||||
out.write(reinterpret_cast<const char *>(magic), SOLID_XML_MAGIC_LENGTH);
|
||||
out.write(reinterpret_cast<const char *>(&version), sizeof(uint32_t));
|
||||
out.write(reinterpret_cast<const char *>(&numOfNodes), sizeof(uint32_t));
|
||||
out.write(reinterpret_cast<const char *>(&numOfAttributes), sizeof(uint32_t));
|
||||
out.write(reinterpret_cast<const char *>(&numOfNameSpaces), sizeof(uint32_t));
|
||||
|
||||
// write node
|
||||
for (const auto &node : nodes_) {
|
||||
node->RawData(out);
|
||||
}
|
||||
|
||||
// write attribute
|
||||
for (const auto &attribute : attributes_) {
|
||||
attribute->RawData(out);
|
||||
}
|
||||
|
||||
// write namespace
|
||||
for (const auto &nameSpace : nameSpaces_) {
|
||||
out.write(reinterpret_cast<const char *>(&nameSpace), sizeof(int32_t));
|
||||
}
|
||||
|
||||
// write href
|
||||
for (const auto &href : hrefs_) {
|
||||
out.write(reinterpret_cast<const char *>(&href), sizeof(int32_t));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SolidXml::PretreatmentAttr(string &value) const
|
||||
{
|
||||
regex ref("^\\$\\+id:");
|
||||
smatch result;
|
||||
if (!regex_search(value, result, ref)) {
|
||||
return;
|
||||
}
|
||||
value.replace(0, result[0].str().length(), "$id:");
|
||||
}
|
||||
|
||||
bool SolidXml::LoadFromFile(const string &sxmlPath)
|
||||
{
|
||||
ifstream in(sxmlPath, ifstream::in | ifstream::binary);
|
||||
if (!in.is_open()) {
|
||||
cerr << "Error: open fail," << sxmlPath << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
char header[SOLID_XML_MAGIC_LENGTH];
|
||||
CHECK_IO(in.read(header, SOLID_XML_MAGIC_LENGTH));
|
||||
|
||||
uint32_t version = 0;
|
||||
CHECK_IO(in.read(reinterpret_cast<char *>(&version), sizeof(uint32_t)));
|
||||
|
||||
uint32_t numOfNodes = 0;
|
||||
CHECK_IO(in.read(reinterpret_cast<char *>(&numOfNodes), sizeof(uint32_t)));
|
||||
|
||||
uint32_t numOfAttributes = 0;
|
||||
CHECK_IO(in.read(reinterpret_cast<char *>(&numOfAttributes), sizeof(uint32_t)));
|
||||
|
||||
uint32_t numOfNameSpaces = 0;
|
||||
CHECK_IO(in.read(reinterpret_cast<char *>(&numOfNameSpaces), sizeof(uint32_t)));
|
||||
|
||||
for (uint32_t i = 0; i < numOfNodes; i++) {
|
||||
auto xmlNode = make_shared<XmlNode>();
|
||||
if (!xmlNode->LoadFrom(in)) {
|
||||
return false;
|
||||
}
|
||||
nodes_.push_back(xmlNode);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < numOfAttributes; i++) {
|
||||
auto attr = make_shared<Node>();
|
||||
if (!attr->LoadFrom(in)) {
|
||||
return false;
|
||||
}
|
||||
attributes_.push_back(attr);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < numOfNameSpaces; i++) {
|
||||
int32_t nameSpace = -1;
|
||||
CHECK_IO(in.read(reinterpret_cast<char *>(&nameSpace), sizeof(int32_t)));
|
||||
nameSpaces_.push_back(nameSpace);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < numOfNameSpaces; i++) {
|
||||
int32_t href = -1;
|
||||
CHECK_IO(in.read(reinterpret_cast<char *>(&href), sizeof(int32_t)));
|
||||
hrefs_.push_back(href);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SolidXml::ChangeToNewKey(const map<XmlKeyNode::KeyType, shared_ptr<XmlKeyNode>> &oldKeys,
|
||||
map<XmlKeyNode::KeyType, shared_ptr<XmlKeyNode>> &newKeys,
|
||||
XmlKeyNode::KeyType keyType, int32_t &keyId)
|
||||
{
|
||||
if (keyId <= 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
string value;
|
||||
if (!oldKeys.at(keyType)->GetKeyValue(keyId, value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
keyId = newKeys[keyType]->PushKey(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SolidXml::FlushXmlnsKey(map<XmlKeyNode::KeyType, shared_ptr<XmlKeyNode>> &newKeys)
|
||||
{
|
||||
if (nameSpaces_.size() != hrefs_.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < nameSpaces_.size(); i++) {
|
||||
if (!ChangeToNewKey(keys_, newKeys, XmlKeyNode::KeyType::NODE, nameSpaces_[i]) ||
|
||||
!ChangeToNewKey(keys_, newKeys, XmlKeyNode::KeyType::NODE, hrefs_[i])) {
|
||||
cerr << "Error: flush namespace key fail, '" << xmlPath_ << "'" << endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 "xml_converter.h"
|
||||
#include<filesystem>
|
||||
#include "resource_util.h"
|
||||
#include "solid_xml.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
XmlConverter::XmlConverter(const vector<string> &xmlPaths, const string &outputPath)
|
||||
: xmlPaths_(xmlPaths), outputPath_(outputPath)
|
||||
{
|
||||
}
|
||||
|
||||
XmlConverter::~XmlConverter()
|
||||
{
|
||||
}
|
||||
|
||||
bool XmlConverter::GenerateSolidXml()
|
||||
{
|
||||
if (!LoadKeys(outputPath_)) {
|
||||
return false;
|
||||
}
|
||||
for (const auto &xmlPath : xmlPaths_) {
|
||||
SolidXml solidXml(xmlPath, keyManager.GetKeys());
|
||||
string filename = filesystem::path(xmlPath).filename().string();
|
||||
string filePath = filesystem::path(outputPath_).append(filename).replace_extension(".sxml").string();
|
||||
if (!solidXml.GenerateSolidXml(filePath)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool XmlConverter::GenerateKey()
|
||||
{
|
||||
return keyManager.SaveKey(outputPath_);
|
||||
}
|
||||
|
||||
bool XmlConverter::LoadKeys(const std::string &folderPath)
|
||||
{
|
||||
return keyManager.LoadKey(folderPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 "xml_key_node.h"
|
||||
#include<algorithm>
|
||||
#include<fstream>
|
||||
#include<iostream>
|
||||
#include<vector>
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace Restool {
|
||||
using namespace std;
|
||||
const map<XmlKeyNode::KeyType, string> XmlKeyNode::KEY_TO_FILE_NAME = {
|
||||
{KeyType::NODE, "nodes.key" },
|
||||
{KeyType::ATTRIBUTE, "attributes.key" },
|
||||
{KeyType::CONSTANT, "constants.key" },
|
||||
{KeyType::CONTENT, "contents.key" }
|
||||
};
|
||||
XmlKeyNode::XmlKeyNode() : keyId_(0)
|
||||
{
|
||||
PushKey("");
|
||||
}
|
||||
|
||||
XmlKeyNode::~XmlKeyNode()
|
||||
{
|
||||
}
|
||||
|
||||
int32_t XmlKeyNode::PushKey(const string &name)
|
||||
{
|
||||
auto result = keyMap_.emplace(name, keyId_);
|
||||
if (result.second) {
|
||||
return keyId_++;
|
||||
}
|
||||
return result.first->second;
|
||||
}
|
||||
|
||||
bool XmlKeyNode::SaveToFile(const string &filePath) const
|
||||
{
|
||||
ofstream out(filePath, ofstream::out | ofstream::binary);
|
||||
if (!out.is_open()) {
|
||||
cerr << "Error: open fail," << filePath << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
vector<pair<string, int32_t>> sets(keyMap_.begin(), keyMap_.end());
|
||||
sort(sets.begin(), sets.end(),[](const auto &a, const auto &b) {
|
||||
return a.second < b.second;
|
||||
});
|
||||
|
||||
char null = 0;
|
||||
for (const auto &iter : sets) {
|
||||
out.write(reinterpret_cast<const char *>(iter.first.c_str()), iter.first.length());
|
||||
out.write(&null, sizeof(char));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool XmlKeyNode::LoadFromFile(const string &filePath)
|
||||
{
|
||||
return LoadFromFile(filePath, nullptr);
|
||||
}
|
||||
|
||||
bool XmlKeyNode::LoadFromFile(const std::string &filePath, RefParser parser)
|
||||
{
|
||||
ifstream in(filePath, ifstream::in | ifstream::binary);
|
||||
if (!in.is_open()) {
|
||||
cerr << "Error: open fail," << filePath << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
string inputLine;
|
||||
getline(in, inputLine);
|
||||
if (inputLine.empty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
string::size_type offset = 0;
|
||||
while (offset < inputLine.length()) {
|
||||
string item(inputLine.c_str() + offset);
|
||||
offset = offset + item.length() + sizeof(char);
|
||||
if (parser && !parser(item)) {
|
||||
return false;
|
||||
}
|
||||
PushKey(item);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool XmlKeyNode::GetKeyValue(int32_t keyId, std::string &value) const
|
||||
{
|
||||
auto result = find_if(keyMap_.begin(), keyMap_.end(), [&keyId](const auto &iter) {
|
||||
return keyId == iter.second;
|
||||
});
|
||||
if (result == keyMap_.end()) {
|
||||
return false;
|
||||
}
|
||||
value = result->first;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
aux_source_directory(${bound_checking_function_dir}/src lib_sec_source)
|
||||
add_library(securec STATIC ${lib_sec_source})
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
aux_source_directory(${jsoncpp_dir}/src/lib_json json_source)
|
||||
|
||||
add_library(jsoncpp STATIC ${json_source})
|
||||
Vendored
+348
@@ -0,0 +1,348 @@
|
||||
include(CheckCSourceCompiles)
|
||||
include(CheckIncludeFiles)
|
||||
include(CheckStructHasMember)
|
||||
include(CheckFunctionExists)
|
||||
include(CheckLibraryExists)
|
||||
include(CheckSymbolExists)
|
||||
|
||||
option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
|
||||
set(LIBXML2_WITH_AUTOMATA ON)
|
||||
option(LIBXML2_WITH_C14N "Add the Canonicalization support" ON)
|
||||
option(LIBXML2_WITH_CATALOG "Add the Catalog support" ON)
|
||||
option(LIBXML2_WITH_DEBUG "Add the debugging module" ON)
|
||||
option(LIBXML2_WITH_DOCB "Add Docbook SGML support" ON)
|
||||
set(LIBXML2_WITH_EXPR ON)
|
||||
option(LIBXML2_WITH_FTP "Add the FTP support" ON)
|
||||
option(LIBXML2_WITH_HTML "Add the HTML support" ON)
|
||||
option(LIBXML2_WITH_HTTP "Add the HTTP support" ON)
|
||||
option(LIBXML2_WITH_ICONV "Add ICONV support" OFF)
|
||||
option(LIBXML2_WITH_ICU "Add ICU support" OFF)
|
||||
option(LIBXML2_WITH_ISO8859X "Add ISO8859X support if no iconv" ON)
|
||||
option(LIBXML2_WITH_LEGACY "Add deprecated APIs for compatibility" ON)
|
||||
option(LIBXML2_WITH_LZMA "Use liblzma" OFF)
|
||||
option(LIBXML2_WITH_MEM_DEBUG "Add the memory debugging module" OFF)
|
||||
option(LIBXML2_WITH_MODULES "Add the dynamic modules support" ON)
|
||||
option(LIBXML2_WITH_OUTPUT "Add the serialization support" ON)
|
||||
option(LIBXML2_WITH_PATTERN "Add the xmlPattern selection interface" ON)
|
||||
option(LIBXML2_WITH_PROGRAMS "Build programs" ON)
|
||||
option(LIBXML2_WITH_PUSH "Add the PUSH parser interfaces" ON)
|
||||
option(LIBXML2_WITH_PYTHON "Build Python bindings" OFF)
|
||||
option(LIBXML2_WITH_READER "Add the xmlReader parsing interface" ON)
|
||||
option(LIBXML2_WITH_REGEXPS "Add Regular Expressions support" ON)
|
||||
option(LIBXML2_WITH_RUN_DEBUG "Add the runtime debugging module" OFF)
|
||||
option(LIBXML2_WITH_SAX1 "Add the older SAX1 interface" ON)
|
||||
option(LIBXML2_WITH_SCHEMAS "Add Relax-NG and Schemas support" ON)
|
||||
option(LIBXML2_WITH_SCHEMATRON "Add Schematron support" ON)
|
||||
option(LIBXML2_WITH_THREADS "Add multithread support" ON)
|
||||
option(LIBXML2_WITH_THREAD_ALLOC "Add per-thread memory" OFF)
|
||||
option(LIBXML2_WITH_TREE "Add the DOM like tree manipulation APIs" ON)
|
||||
set(LIBXML2_WITH_TRIO OFF)
|
||||
set(LIBXML2_WITH_UNICODE ON)
|
||||
option(LIBXML2_WITH_VALID "Add the DTD validation support" ON)
|
||||
option(LIBXML2_WITH_WRITER "Add the xmlWriter saving interface" ON)
|
||||
option(LIBXML2_WITH_XINCLUDE "Add the XInclude support" ON)
|
||||
option(LIBXML2_WITH_XPATH "Add the XPATH support" ON)
|
||||
option(LIBXML2_WITH_XPTR "Add the XPointer support" ON)
|
||||
option(LIBXML2_WITH_ZLIB "Use libz" OFF)
|
||||
|
||||
set(LIBXML_MAJOR_VERSION 2)
|
||||
set(LIBXML_MINOR_VERSION 9)
|
||||
set(LIBXML_MICRO_VERSION 10)
|
||||
|
||||
set(VERSION "${LIBXML_MAJOR_VERSION}.${LIBXML_MINOR_VERSION}.${LIBXML_MICRO_VERSION}")
|
||||
set(LIBXML_VERSION ${LIBXML_MAJOR_VERSION}0${LIBXML_MINOR_VERSION}0${LIBXML_MICRO_VERSION})
|
||||
set(LIBXML_VERSION_STRING "${LIBXML_VERSION}")
|
||||
set(LIBXML_VERSION_EXTRA "")
|
||||
set(LIBXML_VERSION_NUMBER ${LIBXML_VERSION})
|
||||
|
||||
foreach(VARIABLE IN ITEMS WITH_AUTOMATA WITH_C14N WITH_CATALOG WITH_DEBUG WITH_DOCB WITH_EXPR WITH_FTP WITH_HTML WITH_HTTP WITH_ICONV WITH_ICU WITH_ISO8859X WITH_SAX1 WITH_LEGACY WITH_LZMA WITH_MEM_DEBUG WITH_MODULES WITH_OUTPUT WITH_PATTERN WITH_PUSH WITH_READER WITH_REGEXPS WITH_RUN_DEBUG WITH_SCHEMAS WITH_SCHEMATRON WITH_THREADS WITH_THREAD_ALLOC WITH_TREE WITH_TRIO WITH_UNICODE WITH_VALID WITH_WRITER WITH_XINCLUDE WITH_XPATH WITH_XPTR WITH_ZLIB)
|
||||
if (LIBXML2_${VARIABLE})
|
||||
set(${VARIABLE} 1)
|
||||
else()
|
||||
set(${VARIABLE} 0)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
check_c_source_compiles("
|
||||
void __attribute__((destructor))
|
||||
f(void) {}
|
||||
int main(void) { return 0; }
|
||||
" ATTRIBUTE_DESTRUCTOR)
|
||||
check_c_source_compiles("
|
||||
#include <netdb.h>
|
||||
int main() { (void) gethostbyname((const char*) \"\"); return 0; }
|
||||
" GETHOSTBYNAME_ARG_CAST_CONST)
|
||||
if(NOT GETHOSTBYNAME_ARG_CAST_CONST)
|
||||
set(GETHOSTBYNAME_ARG_CAST "(char *)")
|
||||
else()
|
||||
set(GETHOSTBYNAME_ARG_CAST "/**/")
|
||||
endif()
|
||||
check_include_files(arpa/inet.h HAVE_ARPA_INET_H)
|
||||
check_include_files(arpa/nameser.h HAVE_ARPA_NAMESER_H)
|
||||
check_struct_has_member("struct sockaddr_storage" ss_family "sys/socket.h;sys/types.h" HAVE_SS_FAMILY)
|
||||
check_struct_has_member("struct sockaddr_storage" __ss_family "sys/socket.h;sys/types.h" HAVE_BROKEN_SS_FAMILY)
|
||||
if(HAVE_BROKEN_SS_FAMILY)
|
||||
set(ss_family __ss_family)
|
||||
endif()
|
||||
check_function_exists(class HAVE_CLASS)
|
||||
check_include_files(ctype.h HAVE_CTYPE_H)
|
||||
check_include_files(dirent.h HAVE_DIRENT_H)
|
||||
check_include_files(dlfcn.h HAVE_DLFCN_H)
|
||||
check_library_exists(dl dlopen "" HAVE_DLOPEN)
|
||||
check_include_files(dl.h HAVE_DL_H)
|
||||
check_include_files(errno.h HAVE_ERRNO_H)
|
||||
check_include_files(fcntl.h HAVE_FCNTL_H)
|
||||
check_function_exists(finite HAVE_FINITE)
|
||||
check_include_files(float.h HAVE_FLOAT_H)
|
||||
check_function_exists(fpclass HAVE_FPCLASS)
|
||||
check_function_exists(fprintf HAVE_FPRINTF)
|
||||
check_function_exists(fp_class HAVE_FP_CLASS)
|
||||
check_function_exists(ftime HAVE_FTIME)
|
||||
check_function_exists(getaddrinfo HAVE_GETADDRINFO)
|
||||
check_function_exists(gettimeofday HAVE_GETTIMEOFDAY)
|
||||
check_include_files(inttypes.h HAVE_INTTYPES_H)
|
||||
check_function_exists(isascii HAVE_ISASCII)
|
||||
check_function_exists(isinf HAVE_ISINF)
|
||||
check_function_exists(isnan HAVE_ISNAN)
|
||||
check_function_exists(isnand HAVE_ISNAND)
|
||||
check_library_exists(history append_history "" HAVE_LIBHISTORY)
|
||||
check_library_exists(lzma lzma_code "" HAVE_LIBLZMA)
|
||||
check_library_exists(pthread pthread_join "" HAVE_LIBPTHREAD)
|
||||
check_library_exists(readline readline "" HAVE_LIBREADLINE)
|
||||
check_library_exists(z gzread "" HAVE_LIBZ)
|
||||
check_include_files(limits.h HAVE_LIMITS_H)
|
||||
check_function_exists(localtime HAVE_LOCALTIME)
|
||||
check_include_files(lzma.h HAVE_LZMA_H)
|
||||
check_include_files(malloc.h HAVE_MALLOC_H)
|
||||
check_include_files(math.h HAVE_MATH_H)
|
||||
check_include_files(memory.h HAVE_MEMORY_H)
|
||||
check_function_exists(mmap HAVE_MMAP)
|
||||
check_function_exists(munmap HAVE_MUNMAP)
|
||||
check_symbol_exists(DIR ndir.h HAVE_NDIR_H)
|
||||
check_include_files(netdb.h HAVE_NETDB_H)
|
||||
check_include_files(netinet/in.h HAVE_NETINET_IN_H)
|
||||
check_include_files(poll.h HAVE_POLL_H)
|
||||
check_function_exists(printf HAVE_PRINTF)
|
||||
check_include_files(pthread.h HAVE_PTHREAD_H)
|
||||
check_function_exists(putenv HAVE_PUTENV)
|
||||
check_function_exists(rand HAVE_RAND)
|
||||
check_function_exists(rand_r HAVE_RAND_R)
|
||||
check_include_files(resolv.h HAVE_RESOLV_H)
|
||||
check_library_exists(dld shl_load "" HAVE_SHLLOAD)
|
||||
check_function_exists(signal HAVE_SIGNAL)
|
||||
check_include_files(signal.h HAVE_SIGNAL_H)
|
||||
check_function_exists(snprintf HAVE_SNPRINTF)
|
||||
check_function_exists(sprintf HAVE_SPRINTF)
|
||||
check_function_exists(srand HAVE_SRAND)
|
||||
check_function_exists(sscanf HAVE_SSCANF)
|
||||
check_function_exists(stat HAVE_STAT)
|
||||
check_include_files(stdarg.h HAVE_STDARG_H)
|
||||
check_include_files(stdint.h HAVE_STDINT_H)
|
||||
check_include_files(stdlib.h HAVE_STDLIB_H)
|
||||
check_function_exists(strftime HAVE_STRFTIME)
|
||||
check_include_files(strings.h HAVE_STRINGS_H)
|
||||
check_include_files(string.h HAVE_STRING_H)
|
||||
check_symbol_exists(DIR sys/dir.h HAVE_SYS_DIR_H)
|
||||
check_include_files(sys/mman.h HAVE_SYS_MMAN_H)
|
||||
check_symbol_exists(DIR sys/ndir.h HAVE_SYS_NDIR_H)
|
||||
check_include_files(sys/select.h HAVE_SYS_SELECT_H)
|
||||
check_include_files(sys/socket.h HAVE_SYS_SOCKET_H)
|
||||
check_include_files(sys/stat.h HAVE_SYS_STAT_H)
|
||||
check_include_files(sys/timeb.h HAVE_SYS_TIMEB_H)
|
||||
check_include_files(sys/time.h HAVE_SYS_TIME_H)
|
||||
check_include_files(sys/types.h HAVE_SYS_TYPES_H)
|
||||
check_function_exists(time HAVE_TIME)
|
||||
check_include_files(time.h HAVE_TIME_H)
|
||||
check_include_files(unistd.h HAVE_UNISTD_H)
|
||||
check_function_exists(va_copy HAVE_VA_COPY)
|
||||
check_function_exists(vfprintf HAVE_VFPRINTF)
|
||||
check_function_exists(vsnprintf HAVE_VSNPRINTF)
|
||||
check_function_exists(vsprintf HAVE_VSPRINTF)
|
||||
check_function_exists(__va_copy HAVE___VA_COPY)
|
||||
check_c_source_compiles("
|
||||
#include <stdlib.h>
|
||||
#include <iconv.h>
|
||||
extern
|
||||
#ifdef __cplusplus
|
||||
\"C\"
|
||||
#endif
|
||||
#if defined(__STDC__) || defined(__cplusplus)
|
||||
size_t iconv(iconv_t cd, char** inbuf, size_t* inbytesleft, char** outbuf, size_t* outbytesleft);
|
||||
#else
|
||||
size_t iconv();
|
||||
#endif
|
||||
int main() { return 0; }
|
||||
" ICONV_CONST_TEST)
|
||||
if(NOT ICONV_CONST_TEST)
|
||||
set(ICONV_CONST "const")
|
||||
endif()
|
||||
set(LT_OBJDIR ".libs/")
|
||||
check_c_source_compiles("
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
int main() { (void) send(1, (const char*) \"\", 1, 1); return 0; }
|
||||
" SEND_ARG2_CAST_CONST)
|
||||
if(NOT SEND_ARG2_CAST_CONST)
|
||||
set(SEND_ARG2_CAST "(char *)")
|
||||
else()
|
||||
set(SEND_ARG2_CAST "/**/")
|
||||
endif()
|
||||
check_include_files("float.h;stdarg.h;stdlib.h;string.h" STDC_HEADERS)
|
||||
check_c_source_compiles("
|
||||
#include <stdarg.h>
|
||||
void a(va_list* ap) {};
|
||||
int main() { va_list ap1, ap2; a(&ap1); ap2 = (va_list) ap1; return 0; }
|
||||
" VA_LIST_IS_ARRAY_TEST)
|
||||
if(VA_LIST_IS_ARRAY_TEST)
|
||||
set(VA_LIST_IS_ARRAY FALSE)
|
||||
else()
|
||||
set(VA_LIST_IS_ARRAY TRUE)
|
||||
endif()
|
||||
check_c_source_compiles("
|
||||
#include <stddef.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
int main() { (void) getsockopt(1, 1, 1, NULL, (socklen_t*) NULL); return 0; }
|
||||
" XML_SOCKLEN_T_SOCKLEN_T)
|
||||
if(XML_SOCKLEN_T_SOCKLEN_T)
|
||||
set(XML_SOCKLEN_T socklen_t)
|
||||
else()
|
||||
check_c_source_compiles("
|
||||
#include <stddef.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
int main() { (void) getsockopt(1, 1, 1, NULL, (size_t*) NULL); return 0; }
|
||||
" XML_SOCKLEN_T_SIZE_T)
|
||||
if(XML_SOCKLEN_T_SIZE_T)
|
||||
set(XML_SOCKLEN_T size_t)
|
||||
else()
|
||||
check_c_source_compiles("
|
||||
#include <stddef.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
int main() { (void) getsockopt (1, 1, 1, NULL, (int*) NULL); return 0; }
|
||||
" XML_SOCKLEN_T_INT)
|
||||
set(XML_SOCKLEN_T int)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
file(COPY ${libxml2_dir} DESTINATION ./)
|
||||
set(libxml2_original ${CMAKE_CURRENT_BINARY_DIR}/libxml2)
|
||||
include_directories(${libxml2_original}/include)
|
||||
configure_file(config.h.cmake.in ${libxml2_original}/config.h)
|
||||
set(libxml2_original_header
|
||||
${libxml2_original}/include/libxml/c14n.h
|
||||
${libxml2_original}/include/libxml/catalog.h
|
||||
${libxml2_original}/include/libxml/chvalid.h
|
||||
${libxml2_original}/include/libxml/debugXML.h
|
||||
${libxml2_original}/include/libxml/dict.h
|
||||
${libxml2_original}/include/libxml/DOCBparser.h
|
||||
${libxml2_original}/include/libxml/encoding.h
|
||||
${libxml2_original}/include/libxml/entities.h
|
||||
${libxml2_original}/include/libxml/globals.h
|
||||
${libxml2_original}/include/libxml/hash.h
|
||||
${libxml2_original}/include/libxml/HTMLparser.h
|
||||
${libxml2_original}/include/libxml/HTMLtree.h
|
||||
${libxml2_original}/include/libxml/list.h
|
||||
${libxml2_original}/include/libxml/nanoftp.h
|
||||
${libxml2_original}/include/libxml/nanohttp.h
|
||||
${libxml2_original}/include/libxml/parser.h
|
||||
${libxml2_original}/include/libxml/parserInternals.h
|
||||
${libxml2_original}/include/libxml/pattern.h
|
||||
${libxml2_original}/include/libxml/relaxng.h
|
||||
${libxml2_original}/include/libxml/SAX.h
|
||||
${libxml2_original}/include/libxml/SAX2.h
|
||||
${libxml2_original}/include/libxml/schemasInternals.h
|
||||
${libxml2_original}/include/libxml/schematron.h
|
||||
${libxml2_original}/include/libxml/threads.h
|
||||
${libxml2_original}/include/libxml/tree.h
|
||||
${libxml2_original}/include/libxml/uri.h
|
||||
${libxml2_original}/include/libxml/valid.h
|
||||
${libxml2_original}/include/libxml/xinclude.h
|
||||
${libxml2_original}/include/libxml/xlink.h
|
||||
${libxml2_original}/include/libxml/xmlIO.h
|
||||
${libxml2_original}/include/libxml/xmlautomata.h
|
||||
${libxml2_original}/include/libxml/xmlerror.h
|
||||
${libxml2_original}/include/libxml/xmlexports.h
|
||||
${libxml2_original}/include/libxml/xmlmemory.h
|
||||
${libxml2_original}/include/libxml/xmlmodule.h
|
||||
${libxml2_original}/include/libxml/xmlreader.h
|
||||
${libxml2_original}/include/libxml/xmlregexp.h
|
||||
${libxml2_original}/include/libxml/xmlsave.h
|
||||
${libxml2_original}/include/libxml/xmlschemas.h
|
||||
${libxml2_original}/include/libxml/xmlschemastypes.h
|
||||
${libxml2_original}/include/libxml/xmlstring.h
|
||||
${libxml2_original}/include/libxml/xmlunicode.h
|
||||
${libxml2_original}/include/libxml/xmlwriter.h
|
||||
${libxml2_original}/include/libxml/xpath.h
|
||||
${libxml2_original}/include/libxml/xpathInternals.h
|
||||
${libxml2_original}/include/libxml/xpointer.h
|
||||
${libxml2_original}/include/wsockcompat.h
|
||||
)
|
||||
|
||||
set(libxml2_original_other_header
|
||||
${libxml2_original}/buf.h
|
||||
${libxml2_original}/elfgcchack.h
|
||||
${libxml2_original}/enc.h
|
||||
${libxml2_original}/libxml.h
|
||||
${libxml2_original}/save.h
|
||||
${libxml2_original}/timsort.h
|
||||
)
|
||||
|
||||
set(libxml2_original_source
|
||||
${libxml2_original}/buf.c
|
||||
${libxml2_original}/c14n.c
|
||||
${libxml2_original}/catalog.c
|
||||
${libxml2_original}/chvalid.c
|
||||
${libxml2_original}/debugXML.c
|
||||
${libxml2_original}/dict.c
|
||||
${libxml2_original}/encoding.c
|
||||
${libxml2_original}/entities.c
|
||||
${libxml2_original}/error.c
|
||||
${libxml2_original}/globals.c
|
||||
${libxml2_original}/hash.c
|
||||
${libxml2_original}/HTMLparser.c
|
||||
${libxml2_original}/HTMLtree.c
|
||||
${libxml2_original}/legacy.c
|
||||
${libxml2_original}/list.c
|
||||
${libxml2_original}/nanoftp.c
|
||||
${libxml2_original}/nanohttp.c
|
||||
${libxml2_original}/parser.c
|
||||
${libxml2_original}/parserInternals.c
|
||||
${libxml2_original}/pattern.c
|
||||
${libxml2_original}/relaxng.c
|
||||
${libxml2_original}/SAX.c
|
||||
${libxml2_original}/SAX2.c
|
||||
${libxml2_original}/schematron.c
|
||||
${libxml2_original}/threads.c
|
||||
${libxml2_original}/tree.c
|
||||
${libxml2_original}/uri.c
|
||||
${libxml2_original}/valid.c
|
||||
${libxml2_original}/xinclude.c
|
||||
${libxml2_original}/xlink.c
|
||||
${libxml2_original}/xmlIO.c
|
||||
${libxml2_original}/xmlmemory.c
|
||||
${libxml2_original}/xmlmodule.c
|
||||
${libxml2_original}/xmlreader.c
|
||||
${libxml2_original}/xmlregexp.c
|
||||
${libxml2_original}/xmlsave.c
|
||||
${libxml2_original}/xmlschemas.c
|
||||
${libxml2_original}/xmlschemastypes.c
|
||||
${libxml2_original}/xmlstring.c
|
||||
${libxml2_original}/xmlunicode.c
|
||||
${libxml2_original}/xmlwriter.c
|
||||
${libxml2_original}/xpath.c
|
||||
${libxml2_original}/xpointer.c
|
||||
${libxml2_original}/xzlib.c
|
||||
)
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
add_library(myxml2 STATIC ${libxml2_original_header} ${libxml2_original_other_header} ${libxml2_original_source})
|
||||
target_link_libraries(myxml2 PRIVATE Threads::Threads)
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(myxml2 PRIVATE ws2_32)
|
||||
set(WIN32_EXTRA_LIBADD "-lws2_32")
|
||||
endif()
|
||||
configure_file(${libxml2_original}/include/libxml/xmlversion.h.in ${libxml2_original}/include/libxml/xmlversion.h)
|
||||
+288
@@ -0,0 +1,288 @@
|
||||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define if __attribute__((destructor)) is accepted */
|
||||
#cmakedefine ATTRIBUTE_DESTRUCTOR 1
|
||||
|
||||
/* Type cast for the gethostbyname() argument */
|
||||
#cmakedefine GETHOSTBYNAME_ARG_CAST @GETHOSTBYNAME_ARG_CAST@
|
||||
|
||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||
#cmakedefine HAVE_ARPA_INET_H 1
|
||||
|
||||
/* Define to 1 if you have the <arpa/nameser.h> header file. */
|
||||
#cmakedefine HAVE_ARPA_NAMESER_H 1
|
||||
|
||||
/* Whether struct sockaddr::__ss_family exists */
|
||||
#cmakedefine HAVE_BROKEN_SS_FAMILY 1
|
||||
|
||||
/* Define to 1 if you have the <ctype.h> header file. */
|
||||
#cmakedefine HAVE_CTYPE_H 1
|
||||
|
||||
/* Define to 1 if you have the <dirent.h> header file. */
|
||||
#cmakedefine HAVE_DIRENT_H 1
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#cmakedefine HAVE_DLFCN_H 1
|
||||
|
||||
/* Have dlopen based dso */
|
||||
#cmakedefine HAVE_DLOPEN 1
|
||||
|
||||
/* Define to 1 if you have the <dl.h> header file. */
|
||||
#cmakedefine HAVE_DL_H 1
|
||||
|
||||
/* Define to 1 if you have the <errno.h> header file. */
|
||||
#cmakedefine HAVE_ERRNO_H 1
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#cmakedefine HAVE_FCNTL_H 1
|
||||
|
||||
/* Define to 1 if you have the <float.h> header file. */
|
||||
#cmakedefine HAVE_FLOAT_H 1
|
||||
|
||||
/* Define to 1 if you have the `fprintf' function. */
|
||||
#cmakedefine HAVE_FPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `ftime' function. */
|
||||
#cmakedefine HAVE_FTIME 1
|
||||
|
||||
/* Define if getaddrinfo is there */
|
||||
#cmakedefine HAVE_GETADDRINFO 1
|
||||
|
||||
/* Define to 1 if you have the `gettimeofday' function. */
|
||||
#cmakedefine HAVE_GETTIMEOFDAY 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#cmakedefine HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the `isascii' function. */
|
||||
#cmakedefine HAVE_ISASCII 1
|
||||
|
||||
/* Define if isinf is there */
|
||||
#cmakedefine HAVE_ISINF 1
|
||||
|
||||
/* Define if isnan is there */
|
||||
#cmakedefine HAVE_ISNAN 1
|
||||
|
||||
/* Define if history library is there (-lhistory) */
|
||||
#cmakedefine HAVE_LIBHISTORY 1
|
||||
|
||||
/* Define if pthread library is there (-lpthread) */
|
||||
#cmakedefine HAVE_LIBPTHREAD 1
|
||||
|
||||
/* Define if readline library is there (-lreadline) */
|
||||
#cmakedefine HAVE_LIBREADLINE 1
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#cmakedefine HAVE_LIMITS_H 1
|
||||
|
||||
/* Define to 1 if you have the `localtime' function. */
|
||||
#cmakedefine HAVE_LOCALTIME 1
|
||||
|
||||
/* Define to 1 if you have the <lzma.h> header file. */
|
||||
#cmakedefine HAVE_LZMA_H 1
|
||||
|
||||
/* Define to 1 if you have the <malloc.h> header file. */
|
||||
#cmakedefine HAVE_MALLOC_H 1
|
||||
|
||||
/* Define to 1 if you have the <math.h> header file. */
|
||||
#cmakedefine HAVE_MATH_H 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#cmakedefine HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the `mmap' function. */
|
||||
#cmakedefine HAVE_MMAP 1
|
||||
|
||||
/* Define to 1 if you have the `munmap' function. */
|
||||
#cmakedefine HAVE_MUNMAP 1
|
||||
|
||||
/* mmap() is no good without munmap() */
|
||||
#if defined(HAVE_MMAP) && !defined(HAVE_MUNMAP)
|
||||
# undef /**/ HAVE_MMAP
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
|
||||
#cmakedefine HAVE_NDIR_H 1
|
||||
|
||||
/* Define to 1 if you have the <netdb.h> header file. */
|
||||
#cmakedefine HAVE_NETDB_H 1
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
#cmakedefine HAVE_NETINET_IN_H 1
|
||||
|
||||
/* Define to 1 if you have the <poll.h> header file. */
|
||||
#cmakedefine HAVE_POLL_H 1
|
||||
|
||||
/* Define to 1 if you have the `printf' function. */
|
||||
#cmakedefine HAVE_PRINTF 1
|
||||
|
||||
/* Define if <pthread.h> is there */
|
||||
#cmakedefine HAVE_PTHREAD_H 1
|
||||
|
||||
/* Define to 1 if you have the `putenv' function. */
|
||||
#cmakedefine HAVE_PUTENV 1
|
||||
|
||||
/* Define to 1 if you have the `rand' function. */
|
||||
#cmakedefine HAVE_RAND 1
|
||||
|
||||
/* Define to 1 if you have the `rand_r' function. */
|
||||
#cmakedefine HAVE_RAND_R 1
|
||||
|
||||
/* Define to 1 if you have the <resolv.h> header file. */
|
||||
#cmakedefine HAVE_RESOLV_H 1
|
||||
|
||||
/* Have shl_load based dso */
|
||||
#cmakedefine HAVE_SHLLOAD 1
|
||||
|
||||
/* Define to 1 if you have the `signal' function. */
|
||||
#cmakedefine HAVE_SIGNAL 1
|
||||
|
||||
/* Define to 1 if you have the <signal.h> header file. */
|
||||
#cmakedefine HAVE_SIGNAL_H 1
|
||||
|
||||
/* Define to 1 if you have the `snprintf' function. */
|
||||
#cmakedefine HAVE_SNPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `sprintf' function. */
|
||||
#cmakedefine HAVE_SPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `srand' function. */
|
||||
#cmakedefine HAVE_SRAND 1
|
||||
|
||||
/* Define to 1 if you have the `sscanf' function. */
|
||||
#cmakedefine HAVE_SSCANF 1
|
||||
|
||||
/* Define to 1 if you have the `stat' function. */
|
||||
#cmakedefine HAVE_STAT 1
|
||||
|
||||
/* Define to 1 if you have the <stdarg.h> header file. */
|
||||
#cmakedefine HAVE_STDARG_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#cmakedefine HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#cmakedefine HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the `strftime' function. */
|
||||
#cmakedefine HAVE_STRFTIME 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#cmakedefine HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#cmakedefine HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#cmakedefine HAVE_SYS_DIR_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/mman.h> header file. */
|
||||
#cmakedefine HAVE_SYS_MMAN_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#cmakedefine HAVE_SYS_NDIR_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||
#cmakedefine HAVE_SYS_SELECT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#cmakedefine HAVE_SYS_SOCKET_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#cmakedefine HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/timeb.h> header file. */
|
||||
#cmakedefine HAVE_SYS_TIMEB_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#cmakedefine HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#cmakedefine HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the `time' function. */
|
||||
#cmakedefine HAVE_TIME 1
|
||||
|
||||
/* Define to 1 if you have the <time.h> header file. */
|
||||
#cmakedefine HAVE_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#cmakedefine HAVE_UNISTD_H 1
|
||||
|
||||
/* Whether va_copy() is available */
|
||||
#cmakedefine HAVE_VA_COPY 1
|
||||
|
||||
/* Define to 1 if you have the `vfprintf' function. */
|
||||
#cmakedefine HAVE_VFPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `vsnprintf' function. */
|
||||
#cmakedefine HAVE_VSNPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `vsprintf' function. */
|
||||
#cmakedefine HAVE_VSPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the <zlib.h> header file. */
|
||||
#cmakedefine HAVE_ZLIB_H 1
|
||||
|
||||
/* Whether __va_copy() is available */
|
||||
#cmakedefine HAVE___VA_COPY 1
|
||||
|
||||
/* Define as const if the declaration of iconv() needs const. */
|
||||
#define ICONV_CONST @ICONV_CONST@
|
||||
|
||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||
#cmakedefine LT_OBJDIR "@LT_OBJDIR@"
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "@PACKAGE@"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "@PACKAGE_NAME@"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "@PACKAGE_STRING@"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "@PACKAGE_TARNAME@"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL "@PACKAGE_URL@"
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "@PACKAGE_VERSION@"
|
||||
|
||||
/* Type cast for the send() function 2nd arg */
|
||||
#cmakedefine SEND_ARG2_CAST @SEND_ARG2_CAST@
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#cmakedefine STDC_HEADERS 1
|
||||
|
||||
/* Support for IPv6 */
|
||||
#cmakedefine SUPPORT_IP6 1
|
||||
|
||||
/* Define if va_list is an array type */
|
||||
#cmakedefine VA_LIST_IS_ARRAY 1
|
||||
|
||||
/* Version number of package */
|
||||
#cmakedefine VERSION "@VERSION@"
|
||||
|
||||
/* Determine what socket length (socklen_t) data type is */
|
||||
#cmakedefine XML_SOCKLEN_T @XML_SOCKLEN_T@
|
||||
|
||||
/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
|
||||
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
|
||||
#define below would cause a syntax error. */
|
||||
#cmakedefine _UINT32_T @_UINT32_T@
|
||||
|
||||
/* ss_family is not defined here, use __ss_family instead */
|
||||
#cmakedefine ss_family @ss_family@
|
||||
|
||||
/* Define to the type of an unsigned integer type of width exactly 32 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
#cmakedefine uint32_t @uint32_t@
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
set(sqlite3_source
|
||||
${sqlite3_dir}/src/sqlite3.c
|
||||
)
|
||||
|
||||
add_library(sqlite3 STATIC ${sqlite3_source})
|
||||
add_definitions(-DSQLITE_OMIT_LOAD_EXTENSION)
|
||||
target_link_libraries(sqlite3 pthread m)
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
SET(CMAKE_SYSTEM_NAME Windows)
|
||||
SET(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc)
|
||||
SET(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++)
|
||||
SET(CMAKE_CXX_LINK_EXECUTABLE x86_64-w64-mingw32-ld)
|
||||
SET(CMAKE_CXX_COMPILER_AR x86_64-w64-mingw32-ar)
|
||||
SET(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres)
|
||||
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
Reference in New Issue
Block a user