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 "ohos/aafwk/content/intent_params.h"
17
18 #include "ohos/aafwk/base/array_wrapper.h"
19 #include "ohos/aafwk/base/base_object.h"
20 #include "ohos/aafwk/base/bool_wrapper.h"
21 #include "ohos/aafwk/base/byte_wrapper.h"
22 #include "ohos/aafwk/base/short_wrapper.h"
23 #include "ohos/aafwk/base/int_wrapper.h"
24 #include "ohos/aafwk/base/long_wrapper.h"
25 #include "ohos/aafwk/base/float_wrapper.h"
26 #include "ohos/aafwk/base/double_wrapper.h"
27 #include "ohos/aafwk/base/string_wrapper.h"
28 #include "ohos/aafwk/base/zchar_wrapper.h"
29
30 #include "parcel.h"
31 #include "string_ex.h"
32
33 namespace OHOS {
34 namespace AAFwk {
35
SetParam(const std::string & key,IInterface * value)36 void IntentParams::SetParam(const std::string &key, IInterface *value)
37 {
38 params_[key] = value;
39 }
40
GetParam(const std::string & key) const41 sptr<IInterface> IntentParams::GetParam(const std::string &key) const
42 {
43 auto it = params_.find(key);
44 if (it == params_.cend()) {
45 return nullptr;
46 }
47 return it->second;
48 }
49
GetParams() const50 const std::map<std::string, sptr<IInterface>> &IntentParams::GetParams() const
51 {
52 return params_;
53 }
54
HasParam(const std::string & key) const55 bool IntentParams::HasParam(const std::string &key) const
56 {
57 return params_.count(key) > 0;
58 }
59
60 template<typename T1, typename T2, typename T3>
FillArray(IArray * ao,std::vector<T1> & array)61 static void FillArray(IArray *ao, std::vector<T1> &array)
62 {
63 auto func = [&](IInterface *object) { array.push_back(T2::Unbox(T3::Query(object))); };
64 Array::ForEach(ao, func);
65 }
66
WriteArrayToParcel(Parcel & parcel,IArray * ao) const67 bool IntentParams::WriteArrayToParcel(Parcel &parcel, IArray *ao) const
68 {
69 if (Array::IsStringArray(ao)) {
70 std::vector<std::u16string> array;
71 auto func = [&](IInterface *object) {
72 std::string s = String::Unbox(IString::Query(object));
73 array.push_back(Str8ToStr16(s));
74 };
75 Array::ForEach(ao, func);
76 if (!parcel.WriteInt32(VALUE_TYPE_STRINGARRAY)) {
77 return false;
78 }
79 if (!parcel.WriteString16Vector(array)) {
80 return false;
81 }
82 } else if (Array::IsBooleanArray(ao)) {
83 std::vector<int8_t> array;
84 FillArray<int8_t, Boolean, IBoolean>(ao, array);
85 if (!parcel.WriteInt32(VALUE_TYPE_BOOLEANARRAY)) {
86 return false;
87 }
88 if (!parcel.WriteInt8Vector(array)) {
89 return false;
90 }
91 } else if (Array::IsByteArray(ao)) {
92 std::vector<int8_t> array;
93 FillArray<int8_t, Byte, IByte>(ao, array);
94 if (!parcel.WriteInt32(VALUE_TYPE_BYTEARRAY)) {
95 return false;
96 }
97 if (!parcel.WriteInt8Vector(array)) {
98 return false;
99 }
100 } else if (Array::IsCharArray(ao)) {
101 std::vector<int32_t> array;
102 FillArray<int32_t, Char, IChar>(ao, array);
103 if (!parcel.WriteInt32(VALUE_TYPE_CHARARRAY)) {
104 return false;
105 }
106 if (!parcel.WriteInt32Vector(array)) {
107 return false;
108 }
109 } else if (Array::IsShortArray(ao)) {
110 std::vector<short> array;
111 FillArray<short, Short, IShort>(ao, array);
112 if (!parcel.WriteInt32(VALUE_TYPE_SHORTARRAY)) {
113 return false;
114 }
115 if (!parcel.WriteInt16Vector(array)) {
116 return false;
117 }
118 } else if (Array::IsIntegerArray(ao)) {
119 std::vector<int> array;
120 FillArray<int, Integer, IInteger>(ao, array);
121 if (!parcel.WriteInt32(VALUE_TYPE_INTARRAY)) {
122 return false;
123 }
124 if (!parcel.WriteInt32Vector(array)) {
125 return false;
126 }
127 } else if (Array::IsLongArray(ao)) {
128 std::vector<int64_t> array;
129 FillArray<int64_t, Long, ILong>(ao, array);
130 if (!parcel.WriteInt32(VALUE_TYPE_LONGARRAY)) {
131 return false;
132 }
133 if (!parcel.WriteInt64Vector(array)) {
134 return false;
135 }
136 } else if (Array::IsFloatArray(ao)) {
137 std::vector<float> array;
138 FillArray<float, Float, IFloat>(ao, array);
139 if (!parcel.WriteInt32(VALUE_TYPE_FLOATARRAY)) {
140 return false;
141 }
142 if (!parcel.WriteFloatVector(array)) {
143 return false;
144 }
145 } else if (Array::IsDoubleArray(ao)) {
146 std::vector<double> array;
147 FillArray<double, Double, IDouble>(ao, array);
148 if (!parcel.WriteInt32(VALUE_TYPE_DOUBLEARRAY)) {
149 return false;
150 }
151 if (!parcel.WriteDoubleVector(array)) {
152 return false;
153 }
154 }
155
156 return true;
157 }
158
Marshalling(Parcel & parcel) const159 bool IntentParams::Marshalling(Parcel &parcel) const
160 {
161 size_t size = params_.size();
162
163 if (!parcel.WriteInt32(size)) {
164 return false;
165 }
166
167 auto iter = params_.cbegin();
168 while (iter != params_.cend()) {
169 std::string key = iter->first;
170 sptr<IInterface> o = iter->second;
171 if (!parcel.WriteString16(Str8ToStr16(key))) {
172 return false;
173 }
174 if (IString::Query(o) != nullptr) {
175 std::string value = String::Unbox(IString::Query(o));
176 if (!parcel.WriteInt32(VALUE_TYPE_STRING)) {
177 return false;
178 }
179 if (!parcel.WriteString16(Str8ToStr16(value))) {
180 return false;
181 }
182 } else if (IBoolean::Query(o) != nullptr) {
183 bool value = Boolean::Unbox(IBoolean::Query(o));
184 if (!parcel.WriteInt32(VALUE_TYPE_BOOLEAN)) {
185 return false;
186 }
187 if (!parcel.WriteInt8(value)) {
188 return false;
189 }
190 } else if (IByte::Query(o) != nullptr) {
191 byte value = Byte::Unbox(IByte::Query(o));
192 if (!parcel.WriteInt32(VALUE_TYPE_BYTE)) {
193 return false;
194 }
195 if (!parcel.WriteInt8(value)) {
196 return false;
197 }
198 } else if (IChar::Query(o) != nullptr) {
199 zchar value = Char::Unbox(IChar::Query(o));
200 if (!parcel.WriteInt32(VALUE_TYPE_CHAR)) {
201 return false;
202 }
203 if (!parcel.WriteInt32(value)) {
204 return false;
205 }
206 } else if (IShort::Query(o) != nullptr) {
207 short value = Short::Unbox(IShort::Query(o));
208 if (!parcel.WriteInt32(VALUE_TYPE_SHORT)) {
209 return false;
210 }
211 if (!parcel.WriteInt16(value)) {
212 return false;
213 }
214 } else if (IInteger::Query(o) != nullptr) {
215 int value = Integer::Unbox(IInteger::Query(o));
216 if (!parcel.WriteInt32(VALUE_TYPE_INT)) {
217 return false;
218 }
219 if (!parcel.WriteInt32(value)) {
220 return false;
221 }
222 } else if (ILong::Query(o) != nullptr) {
223 long value = Long::Unbox(ILong::Query(o));
224 if (!parcel.WriteInt32(VALUE_TYPE_LONG)) {
225 return false;
226 }
227 if (!parcel.WriteInt64(value)) {
228 return false;
229 }
230 } else if (IFloat::Query(o) != nullptr) {
231 float value = Float::Unbox(IFloat::Query(o));
232 if (!parcel.WriteInt32(VALUE_TYPE_FLOAT)) {
233 return false;
234 }
235 if (!parcel.WriteFloat(value)) {
236 return false;
237 }
238 } else if (IDouble::Query(o) != nullptr) {
239 double value = Double::Unbox(IDouble::Query(o));
240 if (!parcel.WriteInt32(VALUE_TYPE_DOUBLE)) {
241 return false;
242 }
243 if (!parcel.WriteDouble(value)) {
244 return false;
245 }
246 } else {
247 IArray *ao = IArray::Query(o);
248 if (ao != nullptr && !WriteArrayToParcel(parcel, ao)) {
249 return false;
250 }
251 }
252 iter++;
253 }
254
255 return true;
256 }
257
258 template<typename T1, typename T2>
SetArray(const InterfaceID & id,const std::vector<T1> & value,sptr<IArray> & ao)259 static void SetArray(const InterfaceID &id, const std::vector<T1> &value, sptr<IArray> &ao)
260 {
261 typename std::vector<T1>::size_type size = value.size();
262 ao = new (std::nothrow) Array(size, id);
263 if (ao == nullptr) {
264 return;
265 }
266 for (typename std::vector<T1>::size_type i = 0; i < size; i++) {
267 ao->Set(i, T2::Box(value[i]));
268 }
269 }
270
ReadArrayToParcel(Parcel & parcel,int type,sptr<IArray> & ao)271 bool IntentParams::ReadArrayToParcel(Parcel &parcel, int type, sptr<IArray> &ao)
272 {
273 switch (type) {
274 case VALUE_TYPE_STRINGARRAY: {
275 std::vector<std::u16string> value;
276 if (!parcel.ReadString16Vector(&value)) {
277 return false;
278 }
279 std::vector<std::u16string>::size_type size = value.size();
280 ao = new (std::nothrow) Array(size, g_IID_IString);
281 if (ao == nullptr) {
282 return false;
283 }
284 for (std::vector<std::u16string>::size_type i = 0; i < size; i++) {
285 ao->Set(i, String::Box(Str16ToStr8(value[i])));
286 }
287 break;
288 }
289 case VALUE_TYPE_BOOLEANARRAY: {
290 std::vector<int8_t> value;
291 if (!parcel.ReadInt8Vector(&value)) {
292 return false;
293 }
294 SetArray<int8_t, Boolean>(g_IID_IBoolean, value, ao);
295 break;
296 }
297 case VALUE_TYPE_BYTEARRAY: {
298 std::vector<int8_t> value;
299 if (!parcel.ReadInt8Vector(&value)) {
300 return false;
301 }
302 SetArray<int8_t, Byte>(g_IID_IByte, value, ao);
303 break;
304 }
305 case VALUE_TYPE_CHARARRAY: {
306 std::vector<int32_t> value;
307 if (!parcel.ReadInt32Vector(&value)) {
308 return false;
309 }
310 SetArray<int32_t, Char>(g_IID_IChar, value, ao);
311 break;
312 }
313 case VALUE_TYPE_SHORTARRAY: {
314 std::vector<short> value;
315 if (!parcel.ReadInt16Vector(&value)) {
316 return false;
317 }
318 SetArray<short, Short>(g_IID_IShort, value, ao);
319 break;
320 }
321 case VALUE_TYPE_INTARRAY: {
322 std::vector<int> value;
323 if (!parcel.ReadInt32Vector(&value)) {
324 return false;
325 }
326 SetArray<int, Integer>(g_IID_IInteger, value, ao);
327 break;
328 }
329 case VALUE_TYPE_LONGARRAY: {
330 std::vector<int64_t> value;
331 if (!parcel.ReadInt64Vector(&value)) {
332 return false;
333 }
334 SetArray<int64_t, Long>(g_IID_ILong, value, ao);
335 break;
336 }
337 case VALUE_TYPE_FLOATARRAY: {
338 std::vector<float> value;
339 if (!parcel.ReadFloatVector(&value)) {
340 return false;
341 }
342 SetArray<float, Float>(g_IID_IFloat, value, ao);
343 break;
344 }
345 case VALUE_TYPE_DOUBLEARRAY: {
346 std::vector<double> value;
347 if (!parcel.ReadDoubleVector(&value)) {
348 return false;
349 }
350 SetArray<double, Double>(g_IID_IDouble, value, ao);
351 break;
352 }
353 default:
354 // ignore
355 ;
356 }
357
358 return true;
359 }
360
ReadFromParcel(Parcel & parcel)361 bool IntentParams::ReadFromParcel(Parcel &parcel)
362 {
363 int32_t size;
364
365 if (!parcel.ReadInt32(size)) {
366 return false;
367 }
368
369 for (int32_t i = 0; i < size; i++) {
370 std::u16string key;
371 key = parcel.ReadString16();
372
373 sptr<IInterface> intf = nullptr;
374 int type;
375 if (!parcel.ReadInt32(type)) {
376 return false;
377 }
378
379 switch (type) {
380 case VALUE_TYPE_STRING: {
381 std::u16string value = parcel.ReadString16();
382 intf = String::Box(Str16ToStr8(value));
383 break;
384 }
385 case VALUE_TYPE_BOOLEAN: {
386 int8_t value;
387 if (!parcel.ReadInt8(value)) {
388 return false;
389 }
390 intf = Boolean::Box(value);
391 break;
392 }
393 case VALUE_TYPE_BYTE: {
394 int8_t value;
395 if (!parcel.ReadInt8(value)) {
396 return false;
397 }
398 intf = Byte::Box(value);
399 break;
400 }
401 case VALUE_TYPE_CHAR: {
402 int32_t value;
403 if (!parcel.ReadInt32(value)) {
404 return false;
405 }
406 intf = Char::Box(value);
407 break;
408 }
409 case VALUE_TYPE_SHORT: {
410 short value;
411 if (!parcel.ReadInt16(value)) {
412 return false;
413 }
414 intf = Short::Box(value);
415 break;
416 }
417 case VALUE_TYPE_INT: {
418 int value;
419 if (!parcel.ReadInt32(value)) {
420 return false;
421 }
422 intf = Integer::Box(value);
423 break;
424 }
425 case VALUE_TYPE_LONG: {
426 int64_t value;
427 if (!parcel.ReadInt64(value)) {
428 return false;
429 }
430 intf = Long::Box(value);
431 break;
432 }
433 case VALUE_TYPE_FLOAT: {
434 float value;
435 if (!parcel.ReadFloat(value)) {
436 return false;
437 }
438 intf = Float::Box(value);
439 break;
440 }
441 case VALUE_TYPE_DOUBLE: {
442 double value;
443 if (!parcel.ReadDouble(value)) {
444 return false;
445 }
446 intf = Double::Box(value);
447 break;
448 }
449 case VALUE_TYPE_NULL:
450 break;
451 default: {
452 // handle array
453 sptr<IArray> ao = nullptr;
454 if (!ReadArrayToParcel(parcel, type, ao)) {
455 return false;
456 }
457 intf = ao;
458 break;
459 }
460 }
461
462 if (intf) {
463 SetParam(Str16ToStr8(key), intf);
464 }
465 }
466
467 return true;
468 }
469
Unmarshalling(Parcel & parcel)470 IntentParams *IntentParams::Unmarshalling(Parcel &parcel)
471 {
472 IntentParams *intentParams = new (std::nothrow) IntentParams();
473 if (intentParams && !intentParams->ReadFromParcel(parcel)) {
474 delete intentParams;
475 intentParams = nullptr;
476 }
477 return intentParams;
478 }
479
480 } // namespace AAFwk
481 } // namespace OHOS
482