1 /*
2 * Copyright (c) 2023 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 "select_compile_parse.h"
17 #include <algorithm>
18 #include "key_parser.h"
19 #include "cmd_parser.h"
20 #include "resource_util.h"
21
22 namespace OHOS {
23 namespace Global {
24 namespace Restool {
25 using namespace std;
26 vector<Mccmnc> SelectCompileParse::mccmncArray_ = {};
27 vector<Locale> SelectCompileParse::localeArray_ = {};
28
29 // eg: Device[ phone, car ];ColorMode[ dark ]
ParseTargetConfig(const string &limitParams, TargetConfig &targetConfig)30 bool SelectCompileParse::ParseTargetConfig(const string &limitParams, TargetConfig &targetConfig)
31 {
32 vector<string> limitArray;
33 ResourceUtil::Split(limitParams, limitArray, ";");
34 if (limitArray.empty()) {
35 return false;
36 }
37 for (auto &it : limitArray) {
38 vector<string> limit;
39 ResourceUtil::Split(it, limit, "[");
40 if (limit.size() != 2) { // 2 means the size of the valid parameter after split by '['
41 return false;
42 }
43 ResourceUtil::RemoveSpaces(limit.back());
44 if (limit.size() < 2 || limit.back().back() != ']') { // 2 means characters other than ']'
45 return false;
46 }
47 limit.back().pop_back();
48 vector<string> limitValues;
49 ResourceUtil::Split(limit.back(), limitValues, ",");
50 if (limitValues.empty()) {
51 return false;
52 }
53 auto &limitType = limit.front();
54 ResourceUtil::RemoveSpaces(limitType);
55 transform(limitType.begin(), limitType.end(), limitType.begin(), ::tolower);
56 if (!KeyParser::ParseLimit(limitType, limitValues, targetConfig)) {
57 return false;
58 }
59 }
60 return true;
61 }
62
IsSelectCompile(vector<KeyParam> &keyParams)63 bool SelectCompileParse::IsSelectCompile(vector<KeyParam> &keyParams)
64 {
65 if (keyParams.empty()) {
66 return true;
67 }
68 auto &cmdParser = CmdParser<PackageParser>::GetInstance().GetCmdParser();
69 bool isTtargetConfig = cmdParser.IsTargetConfig();
70 if (!isTtargetConfig) {
71 return true;
72 }
73 TargetConfig targetConfig = cmdParser.GetTargetConfigValues();
74 map<KeyType, function<bool(size_t &)>> selectableFuncMatch {
75 {KeyType::MCC, bind(&IsSelectableMccmnc, keyParams, placeholders::_1, targetConfig.mccmnc)},
76 {KeyType::LANGUAGE, bind(&IsSelectableLocale, keyParams, placeholders::_1, targetConfig.locale)},
77 {KeyType::ORIENTATION, bind(&IsSelectableOther, keyParams, placeholders::_1, targetConfig.orientation)},
78 {KeyType::DEVICETYPE, bind(&IsSelectableOther, keyParams, placeholders::_1, targetConfig.device)},
79 {KeyType::NIGHTMODE, bind(&IsSelectableOther, keyParams, placeholders::_1, targetConfig.colormode)},
80 {KeyType::RESOLUTION, bind(&IsSelectableOther, keyParams, placeholders::_1, targetConfig.density)},
81 };
82 for (size_t index = 0; index < keyParams.size(); index++) {
83 auto iter = selectableFuncMatch.find(keyParams[index].keyType);
84 if (iter == selectableFuncMatch.end()) {
85 continue;
86 }
87 if (!iter->second(index)) {
88 return false;
89 }
90 }
91 return true;
92 }
93
94 // {KeyType::OTHER, 0} indicates that the default value is equal to null
InitMccmnc(vector<KeyParam> &limit)95 void SelectCompileParse::InitMccmnc(vector<KeyParam> &limit)
96 {
97 if (!mccmncArray_.empty()) {
98 return;
99 }
100 for (size_t i = 0; i < limit.size(); i++) {
101 if (limit[i].keyType == KeyType::MCC) {
102 mccmncArray_.push_back({limit[i], {KeyType::OTHER, 0}});
103 }
104 if (limit[i].keyType == KeyType::MNC) {
105 mccmncArray_.back().mnc = limit[i];
106 }
107 }
108 }
109
IsSelectableMccmnc(vector<KeyParam> &keyParams, size_t &index, vector<KeyParam> &limit)110 bool SelectCompileParse::IsSelectableMccmnc(vector<KeyParam> &keyParams, size_t &index, vector<KeyParam> &limit)
111 {
112 if (limit.empty()) {
113 return true;
114 }
115 Mccmnc mccmncLimit({keyParams[index++], {KeyType::OTHER, 0}});
116 if (index < keyParams.size() && keyParams[index].keyType == KeyType::MNC) {
117 mccmncLimit.mnc = keyParams[index];
118 } else {
119 index--;
120 }
121 InitMccmnc(limit);
122 return find(mccmncArray_.begin(), mccmncArray_.end(), mccmncLimit) != mccmncArray_.end();
123 }
124
InitLocale(vector<KeyParam> &limit)125 void SelectCompileParse::InitLocale(vector<KeyParam> &limit)
126 {
127 if (!localeArray_.empty()) {
128 return;
129 }
130 for (size_t i = 0; i < limit.size(); i++) {
131 if (limit[i].keyType == KeyType::LANGUAGE) {
132 localeArray_.push_back({limit[i], {KeyType::OTHER, 0},
133 {KeyType::OTHER, 0}});
134 }
135 if (limit[i].keyType == KeyType::SCRIPT) {
136 localeArray_.back().script = limit[i];
137 }
138 if (limit[i].keyType == KeyType::REGION) {
139 localeArray_.back().region = limit[i];
140 }
141 }
142 }
143
IsSelectableLocale(vector<KeyParam> &keyParams, size_t &index, vector<KeyParam> &limit)144 bool SelectCompileParse::IsSelectableLocale(vector<KeyParam> &keyParams, size_t &index, vector<KeyParam> &limit)
145 {
146 if (limit.empty()) {
147 return true;
148 }
149 Locale localeLimit({keyParams[index++], {KeyType::OTHER, 0}, {KeyType::OTHER, 0}});
150 for (; index < keyParams.size(); index++) {
151 if (keyParams[index].keyType == KeyType::SCRIPT) {
152 localeLimit.script = keyParams[index];
153 continue;
154 }
155 if (keyParams[index].keyType == KeyType::REGION) {
156 localeLimit.region = keyParams[index];
157 break;
158 }
159 index--;
160 break;
161 }
162 InitLocale(limit);
163 return find(localeArray_.begin(), localeArray_.end(), localeLimit) != localeArray_.end();
164 }
165
IsSelectableOther(vector<KeyParam> &keyParams, size_t &index, vector<KeyParam> &limit)166 bool SelectCompileParse::IsSelectableOther(vector<KeyParam> &keyParams, size_t &index, vector<KeyParam> &limit)
167 {
168 if (limit.empty()) {
169 return true;
170 }
171 return find(limit.begin(), limit.end(), keyParams[index]) != limit.end();
172 }
173
174 }
175 }
176 }
177