• 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::vector<uint8_t> &input, MessageParcel &data)
142 {
143     return data.WriteUInt8Vector(input);
144 }
145 
146 static inline bool Unmarshalling(std::vector<uint8_t> &output, MessageParcel &data)
147 {
148     return data.ReadUInt8Vector(&output);
149 }
150 
151 static inline bool Marshalling(const sptr<IRemoteObject> &input, MessageParcel &data)
152 {
153     return data.WriteRemoteObject(input);
154 }
155 
156 static inline bool Unmarshalling(sptr<IRemoteObject> &output, MessageParcel &data)
157 {
158     output = data.ReadRemoteObject();
159     return true;
160 }
161 
162 static inline bool Marshalling(IRemoteObject *input, MessageParcel &data)
163 {
164     return data.WriteRemoteObject(input);
165 }
166 
167 template<typename _OutTp>
168 bool ReadVariant(uint32_t step, uint32_t index, const _OutTp &output, MessageParcel &data);
169 template<typename _OutTp, typename _First, typename... _Rest>
170 bool ReadVariant(uint32_t step, uint32_t index, const _OutTp &output, MessageParcel &data);
171 
172 template<typename _InTp>
173 bool WriteVariant(uint32_t step, const _InTp &input, MessageParcel &data);
174 template<typename _InTp, typename _First, typename... _Rest>
175 bool WriteVariant(uint32_t step, const _InTp &input, MessageParcel &data);
176 
177 template<typename... _Types>
178 bool Marshalling(const std::variant<_Types...> &input, MessageParcel &data);
179 template<typename... _Types>
180 bool Unmarshalling(std::variant<_Types...> &output, MessageParcel &data);
181 
182 template<class K, class V>
183 bool Marshalling(const std::map<K, V> &result, MessageParcel &parcel);
184 template<class K, class V>
185 bool Unmarshalling(std::map<K, V> &val, MessageParcel &parcel);
186 
187 template<class T>
188 bool Marshalling(const std::vector<T> &val, MessageParcel &parcel);
189 template<class T>
190 bool Unmarshalling(std::vector<T> &val, MessageParcel &parcel);
191 
192 template<class T>
193 bool Marshalling(const std::list<T> &val, MessageParcel &parcel);
194 template<class T>
195 bool Unmarshalling(std::list<T> &val, MessageParcel &parcel);
196 
197 template<typename T, typename std::enable_if<std::is_pointer<T>{}, int>::type = 0>
198 bool Marshalling(const T &input, MessageParcel &data) = delete;
199 template<typename T, typename std::enable_if<std::is_pointer<T>{}, int>::type = 0>
200 bool Unmarshalling(T &output, MessageParcel &data) = delete;
201 
202 template<typename T>
203 bool Marshalling(const T &input, MessageParcel &data);
204 template<typename T>
205 bool Unmarshalling(T &output, MessageParcel &data);
206 
207 template<class T, typename std::enable_if<is_container<T>{}, int>::type = 0>
208 bool MarshalToContainer(const T &val, MessageParcel &parcel);
209 template<class T, typename std::enable_if<is_container<T>{}, int>::type = 0>
210 bool UnmarshalFromContainer(T &val, MessageParcel &parcel);
211 
212 template<typename T>
213 bool MarshalToBuffer(const T &input, int size, MessageParcel &data);
214 template<typename T>
215 bool MarshalToBuffer(const std::vector<T> &input, int size, MessageParcel &data);
216 
217 template<typename T>
218 bool UnmarshalFromBuffer(MessageParcel &data, T &output);
219 template<typename T>
220 bool UnmarshalFromBuffer(MessageParcel &data, std::vector<T> &output);
221 
222 template<typename T, typename... Types>
223 bool Marshal(MessageParcel &parcel, const T &first, const Types &...others);
224 
225 template<typename T, typename... Types>
226 bool Unmarshal(MessageParcel &parcel, T &first, Types &...others);
227 } // namespace ITypesUtil
228 
229 template<typename _OutTp>
230 bool ITypesUtil::ReadVariant(uint32_t step, uint32_t index, const _OutTp &output, MessageParcel &data)
231 {
232     return false;
233 }
234 
235 template<typename _OutTp, typename _First, typename... _Rest>
236 bool ITypesUtil::ReadVariant(uint32_t step, uint32_t index, const _OutTp &output, MessageParcel &data)
237 {
238     if (step == index) {
239         _First value{};
240         auto success = ITypesUtil::Unmarshalling(value, data);
241         output = value;
242         return success;
243     }
244     return ITypesUtil::ReadVariant<_OutTp, _Rest...>(step + 1, index, output, data);
245 }
246 
247 template<typename _InTp>
248 bool ITypesUtil::WriteVariant(uint32_t step, const _InTp &input, MessageParcel &data)
249 {
250     return false;
251 }
252 
253 template<typename _InTp, typename _First, typename... _Rest>
254 bool ITypesUtil::WriteVariant(uint32_t step, const _InTp &input, MessageParcel &data)
255 {
256     if (step == input.index()) {
257         return ITypesUtil::Marshalling(std::get<_First>(input), data);
258     }
259     return ITypesUtil::WriteVariant<_InTp, _Rest...>(step + 1, input, data);
260 }
261 
262 template<typename... _Types>
263 bool ITypesUtil::Marshalling(const std::variant<_Types...> &input, MessageParcel &data)
264 {
265     uint32_t index = static_cast<uint32_t>(input.index());
266     if (!data.WriteUint32(index)) {
267         return false;
268     }
269 
270     return ITypesUtil::WriteVariant<decltype(input), _Types...>(0, input, data);
271 }
272 
273 template<typename... _Types>
274 bool ITypesUtil::Unmarshalling(std::variant<_Types...> &output, MessageParcel &data)
275 {
276     uint32_t index = data.ReadUint32();
277     if (index >= sizeof...(_Types)) {
278         return false;
279     }
280 
281     return ITypesUtil::ReadVariant<decltype(output), _Types...>(0, index, output, data);
282 }
283 
284 template<class K, class V>
285 bool ITypesUtil::Marshalling(const std::map<K, V> &result, MessageParcel &parcel)
286 {
287     if (!parcel.WriteInt32(static_cast<int32_t>(result.size()))) {
288         return false;
289     }
290     for (const auto &entry : result) {
291         if (!ITypesUtil::Marshalling(entry.first, parcel)) {
292             return false;
293         }
294         if (!ITypesUtil::Marshalling(entry.second, parcel)) {
295             return false;
296         }
297     }
298     return true;
299 }
300 
301 template<class K, class V>
302 bool ITypesUtil::Unmarshalling(std::map<K, V> &val, MessageParcel &parcel)
303 {
304     int32_t size = 0;
305     if (!parcel.ReadInt32(size)) {
306         return false;
307     }
308     if (size < 0) {
309         return false;
310     }
311 
312     size_t readAbleSize = parcel.GetReadableBytes();
313     if ((static_cast<size_t>(size) > readAbleSize) || static_cast<size_t>(size) > val.max_size()) {
314         return false;
315     }
316 
317     for (int32_t i = 0; i < size; i++) {
318         K key;
319         if (!ITypesUtil::Unmarshalling(key, parcel)) {
320             return false;
321         }
322         if (!ITypesUtil::Unmarshalling(val[key], parcel)) {
323             return false;
324         }
325     }
326     return true;
327 }
328 
329 template<class T>
330 bool ITypesUtil::Marshalling(const std::vector<T> &val, MessageParcel &parcel)
331 {
332     return ITypesUtil::MarshalToContainer(val, parcel);
333 }
334 
335 template<class T>
336 bool ITypesUtil::Unmarshalling(std::vector<T> &val, MessageParcel &parcel)
337 {
338     return ITypesUtil::UnmarshalFromContainer(val, parcel);
339 }
340 
341 template<class T>
342 bool ITypesUtil::Marshalling(const std::list<T> &val, MessageParcel &parcel)
343 {
344     return ITypesUtil::MarshalToContainer(val, parcel);
345 }
346 
347 template<class T>
348 bool ITypesUtil::Unmarshalling(std::list<T> &val, MessageParcel &parcel)
349 {
350     return ITypesUtil::UnmarshalFromContainer(val, parcel);
351 }
352 
353 template<class T, typename std::enable_if<is_container<T>{}, int>::type>
354 bool ITypesUtil::MarshalToContainer(const T &val, MessageParcel &parcel)
355 {
356     if (val.size() > INT_MAX) {
357         return false;
358     }
359 
360     if (!parcel.WriteInt32(static_cast<int32_t>(val.size()))) {
361         return false;
362     }
363 
364     for (auto &v : val) {
365         if (!ITypesUtil::Marshalling(v, parcel)) {
366             return false;
367         }
368     }
369     return true;
370 }
371 
372 template<class T, typename std::enable_if<is_container<T>{}, int>::type>
373 bool ITypesUtil::UnmarshalFromContainer(T &val, MessageParcel &parcel)
374 {
375     int32_t len = parcel.ReadInt32();
376     if (len < 0) {
377         return false;
378     }
379 
380     size_t readAbleSize = parcel.GetReadableBytes();
381     size_t size = static_cast<size_t>(len);
382     if ((size > readAbleSize) || (size > val.max_size())) {
383         return false;
384     }
385 
386     val.clear();
387     for (size_t i = 0; i < size; i++) {
388         typename T::value_type value;
389         if (!ITypesUtil::Unmarshalling(value, parcel)) {
390             return false;
391         }
392         val.emplace_back(std::move(value));
393     }
394     return true;
395 }
396 
397 template<typename T>
398 bool ITypesUtil::MarshalToBuffer(const T &input, int size, MessageParcel &data)
399 {
400     if (size < 0 || static_cast<size_t>(size) > MAX_SIZE || !data.WriteInt32(size)) {
401         return false;
402     }
403     if (size == 0) {
404         return true;
405     }
406     std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(size);
407     if (buffer == nullptr) {
408         return false;
409     }
410 
411     int leftSize = size;
412     uint8_t *cursor = buffer.get();
413     if (!input.WriteToBuffer(cursor, leftSize)) {
414         return false;
415     }
416     return data.WriteRawData(buffer.get(), size);
417 }
418 
419 template<typename T>
420 bool ITypesUtil::MarshalToBuffer(const std::vector<T> &input, int size, MessageParcel &data)
421 {
422     if (size < 0 || static_cast<size_t>(size) > MAX_SIZE || input.size() > MAX_COUNT || !data.WriteInt32(size)) {
423         return false;
424     }
425     if (size == 0) {
426         return true;
427     }
428     if (!data.WriteInt32(input.size())) {
429         return false;
430     }
431 
432     std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(size);
433     if (buffer == nullptr) {
434         return false;
435     }
436 
437     uint8_t *cursor = buffer.get();
438     int32_t left = size;
439     for (const auto &entry : input) {
440         if (!entry.WriteToBuffer(cursor, left)) {
441             return false;
442         }
443     }
444     return data.WriteRawData(buffer.get(), size);
445 }
446 
447 template<typename T>
448 bool ITypesUtil::UnmarshalFromBuffer(MessageParcel &data, T &output)
449 {
450     int32_t size = data.ReadInt32();
451     if (size == 0) {
452         return true;
453     }
454     if (size < 0 || static_cast<size_t>(size) > MAX_SIZE) {
455         return false;
456     }
457     const uint8_t *buffer = reinterpret_cast<const uint8_t *>(data.ReadRawData(size));
458     if (buffer == nullptr) {
459         return false;
460     }
461     return output.ReadFromBuffer(buffer, size);
462 }
463 
464 template<typename T>
465 bool ITypesUtil::UnmarshalFromBuffer(MessageParcel &data, std::vector<T> &output)
466 {
467     int size = data.ReadInt32();
468     if (size == 0) {
469         return true;
470     }
471     if (size < 0 || static_cast<size_t>(size) > MAX_SIZE) {
472         return false;
473     }
474     int count = data.ReadInt32();
475     const uint8_t *buffer = reinterpret_cast<const uint8_t *>(data.ReadRawData(size));
476     if (count < 0 || static_cast<size_t>(count) > MAX_COUNT || buffer == nullptr) {
477         return false;
478     }
479 
480     output.resize(count);
481     for (auto &entry : output) {
482         if (!entry.ReadFromBuffer(buffer, size)) {
483             output.clear();
484             return false;
485         }
486     }
487     return true;
488 }
489 
490 template<typename T, typename... Types>
491 bool ITypesUtil::Marshal(MessageParcel &parcel, const T &first, const Types &...others)
492 {
493     if (!ITypesUtil::Marshalling(first, parcel)) {
494         return false;
495     }
496     return ITypesUtil::Marshal(parcel, others...);
497 }
498 
499 template<typename T, typename... Types>
500 bool ITypesUtil::Unmarshal(MessageParcel &parcel, T &first, Types &...others)
501 {
502     if (!ITypesUtil::Unmarshalling(first, parcel)) {
503         return false;
504     }
505     return ITypesUtil::Unmarshal(parcel, others...);
506 }
507 } // namespace OHOS
508 #endif