feature模块独立编译打包,应用中心显示的应用图标和label不正确

Signed-off-by: fangyunzhong <fangyunzhong2@huawei.com>
This commit is contained in:
fangyunzhong
2022-11-24 10:54:11 +08:00
parent 6576a77829
commit ec2886fa0b
16 changed files with 744 additions and 15 deletions
+3
View File
@@ -52,6 +52,7 @@ public:
int32_t GetPriority() const;
const std::vector<std::string> &GetAppend() const;
bool GetCombine() const;
const std::string &GetDependEntry() const;
private:
void InitCommand();
@@ -73,6 +74,7 @@ private:
uint32_t SetPriority(const std::string& argValue);
uint32_t AddAppend(const std::string& argValue);
uint32_t SetCombine();
uint32_t AddDependEntry(const std::string& argValue);
bool IsAscii(const std::string& argValue) const;
static const struct option CMD_OPTS[];
@@ -94,6 +96,7 @@ private:
int32_t priority_ = -1;
std::vector<std::string> append_;
bool combine_ = false;
std::string dependEntry_;
};
template<class T>
+21
View File
@@ -37,9 +37,21 @@ public:
uint32_t Init();
const std::string &GetPackageName() const;
const std::string &GetModuleName() const;
int32_t GetAbilityIconId() const;
int32_t GetAbilityLabelId() const;
bool SetAppIcon(std::string &icon, int32_t id);
bool SetAppLabel(std::string &label, int32_t id);
ModuleType GetModuleType() const;
uint32_t ParseRefence();
uint32_t Save(const std::string &filePath) const;
void SetDependEntry(const bool isDenpend)
{
dependEntry = isDenpend;
}
bool IsDependEntry()
{
return dependEntry;
}
static void SetUseModule()
{
useModule_ = true;
@@ -51,16 +63,25 @@ public:
private:
bool ParseModule(Json::Value &moduleNode);
bool ParseDistro(Json::Value &distroNode);
bool ParseAbilities(const Json::Value &abilites);
bool ParseAbilitiy(const Json::Value &ability, bool &isMainAbility);
bool IsMainAbility(const Json::Value &skills);
bool IsHomeAction(const Json::Value &actions);
bool dependEntry = false;
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);
bool ParseAbilitiesForDepend(Json::Value &moduleNode);
std::string filePath_;
std::string packageName_;
std::string moduleName_;
ModuleType moduleType_;
Json::Value rootNode_;
std::string mainAbility_;
int32_t abilityIconId_;
int32_t abilityLabelId_;
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;
+1 -1
View File
@@ -37,11 +37,11 @@ public:
moduleName_ = moduleName;
};
uint32_t ScanIncrement(const std::string &output);
uint32_t MergeResourceItem(const std::map<int32_t, std::vector<ResourceItem>> &resourceInfos);
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,
+29
View File
@@ -31,8 +31,10 @@ 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 std::string WIN_SEPARATOR = "\\";
const static std::string NEW_LINE_PATH = "\r\nat ";
const static int32_t VERSION_MAX_LEN = 128;
const static int32_t INT_TO_BYTES = sizeof(uint32_t);
static const int8_t RESTOOL_VERSION[VERSION_MAX_LEN] = { "Restool 2.010" };
const static int32_t TAG_LEN = 4;
@@ -142,6 +144,11 @@ struct KeyParam {
uint32_t value;
};
struct IdData {
uint32_t id;
uint32_t dataOffset;
};
const std::map<std::string, ResType> g_fileClusterMap = {
{ "element", ResType::ELEMENT },
{ "media", ResType::MEDIA },
@@ -162,6 +169,28 @@ const std::map<std::string, ResType> g_contentClusterMap = {
{ "float", ResType::FLOAT }
};
const std::map<int32_t, ResType> g_resTypeMap = {
{ static_cast<int32_t>(ResType::ELEMENT), ResType::ELEMENT},
{ static_cast<int32_t>(ResType::ANIMATION), ResType::ANIMATION},
{ static_cast<int32_t>(ResType::LAYOUT), ResType::LAYOUT},
{ static_cast<int32_t>(ResType::RAW), ResType::RAW},
{ static_cast<int32_t>(ResType::INTEGER), ResType::INTEGER},
{ static_cast<int32_t>(ResType::STRING), ResType::STRING},
{ static_cast<int32_t>(ResType::STRARRAY), ResType::STRARRAY},
{ static_cast<int32_t>(ResType::INTARRAY), ResType::INTARRAY},
{ static_cast<int32_t>(ResType::BOOLEAN), ResType::BOOLEAN},
{ static_cast<int32_t>(ResType::COLOR), ResType::COLOR},
{ static_cast<int32_t>(ResType::ID), ResType::ID},
{ static_cast<int32_t>(ResType::THEME), ResType::THEME},
{ static_cast<int32_t>(ResType::PLURAL), ResType::PLURAL},
{ static_cast<int32_t>(ResType::FLOAT), ResType::FLOAT},
{ static_cast<int32_t>(ResType::MEDIA), ResType::MEDIA},
{ static_cast<int32_t>(ResType::PROF), ResType::PROF},
{ static_cast<int32_t>(ResType::GRAPHIC), ResType::GRAPHIC},
{ static_cast<int32_t>(ResType::PATTERN), ResType::PATTERN},
{ static_cast<int32_t>(ResType::INVALID_RES_TYPE), ResType::INVALID_RES_TYPE},
};
struct DirectoryInfo {
std::string limitKey;
std::string fileCluster;
+1
View File
@@ -33,6 +33,7 @@ public:
bool SetData(const int8_t *data, uint32_t length);
void SetFilePath(const std::string &filePath);
void SetLimitKey(const std::string &limitKey);
void SetName(const std::string &name);
const int8_t *GetData() const;
uint32_t GetDataLength() const;
+9
View File
@@ -19,6 +19,8 @@
#include "cmd_parser.h"
#include "config_parser.h"
#include "resource_util.h"
#include "resource_item.h"
#include "resource_data.h"
namespace OHOS {
namespace Global {
@@ -47,6 +49,13 @@ private:
uint32_t PackPreview();
uint32_t PackAppend();
uint32_t PackCombine();
uint32_t HandleFeature();
uint32_t FindResourceItems(const std::map<int32_t, std::vector<ResourceItem>> &resInfoLocal,
std::vector<ResourceItem> &items, int32_t id) const;
uint32_t HandleLabel(std::vector<ResourceItem> &items, ConfigParser &config) const;
uint32_t HandleIcon(std::vector<ResourceItem> &items, ConfigParser &config) const;
void SaveResourceItem(const ResourceItem &resourceItem, int32_t nextId) const;
bool CopyIcon(std::string &dataPath, const std::string &idName, std::string &fileName) const;
PackageParser packageParser_;
std::string moduleName_;
using HeaderCreater = std::function<uint32_t(const std::string&)>;
+11
View File
@@ -30,6 +30,7 @@ public:
virtual ~ResourceTable();
uint32_t CreateResourceTable();
uint32_t CreateResourceTable(const std::map<int32_t, std::vector<std::shared_ptr<ResourceItem>>> &items);
uint32_t LoadResTable(const std::string path, std::map<int32_t, std::vector<ResourceItem>> &resInfos);
private:
struct TableData {
int32_t id;
@@ -71,6 +72,16 @@ private:
void SaveLimitKeyConfigs(const std::map<std::string, LimitKeyConfig> &limitKeyConfigs,
std::ostringstream &out) const;
void SaveIdSets(const std::map<std::string, IdSet> &idSets, std::ostringstream &out) const;
bool ReadFileHeader(std::ifstream &in, IndexHeader &indexHeader, int32_t &pos, int32_t length) const;
bool ReadLimitKeys(std::ifstream &in, std::map<int32_t, std::vector<KeyParam>> &limitKeys,
uint32_t count, int32_t &pos, int32_t length) const;
bool ReadIdTables(std::ifstream &in, std::map<int32_t, std::pair<int32_t, int32_t>> &datas,
uint32_t count, int32_t &pos, int32_t length) const;
bool ReadDataRecordPrepare(std::ifstream &in, RecordItem &record, int32_t &pos, int32_t length) const;
bool ReadDataRecordStart(std::ifstream &in, RecordItem &record,
const std::map<int32_t, std::vector<KeyParam>> &limitKeys,
const std::map<int32_t, std::pair<int32_t, int32_t>> &datas,
std::map<int32_t, std::vector<ResourceItem>> &resInfos) const;
std::string indexFilePath_;
};
}
+19
View File
@@ -33,6 +33,14 @@ public:
*/
static void Split(const std::string &str, std::vector<std::string> &out, const std::string &splitter);
/**
* @brief Replace sub-string in string
* @param sourceStr: The original string to operate on
* @param oldStr: The string to be replaced
* @param newStr: The new string used
*/
static void StringReplace(std::string &sourceStr, const std::string &oldStr, const std::string &newStr);
/**
* @brief check file exist.
* @param path: file path.
@@ -157,6 +165,13 @@ public:
* @return true is legal, other false;
*/
static bool IslegalPath(const std::string &path);
/**
* @brief get an keyParams for limitkey
* @param keyParams
* @return limitkey
*/
static std::string PaserKeyParam(const std::vector<KeyParam> &keyParams);
private:
enum class IgnoreType {
IGNORE_FILE,
@@ -164,6 +179,10 @@ private:
IGNORE_ALL
};
static const std::map<std::string, IgnoreType> IGNORE_FILE_REGEX;
static std::string GetLocaleLimitkey(const KeyParam &KeyParam);
static std::string GetDeviceTypeLimitkey(const KeyParam &KeyParam);
static std::string GetResolutionLimitkey(const KeyParam &KeyParam);
static std::string GetKeyParamValue(const KeyParam &KeyParam);
};
}
}
+2 -1
View File
@@ -34,7 +34,8 @@ uint32_t CmdList::Init(const string &filePath, function<uint32_t(int c, const st
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) {
GetString(root["startId"], 'e', callback) != RESTOOL_SUCCESS ||
GetString(root["entryCompiledResource"], 'd', callback) != RESTOOL_SUCCESS) {
return RESTOOL_ERROR;
}
+14 -1
View File
@@ -38,9 +38,10 @@ const struct option PackageParser::CMD_OPTS[] = {
{ "priority", required_argument, nullptr, 'g' },
{ "append", required_argument, nullptr, 'x' },
{ "combine", required_argument, nullptr, 'z' },
{ "dependEntry", required_argument, nullptr, 'd' },
};
const string PackageParser::CMD_PARAMS = "i:p:o:r:m:j:e:c:l:g:x:afvz";
const string PackageParser::CMD_PARAMS = "i:p:o:r:m:j:e:c:l:g:x:d:afvz";
uint32_t PackageParser::Parse(int argc, char *argv[])
{
@@ -101,6 +102,11 @@ const string &PackageParser::GetCachePath() const
return cachePath_;
}
const string &PackageParser::GetDependEntry() const
{
return dependEntry_;
}
uint32_t PackageParser::AddInput(const string& argValue)
{
auto ret = find_if(inputs_.begin(), inputs_.end(), [argValue](auto iter) {return argValue == iter;});
@@ -302,6 +308,12 @@ bool PackageParser::GetCombine() const
return combine_;
}
uint32_t PackageParser::AddDependEntry(const string& argValue)
{
dependEntry_ = argValue;
return RESTOOL_SUCCESS;
}
bool PackageParser::IsAscii(const string& argValue) const
{
#ifdef __WIN32
@@ -336,6 +348,7 @@ void PackageParser::InitCommand()
handles_.emplace('g', bind(&PackageParser::SetPriority, this, _1));
handles_.emplace('x', bind(&PackageParser::AddAppend, this, _1));
handles_.emplace('z', [this](const string &) -> uint32_t { return SetCombine(); });
handles_.emplace('d', bind(&PackageParser::AddDependEntry, this, _1));
}
uint32_t PackageParser::HandleProcess(int c, const string& argValue)
+138 -1
View File
@@ -89,6 +89,16 @@ const string &ConfigParser::GetModuleName() const
return moduleName_;
}
int32_t ConfigParser::GetAbilityIconId() const
{
return abilityIconId_;
}
int32_t ConfigParser::GetAbilityLabelId() const
{
return abilityLabelId_;
}
ConfigParser::ModuleType ConfigParser::GetModuleType() const
{
return moduleType_;
@@ -110,6 +120,28 @@ uint32_t ConfigParser::Save(const string &filePath) const
return RESTOOL_ERROR;
}
bool ConfigParser::SetAppIcon(string &icon, int32_t id)
{
if (!rootNode_["app"].isObject()) {
cerr << "Error: 'app' not object" << endl;
return false;
}
rootNode_["app"]["icon"] = icon;
rootNode_["app"]["iconId"] = id;
return true;
}
bool ConfigParser::SetAppLabel(string &label, int32_t id)
{
if (!rootNode_["app"].isObject()) {
cerr << "Error: 'app' not object" << endl;
return false;
}
rootNode_["app"]["label"] = label;
rootNode_["app"]["labelId"] = id;
return true;
}
// below private
bool ConfigParser::ParseModule(Json::Value &moduleNode)
{
@@ -126,7 +158,10 @@ bool ConfigParser::ParseModule(Json::Value &moduleNode)
if (moduleNode.isMember("package") && moduleNode["package"].isString()) {
packageName_ = moduleNode["package"].asString();
}
return ParseDistro(moduleNode["distro"]);
if (!ParseDistro(moduleNode["distro"])) {
return false;
}
return ParseAbilitiesForDepend(moduleNode);
}
if (moduleNode["name"].isString()) {
@@ -144,6 +179,21 @@ bool ConfigParser::ParseModule(Json::Value &moduleNode)
return true;
}
bool ConfigParser::ParseAbilitiesForDepend(Json::Value &moduleNode)
{
if (!IsDependEntry()) {
return true;
}
if (moduleNode["mainAbility"].isString()) {
mainAbility_ = moduleNode["mainAbility"].asString();
if (mainAbility_[0] == '.') {
mainAbility_ = packageName_ + mainAbility_;
}
return ParseAbilities(moduleNode["abilities"]);
}
return true;
}
bool ConfigParser::ParseDistro(Json::Value &distroNode)
{
if (!distroNode.isObject()) {
@@ -170,6 +220,93 @@ bool ConfigParser::ParseDistro(Json::Value &distroNode)
return true;
}
bool ConfigParser::ParseAbilities(const Json::Value &abilites)
{
if (abilites.empty()) {
return true;
}
if (!abilites.isArray()) {
cerr << "Error: abilites not array." << NEW_LINE_PATH << filePath_ << endl;
return false;
}
bool isMainAbility = false;
for (Json::ArrayIndex i = 0; i < abilites.size(); i++) {
if (!ParseAbilitiy(abilites[i], isMainAbility)) {
cerr << "Error: ParseAbilitiy fail." << endl;
return false;
}
if (isMainAbility) {
break;
}
}
return true;
}
bool ConfigParser::ParseAbilitiy(const Json::Value &ability, bool &isMainAbility)
{
if (ability.empty()) {
return true;
}
if (!ability["name"].isString()) {
return false;
}
string name = ability["name"].asString();
if (name[0] == '.') {
name = packageName_ + name;
}
if (mainAbility_ != name && !IsMainAbility(ability["skills"])) {
return true;
}
if (ability["iconId"].isInt()) {
abilityIconId_ = ability["iconId"].asInt();
}
if (abilityIconId_ <= 0) {
cerr << "Error: iconId don't found in 'ability'." << NEW_LINE_PATH << filePath_ << endl;
return false;
}
if (ability["labelId"].isInt()) {
abilityLabelId_ = ability["labelId"].asInt();
}
if (abilityLabelId_ <= 0) {
cerr << "Error: labelId don't found in 'ability'." << NEW_LINE_PATH << filePath_ << endl;
return false;
}
isMainAbility = true;
return true;
}
bool ConfigParser::IsMainAbility(const Json::Value &skills)
{
if (!skills.isArray()) {
return false;
}
for (Json::ArrayIndex i = 0; i < skills.size(); i++) {
if (!skills[i].isObject()) {
return false;
}
if (IsHomeAction(skills[i]["actions"])) {
return true;
}
}
return false;
}
bool ConfigParser::IsHomeAction(const Json::Value &actions)
{
if (!actions.isArray()) {
return false;
}
for (Json::ArrayIndex i = 0; i < actions.size(); i++) {
if (!actions[i].isObject()) {
return false;
}
if (actions[i].asString() == "action.system.home") {
return true;
}
}
return false;
}
bool ConfigParser::ParseRefImpl(Json::Value &parent, const std::string &key, Json::Value &node)
{
if (node.isArray()) {
+5 -5
View File
@@ -52,6 +52,11 @@ uint32_t FileManager::ScanIncrement(const string &output)
return ParseReference(output, sxmlFolders);
}
uint32_t FileManager::MergeResourceItem(const map<int32_t, vector<ResourceItem>> &resourceInfos)
{
return ResourceModule::MergeResourceItem(items_, resourceInfos);
}
// below private founction
uint32_t FileManager::ScanModule(const string &input, const string &output,
map<ResType, vector<DirectoryInfo>> &resTypeOfDirs)
@@ -65,11 +70,6 @@ uint32_t FileManager::ScanModule(const string &input, const string &output,
return RESTOOL_SUCCESS;
}
uint32_t FileManager::MergeResourceItem(const map<int32_t, vector<ResourceItem>> &resourceInfos)
{
return ResourceModule::MergeResourceItem(items_, resourceInfos);
}
uint32_t FileManager::ParseReference(const string &output, const vector<string> &sxmlFolders)
{
ReferenceParser referenceParser;
+5
View File
@@ -74,6 +74,11 @@ void ResourceItem::SetLimitKey(const string &limitKey)
limitKey_ = limitKey;
}
void ResourceItem::SetName(const string &name)
{
name_ = name;
}
const int8_t *ResourceItem::GetData() const
{
return data_;
+188 -2
View File
@@ -14,8 +14,8 @@
*/
#include "resource_pack.h"
#include<algorithm>
#include<iomanip>
#include <algorithm>
#include <iomanip>
#include "file_entry.h"
#include "file_manager.h"
#include "header.h"
@@ -365,12 +365,198 @@ uint32_t ResourcePack::PackNormal()
}
ResourceTable resourceTable;
if (!packageParser_.GetDependEntry().empty()) {
if (HandleFeature() != RESTOOL_SUCCESS) {
return RESTOOL_ERROR;
}
if (GenerateHeader() != RESTOOL_SUCCESS) {
return RESTOOL_ERROR;
}
}
if (resourceTable.CreateResourceTable() != RESTOOL_SUCCESS) {
return RESTOOL_ERROR;
}
return RESTOOL_SUCCESS;
}
uint32_t ResourcePack::HandleFeature()
{
string output = packageParser_.GetOutput();
string featureDependEntry = packageParser_.GetDependEntry();
if (featureDependEntry.empty()) {
return RESTOOL_SUCCESS;
}
string jsonFile = FileEntry::FilePath(featureDependEntry).Append(CONFIG_JSON).GetPath();
ConfigParser entryJson(jsonFile);
entryJson.SetDependEntry(true);
if (entryJson.Init() != RESTOOL_SUCCESS) {
cerr << "Error: config json invalid." << NEW_LINE_PATH << jsonFile << endl;
return RESTOOL_ERROR;
}
int32_t labelId = entryJson.GetAbilityLabelId();
int32_t iconId = entryJson.GetAbilityIconId();
if (labelId <= 0 || iconId <= 0) {
cerr << "Error: Entry MainAbility must have 'icon' and 'label'." << endl;
return RESTOOL_ERROR;
}
string path = FileEntry::FilePath(featureDependEntry).Append(RESOURCE_INDEX_FILE).GetPath();
map<int32_t, vector<ResourceItem>> resInfoLocal;
ResourceTable resourceTable;
if (resourceTable.LoadResTable(path, resInfoLocal) != RESTOOL_SUCCESS) {
cerr << "Error: LoadResTable fail." << endl;
return RESTOOL_ERROR;
}
jsonFile = FileEntry::FilePath(output).Append(CONFIG_JSON).GetPath();
ConfigParser config(jsonFile);
if (config.Init() != RESTOOL_SUCCESS) {
cerr << "Error: config json invalid." << NEW_LINE_PATH << jsonFile << endl;
return RESTOOL_ERROR;
}
vector<ResourceItem> items;
if (FindResourceItems(resInfoLocal, items, labelId) != RESTOOL_SUCCESS ||
HandleLabel(items, config) != RESTOOL_SUCCESS) {
return RESTOOL_ERROR;
}
items.clear();
if (FindResourceItems(resInfoLocal, items, iconId) != RESTOOL_SUCCESS ||
HandleIcon(items, config) != RESTOOL_SUCCESS) {
return RESTOOL_ERROR;
}
string outputPath = FileEntry::FilePath(output).Append(ConfigParser::GetConfigName()).GetPath();
if (config.Save(outputPath) != RESTOOL_SUCCESS) {
return RESTOOL_ERROR;
}
entryJson.SetDependEntry(false);
return RESTOOL_SUCCESS;
}
uint32_t ResourcePack::FindResourceItems(const map<int32_t, vector<ResourceItem>> &resInfoLocal,
vector<ResourceItem> &items, int32_t id) const
{
auto ret = resInfoLocal.find(id);
if (ret == resInfoLocal.end()) {
cerr << "Error: FindResourceItems don't found '" << id << "'." << endl;
return RESTOOL_ERROR;
}
ResType type = ResType::INVALID_RES_TYPE;
items = ret->second;
if (items.empty()) {
cerr << "Error: FindResourceItems resource item empty '" << id << "'." << endl;
return RESTOOL_ERROR;
}
for (auto &it : items) {
if (type == ResType::INVALID_RES_TYPE) {
type = it.GetResType();
}
if (type != it.GetResType()) {
cerr << "Error: FindResourceItems invalid restype '" << ResourceUtil::ResTypeToString(type);
cerr << "' vs '" << ResourceUtil::ResTypeToString(it.GetResType()) << "'." << endl;
return RESTOOL_ERROR;
}
}
return RESTOOL_SUCCESS;
}
uint32_t ResourcePack::HandleLabel(vector<ResourceItem> &items, ConfigParser &config) const
{
int32_t nextId = 0;
string idName;
for (auto it : items) {
if (it.GetResType() != ResType::STRING) {
cerr << "Error: HandleLabel invalid restype '";
cerr << ResourceUtil::ResTypeToString(it.GetResType()) << "'." << endl;
return RESTOOL_ERROR;
}
idName = it.GetName() + "_entry";
it.SetName(idName);
string data(reinterpret_cast<const char *>(it.GetData()));
if (!it.SetData(reinterpret_cast<const int8_t *>(data.c_str()), it.GetDataLength()-1)) {
return RESTOOL_ERROR;
}
if (nextId <= 0) {
nextId = IdWorker::GetInstance().GenerateId(ResType::STRING, idName);
}
SaveResourceItem(it, nextId);
}
string label = "$string:" +idName;
config.SetAppLabel(label, nextId);
return RESTOOL_SUCCESS;
}
bool ResourcePack::CopyIcon(string &dataPath, const string &idName, string &fileName) const
{
string featureDependEntry = packageParser_.GetDependEntry();
string source = FileEntry::FilePath(featureDependEntry).Append(dataPath).GetPath();
string suffix = FileEntry::FilePath(source).GetExtension();
fileName = idName + suffix;
string output = packageParser_.GetOutput();
#ifdef _WIN32
ResourceUtil::StringReplace(dataPath, SEPARATOR, WIN_SEPARATOR);
#endif
string dstDir = FileEntry::FilePath(output).Append(dataPath).GetParent().GetPath();
string dst = FileEntry::FilePath(dstDir).Append(fileName).GetPath();
if (!ResourceUtil::CreateDirs(dstDir)) {
cerr << "Error: Create Dirs fail '" << dstDir << "'."<< endl;
return false;
}
if (!ResourceUtil::CopyFleInner(source, dst)) {
cerr << "Error: copy file fail from '" << source << "' to '" << dst << "'." << endl;
return false;
}
return true;
}
uint32_t ResourcePack::HandleIcon(vector<ResourceItem> &items, ConfigParser &config) const
{
int32_t nextId = 0;
string idName;
for (auto it : items) {
if (it.GetResType() != ResType::MEDIA) {
cerr << "Error: HandleLabel invalid restype '";
cerr << ResourceUtil::ResTypeToString(it.GetResType()) << "'." << endl;
return RESTOOL_ERROR;
}
string dataPath(reinterpret_cast<const char *>(it.GetData()));
string::size_type pos = dataPath.find_first_of(SEPARATOR);
if (pos == string::npos) {
cerr << "Error: HandleIcon invalid '" << dataPath << "'."<< endl;
return RESTOOL_ERROR;
}
dataPath = dataPath.substr(pos + 1);
idName = it.GetName() + "_entry";
string fileName;
if (!CopyIcon(dataPath, idName, fileName)) {
return RESTOOL_ERROR;
}
string data = FileEntry::FilePath(moduleName_).Append(dataPath).GetParent().Append(fileName).GetPath();
ResourceUtil::StringReplace(data, WIN_SEPARATOR, SEPARATOR);
ResourceItem resourceItem(fileName, it.GetKeyParam(), ResType::MEDIA);
resourceItem.SetLimitKey(it.GetLimitKey());
if (!resourceItem.SetData(reinterpret_cast<const int8_t *>(data.c_str()), data.length())) {
return RESTOOL_ERROR;
}
if (nextId <= 0) {
nextId = IdWorker::GetInstance().GenerateId(ResType::MEDIA, idName);
}
SaveResourceItem(resourceItem, nextId);
}
string icon = "$media:" + idName;
config.SetAppIcon(icon, nextId);
return RESTOOL_SUCCESS;
}
void ResourcePack::SaveResourceItem(const ResourceItem &resourceItem, int32_t nextId) const
{
map<int32_t, vector<ResourceItem>> resInfo;
vector<ResourceItem> vet;
vet.push_back(resourceItem);
resInfo.insert(make_pair(nextId, vet));
FileManager &fileManager = FileManager::GetInstance();
fileManager.MergeResourceItem(resInfo);
}
uint32_t ResourcePack::PackPreview()
{
PreviewManager preview;
+201 -4
View File
@@ -79,6 +79,52 @@ uint32_t ResourceTable::CreateResourceTable(const map<int32_t, vector<shared_ptr
return RESTOOL_SUCCESS;
}
uint32_t ResourceTable::LoadResTable(const string path, map<int32_t, vector<ResourceItem>> &resInfos)
{
ifstream in(path, ios::binary);
if (!in.is_open()) {
cerr << "Error: open failed." << NEW_LINE_PATH << path <<endl;
return RESTOOL_ERROR;
}
in.seekg(0, ios::end);
int32_t length = in.tellg();
if (length <= 0) {
in.close();
return RESTOOL_ERROR;
}
in.seekg(0, ios::beg);
int32_t pos = 0;
IndexHeader indexHeader;
if (!ReadFileHeader(in, indexHeader, pos, length)) {
in.close();
return RESTOOL_ERROR;
}
map<int32_t, vector<KeyParam>> limitKeys;
if (!ReadLimitKeys(in, limitKeys, indexHeader.limitKeyConfigSize, pos, length)) {
in.close();
return RESTOOL_ERROR;
}
map<int32_t, pair<int32_t, int32_t>> datas;
if (!ReadIdTables(in, datas, indexHeader.limitKeyConfigSize, pos, length)) {
in.close();
return RESTOOL_ERROR;
}
while (in.tellg() < length) {
RecordItem record;
if (!ReadDataRecordPrepare(in, record, pos, length) ||
!ReadDataRecordStart(in, record, limitKeys, datas, resInfos)) {
in.close();
return RESTOOL_ERROR;
}
}
in.close();
return RESTOOL_SUCCESS;
}
// below private
uint32_t ResourceTable::SaveToResouorceIndex(const map<string, vector<TableData>> &configs) const
{
@@ -97,7 +143,7 @@ uint32_t ResourceTable::SaveToResouorceIndex(const map<string, vector<TableData>
ofstream out(indexFilePath_, ofstream::out | ofstream::binary);
if (!out.is_open()) {
cerr << "Error: open failed '" << indexFilePath_ << ", reason: " << strerror(errno) << endl;
cerr << "Error: open failed '" << indexFilePath_ << "', reason: " << strerror(errno) << endl;
return RESTOOL_ERROR;
}
@@ -146,7 +192,7 @@ bool ResourceTable::Prepare(const map<string, vector<TableData>> &configs,
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;
cerr << "Error: limit key config don't find '" << config.first << "'." << endl;
return false;
}
limitKeyConfig->second.offset = pos;
@@ -169,13 +215,13 @@ bool ResourceTable::SaveRecordItem(const map<string, vector<TableData>> &configs
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;
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;
cerr << "Error: resource table don't find id '" << tableData.id << "'." << endl;
return false;
}
idSet->second.data[tableData.id] = pos;
@@ -232,6 +278,157 @@ void ResourceTable::SaveIdSets(const map<string, IdSet> &idSets, ostringstream &
}
}
}
bool ResourceTable::ReadFileHeader(ifstream &in, IndexHeader &indexHeader, int32_t &pos, int32_t length) const
{
pos += sizeof(indexHeader);
if (pos > length) {
cerr << "Error: invalid resources.index File Header." << endl;
return false;
}
in.read(reinterpret_cast<char *>(indexHeader.version), VERSION_MAX_LEN);
in.read(reinterpret_cast<char *>(&indexHeader.fileSize), INT_TO_BYTES);
in.read(reinterpret_cast<char *>(&indexHeader.limitKeyConfigSize), INT_TO_BYTES);
return true;
}
bool ResourceTable::ReadLimitKeys(ifstream &in, map<int32_t, vector<KeyParam>> &limitKeys,
uint32_t count, int32_t &pos, int32_t length) const
{
for (uint32_t i = 0; i< count; i++) {
pos = pos + TAG_LEN + INT_TO_BYTES + INT_TO_BYTES;
if (pos > length) {
cerr << "Error: invalid resources.index KEYS." << endl;
return false;
}
LimitKeyConfig limitKey;
in.read(reinterpret_cast<char *>(limitKey.keyTag), TAG_LEN);
string keyTag(reinterpret_cast<const char *>(limitKey.keyTag), TAG_LEN);
if (keyTag != "KEYS") {
cerr << "Error: invalid resources.index key tag = " << keyTag << endl;
return false;
}
in.read(reinterpret_cast<char *>(&limitKey.offset), INT_TO_BYTES);
in.read(reinterpret_cast<char *>(&limitKey.keyCount), INT_TO_BYTES);
vector<KeyParam> keyParams;
for (uint32_t j = 0; j < limitKey.keyCount; j++) {
pos = pos + INT_TO_BYTES + INT_TO_BYTES;
if (pos > length) {
cerr << "Error: invalid resources.index keyParams." << endl;
return false;
}
KeyParam keyParam;
in.read(reinterpret_cast<char *>(&keyParam.keyType), INT_TO_BYTES);
in.read(reinterpret_cast<char *>(&keyParam.value), INT_TO_BYTES);
keyParams.push_back(keyParam);
}
limitKeys[limitKey.offset] = keyParams;
}
return true;
}
bool ResourceTable::ReadIdTables(std::ifstream &in, std::map<int32_t, std::pair<int32_t, int32_t>> &datas,
uint32_t count, int32_t &pos, int32_t length) const
{
for (uint32_t i = 0; i< count; i++) {
pos = pos + TAG_LEN + INT_TO_BYTES;
if (pos > length) {
cerr << "Error: invalid resources.index IDSS." << endl;
return false;
}
IdSet idss;
int32_t offset = in.tellg();
in.read(reinterpret_cast<char *>(idss.idTag), TAG_LEN);
string idTag(reinterpret_cast<const char *>(idss.idTag), TAG_LEN);
if (idTag != "IDSS") {
cerr << "Error: invalid resources.index id tag = " << idTag << endl;
return false;
}
in.read(reinterpret_cast<char *>(&idss.idCount), INT_TO_BYTES);
for (uint32_t j = 0; j < idss.idCount; j++) {
pos = pos + INT_TO_BYTES + INT_TO_BYTES;
if (pos > length) {
cerr << "Error: invalid resources.index id data." << endl;
return false;
}
IdData data;
in.read(reinterpret_cast<char *>(&data.id), INT_TO_BYTES);
in.read(reinterpret_cast<char *>(&data.dataOffset), INT_TO_BYTES);
datas[data.dataOffset] = make_pair(data.id, offset);
}
}
return true;
}
bool ResourceTable::ReadDataRecordPrepare(ifstream &in, RecordItem &record, int32_t &pos, int32_t length) const
{
pos = pos + INT_TO_BYTES;
if (pos > length) {
cerr << "Error: invalid resources.index data record." << endl;
return false;
}
in.read(reinterpret_cast<char *>(&record.size), INT_TO_BYTES);
pos = pos + record.size;
if (pos > length) {
cerr << "Error: invalid resources.index record.size." << endl;
return false;
}
in.read(reinterpret_cast<char *>(&record.resType), INT_TO_BYTES);
in.read(reinterpret_cast<char *>(&record.id), INT_TO_BYTES);
return true;
}
bool ResourceTable::ReadDataRecordStart(std::ifstream &in, RecordItem &record,
const std::map<int32_t, std::vector<KeyParam>> &limitKeys,
const std::map<int32_t, std::pair<int32_t, int32_t>> &datas,
std::map<int32_t, std::vector<ResourceItem>> &resInfos) const
{
int32_t offset = in.tellg();
offset = offset - INT_TO_BYTES - INT_TO_BYTES - INT_TO_BYTES;
uint16_t value_size = 0;
in.read(reinterpret_cast<char *>(&value_size), sizeof(uint16_t));
if (value_size + sizeof(uint16_t) > record.size) {
cerr << "Error: invalid resources.index value size." << endl;
return false;
}
int8_t values[value_size];
in.read(reinterpret_cast<char *>(&values), value_size);
uint16_t name_size = 0;
in.read(reinterpret_cast<char *>(&name_size), sizeof(uint16_t));
if (value_size + sizeof(uint16_t) + name_size + sizeof(uint16_t) > record.size) {
cerr << "Error: invalid resources.index name size." << endl;
return false;
}
int8_t name[name_size];
in.read(reinterpret_cast<char *>(name), name_size);
string filename(reinterpret_cast<char *>(name));
auto idTableOffset = datas.find(offset);
if (idTableOffset == datas.end()) {
cerr << "Error: invalid resources.index id offset." << endl;
return false;
}
if (idTableOffset->second.first != record.id) {
cerr << "Error: invalid resources.index id." << endl;
return false;
}
if (limitKeys.find(idTableOffset->second.second) == limitKeys.end()) {
cerr << "Error: invalid resources.index limit key offset." << endl;
return false;
}
const vector<KeyParam> &keyparams = limitKeys.find(datas.find(offset)->second.second)->second;
ResourceItem resourceitem(filename, keyparams, g_resTypeMap.find(record.resType)->second);
resourceitem.SetLimitKey(ResourceUtil::PaserKeyParam(keyparams));
resourceitem.SetData(values, value_size);
resInfos[record.id].push_back(resourceitem);
return true;
}
}
}
}
+97
View File
@@ -272,6 +272,103 @@ bool ResourceUtil::IslegalPath(const string &path)
{
return path == "element" || path == "media" || path == "profile";
}
void ResourceUtil::StringReplace(string &sourceStr, const string &oldStr, const string &newStr)
{
string::size_type pos = 0;
string::size_type oldSize = oldStr.size();
string::size_type newSize = newStr.size();
while ((pos = sourceStr.find(oldStr, pos)) != string::npos) {
sourceStr.replace(pos, oldSize, newStr.c_str());
pos += newSize;
}
}
string ResourceUtil::GetLocaleLimitkey(const KeyParam &KeyParam)
{
string str(reinterpret_cast<const char *>(&KeyParam.value));
reverse(str.begin(), str.end());
return str;
}
string ResourceUtil::GetDeviceTypeLimitkey(const KeyParam &KeyParam)
{
auto ret = find_if(g_deviceMap.begin(), g_deviceMap.end(), [KeyParam](const auto &iter) {
return KeyParam.value == static_cast<const int32_t>(iter.second);
});
if (ret == g_deviceMap.end()) {
return string();
}
return ret->first;
}
string ResourceUtil::GetResolutionLimitkey(const KeyParam &KeyParam)
{
auto ret = find_if(g_resolutionMap.begin(), g_resolutionMap.end(), [KeyParam](const auto &iter) {
return KeyParam.value == static_cast<const int32_t>(iter.second);
});
if (ret == g_resolutionMap.end()) {
return string();
}
return ret->first;
}
string ResourceUtil::GetKeyParamValue(const KeyParam &KeyParam)
{
string val;
switch (KeyParam.keyType) {
case KeyType::ORIENTATION:
val = KeyParam.value == static_cast<const int32_t>(OrientationType::VERTICAL) ? "vertical" : "horizontal";
break;
case KeyType::NIGHTMODE:
val = KeyParam.value == static_cast<const int32_t>(NightMode::DARK) ? "dark" : "light";
break;
case KeyType::DEVICETYPE:
val = GetDeviceTypeLimitkey(KeyParam);
break;
case KeyType::RESOLUTION:
val = GetResolutionLimitkey(KeyParam);
break;
case KeyType::LANGUAGE:
case KeyType::REGION:
val = GetLocaleLimitkey(KeyParam);
break;
default:
val = to_string(KeyParam.value);
break;
}
return val;
}
string ResourceUtil::PaserKeyParam(const vector<KeyParam> &keyParams)
{
if (keyParams.size() == 0) {
return "base";
}
string result;
for (const auto &keyparam : keyParams) {
string limitKey = GetKeyParamValue(keyparam);
if (limitKey.empty()) {
continue;
}
if (keyparam.keyType == KeyType::MCC) {
limitKey = "mcc" + limitKey;
}
if (keyparam.keyType == KeyType::MNC) {
limitKey = "mnc" + limitKey;
}
if (keyparam.keyType == KeyType::REGION || keyparam.keyType == KeyType::MNC) {
result = result + "_" + limitKey;
} else {
result = result + "-" + limitKey;
}
}
if (!result.empty()) {
result = result.substr(1);
}
return result;
}
}
}
}