• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "base/resource/ace_res_key_parser.h"
17 
18 #ifdef WINDOWS_PLATFORM
19 #include <cstdio>
20 #else
21 #include "securec.h"
22 #endif
23 #include <regex>
24 #include <unordered_map>
25 
26 #include "base/log/log.h"
27 #include "base/utils/string_utils.h"
28 
29 namespace OHOS::Ace {
30 namespace {
31 
32 constexpr int32_t MCC_MNC_KEYWORD_LEN = 3;
33 constexpr int32_t MCC_MNC_VALUE_LEN = 3;
34 constexpr int32_t MAX_MCC_MNC_LEN = 8;
35 
36 const std::unordered_map<std::string, ResolutionType> RES_RESOLUTION = {
37     { "ldpi", ResolutionType::RESOLUTION_LDPI },
38     { "mdpi", ResolutionType::RESOLUTION_MDPI },
39     { "hdpi", ResolutionType::RESOLUTION_HDPI },
40     { "xhdpi", ResolutionType::RESOLUTION_XHDPI },
41     { "xxhdpi", ResolutionType::RESOLUTION_XXHDPI },
42     { "xxxhdpi", ResolutionType::RESOLUTION_XXXHDPI },
43 };
44 
45 const std::unordered_map<std::string, DeviceOrientation> RES_ORIENTATION = {
46     { "horizontal", DeviceOrientation::LANDSCAPE },
47     { "vertical", DeviceOrientation::PORTRAIT }
48 };
49 
50 const std::unordered_map<std::string, ColorMode> RES_COLOR_MODE = {
51     { "dark", ColorMode::DARK },
52 };
53 
54 const std::unordered_map<std::string, ColorMode> DECLARATIVE_RES_COLOR_MODE = {
55     { "dark", ColorMode::DARK },
56     { "light", ColorMode::LIGHT },
57 };
58 
59 const std::unordered_map<std::string, DeviceType> RES_DEVICE_TYPE = {
60     { "phone", DeviceType::PHONE },
61     { "tablet", DeviceType::TABLET },
62     { "tv", DeviceType::TV },
63     { "wearable", DeviceType::WATCH },
64 };
65 
66 const std::unordered_map<std::string, ScreenShape> RES_SCREEN_SHAPE = {
67     { "round", ScreenShape::ROUND },
68     { "notround", ScreenShape::NOT_ROUND },
69 };
70 
71 const std::unordered_map<std::string, LongScreenType> RES_LONG_SCREEN = {
72     { "long", LongScreenType::LONG },
73     { "notlong", LongScreenType::NOT_LONG },
74 };
75 
76 }
77 
78 AceResKeyParser::AceResKeyParser() = default;
79 AceResKeyParser::~AceResKeyParser() = default;
80 
Parse(const std::string & deviceResConfigTag,std::vector<KeyParam> & keyParams,bool styleRes)81 bool AceResKeyParser::Parse(const std::string& deviceResConfigTag, std::vector<KeyParam> &keyParams, bool styleRes)
82 {
83     std::vector<std::string> keyParts;
84     StringUtils::StringSpliter(deviceResConfigTag, '-', keyParts);
85 
86     static parse_key_function functions[] = {
87         ParseMcc,
88         ParseMnc,
89         ParseOrientation,
90         ParseColorMode,
91         ParseDeviceType,
92         ParseResolution,
93         ParseDefaults,
94     };
95     const int32_t FUNC_LEN = static_cast<int32_t>(sizeof(functions) / sizeof(functions[0]));
96     if (!keyParts.empty()) {
97         if (!ParseMatch(keyParts, keyParams, functions, FUNC_LEN, styleRes)) {
98             LOGE("Invalid config:%{public}s", deviceResConfigTag.c_str());
99             return false;
100         }
101         return true;
102     }
103     return false;
104 }
105 
DeclarativeParse(const std::string & deviceResConfigTag,std::vector<KeyParam> & keyParams)106 bool AceResKeyParser::DeclarativeParse(const std::string& deviceResConfigTag, std::vector<KeyParam>& keyParams)
107 {
108     std::vector<std::string> reskeyParts;
109     std::string resConfigTag(deviceResConfigTag);
110     StringUtils::StringSpliter(resConfigTag, '-', reskeyParts);
111 
112     static parse_key_function functions[] = {
113         ParseLongScreen,
114         ParseScreenShape,
115         ParseOrientation,
116         ParseDeclarativeColorMode,
117         ParseDeviceType,
118         ParseResolution,
119         ParseDefaults,
120     };
121     const int32_t FUNC_LEN = static_cast<int32_t>(sizeof(functions) / sizeof(functions[0]));
122     if (!reskeyParts.empty()) {
123         if (!ParseMatch(reskeyParts, keyParams, functions, FUNC_LEN, true)) {
124             LOGE("Invalid config:%{public}s", resConfigTag.c_str());
125             return false;
126         }
127         return true;
128     }
129     return false;
130 }
131 
ParseMatch(const std::vector<std::string> & keys,std::vector<KeyParam> & keyParams,parse_key_function functions[],int32_t funcLen,bool styleRes) const132 bool AceResKeyParser::ParseMatch(const std::vector<std::string>& keys, std::vector<KeyParam> &keyParams,
133     parse_key_function functions[], int32_t funcLen, bool styleRes) const
134 {
135     for (auto iter = keys.begin(); iter != keys.end(); iter++) {
136         if (iter == keys.begin() && !styleRes) {
137             if (*iter == "res") {
138                 continue;
139             } else {
140                 LOGE("Invalid first key part:%{private}s", iter->c_str());
141                 return false;
142             }
143         }
144         bool parseRet = false;
145         for (int32_t k = 0; k < funcLen; k++) {
146             if (functions[k](*iter, keyParams)) {
147                 parseRet = true;
148                 break;
149             }
150         }
151         if (!parseRet) {
152             LOGE("Invalid key:%{private}s", iter->c_str());
153             return false;
154         }
155     }
156     return true;
157 }
158 
ParseMcc(const std::string & key,std::vector<KeyParam> & keyParams)159 bool AceResKeyParser::ParseMcc(const std::string& key, std::vector<KeyParam>& keyParams)
160 {
161     std::regex mcc("mcc(\\d{3})");
162     if (regex_match(key, mcc)) {
163         KeyParam keyParam;
164         keyParam.value = StringUtils::StringToInt(key.substr(MCC_MNC_KEYWORD_LEN));
165         keyParam.keyType = KeyType::MCC;
166         keyParams.emplace_back(keyParam);
167         return true;
168     }
169     return false;
170 }
171 
ParseMnc(const std::string & key,std::vector<KeyParam> & keyParams)172 bool AceResKeyParser::ParseMnc(const std::string& key, std::vector<KeyParam>& keyParams)
173 {
174     std::regex mnc("mnc(\\d{2,3})");
175     if (regex_match(key, mnc)) {
176         KeyParam keyParam;
177         keyParam.value = StringUtils::StringToInt(key.substr(MCC_MNC_KEYWORD_LEN));
178         if (key.substr(MCC_MNC_KEYWORD_LEN).length() == MCC_MNC_VALUE_LEN) {
179             keyParam.keyType = KeyType::MNC;
180         } else {
181             keyParam.keyType = KeyType::MNC_SHORT_LEN;
182         }
183         keyParams.emplace_back(keyParam);
184         return true;
185     }
186     return false;
187 }
188 
ParseScreenShape(const std::string & key,std::vector<KeyParam> & keyParams)189 bool AceResKeyParser::ParseScreenShape(const std::string& key, std::vector<KeyParam>& keyParams)
190 {
191     auto iter = RES_SCREEN_SHAPE.find(key);
192     if (iter != RES_SCREEN_SHAPE.end()) {
193         KeyParam keyParam;
194         keyParam.keyType = KeyType::SCREENSHAPE;
195         keyParam.value = static_cast<int32_t>(iter->second);
196         keyParams.emplace_back(keyParam);
197         return true;
198     }
199     return false;
200 }
201 
ParseLongScreen(const std::string & key,std::vector<KeyParam> & keyParams)202 bool AceResKeyParser::ParseLongScreen(const std::string& key, std::vector<KeyParam>& keyParams)
203 {
204     auto iter = RES_LONG_SCREEN.find(key);
205     if (iter != RES_LONG_SCREEN.end()) {
206         KeyParam keyParam;
207         keyParam.keyType = KeyType::LONGSCREEN;
208         keyParam.value = static_cast<int32_t>(iter->second);
209         keyParams.emplace_back(keyParam);
210         return true;
211     }
212     return false;
213 }
214 
ParseOrientation(const std::string & key,std::vector<KeyParam> & keyParams)215 bool AceResKeyParser::ParseOrientation(const std::string& key, std::vector<KeyParam>& keyParams)
216 {
217     auto iter = RES_ORIENTATION.find(key);
218     if (iter != RES_ORIENTATION.end()) {
219         KeyParam keyParam;
220         keyParam.keyType = KeyType::ORIENTATION;
221         keyParam.value = static_cast<int32_t>(iter->second);
222         keyParams.emplace_back(keyParam);
223         return true;
224     }
225     return false;
226 }
227 
ParseColorMode(const std::string & key,std::vector<KeyParam> & keyParams)228 bool AceResKeyParser::ParseColorMode(const std::string& key, std::vector<KeyParam>& keyParams)
229 {
230     auto iter = RES_COLOR_MODE.find(key);
231     if (iter != RES_COLOR_MODE.end()) {
232         KeyParam keyParam;
233         keyParam.keyType = KeyType::COLOR_MODE;
234         keyParam.value = static_cast<int32_t>(iter->second);
235         keyParams.emplace_back(keyParam);
236         return true;
237     }
238     return false;
239 }
240 
ParseDeclarativeColorMode(const std::string & key,std::vector<KeyParam> & keyParams)241 bool AceResKeyParser::ParseDeclarativeColorMode(const std::string& key, std::vector<KeyParam>& keyParams)
242 {
243     auto iter = DECLARATIVE_RES_COLOR_MODE.find(key);
244     if (iter != DECLARATIVE_RES_COLOR_MODE.end()) {
245         KeyParam keyParam;
246         keyParam.keyType = KeyType::DECLARATIVE_COLOR_MODE;
247         keyParam.value = static_cast<int32_t>(iter->second);
248         keyParams.emplace_back(keyParam);
249         return true;
250     }
251     return false;
252 }
253 
ParseDeviceType(const std::string & key,std::vector<KeyParam> & keyParams)254 bool AceResKeyParser::ParseDeviceType(const std::string& key, std::vector<KeyParam>& keyParams)
255 {
256     auto iter = RES_DEVICE_TYPE.find(key);
257     if (iter != RES_DEVICE_TYPE.end()) {
258         KeyParam keyParam;
259         keyParam.keyType = KeyType::DEVICETYPE;
260         keyParam.value = static_cast<int32_t>(iter->second);
261         keyParams.emplace_back(keyParam);
262         return true;
263     }
264     return false;
265 }
266 
ParseResolution(const std::string & key,std::vector<KeyParam> & keyParams)267 bool AceResKeyParser::ParseResolution(const std::string& key, std::vector<KeyParam>& keyParams)
268 {
269     auto iter = RES_RESOLUTION.find(key);
270     if (iter != RES_RESOLUTION.end()) {
271         KeyParam keyParam;
272         keyParam.keyType = KeyType::RESOLUTION;
273         keyParam.value = static_cast<int32_t>(iter->second);
274         keyParams.emplace_back(keyParam);
275         return true;
276     }
277     return false;
278 }
279 
ParseDefaults(const std::string & key,std::vector<KeyParam> & keyParams)280 bool AceResKeyParser::ParseDefaults(const std::string& key, std::vector<KeyParam>& keyParams)
281 {
282     return key == "defaults" || key == "default";
283 }
284 
GetMccByValue(uint32_t value) const285 std::string AceResKeyParser::GetMccByValue(uint32_t value) const
286 {
287     char mccStr[MAX_MCC_MNC_LEN] = {0};
288     if (sprintf_s(mccStr, MAX_MCC_MNC_LEN, "mcc%03d", value) < 0) {
289         LOGE("output mcc exception");
290         return "";
291     }
292     return std::string(mccStr);
293 }
294 
GetMncShortLenByValue(uint32_t value) const295 std::string AceResKeyParser::GetMncShortLenByValue(uint32_t value) const
296 {
297     char mncStr[MAX_MCC_MNC_LEN] = {0};
298     if (sprintf_s(mncStr, MAX_MCC_MNC_LEN, "mnc%02d", value) < 0) {
299         LOGE("output mnc short len exception");
300         return "";
301     }
302     return std::string(mncStr);
303 }
304 
GetMncByValue(uint32_t value) const305 std::string AceResKeyParser::GetMncByValue(uint32_t value) const
306 {
307     char mncStr[MAX_MCC_MNC_LEN] = {0};
308     if (sprintf_s(mncStr, MAX_MCC_MNC_LEN, "mnc%03d", value) < 0) {
309         LOGE("output mnc len exception");
310         return "";
311     }
312     return std::string(mncStr);
313 }
314 
GetOrientationByType(DeviceOrientation type) const315 std::string AceResKeyParser::GetOrientationByType(DeviceOrientation type) const
316 {
317     auto item = find_if(RES_ORIENTATION.begin(), RES_ORIENTATION.end(),
318                         [type](auto iter) { return iter.second == type; });
319     if (item != RES_ORIENTATION.end()) {
320         return item->first;
321     }
322     return "";
323 }
324 
GetColorModeByType(ColorMode type) const325 std::string AceResKeyParser::GetColorModeByType(ColorMode type) const
326 {
327     auto item = find_if(RES_COLOR_MODE.begin(), RES_COLOR_MODE.end(),
328                         [type](auto iter) { return iter.second == type; });
329     if (item != RES_COLOR_MODE.end()) {
330         return item->first;
331     }
332     return "";
333 }
334 
GetDeclarativeColorModeByType(ColorMode type) const335 std::string AceResKeyParser::GetDeclarativeColorModeByType(ColorMode type) const
336 {
337     auto item = find_if(DECLARATIVE_RES_COLOR_MODE.begin(), DECLARATIVE_RES_COLOR_MODE.end(),
338                         [type](auto iter) { return iter.second == type; });
339     if (item != DECLARATIVE_RES_COLOR_MODE.end()) {
340         return item->first;
341     }
342     return "";
343 }
344 
GetDeviceByType(DeviceType type) const345 std::string AceResKeyParser::GetDeviceByType(DeviceType type) const
346 {
347     auto deviceTypeItem = find_if(RES_DEVICE_TYPE.begin(), RES_DEVICE_TYPE.end(),
348                                   [type](auto iter) { return iter.second == type; });
349     if (deviceTypeItem != RES_DEVICE_TYPE.end()) {
350         return deviceTypeItem->first;
351     }
352     return "";
353 }
354 
GetResolutionByType(ResolutionType type) const355 std::string AceResKeyParser::GetResolutionByType(ResolutionType type) const
356 {
357     auto resolutionItem = find_if(RES_RESOLUTION.begin(), RES_RESOLUTION.end(),
358                                   [type](auto iter) { return iter.second == type; });
359     if (resolutionItem != RES_RESOLUTION.end()) {
360         return resolutionItem->first;
361     }
362     return "";
363 }
GetScreenShapeByType(ScreenShape type) const364 std::string AceResKeyParser::GetScreenShapeByType(ScreenShape type) const
365 {
366     auto shapeItem = find_if(RES_SCREEN_SHAPE.begin(), RES_SCREEN_SHAPE.end(),
367         [type](auto iter) { return iter.second == type; });
368     if (shapeItem != RES_SCREEN_SHAPE.end()) {
369         return shapeItem->first;
370     }
371     return "";
372 }
373 
GetScreenLongByType(LongScreenType type) const374 std::string AceResKeyParser::GetScreenLongByType(LongScreenType type) const
375 {
376     auto longItem = find_if(RES_LONG_SCREEN.begin(), RES_LONG_SCREEN.end(),
377         [type](auto iter) { return iter.second == type; });
378     if (longItem != RES_LONG_SCREEN.end()) {
379         return longItem->first;
380     }
381     return "";
382 }
383 
384 } // namespace OHOS::Ace