• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "hap_parser.h"
17 
18 #include <cstdlib>
19 #include <string>
20 #include <fcntl.h>
21 #include <unzip.h>
22 #include <unistd.h>
23 #include <set>
24 
25 #include "hilog_wrapper.h"
26 #include "locale_matcher.h"
27 #if defined(__WINNT__)
28 #include <cstring>
29 #else
30 #include "securec.h"
31 #endif
32 #include "utils/errors.h"
33 #include "utils/string_utils.h"
34 #include "utils/utils.h"
35 
36 namespace OHOS {
37 namespace Global {
38 namespace Resource {
39 const char *HapParser::RES_FILE_NAME = "/resources.index";
40 
LocateFile(unzFile & uf,const char * fileName)41 int32_t LocateFile(unzFile &uf, const char *fileName)
42 {
43     if (unzLocateFile2(uf, fileName, 1)) { // try to locate file inside zip, 1 = case sensitive
44         return UNKNOWN_ERROR;
45     }
46     return OK;
47 }
48 
GetCurrentFileInfo(unzFile & uf,unz_file_info & fileInfo)49 int32_t GetCurrentFileInfo(unzFile &uf, unz_file_info &fileInfo)
50 {
51     // obtained the necessary details about file inside zip
52     char filenameInzip[256];  // for unzGetCurrentFileInfo
53     int err = unzGetCurrentFileInfo(uf, &fileInfo, filenameInzip, sizeof(filenameInzip), nullptr, 0, nullptr, 0);
54     if (err != UNZ_OK) {
55         HILOG_ERROR("GetCurrentFileInfo failed");
56         return UNKNOWN_ERROR;
57     }
58     return OK;
59 }
60 
ReadCurrentFile(unzFile & uf,unz_file_info & fileInfo,std::unique_ptr<uint8_t[]> & buffer,size_t & bufLen)61 int32_t ReadCurrentFile(unzFile &uf, unz_file_info &fileInfo, std::unique_ptr<uint8_t[]> &buffer,
62     size_t &bufLen)
63 {
64     buffer = std::make_unique<uint8_t[]>(fileInfo.uncompressed_size);
65     bufLen = fileInfo.uncompressed_size;
66     if (buffer == nullptr) {
67         HILOG_ERROR("Error allocating memory for read buffer");
68         return UNKNOWN_ERROR;
69     }
70 
71     int err = unzOpenCurrentFilePassword(uf, nullptr);
72     if (err != UNZ_OK) {
73         HILOG_ERROR("Error %d in unzOpenCurrentFilePassword.", err);
74         return UNKNOWN_ERROR;
75     } // file inside the zip is open
76 
77     err = unzReadCurrentFile(uf, buffer.get(), bufLen);
78     if (err < 0) {
79         HILOG_ERROR("Error %d in unzReadCurrentFile", err);
80         return UNKNOWN_ERROR;
81     }
82 
83     return OK;
84 }
85 
ReadFileFromZip(unzFile & uf,const char * fileName,std::unique_ptr<uint8_t[]> & buffer,size_t & bufLen)86 int32_t HapParser::ReadFileFromZip(unzFile &uf, const char *fileName, std::unique_ptr<uint8_t[]> &buffer,
87     size_t &bufLen)
88 {
89     unz_file_info fileInfo;
90     if (LocateFile(uf, fileName) != OK) {
91         return UNKNOWN_ERROR;
92     }
93     if (GetCurrentFileInfo(uf, fileInfo) != OK) {
94         return UNKNOWN_ERROR;
95     }
96     if (ReadCurrentFile(uf, fileInfo, buffer, bufLen) != OK) {
97         return UNKNOWN_ERROR;
98     }
99     return OK;
100 }
101 
GetModuleName(const char * configStr,size_t len)102 std::string GetModuleName(const char *configStr, size_t len)
103 {
104     if (configStr == nullptr) {
105         return std::string();
106     }
107     std::string config(configStr, len);
108     static const char *key = "\"moduleName\"";
109     auto idx = config.find(key);
110     if (idx == std::string::npos) {
111         return std::string();
112     }
113     auto start = config.find("\"", idx + strlen(key));
114     if (start == std::string::npos) {
115         return std::string();
116     }
117     auto end = config.find("\"", start + 1);
118     if (end == std::string::npos) {
119         return std::string();
120     }
121 
122     std::string retStr = std::string(configStr + start + 1, end - start - 1);
123     return retStr;
124 }
125 
IsStageMode(unzFile & uf)126 bool HapParser::IsStageMode(unzFile &uf)
127 {
128     // stage mode contains "module.json", The 1 means the case sensitive
129     if (unzLocateFile2(uf, "module.json", 1) != UNZ_OK) {
130         return false;
131     }
132     return true;
133 }
134 
ParseModuleNameFromHap(unzFile & uf)135 std::string ParseModuleNameFromHap(unzFile &uf)
136 {
137     std::unique_ptr<uint8_t[]> tmpBuf;
138     int32_t ret = UNZ_OK;
139     size_t tmpLen;
140     ret = HapParser::ReadFileFromZip(uf, "config.json", tmpBuf, tmpLen);
141     if (ret != OK) {
142         HILOG_ERROR("read config.json error");
143         return std::string();
144     }
145     // parse config.json
146     std::string mName = GetModuleName(reinterpret_cast<char *>(tmpBuf.get()), tmpLen);
147     if (mName.size() == 0) {
148         HILOG_ERROR("parse moduleName from config.json error");
149         return std::string();
150     }
151     return mName;
152 }
153 
GetIndexFilePath(unzFile uf)154 std::string GetIndexFilePath(unzFile uf)
155 {
156     std::string mName = ParseModuleNameFromHap(uf);
157     std::string indexFilePath = std::string("assets/");
158     indexFilePath.append(mName);
159     indexFilePath.append("/resources.index");
160     return indexFilePath;
161 }
162 
ReadFileInfoFromZip(unzFile & uf,const char * fileName,std::unique_ptr<uint8_t[]> & buffer,size_t & bufLen)163 int32_t ReadFileInfoFromZip(unzFile &uf, const char *fileName, std::unique_ptr<uint8_t[]> &buffer, size_t &bufLen)
164 {
165     int err = HapParser::ReadFileFromZip(uf, fileName, buffer, bufLen);
166     if (err < 0) {
167         unzClose(uf);
168         return UNKNOWN_ERROR;
169     }
170     unzClose(uf);
171     return OK;
172 }
173 
ReadIndexFromFile(const char * zipFile,std::unique_ptr<uint8_t[]> & buffer,size_t & bufLen)174 int32_t HapParser::ReadIndexFromFile(const char *zipFile, std::unique_ptr<uint8_t[]> &buffer,
175     size_t &bufLen)
176 {
177     unzFile uf = unzOpen64(zipFile);
178     if (uf == nullptr) {
179         HILOG_ERROR("Error open %{public}s in ReadIndexFromFile %{public}d", zipFile, errno);
180         return UNKNOWN_ERROR;
181     } // file is open
182     if (IsStageMode(uf)) {
183         return ReadFileInfoFromZip(uf, "resources.index", buffer, bufLen);
184     }
185     std::string indexFilePath = GetIndexFilePath(uf);
186     return ReadFileInfoFromZip(uf, indexFilePath.c_str(), buffer, bufLen);
187 }
188 
GetPath(const std::string & filePath,std::string & rawFilePath)189 std::string HapParser::GetPath(const std::string &filePath, std::string &rawFilePath)
190 {
191     std::string tempName = filePath;
192     const std::string rawFileDirName = "rawfile/";
193     if (tempName.length() <= rawFileDirName.length()
194     || (tempName.compare(0, rawFileDirName.length(), rawFileDirName) != 0)) {
195         tempName = rawFileDirName + tempName;
196     }
197     rawFilePath.append(tempName);
198     return rawFilePath;
199 }
200 
201 #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__)
ParseModuleName(std::shared_ptr<AbilityBase::Extractor> & extractor)202 std::string HapParser::ParseModuleName(std::shared_ptr<AbilityBase::Extractor> &extractor)
203 {
204     if (extractor == nullptr) {
205         return std::string();
206     }
207     std::unique_ptr<uint8_t[]> configBuf;
208     size_t len;
209     bool ret = extractor->ExtractToBufByName("config.json", configBuf, len);
210     if (!ret) {
211         HILOG_ERROR("failed to get config data from ability");
212         return std::string();
213     }
214     // parse config.json
215     std::string mName = GetModuleName(reinterpret_cast<char *>(configBuf.get()), len);
216     if (mName.size() == 0) {
217         HILOG_ERROR("parse moduleName from config.json error");
218         return std::string();
219     }
220     return mName;
221 }
222 
GetRawFilePathFromFA(std::shared_ptr<AbilityBase::Extractor> & extractor,const std::string & filePath)223 std::string GetRawFilePathFromFA(std::shared_ptr<AbilityBase::Extractor> &extractor,
224     const std::string &filePath)
225 {
226     std::string moduleName = HapParser::ParseModuleName(extractor);
227     std::string rawFilePath("assets/");
228     rawFilePath.append(moduleName);
229     rawFilePath.append("/resources/");
230     HapParser::GetPath(filePath, rawFilePath);
231     return rawFilePath;
232 }
233 
GetRawFilePathFromStage(const std::string & filePath)234 std::string GetRawFilePathFromStage(const std::string &filePath)
235 {
236     std::string rawFilePath("resources/");
237     HapParser::GetPath(filePath, rawFilePath);
238     return rawFilePath;
239 }
240 
GetRawFilePath(std::shared_ptr<AbilityBase::Extractor> & extractor,const std::string & rawFileName)241 std::string HapParser::GetRawFilePath(std::shared_ptr<AbilityBase::Extractor> &extractor,
242     const std::string &rawFileName)
243 {
244     std::string rawfilePath;
245     if (extractor->IsStageModel()) {
246         rawfilePath = GetRawFilePathFromStage(rawFileName);
247     } else {
248         rawfilePath = GetRawFilePathFromFA(extractor, rawFileName);
249     }
250     return rawfilePath;
251 }
252 #endif
253 
ReadRawFileFromHap(const std::string & hapPath,const std::string & rawFileName,size_t & len,std::unique_ptr<uint8_t[]> & outValue)254 RState HapParser::ReadRawFileFromHap(const std::string &hapPath, const std::string &rawFileName, size_t &len,
255     std::unique_ptr<uint8_t[]> &outValue)
256 {
257 #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__)
258     bool isNewExtractor = false;
259     auto extractor = AbilityBase::ExtractorUtil::GetExtractor(hapPath, isNewExtractor);
260     if (extractor == nullptr) {
261         HILOG_ERROR("failed to get extractor hapPath, %{public}s", hapPath.c_str());
262         return NOT_FOUND;
263     }
264     std::string rawfilePath = HapParser::GetRawFilePath(extractor, rawFileName);
265     if (!extractor->HasEntry(rawfilePath)) {
266         HILOG_ERROR("the rawfile file %{public}s is not exist in %{public}s", rawfilePath.c_str(), hapPath.c_str());
267         return ERROR_CODE_RES_PATH_INVALID;
268     }
269     bool ret = extractor->ExtractToBufByName(rawfilePath, outValue, len);
270     if (!ret) {
271         HILOG_ERROR("failed to get rawfile data rawfilePath, %{public}s, hapPath, %{public}s",
272             rawfilePath.c_str(), hapPath.c_str());
273         return NOT_FOUND;
274     }
275 #endif
276     return SUCCESS;
277 }
278 
ReadRawFileDescriptor(const char * hapPath,const std::string & rawFileName,ResourceManager::RawFileDescriptor & descriptor)279 RState HapParser::ReadRawFileDescriptor(const char *hapPath, const std::string &rawFileName,
280     ResourceManager::RawFileDescriptor &descriptor)
281 {
282 #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__)
283     char outPath[PATH_MAX + 1] = {0};
284     Utils::CanonicalizePath(hapPath, outPath, PATH_MAX);
285     int zipFd = open(outPath, O_RDONLY);
286     if (zipFd < 0) {
287         HILOG_ERROR("failed open file %{public}s", outPath);
288         return NOT_FOUND;
289     }
290     bool isNewExtractor = false;
291     auto extractor = AbilityBase::ExtractorUtil::GetExtractor(outPath, isNewExtractor);
292     if (extractor == nullptr) {
293         HILOG_ERROR("failed to get extractor in ReadRawFileDescriptor hapPath, %{public}s", outPath);
294         return NOT_FOUND;
295     }
296     std::string rawfilePath = HapParser::GetRawFilePath(extractor, rawFileName);
297     if (!extractor->HasEntry(rawfilePath)) {
298         HILOG_ERROR("the rawfile file %{public}s is not exist in %{public}s", rawfilePath.c_str(), hapPath);
299         return ERROR_CODE_RES_PATH_INVALID;
300     }
301     AbilityBase::FileInfo fileInfo;
302     bool ret = extractor->GetFileInfo(rawfilePath, fileInfo);
303     if (!ret) {
304         HILOG_ERROR("failed to get rawFileDescriptor rawfilePath, %{public}s", rawfilePath.c_str());
305         return NOT_FOUND;
306     }
307     descriptor.offset = static_cast<long>(fileInfo.offset);
308     descriptor.length = static_cast<long>(fileInfo.length);
309     descriptor.fd = zipFd;
310 #endif
311     return SUCCESS;
312 }
313 
GetRawFileList(const std::string & hapPath,const std::string & rawDirPath,std::vector<std::string> & fileList)314 RState HapParser::GetRawFileList(const std::string &hapPath, const std::string &rawDirPath,
315     std::vector<std::string>& fileList)
316 {
317 #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__)
318     bool isNewExtractor = false;
319     auto extractor = AbilityBase::ExtractorUtil::GetExtractor(hapPath, isNewExtractor);
320     if (extractor == nullptr) {
321         HILOG_ERROR("failed to get extractor from ability in GetRawFileList hapPath, %{public}s", hapPath.c_str());
322         return NOT_FOUND;
323     }
324     std::set<std::string> fileSet;
325     std::string rawfilePath = HapParser::GetRawFilePath(extractor, rawDirPath);
326     if (!extractor->IsDirExist(rawfilePath)) {
327         HILOG_ERROR("the rawfile dir %{public}s is not exist in %{public}s", rawfilePath.c_str(), hapPath.c_str());
328         return ERROR_CODE_RES_PATH_INVALID;
329     }
330     bool ret = extractor->GetFileList(rawfilePath, fileSet);
331     if (!ret) {
332         HILOG_ERROR("failed to get fileSet from ability rawfilePath, %{public}s", rawfilePath.c_str());
333         return ERROR_CODE_RES_PATH_INVALID;
334     }
335     for (auto it = fileSet.begin(); it != fileSet.end(); it++) {
336         fileList.emplace_back(*it);
337     }
338 #endif
339     return SUCCESS;
340 }
341 
342 /**
343  *
344  * @param buffer
345  * @param offset
346  * @param id
347  * @param includeTemi dose length include '\0'
348  * @return OK or ERROR
349  */
ParseString(const char * buffer,uint32_t & offset,std::string & id,bool includeTemi=true)350 int32_t ParseString(const char *buffer, uint32_t &offset, std::string &id, bool includeTemi = true)
351 {
352     uint16_t strLen;
353     errno_t eret = memcpy_s(&strLen, sizeof(strLen), buffer + offset, 2);
354     if (eret != OK || (includeTemi && strLen == 0)) {
355         return SYS_ERROR;
356     }
357     offset += 2;
358     std::string tmp = std::string(const_cast<char *>(buffer) + offset, includeTemi ? (strLen - 1) : strLen);
359     offset += includeTemi ? strLen : (strLen + 1);
360     id = tmp;
361     return OK;
362 }
363 
364 /**
365  *
366  * @param buffer
367  * @param offset
368  * @param values
369  * @return
370  */
ParseStringArray(const char * buffer,uint32_t & offset,std::vector<std::string> & values)371 int32_t ParseStringArray(const char *buffer, uint32_t &offset, std::vector<std::string> &values)
372 {
373     uint16_t arrLen;
374     errno_t eret = memcpy_s(&arrLen, sizeof(arrLen), buffer + offset, 2);
375     if (eret != OK) {
376         return SYS_ERROR;
377     }
378     offset += 2;
379     // next arrLen bytes are several strings. then after, is one '\0'
380     uint32_t startOffset = offset;
381     while (true) {
382         std::string value;
383         int32_t ret = ParseString(buffer, offset, value, false);
384         if (ret != OK) {
385             return ret;
386         }
387         values.push_back(value);
388 
389         uint32_t readSize = offset - startOffset;
390         if (readSize + 1 == arrLen) {
391             offset += 1; // after arrLen, got '\0'
392             break;
393         }
394         if (readSize + 1 > arrLen) {
395             // size not match, cannot > arrLen
396             return SYS_ERROR;
397         }
398     }
399 
400     return OK;
401 }
402 
ParseIdItem(const char * buffer,uint32_t & offset,IdItem * idItem)403 int32_t ParseIdItem(const char *buffer, uint32_t &offset, IdItem *idItem)
404 {
405     errno_t eret = memcpy_s(idItem, sizeof(IdItem), buffer + offset, IdItem::HEADER_LEN);
406     if (eret != OK) {
407         return SYS_ERROR;
408     }
409     offset += IdItem::HEADER_LEN;
410 
411     idItem->JudgeArray();
412     if (idItem->isArray_) {
413         int32_t ret = ParseStringArray(buffer, offset, idItem->values_);
414         if (ret != OK) {
415             return ret;
416         }
417     } else {
418         std::string value;
419         int32_t ret = ParseString(buffer, offset, value);
420         if (ret != OK) {
421             return ret;
422         }
423         idItem->value_ = std::string(value);
424         idItem->valueLen_ = value.size();
425     }
426     std::string name;
427     int32_t ret = ParseString(buffer, offset, name);
428     if (ret != OK) {
429         return ret;
430     }
431     idItem->name_ = std::string(name);
432     return OK;
433 }
434 
ParseId(const char * buffer,uint32_t & offset,ResId * id)435 int32_t ParseId(const char *buffer, uint32_t &offset, ResId *id)
436 {
437     errno_t eret = memcpy_s(id, sizeof(ResId), buffer + offset, ResId::RESID_HEADER_LEN);
438     if (eret != OK) {
439         return SYS_ERROR;
440     }
441     offset += ResId::RESID_HEADER_LEN;
442     if (id->tag_[0] != 'I' || id->tag_[1] != 'D'
443         || id->tag_[2] != 'S' || id->tag_[3] != 'S') {
444         return -1;
445     }
446     for (uint32_t i = 0; i < id->count_; ++i) {
447         IdParam *ip = new (std::nothrow) IdParam();
448         if (ip == nullptr) {
449             HILOG_ERROR("new IdParam failed when ParseId");
450             return SYS_ERROR;
451         }
452         errno_t eret = memcpy_s(ip, sizeof(IdParam), buffer + offset, ResId::IDPARAM_HEADER_LEN);
453         if (eret != OK) {
454             delete (ip);
455             return SYS_ERROR;
456         }
457         offset += ResId::IDPARAM_HEADER_LEN;
458         IdItem *idItem = new (std::nothrow) IdItem();
459         if (idItem == nullptr) {
460             HILOG_ERROR("new IdItem failed when ParseId");
461             delete (ip);
462             return SYS_ERROR;
463         }
464         uint32_t ipOffset = ip->offset_;
465         int32_t ret = ParseIdItem(buffer, ipOffset, idItem);
466         if (ret != OK) {
467             delete (ip);
468             delete (idItem);
469             return ret;
470         }
471         ip->idItem_ = idItem;
472         id->idParams_.push_back(ip);
473     }
474 
475     return OK;
476 }
477 
IsLocaleMatch(const ResConfigImpl * defaultConfig,const std::vector<KeyParam * > & keyParams)478 bool IsLocaleMatch(const ResConfigImpl *defaultConfig, const std::vector<KeyParam *> &keyParams)
479 {
480     if (defaultConfig == nullptr) {
481         return true;
482     }
483     ResConfigImpl *config = HapParser::CreateResConfigFromKeyParams(keyParams);
484     if (config == nullptr) {
485         return false;
486     }
487     if (LocaleMatcher::Match(defaultConfig->GetResLocale(), config->GetResLocale())) {
488         delete (config);
489         return true;
490     }
491     HILOG_DEBUG("mismatch, do not parse %s", HapParser::ToFolderPath(keyParams).c_str());
492     delete (config);
493     return false;
494 }
495 
ParseKey(const char * buffer,uint32_t & offset,ResKey * key,bool & match,const ResConfigImpl * defaultConfig)496 int32_t ParseKey(const char *buffer, uint32_t &offset,  ResKey *key,
497                  bool &match, const ResConfigImpl *defaultConfig)
498 {
499     errno_t eret = memcpy_s(key, sizeof(ResKey), buffer + offset, ResKey::RESKEY_HEADER_LEN);
500     if (eret != OK) {
501         return SYS_ERROR;
502     }
503     offset += ResKey::RESKEY_HEADER_LEN;
504     if (key->tag_[0] != 'K' || key->tag_[1] != 'E'
505         || key->tag_[2] != 'Y' || key->tag_[3] != 'S') {
506         return -1;
507     }
508     for (uint32_t i = 0; i < key->keyParamsCount_; ++i) {
509         KeyParam *kp = new (std::nothrow) KeyParam();
510         if (kp == nullptr) {
511             HILOG_ERROR("new KeyParam failed when ParseKey");
512             return SYS_ERROR;
513         }
514         errno_t eret = memcpy_s(kp, sizeof(KeyParam), buffer + offset, ResKey::KEYPARAM_HEADER_LEN);
515         if (eret != OK) {
516             delete (kp);
517             return SYS_ERROR;
518         }
519         offset += ResKey::KEYPARAM_HEADER_LEN;
520         kp->InitStr();
521         key->keyParams_.push_back(kp);
522     }
523     uint32_t idOffset = key->offset_;
524     ResId *id = new (std::nothrow) ResId();
525     if (id == nullptr) {
526         HILOG_ERROR("new ResId failed when ParseKey");
527         return SYS_ERROR;
528     }
529     int32_t ret = ParseId(buffer, idOffset, id);
530     if (ret != OK) {
531         delete (id);
532         return ret;
533     }
534     key->resId_ = id;
535     return OK;
536 }
537 
538 
ParseResHex(const char * buffer,const size_t bufLen,ResDesc & resDesc,const ResConfigImpl * defaultConfig)539 int32_t HapParser::ParseResHex(const char *buffer, const size_t bufLen, ResDesc &resDesc,
540                                const ResConfigImpl *defaultConfig)
541 {
542     ResHeader *resHeader = new (std::nothrow) ResHeader();
543     if (resHeader == nullptr) {
544         HILOG_ERROR("new ResHeader failed when ParseResHex");
545         return SYS_ERROR;
546     }
547     uint32_t offset = 0;
548     errno_t eret = memcpy_s(resHeader, sizeof(ResHeader), buffer + offset, RES_HEADER_LEN);
549     if (eret != OK) {
550         delete (resHeader);
551         return SYS_ERROR;
552     }
553     offset += RES_HEADER_LEN;
554     if (resHeader->keyCount_ == 0 || resHeader->length_ == 0) {
555         delete (resHeader);
556         return UNKNOWN_ERROR;
557     }
558 
559     resDesc.resHeader_ = resHeader;
560     for (uint32_t i = 0; i < resHeader->keyCount_; i++) {
561         ResKey *key = new (std::nothrow) ResKey();
562         if (key == nullptr) {
563             HILOG_ERROR("new ResKey failed when ParseResHex");
564             return SYS_ERROR;
565         }
566         bool match = true;
567         int32_t ret = ParseKey(buffer, offset, key, match, defaultConfig);
568         if (ret != OK) {
569             delete (key);
570             return ret;
571         }
572         if (match) {
573             resDesc.keys_.push_back(key);
574         } else {
575             delete (key);
576         }
577     }
578     return OK;
579 }
580 
CreateResConfigFromKeyParams(const std::vector<KeyParam * > & keyParams)581 ResConfigImpl *HapParser::CreateResConfigFromKeyParams(const std::vector<KeyParam *> &keyParams)
582 {
583     ResConfigImpl *resConfig = new (std::nothrow) ResConfigImpl;
584     if (resConfig == nullptr) {
585         HILOG_ERROR("new ResConfigImpl failed when CreateResConfigFromKeyParams");
586         return nullptr;
587     }
588     size_t len = keyParams.size();
589     // default path
590     if (len == 0) {
591         resConfig->SetColorMode(COLOR_MODE_NOT_SET);
592         return resConfig;
593     }
594     delete resConfig;
595     size_t i = 0;
596     ResConfigKey configKey;
597     for (i = 0; i < len; ++i) {
598         const KeyParam *kp = keyParams.at(i);
599         if (kp->type_ == LANGUAGES) {
600             configKey.language = kp->GetStr().c_str();
601         } else if (kp->type_ == REGION) {
602             configKey.region = kp->GetStr().c_str();
603         } else if (kp->type_ == SCRIPT) {
604             configKey.script = kp->GetStr().c_str();
605         } else if (kp->type_ == SCREEN_DENSITY) {
606             configKey.screenDensity = GetScreenDensity(kp->value_);
607         } else if (kp->type_ == DEVICETYPE) {
608             configKey.deviceType = GetDeviceType(kp->value_);
609         } else if (kp->type_ == DIRECTION) {
610             if (kp->value_ == 0) {
611                 configKey.direction = DIRECTION_VERTICAL;
612             } else {
613                 configKey.direction = DIRECTION_HORIZONTAL;
614             }
615         } else if (kp->type_ == INPUTDEVICE) {
616             configKey.inputDevice = GetInputDevice(kp->value_);
617         } else if (kp->type_ == COLORMODE) {
618             configKey.colorMode = GetColorMode(kp->value_);
619         } else if (kp->type_ == MCC) {
620             configKey.mcc = GetMcc(kp->value_);
621         } else if (kp->type_ == MNC) {
622             configKey.mnc = GetMnc(kp->value_);
623         }
624     }
625 
626     return BuildResConfig(&configKey);
627 }
628 
BuildResConfig(ResConfigKey * configKey)629 ResConfigImpl *HapParser::BuildResConfig(ResConfigKey *configKey)
630 {
631     if (configKey == nullptr) {
632         HILOG_ERROR("configKey is null");
633         return nullptr;
634     }
635     ResConfigImpl *resConfig = new (std::nothrow) ResConfigImpl;
636     if (resConfig == nullptr) {
637         HILOG_ERROR("new ResConfigImpl failed when BuildResConfig");
638         return nullptr;
639     }
640     resConfig->SetDeviceType(configKey->deviceType);
641     resConfig->SetDirection(configKey->direction);
642     resConfig->SetColorMode(configKey->colorMode);
643     resConfig->SetMcc(configKey->mcc);
644     resConfig->SetMnc(configKey->mnc);
645     resConfig->SetInputDevice(configKey->inputDevice);
646     resConfig->SetScreenDensity((configKey->screenDensity) / Utils::DPI_BASE);
647     RState r = resConfig->SetLocaleInfo(configKey->language, configKey->script, configKey->region);
648     if (r != SUCCESS) {
649         HILOG_ERROR("error set locale,lang %s,script %s,region %s", configKey->language, configKey->script,
650             configKey->region);
651     }
652 
653     return resConfig;
654 }
655 
GetDeviceType(uint32_t value)656 DeviceType HapParser::GetDeviceType(uint32_t value)
657 {
658     DeviceType deviceType = DEVICE_NOT_SET;
659     if (value == DEVICE_CAR) {
660         deviceType = DEVICE_CAR;
661     } else if (value == DEVICE_PAD) {
662         deviceType = DEVICE_PAD;
663     } else if (value == DEVICE_PHONE) {
664         deviceType = DEVICE_PHONE;
665     } else if (value == DEVICE_TABLET) {
666         deviceType = DEVICE_TABLET;
667     } else if (value == DEVICE_TV) {
668         deviceType = DEVICE_TV;
669     } else if (value == DEVICE_WEARABLE) {
670         deviceType = DEVICE_WEARABLE;
671     }
672     return deviceType;
673 }
674 
GetMcc(uint32_t value)675 uint32_t HapParser::GetMcc(uint32_t value)
676 {
677     return value;
678 }
679 
GetMnc(uint32_t value)680 uint32_t HapParser::GetMnc(uint32_t value)
681 {
682     return value;
683 }
684 
GetColorMode(uint32_t value)685 ColorMode HapParser::GetColorMode(uint32_t value)
686 {
687     ColorMode colorMode = COLOR_MODE_NOT_SET;
688     if (value == DARK) {
689         colorMode = DARK;
690     } else {
691         colorMode = LIGHT;
692     }
693     return colorMode;
694 }
695 
GetInputDevice(uint32_t value)696 InputDevice HapParser::GetInputDevice(uint32_t value)
697 {
698     InputDevice inputDevice = INPUTDEVICE_NOT_SET;
699     if (value == INPUTDEVICE_POINTINGDEVICE) {
700         inputDevice = INPUTDEVICE_POINTINGDEVICE;
701     }
702     return inputDevice;
703 }
704 
GetScreenDensity(uint32_t value)705 ScreenDensity HapParser::GetScreenDensity(uint32_t value)
706 {
707     ScreenDensity screenDensity = SCREEN_DENSITY_NOT_SET;
708     if (value == SCREEN_DENSITY_SDPI) {
709         screenDensity = SCREEN_DENSITY_SDPI;
710     } else if (value == SCREEN_DENSITY_MDPI) {
711         screenDensity = SCREEN_DENSITY_MDPI;
712     } else if (value == SCREEN_DENSITY_LDPI) {
713         screenDensity = SCREEN_DENSITY_LDPI;
714     } else if (value == SCREEN_DENSITY_XLDPI) {
715         screenDensity = SCREEN_DENSITY_XLDPI;
716     } else if (value == SCREEN_DENSITY_XXLDPI) {
717         screenDensity = SCREEN_DENSITY_XXLDPI;
718     } else if (value == SCREEN_DENSITY_XXXLDPI) {
719         screenDensity = SCREEN_DENSITY_XXXLDPI;
720     }
721     return screenDensity;
722 }
723 
PathAppend(std::string & path,const std::string & append,const std::string & connector)724 void PathAppend(std::string &path, const std::string &append, const std::string &connector)
725 {
726     if (append.size() > 0) {
727         if (path.size() > 0) {
728             path.append(connector);
729         }
730         path.append(append);
731     }
732 }
733 
ToFolderPath(const std::vector<KeyParam * > & keyParams)734 std::string HapParser::ToFolderPath(const std::vector<KeyParam *> &keyParams)
735 {
736     if (keyParams.size() == 0) {
737         return std::string("default");
738     }
739     // mcc-mnc-language_script_region-direction-deviceType-colorMode-inputDevice-screenDensity
740     Determiner determiner;
741     for (size_t i = 0; i < keyParams.size(); ++i) {
742         KeyParam *keyParam = keyParams[i];
743         switch (keyParam->type_) {
744             case KeyType::LANGUAGES:
745                 determiner.language = keyParam->GetStr();
746                 break;
747             case KeyType::SCRIPT:
748                 determiner.script = keyParam->GetStr();
749                 break;
750             case KeyType::REGION:
751                 determiner.region = keyParam->GetStr();
752                 break;
753             case KeyType::DIRECTION:
754                 determiner.direction = keyParam->GetStr();
755                 break;
756             case KeyType::DEVICETYPE:
757                 determiner.deviceType = keyParam->GetStr();
758                 break;
759             case KeyType::COLORMODE:
760                 determiner.colorMode = keyParam->GetStr();
761                 break;
762             case KeyType::INPUTDEVICE:
763                 determiner.inputDevice = keyParam->GetStr();
764                 break;
765             case KeyType::MCC:
766                 determiner.mcc = keyParam->GetStr();
767                 break;
768             case KeyType::MNC:
769                 determiner.mnc = keyParam->GetStr();
770                 break;
771             case KeyType::SCREEN_DENSITY:
772                 determiner.screenDensity = keyParam->GetStr();
773                 break;
774             default:
775                 break;
776         }
777     }
778 
779     return BuildFolderPath(&determiner);
780 }
781 
BuildFolderPath(Determiner * determiner)782 std::string HapParser::BuildFolderPath(Determiner *determiner)
783 {
784     std::string path;
785     if (determiner == nullptr) {
786         HILOG_ERROR("determiner is null");
787         return path;
788     }
789     std::string connecter1("_");
790     std::string connecter2("-");
791     if (determiner->mcc.size() > 0) {
792         path.append(determiner->mcc);
793         if (determiner->mnc.size() > 0) {
794             PathAppend(path, determiner->mnc, connecter1);
795         }
796         if (determiner->language.size() > 0) {
797             PathAppend(path, determiner->language, connecter2);
798         }
799     } else {
800         if (determiner->language.size() > 0) {
801             path.append(determiner->language);
802         }
803     }
804     PathAppend(path, determiner->script, connecter1);
805     PathAppend(path, determiner->region, connecter1);
806     PathAppend(path, determiner->direction, connecter2);
807     PathAppend(path, determiner->deviceType, connecter2);
808     PathAppend(path, determiner->colorMode, connecter2);
809     PathAppend(path, determiner->inputDevice, connecter2);
810     PathAppend(path, determiner->screenDensity, connecter2);
811 
812     return path;
813 }
814 } // namespace Resource
815 } // namespace Global
816 } // namespace OHOS