1 /*
2  * Copyright (c) 2021-2022 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 #include "want_params_wrapper.h"
16 
17 #include <algorithm>
18 
19 namespace OHOS {
20 namespace AAFwk {
21 namespace {
FindMatchingBrackets(const std::string & str,size_t leftIndex)22 size_t FindMatchingBrackets(const std::string &str, size_t leftIndex)
23 {
24     int count = 0;
25     for (size_t i = leftIndex + 1; i < str.size(); ++i) {
26         if (str[i] == '{') {
27             count++;
28         } else if (str[i] == '}') {
29             if (count == 0) {
30                 return i;
31             }
32             count--;
33         }
34     }
35     return -1;
36 }
37 }
38 constexpr int32_t WANT_PARAM_WRAPPER_TWO = 2;
39 
40 IINTERFACE_IMPL_1(WantParamWrapper, Object, IWantParams);
41 const InterfaceID g_IID_IWantParams = {
42     0xa75b9db6, 0x9813, 0x4371, 0x8848, {0xd, 0x2, 0x9, 0x6, 0x6, 0xc, 0xe, 0x6, 0xe, 0xc, 0x6, 0x8}
43 };
GetValue(WantParams & value)44 ErrCode WantParamWrapper::GetValue(WantParams &value)
45 {
46     value = wantParams_;
47     return ERR_OK;
48 }
49 
Equals(IObject & other)50 bool WantParamWrapper::Equals(IObject &other)
51 {
52     WantParamWrapper *otherObj = static_cast<WantParamWrapper *>(IWantParams::Query(&other));
53     return otherObj != nullptr && otherObj->wantParams_ == wantParams_;
54 }
55 
ToString()56 std::string WantParamWrapper::ToString()
57 {
58     std::string result;
59     if (wantParams_.Size() != 0) {
60         result += "{";
61         for (auto it : wantParams_.GetParams()) {
62             int typeId = WantParams::GetDataType(it.second);
63             result = result + "\"" + it.first + "\":{\"" + std::to_string(typeId) + "\":";
64             if (IWantParams::Query(it.second) != nullptr) {
65                 result = result + static_cast<WantParamWrapper *>(IWantParams::Query(it.second))->ToString();
66             } else {
67                 result = result + "\"" + WantParams::GetStringByType(it.second, typeId) + "\"";
68             }
69             if (it == *wantParams_.GetParams().rbegin()) {
70                 result += "}";
71             } else {
72                 result += "},";
73             }
74         }
75         result += "}";
76     } else {
77         result = "{}";
78     }
79     return result;
80 }
81 
Box(const WantParams & value)82 sptr<IWantParams> WantParamWrapper::Box(const WantParams &value)
83 {
84     sptr<IWantParams> object = new (std::nothrow)WantParamWrapper(value);
85     return object;
86 }
87 
Box(WantParams && value)88 sptr<IWantParams> WantParamWrapper::Box(WantParams &&value)
89 {
90     sptr<IWantParams> object = new (std::nothrow) WantParamWrapper(std::move(value));
91     return object;
92 }
93 
Unbox(IWantParams * object)94 WantParams WantParamWrapper::Unbox(IWantParams *object)
95 {
96     WantParams value;
97     if (object != nullptr) {
98         object->GetValue(value);
99     }
100     return value;
101 }
ValidateStr(const std::string & str)102 bool WantParamWrapper::ValidateStr(const std::string &str)
103 {
104     if (str == "" || str == "{}" || str == "{\"\"}") {
105         return false;
106     }
107     if (count(str.begin(), str.end(), '\"') % WANT_PARAM_WRAPPER_TWO != 0) {
108         return false;
109     }
110     if (count(str.begin(), str.end(), '{') != count(str.begin(), str.end(), '}')) {
111         return false;
112     }
113     int count = 0;
114     for (auto it : str) {
115         if (it == '{') {
116             count++;
117         }
118         if (it == '}') {
119             count--;
120         }
121         if (count < 0) {
122             return false;
123         }
124     }
125     return true;
126 }
127 
Parse(const std::string & str)128 sptr<IWantParams> WantParamWrapper::Parse(const std::string &str)
129 {
130     WantParams wantParams;
131     std::string key = "";
132     int typeId = 0;
133     if (ValidateStr(str)) {
134         for (size_t strnum = 0; strnum < str.size(); strnum++) {
135             if (str[strnum] == '{' && key != "" && typeId == WantParams::VALUE_TYPE_WANTPARAMS) {
136                 size_t num;
137                 int count = 0;
138                 for (num = strnum; num < str.size(); num++) {
139                     if (str[num] == '{') {
140                         count++;
141                     } else if (str[num] == '}') {
142                         count--;
143                     }
144                     if (count == 0) {
145                         break;
146                     }
147                 }
148                 wantParams.SetParam(key, WantParamWrapper::Parse(str.substr(strnum, num - strnum + 1)));
149                 key = "";
150                 typeId = 0;
151                 strnum = num + 1;
152             } else if (str[strnum] == '"') {
153                 if (key == "") {
154                     strnum++;
155                     key = str.substr(strnum, str.find('"', strnum) - strnum);
156                     strnum = str.find('"', strnum);
157                 } else if (typeId == 0) {
158                     strnum++;
159                     typeId = atoi(str.substr(strnum, str.find('"', strnum) - strnum).c_str());
160                     if (errno == ERANGE) {
161                         return nullptr;
162                     }
163                     strnum = str.find('"', strnum);
164                 } else {
165                     strnum++;
166                     wantParams.SetParam(key,
167                         WantParams::GetInterfaceByType(typeId, str.substr(strnum, str.find('"', strnum) - strnum)));
168                     strnum = str.find('"', strnum);
169                     typeId = 0;
170                     key = "";
171                 }
172             }
173         }
174     }
175     sptr<IWantParams> iwantParams = new (std::nothrow) WantParamWrapper(wantParams);
176     return iwantParams;
177 }
178 
ParseWantParams(const std::string & str)179 WantParams WantParamWrapper::ParseWantParams(const std::string &str)
180 {
181     WantParams wantParams;
182     std::string key = "";
183     int typeId = 0;
184     if (!ValidateStr(str)) {
185         return wantParams;
186     }
187     for (size_t strnum = 0; strnum < str.size(); strnum++) {
188         if (str[strnum] == '{' && key != "" && typeId == WantParams::VALUE_TYPE_WANTPARAMS) {
189             size_t num;
190             int count = 0;
191             for (num = strnum; num < str.size(); num++) {
192                 if (str[num] == '{') {
193                     count++;
194                 } else if (str[num] == '}') {
195                     count--;
196                 }
197                 if (count == 0) {
198                     break;
199                 }
200             }
201             wantParams.SetParam(key, WantParamWrapper::Parse(str.substr(strnum, num - strnum)));
202             key = "";
203             typeId = 0;
204             strnum = num + 1;
205         } else if (str[strnum] == '"') {
206             if (key == "") {
207                 strnum++;
208                 key = str.substr(strnum, str.find('"', strnum) - strnum);
209                 strnum = str.find('"', strnum);
210             } else if (typeId == 0) {
211                 strnum++;
212                 typeId = atoi(str.substr(strnum, str.find('"', strnum) - strnum).c_str());
213                 if (errno == ERANGE) {
214                     return wantParams;
215                 }
216                 strnum = str.find('"', strnum);
217             } else {
218                 strnum++;
219                 wantParams.SetParam(key,
220                     WantParams::GetInterfaceByType(typeId, str.substr(strnum, str.find('"', strnum) - strnum)));
221                 strnum = str.find('"', strnum);
222                 typeId = 0;
223                 key = "";
224             }
225         }
226     }
227     return wantParams;
228 }
229 
ParseWantParamsWithBrackets(const std::string & str)230 WantParams WantParamWrapper::ParseWantParamsWithBrackets(const std::string &str)
231 {
232     WantParams wantParams;
233     std::string key = "";
234     int typeId = 0;
235     size_t type_index_before = 0;
236     if (!ValidateStr(str)) {
237         return wantParams;
238     }
239     for (size_t strnum = 0; strnum < str.size(); strnum++) {
240         if (str[strnum] == '{' && key != "" && typeId == WantParams::VALUE_TYPE_WANTPARAMS) {
241             size_t num;
242             int count = 0;
243             for (num = strnum; num < str.size(); num++) {
244                 if (str[num] == '{') {
245                     count++;
246                 } else if (str[num] == '}') {
247                     count--;
248                 }
249                 if (count == 0) {
250                     break;
251                 }
252             }
253             wantParams.SetParam(key, WantParamWrapper::Parse(str.substr(strnum, num - strnum + 1)));
254             key = "";
255             typeId = 0;
256             strnum = num + 1;
257         } else if (str[strnum] == '"') {
258             if (key == "") {
259                 strnum++;
260                 key = str.substr(strnum, str.find('"', strnum) - strnum);
261                 strnum = str.find('"', strnum);
262             } else if (typeId == 0) {
263                 type_index_before = strnum;
264                 strnum++;
265                 typeId = atoi(str.substr(strnum, str.find('"', strnum) - strnum).c_str());
266                 if (errno == ERANGE) {
267                     return wantParams;
268                 }
269                 strnum = str.find('"', strnum);
270             } else {
271                 strnum++;
272                 auto index = FindMatchingBrackets(str, type_index_before - 1);
273                 wantParams.SetParam(key,
274                     WantParams::GetInterfaceByType(typeId, str.substr(strnum, index - 1 - strnum)));
275                 strnum = index + 1;
276                 typeId = 0;
277                 key = "";
278             }
279         }
280     }
281     return wantParams;
282 }
283 }  // namespace AAFwk
284 }  // namespace OHOS