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