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