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