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