• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 
16 #ifndef DISTRIBUTED_DATA_FRAMEWORKS_COMMON_ITYPES_UTIL_H
17 #define DISTRIBUTED_DATA_FRAMEWORKS_COMMON_ITYPES_UTIL_H
18 #include <climits>
19 #include <list>
20 #include <map>
21 #include <memory>
22 #include <type_traits>
23 #include <variant>
24 #include <vector>
25 
26 #include "iremote_object.h"
27 #include "message_parcel.h"
28 namespace OHOS {
29 template<class T>
30 struct is_container : std::false_type {
31 };
32 template<class T>
33 struct is_container<std::vector<T>> : std::true_type {
34 };
35 template<class T>
36 struct is_container<std::list<T>> : std::true_type {
37 };
38 namespace ITypesUtil {
39 inline constexpr size_t MAX_COUNT = 100000;
40 inline constexpr size_t MAX_SIZE = 1 * 1024 * 1024 * 1024; //1G
41 static inline bool Marshal(MessageParcel &data)
42 {
43     return true;
44 }
45 
46 static inline bool Unmarshal(MessageParcel &data)
47 {
48     return true;
49 }
50 
51 static inline bool Marshalling(int16_t input, MessageParcel &data)
52 {
53     return data.WriteInt16(input);
54 }
55 
56 static inline bool Unmarshalling(int16_t &output, MessageParcel &data)
57 {
58     return data.ReadInt16(output);
59 }
60 
61 static inline bool Marshalling(uint32_t input, MessageParcel &data)
62 {
63     return data.WriteUint32(input);
64 }
65 
66 static inline bool Unmarshalling(uint32_t &output, MessageParcel &data)
67 {
68     return data.ReadUint32(output);
69 }
70 
71 static inline bool Marshalling(int32_t input, MessageParcel &data)
72 {
73     return data.WriteInt32(input);
74 }
75 
76 static inline bool Unmarshalling(int32_t &output, MessageParcel &data)
77 {
78     return data.ReadInt32(output);
79 }
80 
81 static inline bool Marshalling(uint64_t input, MessageParcel &data)
82 {
83     return data.WriteUint64(input);
84 }
85 
86 static inline bool Unmarshalling(uint64_t &output, MessageParcel &data)
87 {
88     return data.ReadUint64(output);
89 }
90 
91 static inline bool Marshalling(int64_t input, MessageParcel &data)
92 {
93     return data.WriteInt64(input);
94 }
95 
96 static inline bool Unmarshalling(int64_t &output, MessageParcel &data)
97 {
98     return data.ReadInt64(output);
99 }
100 
101 static inline bool Marshalling(double input, MessageParcel &data)
102 {
103     return data.WriteDouble(input);
104 }
105 
106 static inline bool Unmarshalling(double &output, MessageParcel &data)
107 {
108     return data.ReadDouble(output);
109 }
110 
111 static inline bool Marshalling(bool input, MessageParcel &data)
112 {
113     return data.WriteBool(input);
114 }
115 
116 static inline bool Unmarshalling(bool &output, MessageParcel &data)
117 {
118     return data.ReadBool(output);
119 }
120 
121 static inline bool Marshalling(const std::monostate &input, MessageParcel &data)
122 {
123     return true;
124 }
125 
126 static inline bool Unmarshalling(std::monostate &output, MessageParcel &data)
127 {
128     return true;
129 }
130 
131 static inline bool Marshalling(const std::string &input, MessageParcel &data)
132 {
133     return data.WriteString(input);
134 }
135 
136 static inline bool Unmarshalling(std::string &output, MessageParcel &data)
137 {
138     return data.ReadString(output);
139 }
140 
141 static inline bool Marshalling(const std::u16string &input, MessageParcel &data)
142 {
143     return data.WriteString16(input);
144 }
145 
146 static inline bool Unmarshalling(std::u16string &output, MessageParcel &data)
147 {
148     return data.ReadString16(output);
149 }
150 
151 static inline bool Marshalling(const std::vector<uint8_t> &input, MessageParcel &data)
152 {
153     return data.WriteUInt8Vector(input);
154 }
155 
156 static inline bool Unmarshalling(std::vector<uint8_t> &output, MessageParcel &data)
157 {
158     return data.ReadUInt8Vector(&output);
159 }
160 
161 static inline bool Marshalling(const sptr<IRemoteObject> &input, MessageParcel &data)
162 {
163     return data.WriteRemoteObject(input);
164 }
165 
166 static inline bool Unmarshalling(sptr<IRemoteObject> &output, MessageParcel &data)
167 {
168     output = data.ReadRemoteObject();
169     return true;
170 }
171 
172 static inline bool Marshalling(IRemoteObject *input, MessageParcel &data)
173 {
174     return data.WriteRemoteObject(input);
175 }
176 
177 template<typename _OutTp>
178 bool ReadVariant(uint32_t step, uint32_t index, const _OutTp &output, MessageParcel &data);
179 template<typename _OutTp, typename _First, typename... _Rest>
180 bool ReadVariant(uint32_t step, uint32_t index, const _OutTp &output, MessageParcel &data);
181 
182 template<typename _InTp>
183 bool WriteVariant(uint32_t step, const _InTp &input, MessageParcel &data);
184 template<typename _InTp, typename _First, typename... _Rest>
185 bool WriteVariant(uint32_t step, const _InTp &input, MessageParcel &data);
186 
187 template<typename... _Types>
188 bool Marshalling(const std::variant<_Types...> &input, MessageParcel &data);
189 template<typename... _Types>
190 bool Unmarshalling(std::variant<_Types...> &output, MessageParcel &data);
191 
192 template<class K, class V>
193 bool Marshalling(const std::map<K, V> &result, MessageParcel &parcel);
194 template<class K, class V>
195 bool Unmarshalling(std::map<K, V> &val, MessageParcel &parcel);
196 
197 template<class F, class S, class T>
198 bool Marshalling(const std::tuple<F, S, T> &result, MessageParcel &parcel);
199 template<class F, class S, class T>
200 bool Unmarshalling(std::tuple<F, S, T> &val, MessageParcel &parcel);
201 
202 template<class F, class S>
203 bool Marshalling(const std::pair<F, S> &result, MessageParcel &parcel);
204 template<class F, class S>
205 bool Unmarshalling(std::pair<F, S> &val, MessageParcel &parcel);
206 
207 template<class T>
208 bool Marshalling(const std::vector<T> &val, MessageParcel &parcel);
209 template<class T>
210 bool Unmarshalling(std::vector<T> &val, MessageParcel &parcel);
211 
212 template<class T>
213 bool Marshalling(const std::list<T> &val, MessageParcel &parcel);
214 template<class T>
215 bool Unmarshalling(std::list<T> &val, MessageParcel &parcel);
216 
217 template<typename T, typename std::enable_if<std::is_pointer<T>{}, int>::type = 0>
218 bool Marshalling(const T &input, MessageParcel &data) = delete;
219 template<typename T, typename std::enable_if<std::is_pointer<T>{}, int>::type = 0>
220 bool Unmarshalling(T &output, MessageParcel &data) = delete;
221 
222 template<typename T>
223 bool Marshalling(const T &input, MessageParcel &data);
224 template<typename T>
225 bool Unmarshalling(T &output, MessageParcel &data);
226 
227 template<class T, typename std::enable_if<is_container<T>{}, int>::type = 0>
228 bool MarshalToContainer(const T &val, MessageParcel &parcel);
229 template<class T, typename std::enable_if<is_container<T>{}, int>::type = 0>
230 bool UnmarshalFromContainer(T &val, MessageParcel &parcel);
231 
232 template<typename T>
233 bool MarshalToBuffer(const T &input, int size, MessageParcel &data);
234 template<typename T>
235 bool MarshalToBuffer(const std::vector<T> &input, int size, MessageParcel &data);
236 
237 template<typename T>
238 bool UnmarshalFromBuffer(MessageParcel &data, T &output);
239 template<typename T>
240 bool UnmarshalFromBuffer(MessageParcel &data, std::vector<T> &output);
241 
242 template<typename T, typename... Types>
243 bool Marshal(MessageParcel &parcel, const T &first, const Types &...others);
244 
245 template<typename T, typename... Types>
246 bool Unmarshal(MessageParcel &parcel, T &first, Types &...others);
247 } // namespace ITypesUtil
248 
249 template<typename _OutTp>
250 bool ITypesUtil::ReadVariant(uint32_t step, uint32_t index, const _OutTp &output, MessageParcel &data)
251 {
252     return false;
253 }
254 
255 template<typename _OutTp, typename _First, typename... _Rest>
256 bool ITypesUtil::ReadVariant(uint32_t step, uint32_t index, const _OutTp &output, MessageParcel &data)
257 {
258     if (step == index) {
259         _First value{};
260         auto success = ITypesUtil::Unmarshalling(value, data);
261         output = value;
262         return success;
263     }
264     return ITypesUtil::ReadVariant<_OutTp, _Rest...>(step + 1, index, output, data);
265 }
266 
267 template<typename _InTp>
268 bool ITypesUtil::WriteVariant(uint32_t step, const _InTp &input, MessageParcel &data)
269 {
270     return false;
271 }
272 
273 template<typename _InTp, typename _First, typename... _Rest>
274 bool ITypesUtil::WriteVariant(uint32_t step, const _InTp &input, MessageParcel &data)
275 {
276     if (step == input.index()) {
277         return ITypesUtil::Marshalling(std::get<_First>(input), data);
278     }
279     return ITypesUtil::WriteVariant<_InTp, _Rest...>(step + 1, input, data);
280 }
281 
282 template<typename... _Types>
283 bool ITypesUtil::Marshalling(const std::variant<_Types...> &input, MessageParcel &data)
284 {
285     uint32_t index = static_cast<uint32_t>(input.index());
286     if (!data.WriteUint32(index)) {
287         return false;
288     }
289 
290     return ITypesUtil::WriteVariant<decltype(input), _Types...>(0, input, data);
291 }
292 
293 template<typename... _Types>
294 bool ITypesUtil::Unmarshalling(std::variant<_Types...> &output, MessageParcel &data)
295 {
296     uint32_t index = data.ReadUint32();
297     if (index >= sizeof...(_Types)) {
298         return false;
299     }
300 
301     return ITypesUtil::ReadVariant<decltype(output), _Types...>(0, index, output, data);
302 }
303 
304 template<class K, class V>
305 bool ITypesUtil::Marshalling(const std::map<K, V> &result, MessageParcel &parcel)
306 {
307     if (!parcel.WriteInt32(static_cast<int32_t>(result.size()))) {
308         return false;
309     }
310     for (const auto &entry : result) {
311         if (!ITypesUtil::Marshalling(entry.first, parcel)) {
312             return false;
313         }
314         if (!ITypesUtil::Marshalling(entry.second, parcel)) {
315             return false;
316         }
317     }
318     return true;
319 }
320 
321 template<class K, class V>
322 bool ITypesUtil::Unmarshalling(std::map<K, V> &val, MessageParcel &parcel)
323 {
324     int32_t size = 0;
325     if (!parcel.ReadInt32(size)) {
326         return false;
327     }
328     if (size < 0) {
329         return false;
330     }
331 
332     size_t readAbleSize = parcel.GetReadableBytes();
333     if ((static_cast<size_t>(size) > readAbleSize) || static_cast<size_t>(size) > val.max_size()) {
334         return false;
335     }
336 
337     for (int32_t i = 0; i < size; i++) {
338         K key;
339         if (!ITypesUtil::Unmarshalling(key, parcel)) {
340             return false;
341         }
342         if (!ITypesUtil::Unmarshalling(val[key], parcel)) {
343             return false;
344         }
345     }
346     return true;
347 }
348 
349 template<class F, class S, class T>
350 bool ITypesUtil::Marshalling(const std::tuple<F, S, T> &result, MessageParcel &parcel)
351 {
352     if (!ITypesUtil::Marshalling(std::get<0>(result), parcel)) {
353         return false;
354     }
355     if (!ITypesUtil::Marshalling(std::get<1>(result), parcel)) {
356         return false;
357     }
358     if (!ITypesUtil::Marshalling(std::get<2>(result), parcel)) { // 2 is the last element in tuple
359         return false;
360     }
361     return true;
362 }
363 
364 template<class F, class S, class T>
365 bool ITypesUtil::Unmarshalling(std::tuple<F, S, T> &val, MessageParcel &parcel)
366 {
367     F first;
368     if (!ITypesUtil::Unmarshalling(first, parcel)) {
369         return false;
370     }
371     S second;
372     if (!ITypesUtil::Unmarshalling(second, parcel)) {
373         return false;
374     }
375     T third;
376     if (!ITypesUtil::Unmarshalling(third, parcel)) {
377         return false;
378     }
379     val = { first, second, third };
380     return true;
381 }
382 
383 template<class F, class S>
384 bool ITypesUtil::Marshalling(const std::pair<F, S> &result, MessageParcel &parcel)
385 {
386     if (!ITypesUtil::Marshalling(result.first, parcel)) {
387         return false;
388     }
389     if (!ITypesUtil::Marshalling(result.second, parcel)) {
390         return false;
391     }
392     return true;
393 }
394 
395 template<class F, class S>
396 bool ITypesUtil::Unmarshalling(std::pair<F, S> &val, MessageParcel &parcel)
397 {
398     F first;
399     if (!ITypesUtil::Unmarshalling(first, parcel)) {
400         return false;
401     }
402     S second;
403     if (!ITypesUtil::Unmarshalling(second, parcel)) {
404         return false;
405     }
406     val = { first, second };
407     return true;
408 }
409 
410 template<class T>
411 bool ITypesUtil::Marshalling(const std::vector<T> &val, MessageParcel &parcel)
412 {
413     return ITypesUtil::MarshalToContainer(val, parcel);
414 }
415 
416 template<class T>
417 bool ITypesUtil::Unmarshalling(std::vector<T> &val, MessageParcel &parcel)
418 {
419     return ITypesUtil::UnmarshalFromContainer(val, parcel);
420 }
421 
422 template<class T>
423 bool ITypesUtil::Marshalling(const std::list<T> &val, MessageParcel &parcel)
424 {
425     return ITypesUtil::MarshalToContainer(val, parcel);
426 }
427 
428 template<class T>
429 bool ITypesUtil::Unmarshalling(std::list<T> &val, MessageParcel &parcel)
430 {
431     return ITypesUtil::UnmarshalFromContainer(val, parcel);
432 }
433 
434 template<class T, typename std::enable_if<is_container<T>{}, int>::type>
435 bool ITypesUtil::MarshalToContainer(const T &val, MessageParcel &parcel)
436 {
437     if (val.size() > INT_MAX) {
438         return false;
439     }
440 
441     if (!parcel.WriteInt32(static_cast<int32_t>(val.size()))) {
442         return false;
443     }
444 
445     for (auto &v : val) {
446         if (!ITypesUtil::Marshalling(v, parcel)) {
447             return false;
448         }
449     }
450     return true;
451 }
452 
453 template<class T, typename std::enable_if<is_container<T>{}, int>::type>
454 bool ITypesUtil::UnmarshalFromContainer(T &val, MessageParcel &parcel)
455 {
456     int32_t len = parcel.ReadInt32();
457     if (len < 0) {
458         return false;
459     }
460 
461     size_t readAbleSize = parcel.GetReadableBytes();
462     size_t size = static_cast<size_t>(len);
463     if ((size > readAbleSize) || (size > val.max_size())) {
464         return false;
465     }
466 
467     val.clear();
468     for (size_t i = 0; i < size; i++) {
469         typename T::value_type value;
470         if (!ITypesUtil::Unmarshalling(value, parcel)) {
471             return false;
472         }
473         val.emplace_back(std::move(value));
474     }
475     return true;
476 }
477 
478 template<typename T>
479 bool ITypesUtil::MarshalToBuffer(const T &input, int size, MessageParcel &data)
480 {
481     if (size < 0 || static_cast<size_t>(size) > MAX_SIZE || !data.WriteInt32(size)) {
482         return false;
483     }
484     if (size == 0) {
485         return true;
486     }
487     std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(size);
488     if (buffer == nullptr) {
489         return false;
490     }
491 
492     int leftSize = size;
493     uint8_t *cursor = buffer.get();
494     if (!input.WriteToBuffer(cursor, leftSize)) {
495         return false;
496     }
497     return data.WriteRawData(buffer.get(), size);
498 }
499 
500 template<typename T>
501 bool ITypesUtil::MarshalToBuffer(const std::vector<T> &input, int size, MessageParcel &data)
502 {
503     if (size < 0 || static_cast<size_t>(size) > MAX_SIZE || input.size() > MAX_COUNT || !data.WriteInt32(size)) {
504         return false;
505     }
506     if (size == 0) {
507         return true;
508     }
509     if (!data.WriteInt32(input.size())) {
510         return false;
511     }
512 
513     std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(size);
514     if (buffer == nullptr) {
515         return false;
516     }
517 
518     uint8_t *cursor = buffer.get();
519     int32_t left = size;
520     for (const auto &entry : input) {
521         if (!entry.WriteToBuffer(cursor, left)) {
522             return false;
523         }
524     }
525     return data.WriteRawData(buffer.get(), size);
526 }
527 
528 template<typename T>
529 bool ITypesUtil::UnmarshalFromBuffer(MessageParcel &data, T &output)
530 {
531     int32_t size = data.ReadInt32();
532     if (size == 0) {
533         return true;
534     }
535     if (size < 0 || static_cast<size_t>(size) > MAX_SIZE) {
536         return false;
537     }
538     const uint8_t *buffer = reinterpret_cast<const uint8_t *>(data.ReadRawData(size));
539     if (buffer == nullptr) {
540         return false;
541     }
542     return output.ReadFromBuffer(buffer, size);
543 }
544 
545 template<typename T>
546 bool ITypesUtil::UnmarshalFromBuffer(MessageParcel &data, std::vector<T> &output)
547 {
548     int size = data.ReadInt32();
549     if (size == 0) {
550         return true;
551     }
552     if (size < 0 || static_cast<size_t>(size) > MAX_SIZE) {
553         return false;
554     }
555     int count = data.ReadInt32();
556     const uint8_t *buffer = reinterpret_cast<const uint8_t *>(data.ReadRawData(size));
557     if (count < 0 || static_cast<size_t>(count) > MAX_COUNT || buffer == nullptr) {
558         return false;
559     }
560 
561     output.resize(count);
562     for (auto &entry : output) {
563         if (!entry.ReadFromBuffer(buffer, size)) {
564             output.clear();
565             return false;
566         }
567     }
568     return true;
569 }
570 
571 template<typename T, typename... Types>
572 bool ITypesUtil::Marshal(MessageParcel &parcel, const T &first, const Types &...others)
573 {
574     if (!ITypesUtil::Marshalling(first, parcel)) {
575         return false;
576     }
577     return ITypesUtil::Marshal(parcel, others...);
578 }
579 
580 template<typename T, typename... Types>
581 bool ITypesUtil::Unmarshal(MessageParcel &parcel, T &first, Types &...others)
582 {
583     if (!ITypesUtil::Unmarshalling(first, parcel)) {
584         return false;
585     }
586     return ITypesUtil::Unmarshal(parcel, others...);
587 }
588 } // namespace OHOS
589 #endif