• 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 "key_parser.h"
17 #include <regex>
18 #include "resource_util.h"
19 
20 namespace OHOS {
21 namespace Global {
22 namespace Restool {
23 using namespace std;
24 map<string, vector<KeyParam>> KeyParser::caches_ = {};
Parse(const string & folderName,vector<KeyParam> & keyparams)25 bool KeyParser::Parse(const string &folderName, vector<KeyParam> &keyparams)
26 {
27     if (folderName == "base") {
28         return true;
29     }
30 
31     if (caches_.count(folderName) != 0) {
32         keyparams = caches_[folderName];
33         return true;
34     }
35     vector<string> keyParts;
36     ResourceUtil::Split(folderName, keyParts, "-");
37 
38     vector<parse_key_founction> founctions = {
39         ParseMccMnc,
40         ParseLSR,
41         ParseOrientation,
42         ParseDeviceType,
43         ParseNightMode,
44         ParseInputDevice,
45         ParseResolution,
46     };
47 
48     if (!ParseMatch(keyParts, keyparams, founctions)) {
49         return false;
50     }
51     caches_.emplace(folderName, keyparams);
52     return true;
53 }
54 
ParseMatch(const vector<string> & keys,vector<KeyParam> & keyparams,const vector<parse_key_founction> & founctions)55 bool KeyParser::ParseMatch(const vector<string> &keys,
56     vector<KeyParam> &keyparams, const vector<parse_key_founction> &founctions)
57 {
58     size_t next = 0;
59     for (const auto &key : keys) {
60         bool parseMatch = false;
61         for (size_t i = next; i < founctions.size(); i++) {
62             if (founctions[i](key, keyparams)) {
63                 parseMatch = true;
64                 next = i;
65                 break;
66             }
67         }
68 
69         if (!parseMatch) {
70             return false;
71         }
72     }
73     return true;
74 }
75 
ParseLimit(const string & func,std::vector<std::string> & limitValues,TargetConfig & targetConfig)76 bool KeyParser::ParseLimit(const string &func, std::vector<std::string> &limitValues,
77     TargetConfig &targetConfig)
78 {
79     map<string, function<bool(const string &)>> parseLimitFunc {
80         {"mccmnc", [&targetConfig](const string &limitValue) { return ParseMccMnc(limitValue,
81             targetConfig.mccmnc); }},
82         {"locale", [&targetConfig](const string &limitValue) { return ParseLSR(limitValue,
83             targetConfig.locale); }},
84         {"orientation", [&targetConfig](const string &limitValue) { return ParseOrientation(limitValue,
85             targetConfig.orientation); }},
86         {"device", [&targetConfig](const string &limitValue) { return ParseDeviceType(limitValue,
87             targetConfig.device); }},
88         {"colormode", [&targetConfig](const string &limitValue) { return ParseNightMode(limitValue,
89             targetConfig.colormode); }},
90         {"density", [&targetConfig](const string &limitValue) { return ParseResolution(limitValue,
91             targetConfig.density); }}
92     };
93 
94     auto iter = parseLimitFunc.find(func);
95     if (iter == parseLimitFunc.end()) {
96         return false;
97     }
98     for (auto &limitValue : limitValues) {
99         ResourceUtil::RemoveSpaces(limitValue);
100         if (!iter->second(limitValue)) {
101             return false;
102         }
103     }
104     return true;
105 }
106 
ParseMatchBySeq(const vector<string> & keys,vector<KeyParam> & keyparams,const vector<parse_key_founction> & founctions)107 bool KeyParser::ParseMatchBySeq(const vector<string> &keys,
108     vector<KeyParam> &keyparams, const vector<parse_key_founction> &founctions)
109 {
110     for (size_t i = 0; i < keys.size(); i++) {
111         if (!founctions[i](keys[i], keyparams)) {
112             return false;
113         }
114     }
115     return true;
116 }
117 
ParseMccMnc(const string & folderName,vector<KeyParam> & keyparams)118 bool KeyParser::ParseMccMnc(const string &folderName, vector<KeyParam> &keyparams)
119 {
120     vector<parse_key_founction> founctions = {
121         ParseMcc,
122         ParseMnc,
123     };
124 
125     vector<string> keyParts;
126     ResourceUtil::Split(folderName, keyParts, "_");
127     if (keyParts.size() > founctions.size()) {
128         return false;
129     }
130     return ParseMatchBySeq(keyParts, keyparams, founctions);
131 }
132 
ParseMcc(const string & folderName,vector<KeyParam> & keyparams)133 bool KeyParser::ParseMcc(const string &folderName, vector<KeyParam> &keyparams)
134 {
135     regex mcc("mcc(\\d{3})");
136     if (!regex_match(folderName, mcc)) {
137         return false;
138     }
139 
140     PushMccMnc(folderName, KeyType::MCC, keyparams);
141     return true;
142 }
143 
ParseMnc(const string & folderName,vector<KeyParam> & keyparams)144 bool KeyParser::ParseMnc(const string &folderName, vector<KeyParam> &keyparams)
145 {
146     regex mcc("mnc(\\d{2,3})");
147     if (!regex_match(folderName, mcc)) {
148         return false;
149     }
150 
151     PushMccMnc(folderName, KeyType::MNC, keyparams);
152     return true;
153 }
154 
ParseLSR(const string & folderName,vector<KeyParam> & keyparams)155 bool KeyParser::ParseLSR(const string &folderName, vector<KeyParam> &keyparams)
156 {
157     map<string, vector<parse_key_founction>> founctionModels = {
158         { "all", { ParseLanguage, ParseScript, ParseRegion } },
159         { "language script", { ParseLanguage, ParseScript} },
160         { "language region", { ParseLanguage, ParseRegion } },
161     };
162 
163     vector<string> keyParts;
164     ResourceUtil::Split(folderName, keyParts, "_");
165     if (keyParts.size() > founctionModels["all"].size()) {
166         return false;
167     }
168 
169     for (auto model : founctionModels) {
170         vector<KeyParam> tmp;
171         if (ParseMatchBySeq(keyParts, tmp, model.second)) {
172             keyparams.insert(keyparams.end(), tmp.begin(), tmp.end());
173             return true;
174         }
175     }
176     return false;
177 }
178 
ParseLanguage(const string & folderName,vector<KeyParam> & keyparams)179 bool KeyParser::ParseLanguage(const string &folderName, vector<KeyParam> &keyparams)
180 {
181     if (g_deviceMap.find(folderName) != g_deviceMap.end()) {
182         return false;
183     }
184 
185     regex language("[a-z]{2,3}");
186     if (!regex_match(folderName, language)) {
187         return false;
188     }
189 
190     PushLSR(folderName, KeyType::LANGUAGE, keyparams);
191     return true;
192 }
193 
ParseScript(const string & folderName,vector<KeyParam> & keyparams)194 bool KeyParser::ParseScript(const string &folderName, vector<KeyParam> &keyparams)
195 {
196     if (folderName.length() != SCRIPT_LENGHT) {
197         return false;
198     }
199 
200     regex script("^[A-Z][a-z]{3}");
201     if (!regex_match(folderName, script)) {
202         return false;
203     }
204 
205     PushLSR(folderName, KeyType::SCRIPT, keyparams);
206     return true;
207 }
208 
ParseRegion(const string & folderName,vector<KeyParam> & keyparams)209 bool KeyParser::ParseRegion(const string &folderName, vector<KeyParam> &keyparams)
210 {
211     if (folderName.length() < MIN_REGION_LENGHT || folderName.length() > MAX_REGION_LENGHT) {
212         return false;
213     }
214 
215     regex regionOfNumber("[0-9]{3}");
216     regex regionOfSupper("[A-Z]{2,3}");
217 
218     if (!regex_match(folderName, regionOfNumber) && !regex_match(folderName, regionOfSupper)) {
219         return false;
220     }
221 
222     PushLSR(folderName, KeyType::REGION, keyparams);
223     return true;
224 }
225 
ParseOrientation(const string & folderName,vector<KeyParam> & keyparams)226 bool KeyParser::ParseOrientation(const string &folderName, vector<KeyParam> &keyparams)
227 {
228     auto it = g_orientaionMap.find(folderName);
229     if (it == g_orientaionMap.end()) {
230         return false;
231     }
232 
233     PushValue(static_cast<uint32_t>(it->second), KeyType::ORIENTATION, keyparams);
234     return true;
235 }
236 
ParseDeviceType(const string & folderName,vector<KeyParam> & keyparams)237 bool KeyParser::ParseDeviceType(const string &folderName, vector<KeyParam> &keyparams)
238 {
239     auto it = g_deviceMap.find(folderName);
240     if (it == g_deviceMap.end()) {
241         return false;
242     }
243 
244     PushValue(static_cast<uint32_t>(it->second), KeyType::DEVICETYPE, keyparams);
245     return true;
246 }
247 
ParseNightMode(const string & folderName,vector<KeyParam> & keyparams)248 bool KeyParser::ParseNightMode(const string &folderName, vector<KeyParam> &keyparams)
249 {
250     auto it = g_nightModeMap.find(folderName);
251     if (it == g_nightModeMap.end()) {
252         return false;
253     }
254 
255     PushValue(static_cast<uint32_t>(it->second), KeyType::NIGHTMODE, keyparams);
256     return true;
257 }
258 
ParseInputDevice(const string & folderName,vector<KeyParam> & keyparams)259 bool KeyParser::ParseInputDevice(const string &folderName, vector<KeyParam> &keyparams)
260 {
261     auto it = g_inputDeviceMap.find(folderName);
262     if (it == g_inputDeviceMap.end()) {
263         return false;
264     }
265 
266     PushValue(static_cast<uint32_t>(it->second), KeyType::INPUTDEVICE, keyparams);
267     return true;
268 }
269 
ParseResolution(const string & folderName,vector<KeyParam> & keyparams)270 bool KeyParser::ParseResolution(const string &folderName, vector<KeyParam> &keyparams)
271 {
272     auto it = g_resolutionMap.find(folderName);
273     if (it == g_resolutionMap.end()) {
274         return false;
275     }
276 
277     PushValue(static_cast<uint32_t>(it->second), KeyType::RESOLUTION, keyparams);
278     return true;
279 }
280 
PushMccMnc(const string & folderName,KeyType type,vector<KeyParam> & keyparams)281 void KeyParser::PushMccMnc(const string &folderName, KeyType type, vector<KeyParam> &keyparams)
282 {
283     KeyParam keyParam;
284     keyParam.keyType = type;
285     keyParam.value = static_cast<uint32_t>(atoi(folderName.substr(MCC_MNC_KEY_LENGHT).c_str()));
286     keyparams.push_back(keyParam);
287 }
288 
PushLSR(const string & folderName,KeyType type,vector<KeyParam> & keyparams)289 void KeyParser::PushLSR(const string &folderName, KeyType type, vector<KeyParam> &keyparams)
290 {
291     KeyParam keyParam;
292     keyParam.keyType = type;
293     keyParam.value = 0;
294     for (size_t i = 0; i < folderName.size(); i++) {
295         keyParam.value = (keyParam.value << 8) | (folderName[i] & 0xff); // Move 8 bits to the left
296     }
297     keyparams.push_back(keyParam);
298 }
299 
PushValue(uint32_t value,KeyType type,vector<KeyParam> & keyparams)300 void KeyParser::PushValue(uint32_t value, KeyType type, vector<KeyParam> &keyparams)
301 {
302     KeyParam keyParam;
303     keyParam.keyType = type;
304     keyParam.value = value;
305     keyparams.push_back(keyParam);
306 }
307 }
308 }
309 }
310