• 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 #include "utils/utils.h"
16 
17 #include <fstream>
18 #include <vector>
19 #include <sys/stat.h>
20 #include "hilog_wrapper.h"
21 
22 #ifdef __LINUX__
23 #include <cstring>
24 #endif
25 
26 namespace OHOS {
27 namespace Global {
28 namespace Resource {
29 constexpr int BIT_SIX = 6;
30 constexpr int BIT_FOUR = 4;
31 constexpr int BIT_TWO = 2;
32 constexpr int LEN_THREE = 3;
33 
34 const std::set<std::string> Utils::tailSet {
35     ".hap",
36     ".hsp",
37 };
38 
39 std::vector<char> g_codes = {
40     'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
41     'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
42     'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
43     'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
44     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
45 };
46 
LoadResourceFile(const std::string & path,int & len)47 std::unique_ptr<uint8_t[]> Utils::LoadResourceFile(const std::string &path, int &len)
48 {
49     std::ifstream mediaStream(path, std::ios::binary);
50     if (!mediaStream.is_open()) {
51         return nullptr;
52     }
53     mediaStream.seekg(0, std::ios::end);
54     len = mediaStream.tellg();
55     std::unique_ptr<uint8_t[]> tempData = std::make_unique<uint8_t[]>(len);
56     if (tempData == nullptr) {
57         return nullptr;
58     }
59     mediaStream.seekg(0, std::ios::beg);
60     mediaStream.read(reinterpret_cast<char *>(tempData.get()), len);
61     return tempData;
62 }
63 
EncodeBase64(std::unique_ptr<uint8_t[]> & data,int srcLen,const std::string & imgType,std::string & dstData)64 RState Utils::EncodeBase64(std::unique_ptr<uint8_t[]> &data, int srcLen,
65     const std::string &imgType, std::string &dstData)
66 {
67     const unsigned char *srcData = data.get();
68     if (srcData == nullptr) {
69         return ERROR;
70     }
71     std::string base64data;
72     base64data += "data:image/" + imgType + ";base64,";
73     int i = 0;
74     // encode in groups of every 3 bytes
75     for (; i < srcLen - 3; i += 3) {
76         unsigned char byte1 = static_cast<unsigned char>(srcData[i]);
77         unsigned char byte2 = static_cast<unsigned char>(srcData[i + 1]);
78         unsigned char byte3 = static_cast<unsigned char>(srcData[i + 2]);
79         base64data += g_codes[byte1 >> BIT_TWO];
80         base64data += g_codes[((byte1 & 0x3) << BIT_FOUR) | (byte2 >> BIT_FOUR)];
81         base64data += g_codes[((byte2 & 0xF) << BIT_TWO) | (byte3 >> BIT_SIX)];
82         base64data += g_codes[byte3 & 0x3F];
83     }
84     // Handle the case where there is one element left
85     if (srcLen % LEN_THREE == 1) {
86         unsigned char byte1 = static_cast<unsigned char>(srcData[i]);
87         base64data += g_codes[byte1 >> BIT_TWO];
88         base64data += g_codes[(byte1 & 0x3) << BIT_FOUR];
89         base64data += '=';
90         base64data += '=';
91     } else {
92         unsigned char byte1 = static_cast<unsigned char>(srcData[i]);
93         unsigned char byte2 = static_cast<unsigned char>(srcData[i + 1]);
94         base64data += g_codes[byte1 >> BIT_TWO];
95         base64data += g_codes[((byte1 & 0x3) << BIT_FOUR) | (byte2 >> BIT_FOUR)];
96         base64data += g_codes[(byte2 & 0xF) << BIT_TWO];
97         base64data += '=';
98     }
99     dstData = base64data;
100     return SUCCESS;
101 }
102 
IsAlphaString(const char * s,int32_t len)103 bool Utils::IsAlphaString(const char *s, int32_t len)
104 {
105     if (s == nullptr) {
106         return false;
107     }
108     int32_t i;
109     for (i = 0; i < len; i++) {
110         char c = *(s + i);
111         if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) {
112             return false;
113         }
114     }
115     return true;
116 }
117 
IsNumericString(const char * s,int32_t len)118 bool Utils::IsNumericString(const char *s, int32_t len)
119 {
120     if (s == nullptr) {
121         return false;
122     }
123     int32_t i;
124     for (i = 0; i < len; i++) {
125         char c = *(s + i);
126         if (!(c >= '0' && c <= '9')) {
127             return false;
128         }
129     }
130 
131     return true;
132 }
133 
134 /**
135  * @brief decode 32 bits as script array.
136  * 31-24 bits is script[0]
137  * 23-16 bits is script[1]
138  * 15-8 bits is script[2]
139  * 0-7 bits is script[3]
140  *
141  * @param encodeScript
142  * @param outValue
143  */
DecodeScript(uint32_t encodeScript,char * outValue)144 void Utils::DecodeScript(uint32_t encodeScript, char *outValue)
145 {
146     if (outValue == nullptr) {
147         return;
148     }
149     outValue[0] = (encodeScript & 0xFF000000) >> 24;
150     outValue[1] = (encodeScript & 0x00FF0000) >> 16;
151     outValue[2] = (encodeScript & 0x0000FF00) >> 8;
152     outValue[3] = (encodeScript & 0x000000FF);
153 }
154 
IsStrEmpty(const char * s)155 bool Utils::IsStrEmpty(const char *s)
156 {
157     return (s == nullptr || *s == '\0');
158 }
159 
StrLen(const char * s)160 size_t Utils::StrLen(const char *s)
161 {
162     if (s == nullptr) {
163         return 0;
164     }
165     return strlen(s);
166 }
167 
EncodeLanguage(const char * language)168 uint16_t Utils::EncodeLanguage(const char *language)
169 {
170     if (Utils::IsStrEmpty(language)) {
171         return NULL_LANGUAGE;
172     }
173     return Utils::EncodeLanguageOrRegion(language, 'a');
174 }
175 
176 /**
177  * @brief  locale compose of language,script and region,encode as 64bits.
178  * 63-48 bits represent language,detail format see EncodeLanguageOrRegion method
179  * 47-16 bits represent script,detail format see EncodeScript method
180  * 15-0 bits represent region,detail format see EncodeLanguageOrRegion method
181  *
182  * @param language
183  * @param script
184  * @param region
185  * @return uint64_t
186  */
EncodeLocale(const char * language,const char * script,const char * region)187 uint64_t Utils::EncodeLocale(const char *language,
188                              const char *script,
189                              const char *region)
190 {
191     uint16_t languageData = Utils::EncodeLanguage(language);
192     uint32_t scriptData = Utils::EncodeScript(script);
193     uint16_t regionData = Utils::EncodeRegion(region);
194 
195     return (uint64_t)(0xffff000000000000 & (((uint64_t)languageData) << 48)) |
196            (0x0000ffffffff0000 & (((uint64_t)scriptData) << 16)) | (0x000000000000ffff & (uint64_t)(regionData));
197 }
198 
EncodeRegionByResLocale(const ResLocale * locale)199 uint16_t Utils::EncodeRegionByResLocale(const ResLocale *locale)
200 {
201     if (locale == nullptr) {
202         return NULL_REGION;
203     }
204     return Utils::EncodeRegion(locale->GetRegion());
205 }
206 
EncodeLanguageByResLocale(const ResLocale * locale)207 uint16_t Utils::EncodeLanguageByResLocale(const ResLocale *locale)
208 {
209     if (locale == nullptr) {
210         return NULL_LANGUAGE;
211     }
212     return Utils::EncodeLanguage(locale->GetLanguage());
213 }
214 
EncodeScriptByResLocale(const ResLocale * locale)215 uint32_t Utils::EncodeScriptByResLocale(const ResLocale *locale)
216 {
217     if (locale == nullptr) {
218         return NULL_SCRIPT;
219     }
220     return Utils::EncodeScript(locale->GetScript());
221 }
222 
EncodeRegion(const char * region)223 uint16_t Utils::EncodeRegion(const char *region)
224 {
225     if (Utils::IsStrEmpty(region)) {
226         return NULL_REGION;
227     }
228     if (region[0] >= '0' && region[0] <= '9') {
229         return Utils::EncodeLanguageOrRegion(region, '0');
230     }
231     return Utils::EncodeLanguageOrRegion(region, 'A');
232 }
233 
234 /**
235  * @brief script is four letter array.encode script array as four bytes.Encode format.
236  * 31-24 bits represent script[0]
237  * 23-16 bits represent script[1]
238  * 15-8 bits represent script[2]
239  * 0-7 bits represent script[3]
240  *
241  * @param script
242  * @return uint32_t
243  */
EncodeScript(const char * script)244 uint32_t Utils::EncodeScript(const char *script)
245 {
246     if (Utils::IsStrEmpty(script)) {
247         return NULL_SCRIPT;
248     }
249     return ((uint8_t)script[0] << 24) | ((uint8_t)script[1] << 16) | ((uint8_t)script[2] << 8) | (uint8_t)script[3];
250 }
251 
252 /**
253  * @brief encode language or region str as two byte.
254  * language is two or three lowercase.
255  * region is two capital  letter or three digit.
256  *
257  * two char,encode format
258  * 15-8 bits is the first char
259  * 7-0 bits is the second char
260  *
261  * three chars,encode format
262  * 15 bit is 1
263  * 14-10 bits represent the value of  the first char subtract base char,
264  * 9-5 bits represent the value of the second char subtract base char  .
265  * 4-0 bits represent the value of the third char subtract base char.
266  * base char is 'a','A','0'.
267  * example when base is 'a',max value('z' - 'a') is 26,so five bits can represent a char.
268  *
269  * @param str
270  * @param base is '0' or 'a' or 'A'
271  * @return uint16_t
272  */
EncodeLanguageOrRegion(const char * str,char base)273 uint16_t Utils::EncodeLanguageOrRegion(const char *str, char base)
274 {
275     if (str[2] == 0 || str[2] == '-' || str[2] == '_') {
276         return ((uint8_t)str[0] << 8) | ((uint8_t)str[1]);
277     }
278     uint8_t first = ((uint8_t)(str[0] - base)) & 0x7f;
279     uint8_t second = ((uint8_t)(str[1] - base)) & 0x7f;
280     uint8_t third = ((uint8_t)(str[2] - base)) & 0x7f;
281     return ((0x80 | (first << 2) | (second >> 3)) << 8) | ((second << 5) | third);
282 };
283 
StrCompare(const char * left,const char * right,size_t len,bool isCaseSensitive)284 bool Utils::StrCompare(const char *left, const char *right, size_t len, bool isCaseSensitive)
285 {
286     if (left == nullptr && right == nullptr) {
287         return true;
288     }
289 
290     if (left == nullptr || right == nullptr) {
291         return false;
292     }
293 
294     int rc;
295     unsigned char c1;
296     unsigned char c2;
297     while (len--) {
298         c1 = (unsigned char)*left;
299         c2 = (unsigned char)*right;
300         if (c1 == 0) {
301             if (c2 == 0) {
302                 return true;
303             }
304             return false;
305         } else if (c2 == 0) {
306             return false;
307         } else {
308             if (isCaseSensitive) {
309                 rc = (int)(c1) - (int)(c2);
310             } else {
311                 rc = tolower(c1) - tolower(c2);
312             }
313             if (rc != 0) {
314                 return false;
315             }
316         }
317         ++left;
318         ++right;
319     }
320     return true;
321 }
322 
323 /**
324  * @brief convert hex char as int value
325  *
326  * @param c
327  * @param state
328  * @return uint32_t
329  */
ParseHex(char c,RState & state)330 static uint32_t ParseHex(char c, RState &state)
331 {
332     if (c >= '0' && c <= '9') {
333         return (c - '0');
334     } else if (c >= 'a' && c <= 'f') {
335         return (c - 'a' + 0xa);
336     } else if (c >= 'A' && c <= 'F') {
337         return (c - 'A' + 0xa);
338     }
339     state = INVALID_FORMAT;
340 
341     return -1;
342 }
343 
344 /**
345  * @brief  convert color string to 32 bits value 0xaarrggbb.
346  * color string format is
347  * #rgb  red (0-f) greed(0-f) blue(0-f)
348  * #argb transparency(0-f)  red (0-f) greed(0-f) blue(0-f)
349  * #rrggbb red (00-ff) greed(00-ff) blue(00-ff)
350  * #aarrggbb transparency(00-ff) red (00-ff) greed(00-ff) blue(00-ff)
351  *
352  * @param s
353  * @param outValue
354  * @return RState
355  */
ConvertColorToUInt32(const char * s,uint32_t & outValue)356 RState Utils::ConvertColorToUInt32(const char *s, uint32_t &outValue)
357 {
358     if (s == nullptr) {
359         return INVALID_FORMAT;
360     }
361     uint32_t color = 0;
362     RState parseState = SUCCESS;
363     size_t len = strlen(s);
364     if (*s == '#') {
365         if (len == 4) {
366             color |= 0xFF000000;
367             color |= ParseHex(s[1], parseState) << 20;
368             color |= ParseHex(s[1], parseState) << 16;
369             color |= ParseHex(s[2], parseState) << 12;
370             color |= ParseHex(s[2], parseState) << 8;
371             color |= ParseHex(s[3], parseState) << 4;
372             color |= ParseHex(s[3], parseState);
373         } else if (len == 5) {
374             color |= ParseHex(s[1], parseState) << 28;
375             color |= ParseHex(s[1], parseState) << 24;
376             color |= ParseHex(s[2], parseState) << 20;
377             color |= ParseHex(s[2], parseState) << 16;
378             color |= ParseHex(s[3], parseState) << 12;
379             color |= ParseHex(s[3], parseState) << 8;
380             color |= ParseHex(s[4], parseState) << 4;
381             color |= ParseHex(s[4], parseState);
382         } else if (len == 7) {
383             color |= 0xFF000000;
384             color |= ParseHex(s[1], parseState) << 20;
385             color |= ParseHex(s[2], parseState) << 16;
386             color |= ParseHex(s[3], parseState) << 12;
387             color |= ParseHex(s[4], parseState) << 8;
388             color |= ParseHex(s[5], parseState) << 4;
389             color |= ParseHex(s[6], parseState);
390         } else if (len == 9) {
391             color |= ParseHex(s[1], parseState) << 28;
392             color |= ParseHex(s[2], parseState) << 24;
393             color |= ParseHex(s[3], parseState) << 20;
394             color |= ParseHex(s[4], parseState) << 16;
395             color |= ParseHex(s[5], parseState) << 12;
396             color |= ParseHex(s[6], parseState) << 8;
397             color |= ParseHex(s[7], parseState) << 4;
398             color |= ParseHex(s[8], parseState);
399         }
400     } else {
401         parseState = INVALID_FORMAT;
402     }
403     outValue = color;
404     return parseState;
405 }
406 
endWithTail(const std::string & path,const std::string & tail)407 bool Utils::endWithTail(const std::string& path, const std::string& tail)
408 {
409     if (path.size() < tail.size()) {
410         HILOG_ERROR("the path is shorter than tail");
411         return false;
412     }
413     return path.compare(path.size() - tail.size(), tail.size(), tail) == 0;
414 }
415 
isFileExist(const std::string & filePath)416 bool Utils::isFileExist(const std::string& filePath)
417 {
418     struct stat buffer;
419     return (stat(filePath.c_str(), &buffer) == 0);
420 }
421 
ContainsTail(std::string hapPath,std::set<std::string> tailSet)422 bool Utils::ContainsTail(std::string hapPath, std::set<std::string> tailSet)
423 {
424     for (auto tail : tailSet) {
425         if (Utils::endWithTail(hapPath, tail)) {
426             return true;
427         }
428     }
429     return false;
430 }
431 
432 } // namespace Resource
433 } // namespace Global
434 } // namespace OHOS
435