• 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 
ParseMatchBySeq(const vector<string> & keys,vector<KeyParam> & keyparams,const vector<parse_key_founction> & founctions)76 bool KeyParser::ParseMatchBySeq(const vector<string> &keys,
77     vector<KeyParam> &keyparams, const vector<parse_key_founction> &founctions)
78 {
79     for (size_t i = 0; i < keys.size(); i++) {
80         if (!founctions[i](keys[i], keyparams)) {
81             return false;
82         }
83     }
84     return true;
85 }
86 
ParseMccMnc(const string & folderName,vector<KeyParam> & keyparams)87 bool KeyParser::ParseMccMnc(const string &folderName, vector<KeyParam> &keyparams)
88 {
89     vector<parse_key_founction> founctions = {
90         ParseMcc,
91         ParseMnc,
92     };
93 
94     vector<string> keyParts;
95     ResourceUtil::Split(folderName, keyParts, "_");
96     if (keyParts.size() > founctions.size()) {
97         return false;
98     }
99     return ParseMatchBySeq(keyParts, keyparams, founctions);
100 }
101 
ParseMcc(const string & folderName,vector<KeyParam> & keyparams)102 bool KeyParser::ParseMcc(const string &folderName, vector<KeyParam> &keyparams)
103 {
104     regex mcc("mcc(\\d{3})");
105     if (!regex_match(folderName, mcc)) {
106         return false;
107     }
108 
109     PushMccMnc(folderName, KeyType::MCC, keyparams);
110     return true;
111 }
112 
ParseMnc(const string & folderName,vector<KeyParam> & keyparams)113 bool KeyParser::ParseMnc(const string &folderName, vector<KeyParam> &keyparams)
114 {
115     regex mcc("mnc(\\d{2,3})");
116     if (!regex_match(folderName, mcc)) {
117         return false;
118     }
119 
120     PushMccMnc(folderName, KeyType::MNC, keyparams);
121     return true;
122 }
123 
ParseLSR(const string & folderName,vector<KeyParam> & keyparams)124 bool KeyParser::ParseLSR(const string &folderName, vector<KeyParam> &keyparams)
125 {
126     map<string, vector<parse_key_founction>> founctionModels = {
127         { "all", { ParseLanguage, ParseScript, ParseRegion } },
128         { "language script", { ParseLanguage, ParseScript} },
129         { "language region", { ParseLanguage, ParseRegion } },
130     };
131 
132     vector<string> keyParts;
133     ResourceUtil::Split(folderName, keyParts, "_");
134     if (keyParts.size() > founctionModels["all"].size()) {
135         return false;
136     }
137 
138     for (auto model : founctionModels) {
139         vector<KeyParam> tmp;
140         if (ParseMatchBySeq(keyParts, tmp, model.second)) {
141             keyparams.insert(keyparams.end(), tmp.begin(), tmp.end());
142             return true;
143         }
144     }
145     return false;
146 }
147 
ParseLanguage(const string & folderName,vector<KeyParam> & keyparams)148 bool KeyParser::ParseLanguage(const string &folderName, vector<KeyParam> &keyparams)
149 {
150     if (g_deviceMap.find(folderName) != g_deviceMap.end()) {
151         return false;
152     }
153 
154     regex language("[a-z]{2,3}");
155     if (!regex_match(folderName, language)) {
156         return false;
157     }
158 
159     PushLSR(folderName, KeyType::LANGUAGE, keyparams);
160     return true;
161 }
162 
ParseScript(const string & folderName,vector<KeyParam> & keyparams)163 bool KeyParser::ParseScript(const string &folderName, vector<KeyParam> &keyparams)
164 {
165     if (folderName.length() != SCRIPT_LENGHT) {
166         return false;
167     }
168 
169     regex script("^[A-Z][a-z]{3}");
170     if (!regex_match(folderName, script)) {
171         return false;
172     }
173 
174     PushLSR(folderName, KeyType::SCRIPT, keyparams);
175     return true;
176 }
177 
ParseRegion(const string & folderName,vector<KeyParam> & keyparams)178 bool KeyParser::ParseRegion(const string &folderName, vector<KeyParam> &keyparams)
179 {
180     if (folderName.length() < MIN_REGION_LENGHT || folderName.length() > MAX_REGION_LENGHT) {
181         return false;
182     }
183 
184     regex regionOfNumber("[0-9]{3}");
185     regex regionOfSupper("[A-Z]{2,3}");
186 
187     if (!regex_match(folderName, regionOfNumber) && !regex_match(folderName, regionOfSupper)) {
188         return false;
189     }
190 
191     PushLSR(folderName, KeyType::REGION, keyparams);
192     return true;
193 }
194 
ParseOrientation(const string & folderName,vector<KeyParam> & keyparams)195 bool KeyParser::ParseOrientation(const string &folderName, vector<KeyParam> &keyparams)
196 {
197     auto it = g_orientaionMap.find(folderName);
198     if (it == g_orientaionMap.end()) {
199         return false;
200     }
201 
202     PushValue(static_cast<uint32_t>(it->second), KeyType::ORIENTATION, keyparams);
203     return true;
204 }
205 
ParseDeviceType(const string & folderName,vector<KeyParam> & keyparams)206 bool KeyParser::ParseDeviceType(const string &folderName, vector<KeyParam> &keyparams)
207 {
208     auto it = g_deviceMap.find(folderName);
209     if (it == g_deviceMap.end()) {
210         return false;
211     }
212 
213     PushValue(static_cast<uint32_t>(it->second), KeyType::DEVICETYPE, keyparams);
214     return true;
215 }
216 
ParseNightMode(const string & folderName,vector<KeyParam> & keyparams)217 bool KeyParser::ParseNightMode(const string &folderName, vector<KeyParam> &keyparams)
218 {
219     auto it = g_nightModeMap.find(folderName);
220     if (it == g_nightModeMap.end()) {
221         return false;
222     }
223 
224     PushValue(static_cast<uint32_t>(it->second), KeyType::NIGHTMODE, keyparams);
225     return true;
226 }
227 
ParseInputDevice(const string & folderName,vector<KeyParam> & keyparams)228 bool KeyParser::ParseInputDevice(const string &folderName, vector<KeyParam> &keyparams)
229 {
230     auto it = g_inputDeviceMap.find(folderName);
231     if (it == g_inputDeviceMap.end()) {
232         return false;
233     }
234 
235     PushValue(static_cast<uint32_t>(it->second), KeyType::INPUTDEVICE, keyparams);
236     return true;
237 }
238 
ParseResolution(const string & folderName,vector<KeyParam> & keyparams)239 bool KeyParser::ParseResolution(const string &folderName, vector<KeyParam> &keyparams)
240 {
241     auto it = g_resolutionMap.find(folderName);
242     if (it == g_resolutionMap.end()) {
243         return false;
244     }
245 
246     PushValue(static_cast<uint32_t>(it->second), KeyType::RESOLUTION, keyparams);
247     return true;
248 }
249 
PushMccMnc(const string & folderName,KeyType type,vector<KeyParam> & keyparams)250 void KeyParser::PushMccMnc(const string &folderName, KeyType type, vector<KeyParam> &keyparams)
251 {
252     KeyParam keyParam;
253     keyParam.keyType = type;
254     keyParam.value = atoi(folderName.substr(MCC_MNC_KEY_LENGHT).c_str());
255     keyparams.push_back(keyParam);
256 }
257 
PushLSR(const string & folderName,KeyType type,vector<KeyParam> & keyparams)258 void KeyParser::PushLSR(const string &folderName, KeyType type, vector<KeyParam> &keyparams)
259 {
260     KeyParam keyParam;
261     keyParam.keyType = type;
262     keyParam.value = 0;
263     for (size_t i = 0; i < folderName.size(); i++) {
264         keyParam.value = (keyParam.value << 8) | (folderName[i] & 0xff);
265     }
266     keyparams.push_back(keyParam);
267 }
268 
PushValue(uint32_t value,KeyType type,vector<KeyParam> & keyparams)269 void KeyParser::PushValue(uint32_t value, KeyType type, vector<KeyParam> &keyparams)
270 {
271     KeyParam keyParam;
272     keyParam.keyType = type;
273     keyParam.value = value;
274     keyparams.push_back(keyParam);
275 }
276 }
277 }
278 }
279