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 /**
17 * @file parcel.h
18 *
19 * @brief Provides classes for the data container implemented in c_utils.
20 *
21 * The <b>Parcel</b> and <b>Parcelable</b> classes and the related memory
22 * allocator are provided.
23 */
24
25 #ifndef OHOS_UTILS_PARCEL_H
26 #define OHOS_UTILS_PARCEL_H
27
28 #include <string>
29 #include <vector>
30 #include "nocopyable.h"
31 #include "refbase.h"
32 #include "flat_obj.h"
33
34 namespace OHOS {
35
36 class Parcel;
37
38 /**
39 * @brief Defines a class for which the instance can be written into a parcel.
40 *
41 * @note If this object is remote, its position will be used in
42 * kernel data transaction.
43 */
44 class Parcelable : public virtual RefBase {
45 public:
46 virtual ~Parcelable() = default;
47
48 Parcelable();
49 /**
50 * @brief Creates a `Parcelable` object.
51 *
52 * @param asRemote Specifies whether the object is remote.
53 */
54 explicit Parcelable(bool asRemote);
55
56 /**
57 * @brief Writes a `Parcelable` object into a parcel.
58 *
59 * @param parcel Indicates the parcel.
60 * @return Returns `true` if the operation is successful; returns `false`
61 * otherwise.
62 * @note If the `Parcelable` object is remote, its position will be saved
63 * in the parcel.
64 * @note You must implement a static Unmarshalling function to
65 * fetch data from the given parcel into this `Parcelable` object.
66 * See `static TestParcelable *Unmarshalling(Parcel &parcel)` as an example.
67 */
68 virtual bool Marshalling(Parcel &parcel) const = 0;
69
70 /**
71 * @brief Enumerates the behavior types of a `Parcelable` object.
72 *
73 * @var IPC Indicate an object that can be used in IPC.
74 * @var RPC Indicate an object that can be used in RPC.
75 * @var HOLD_OBJECT Indicate an object that will be always alive
76 * during data transaction.
77 *
78 */
79 enum BehaviorFlag { IPC = 0x01, RPC = 0x02, HOLD_OBJECT = 0x10 };
80
81 /**
82 * @brief Enables the specified behavior.
83 *
84 * @param b Indicates the behavior.
85 * @see BehaviorFlag.
86 */
SetBehavior(BehaviorFlag b)87 inline void SetBehavior(BehaviorFlag b) const
88 {
89 behavior_ |= static_cast<uint8_t>(b);
90 }
91
92 /**
93 * @brief Disables the specified behavior.
94 *
95 * @param b Indicates the behavior.
96 * @see BehaviorFlag.
97 */
ClearBehavior(BehaviorFlag b)98 inline void ClearBehavior(BehaviorFlag b) const
99 {
100 behavior_ &= static_cast<uint8_t>(~b);
101 }
102
103 /**
104 * @brief Checks whether the specified behavior is enabled.
105 *
106 * @param b Indicates the behavior.
107
108 * @return Returns `true` if the behavior is enabled; returns `false`
109 * otherwise.
110 * @see BehaviorFlag.
111 */
TestBehavior(BehaviorFlag b)112 inline bool TestBehavior(BehaviorFlag b) const
113 {
114 return behavior_ & (static_cast<uint8_t>(b));
115 }
116
117 public:
118 bool asRemote_; // If the object is remote.
119 mutable uint8_t behavior_; // Behavior of the object.
120 };
121
122 /**
123 * @brief Defines a memory allocator for data in `Parcel`.
124 */
125 class Allocator {
126 public:
127 virtual ~Allocator() = default;
128
129 virtual void *Realloc(void *data, size_t newSize) = 0;
130
131 virtual void *Alloc(size_t size) = 0;
132
133 virtual void Dealloc(void *data) = 0;
134 };
135
136 /**
137 * @brief Provides the default implementation for a memory allocator.
138 *
139 * @note A non-default allocator for a parcel must be specified manually.
140 */
141 class DefaultAllocator : public Allocator {
142 public:
143 /**
144 * @brief Allocates memory for this parcel.
145 *
146 * @param size Indicates the size of the memory to allocate.
147 * @return Returns the void pointer to the memory region.
148 */
149 void *Alloc(size_t size) override;
150
151 /**
152 * @brief Deallocates memory for this parcel.
153 *
154 * @param data Indicates the void pointer to the memory region.
155 */
156 void Dealloc(void *data) override;
157 private:
158 /**
159 * @brief Reallocates memory for this parcel.
160 *
161 * @param data Indicates the void pointer to the existing memory region.
162 * @param newSize Indicates the size of the memory to reallocate.
163 * @return Returns the void pointer to the new memory region.
164 */
165 void *Realloc(void *data, size_t newSize) override;
166 };
167
168 /**
169 * @brief Provides a data/message container.
170 *
171 * This class provides methods for writing and reading data of various types,
172 * including primitives and parcelable objects.
173 *
174 * @note This class is usually used in IPC and RPC scenarios.
175 */
176 class Parcel {
177 public:
178 Parcel();
179
180 /**
181 * @brief Creates a `Parcel` object with the specified memory allocator.
182 *
183 * @param allocator Indicates the memory allocator.
184 */
185 explicit Parcel(Allocator *allocator);
186
187 virtual ~Parcel();
188
189 /**
190 * @brief Obtains the total size of existing data in this parcel.
191 *
192 * @return Returns the size, in bytes.
193 */
194 size_t GetDataSize() const;
195
196 /**
197 * @brief Obtains the pointer to the beginning of data in this parcel.
198 *
199 * @return Returns a pointer of the `uintptr_t` type.
200 */
201 uintptr_t GetData() const;
202
203 /**
204 * @brief Obtains the position (offset) of every object written
205 * in this parcel.
206 *
207 * @return Returns a pointer of the `binder_size_t` type to
208 * the first slot of the position array.
209 * @see flat_obj.h
210 */
211 binder_size_t GetObjectOffsets() const;
212
213 /**
214 * @brief Obtains the size of the position array.
215 *
216 * @return Returns the size, in bytes.
217 */
218 size_t GetOffsetsSize() const;
219
220 /**
221 * @brief Obtains the total number of available bytes to write
222 * into this parcel.
223 *
224 * @return Returns the number of available bytes.
225 */
226 size_t GetWritableBytes() const;
227
228 /**
229 * @brief Obtains the total number of available bytes to read
230 * from this parcel.
231 *
232 * @return Returns the number of available bytes.
233 */
234 size_t GetReadableBytes() const;
235
236 /**
237 * @brief Obtains the total capacity of this parcel, that is, the size of
238 * the current data region in the parcel.
239 *
240 * @return Returns the capacity, in bytes.
241 */
242 size_t GetDataCapacity() const;
243
244 /**
245 * @brief Obtains the maximum capacity of this parcel.
246 *
247 * @return Returns the capacity, in bytes.
248 */
249 size_t GetMaxCapacity() const;
250
251 /**
252 * @brief Sets the capacity for this parcel, that is, the size of the
253 * current data region in the parcel.
254 *
255 * @param newCapacity Indicates the capacity to set.
256 * @return Returns `true` if the operation is successful;
257 * returns `false` otherwise.
258 * @note The memory allocator will try to reallocate the data region
259 * with the new capacity.
260 *
261 */
262 bool SetDataCapacity(size_t newCapacity);
263
264 /**
265 * @brief Sets the total size of existing data in this parcel.
266 *
267 * @param dataSize Indicates the size, in bytes.
268 * @return Returns `true` if the operation is successful;
269 * returns `false` otherwise.
270 * @note Do not call this function independently; otherwise, it may fail to
271 * return the correct data size.
272 */
273 bool SetDataSize(size_t dataSize);
274
275 /**
276 * @brief Sets the maximum capacity for this parcel.
277 *
278 * @param maxCapacity Indicates the maximum capacity to set.
279 * @return Returns `true` if the operation is successful;
280 * returns `false` otherwise.
281 */
282 bool SetMaxCapacity(size_t maxCapacity);
283
284 // write primitives in alignment
285 bool WriteBool(bool value);
286 bool WriteInt8(int8_t value);
287 bool WriteInt16(int16_t value);
288 bool WriteInt32(int32_t value);
289 bool WriteInt64(int64_t value);
290 bool WriteUint8(uint8_t value);
291 bool WriteUint16(uint16_t value);
292 bool WriteUint32(uint32_t value);
293 bool WriteUint64(uint64_t value);
294 bool WriteFloat(float value);
295 bool WriteDouble(double value);
296 bool WritePointer(uintptr_t value);
297
298 /**
299 * @brief Writes a data region (buffer) to this parcel.
300 *
301 * @param data Indicates the void pointer to the buffer.
302 * @param size Indicates the size of the buffer.
303 * @return Returns `true` if the operation is successful;
304 * returns `false` otherwise.
305 */
306 bool WriteBuffer(const void *data, size_t size);
307
308 /**
309 * @brief Writes a data region (buffer) to this parcel in alignment
310 * and with the terminator replaced.
311 *
312 * @param data Indicates the void pointer to the buffer.
313 * @param size Indicates the size of the buffer.
314 * @param typeSize Indicates the size of the terminator.
315 * @return Returns `true` if the operation is successful;
316 * returns `false` otherwise.
317 * @note The last several bytes specified by `typeSize` of the aligned data
318 * will be treated as a terminator and replaced by '0b00000000'.
319 */
320 bool WriteBufferAddTerminator(const void *data, size_t size, size_t typeSize);
321
322 /**
323 * @brief Writes a data region (buffer) to this parcel.
324 *
325 * Currently, this function provides the same capability as `WriteBuffer()`.
326 *
327 * @param data Indicates the void pointer to the buffer.
328 * @param size Indicates the size of the buffer.
329 * @return Returns `true` if the operation is successful;
330 * returns `false` otherwise.
331 */
332 bool WriteUnpadBuffer(const void *data, size_t size);
333
334 /**
335 * @brief Writes a C-style string to this parcel.
336 *
337 * The default terminator `\0` of the C-style string will also be written.
338 *
339 * @param value Indicates a pointer of the char type to a C-style string.
340 * @return Returns `true` if the operation is successful;
341 * returns `false` otherwise.
342 */
343 bool WriteCString(const char *value);
344
345 /**
346 * @brief Writes a C++ string (`std::string`) to this parcel.
347 *
348 * The exact length of the string will be written first, and then the string
349 * itself with the appended terminator `\0` will be written.
350 *
351 * @param value Indicates the reference to an `std::string` object.
352 * @return Returns `true` if the operation is successful;
353 * returns `false` otherwise.
354 */
355 bool WriteString(const std::string &value);
356
357 /**
358 * @brief Writes a C++ UTF-16 encoded string (`std::u16string`)
359 * to this parcel.
360 *
361 * The exact length of the string will be written first, and then the string
362 * itself with the appended terminator `\0` will be written.
363 *
364 * @param value Indicates the reference to an `std::u16string` object.
365 * @return Returns `true` if the operation is successful;
366 * returns `false` otherwise.
367 */
368 bool WriteString16(const std::u16string &value);
369
370 /**
371 * @brief Writes a UTF-16 encoded string with the specified length
372 * to this parcel.
373 *
374 * An `std::u16string` object will be constructed based on the `char16_t*`
375 * pointer and the length `len` first. Then the input length and the string
376 * data in the `u16string` object with the appended terminator `\0` will
377 * be written.
378 *
379 * @param value Indicates the pointer to a UTF-16 encoded string.
380 * @param len Indicates the exact length of the input string.
381 * @return Returns `true` if the operation is successful;
382 * returns `false` otherwise.
383 */
384 bool WriteString16WithLength(const char16_t *value, size_t len);
385
386 /**
387 * @brief Writes a UTF-8 encoded string with the specified length
388 * to this parcel.
389 *
390 * The input length `len` and the string itself
391 * with the appended terminator `\0` will be written.
392 *
393 * @param value Indicates the pointer to a UTF-8 encoded string.
394 * @param len Indicates the exact length of the input string.
395 * @return Returns `true` if the operation is successful;
396 * returns `false` otherwise.
397 */
398 bool WriteString8WithLength(const char *value, size_t len);
399
400 /**
401 * @brief Writes a `Parcelable` object to this parcel.
402 *
403 * Call `WriteRemoteObject(const Parcelable *)` to write a remote object.
404 * Call `Marshalling(Parcel &parcel)` to write a non-remote object.
405 *
406 * @param object Indicates the pointer to a `Parcelable` object.
407 * @return Returns `true` if the operation is successful;
408 * returns `false` otherwise.
409 * @note The value '0' of `Int32_t` will be written if a null pointer
410 * is passed in.
411 */
412 bool WriteParcelable(const Parcelable *object);
413
414 /**
415 * @brief Writes a `Parcelable` object to this parcel, and enables its
416 * behavior of `HOLD_OBJECT`.
417 *
418 * @param object Indicates the smart pointer to a `Parcelable` object.
419 * @return Returns `true` if the operation is successful;
420 * returns `false` otherwise.
421 */
422 bool WriteStrongParcelable(const sptr<Parcelable> &object);
423
424 /**
425 * @brief Writes a remote object to this parcel.
426 *
427 * @param object Indicates the pointer to a remote object.
428 * @return Returns `true` if the operation is successful;
429 * returns `false` otherwise.
430 * @note If `HOLD_OBJECT` is enabled for the remote object, it will stay
431 * alive as long as this parcel is alive.
432 *
433 */
434 bool WriteRemoteObject(const Parcelable *object);
435
436 /**
437 * @brief Writes an object to this parcel.
438 *
439 * Use its own `Marshalling(Parcel &parcel)` when a null pointer is passed
440 * in; in other scenarios, use `WriteRemoteObject(const Parcelable *)`.
441 *
442 * @tparam T Indicates the class type of the object.
443 * @param object Indicates the smart pointer to the object.
444 * @return Returns `true` if the operation is successful;
445 * returns `false` otherwise.
446 */
447 template<typename T>
448 bool WriteObject(const sptr<T> &object);
449
450 /**
451 * @brief Parses input data by this parcel.
452 *
453 * @param data Indicates the pointer to input data.
454 * @param size Indicates the size of the input data, in bytes.
455 * @return Returns `true` if the operation is successful;
456 * returns `false` otherwise.
457 * @note Only the read operation from this parcel is allowed after
458 * successful calling of this method.
459 */
460 bool ParseFrom(uintptr_t data, size_t size);
461
462 bool ReadBool();
463
464 int8_t ReadInt8();
465
466 int16_t ReadInt16();
467
468 int32_t ReadInt32();
469
470 int64_t ReadInt64();
471
472 uint8_t ReadUint8();
473
474 uint16_t ReadUint16();
475
476 uint32_t ReadUint32();
477
478 uint64_t ReadUint64();
479
480 float ReadFloat();
481
482 double ReadDouble();
483
484 uintptr_t ReadPointer();
485
486 bool ReadBool(bool &value);
487
488 bool ReadInt8(int8_t &value);
489
490 bool ReadInt16(int16_t &value);
491
492 bool ReadInt32(int32_t &value);
493
494 bool ReadInt64(int64_t &value);
495
496 bool ReadUint8(uint8_t &value);
497
498 bool ReadUint16(uint16_t &value);
499
500 bool ReadUint32(uint32_t &value);
501
502 bool ReadUint64(uint64_t &value);
503
504 bool ReadFloat(float &value);
505
506 bool ReadDouble(double &value);
507
508 /**
509 * @brief Reads a block of data (buffer data) from this parcel.
510 *
511 * @param length Indicates the size of the buffer, in bytes.
512 * @return Returns a pointer of the `uint8_t` type to the buffer.
513 */
514 const uint8_t *ReadBuffer(size_t length);
515
516 /**
517 * @brief Read a block of data (buffer data) from this parcel.
518 *
519 * @param length Size of the buffer(Bytes).
520 * @return A `uint8_t` pointer to the buffer.
521 */
522 const uint8_t *ReadBuffer(size_t length, bool isValidate);
523
524 /**
525 * @brief Reads a block of data (buffer data) without padding (alignment)
526 * from this parcel.
527 *
528 * This method will read the effective data with the specified
529 * `length` and discard the bytes used for padding.
530 *
531 * @param length Indicates the effective size of the buffer, in bytes.
532 * @return Returns a pointer of the `uint8_t` type to the buffer.
533 *
534 */
535 const uint8_t *ReadUnpadBuffer(size_t length);
536
537 /**
538 * @brief Skips the next several bytes specified by `bytes` in the read
539 * operation.
540 *
541 * @param bytes Indicates the number of bytes to skip.
542 */
543 void SkipBytes(size_t bytes);
544
545 /**
546 * @brief Reads a C-style string from this parcel.
547 *
548 * @return Returns a pointer of the `char` type to the C-style string.
549 */
550 const char *ReadCString();
551
552 /**
553 * @brief Reads a C++ string (`std::string`) object from this parcel.
554 *
555 * @return Returns a pointer of the `std::string` type to the C-style
556 * string.
557 */
558 const std::string ReadString();
559
560 /**
561 * @brief Reads a C++ string (`std::string`) object from this parcel to
562 * an object.
563 *
564 * @param value Indicates the `std::string` object to hold the data read.
565 * @return Returns `true` if the operation is successful;
566 * returns `false` otherwise.
567 */
568 bool ReadString(std::string &value);
569
570 /**
571 * @brief Reads a C++ UTF-16 encoded string (`std::u16string`) object
572 * from this parcel.
573 *
574 * @return Returns a pointer of the `std::u16string` type to the C-style
575 * string.
576 */
577 const std::u16string ReadString16();
578
579 /**
580 * @brief Reads a C++ UTF-16 string (`std::u16string`) object from this
581 * parcel to an object.
582 *
583 * @param value Indicates the `std::u16string` object to hold the data read.
584 * @return Returns `true` if the operation is successful;
585 * returns `false` otherwise.
586 */
587 bool ReadString16(std::u16string &value);
588
589 /**
590 * @brief Reads a C++ UTF-16 string (`std::u16string`) object and its length
591 * from this parcel.
592 *
593 * @param len Indicates the reference to a variable of the `int32_t` type
594 * to receive the length.
595 * @return Returns an `std::u16string` object.
596 */
597 const std::u16string ReadString16WithLength(int32_t &len);
598
599 /**
600 * @brief Reads a C++ string (`std::string`) object and its length from
601 * this parcel.
602 *
603 * @param len Indicates the reference to a variable of the `int32_t` type
604 * to receive the length.
605 * @return Returns an `std::string` object.
606 */
607 const std::string ReadString8WithLength(int32_t &len);
608
609 /**
610 * @brief Sets the read cursor to the specified position.
611 *
612 * @param newPosition Indicates the position, represented by the offset
613 * (in bytes) from the beginning of the data region.
614 * @return Returns `true` if the operation is successful;
615 * returns `false` otherwise.
616 */
617 bool RewindRead(size_t newPosition);
618
619 /**
620 * @brief Sets the write cursor to the specified position.
621 *
622 * @param offsets Indicates the position, represented by the offset
623 * (in bytes) from the beginning of the data region.
624 * @return Returns `true` if the operation is successful;
625 * returns `false` otherwise.
626 */
627 bool RewindWrite(size_t offsets);
628
629 /**
630 * @brief Obtains the current position of the read cursor.
631 *
632 * @return Returns the position, represented by the offset (in bytes)
633 * from the beginning of the data region.
634 */
635 size_t GetReadPosition();
636
637 /**
638 * @brief Obtains the current position of the write cursor.
639 *
640 * @return Returns the position, represented by the offset (in bytes)
641 * from the beginning of the data region.
642 */
643 size_t GetWritePosition();
644
645 /**
646 * @brief Reads a `Parcelable` object and its child class objects
647 * from this parcel.
648 *
649 * @tparam T Indicates the class type of the output object.
650 * @return Returns the object read.
651 * @note A null pointer will be returned if '0' is read.
652 */
653 template <typename T>
654 T *ReadParcelable();
655
656 /**
657 * @brief Reads a `Parcelable` object from this parcel and manages it by a
658 * smart pointer.
659 *
660 * @tparam T Indicates the class type of the output object.
661 * @return Returns the object managed by a smart pointer.
662 * @note A null pointer will be returned if '0' is read.
663 */
664 template <typename T>
665 sptr<T> ReadStrongParcelable();
666
667 /**
668 * @brief Checks whether it is valid to read an object from the current
669 * cursor.
670 *
671 * @return Returns `true` if valid; returns `false` otherwise.
672 */
673 bool CheckOffsets();
674
675 /**
676 * @brief Reads an object from this parcel.
677 *
678 * Call `CheckOffsets()` first to check whether it is valid to read an
679 * object.
680 *
681 * @tparam T Indicates the class type of the output object.
682 * @return Returns the smart pointer to the object.
683 * @note A null pointer will be returned if `CheckOffsets()` fails
684 * to be called.
685 */
686 template<typename T>
687 sptr<T> ReadObject();
688
689 /**
690 * @brief Sets a memory allocator for this parcel.
691 *
692 * The new allocator will reallocate the data region that has been written.
693 *
694 * @param allocator Indicates the pointer to an `Allocator` object.
695 * @return Returns `true` if the operation is successful;
696 * returns `false` otherwise.
697 */
698 bool SetAllocator(Allocator *allocator);
699
700 /**
701 * @brief Records an array of positions of this parcel.
702 *
703 * @param offsets Indicates the pointer to the position array.
704 * @param offsetSize Indicates the size of the position array.
705 * @note The method returns directly if the call fail.
706 */
707 void InjectOffsets(binder_size_t offsets, size_t offsetSize);
708
709 /**
710 * @brief Deallocates the data region and resets this parcel.
711 */
712 void FlushBuffer();
713
714 /**
715 * @brief Writes an `std::vector` object to this parcel.
716 *
717 * @tparam T1 Indicates the class type for the vector.
718 * @tparam T2 Indicates the class type for the write method of this parcel.
719 * @param val Indicates the reference to the vector.
720 * @param Write Indicates the `Parcel::Write(T2 value)` method.
721 * @return Returns `true` if the operation is successful;
722 * returns `false` otherwise.
723 */
724 template <typename T1, typename T2>
725 bool WriteVector(const std::vector<T1> &val, bool (Parcel::*Write)(T2));
726 template <typename Type, typename T1, typename T2>
727 bool WriteFixedAlignVector(const std::vector<T1> &originVal, bool (Parcel::*SpecialWrite)(T2));
728 bool WriteBoolVector(const std::vector<bool> &val);
729 bool WriteInt8Vector(const std::vector<int8_t> &val);
730 bool WriteInt16Vector(const std::vector<int16_t> &val);
731 bool WriteInt32Vector(const std::vector<int32_t> &val);
732 bool WriteInt64Vector(const std::vector<int64_t> &val);
733 bool WriteUInt8Vector(const std::vector<uint8_t> &val);
734 bool WriteUInt16Vector(const std::vector<uint16_t> &val);
735 bool WriteUInt32Vector(const std::vector<uint32_t> &val);
736 bool WriteUInt64Vector(const std::vector<uint64_t> &val);
737 bool WriteFloatVector(const std::vector<float> &val);
738 bool WriteDoubleVector(const std::vector<double> &val);
739 bool WriteStringVector(const std::vector<std::string> &val);
740 bool WriteString16Vector(const std::vector<std::u16string> &val);
741
742 /**
743 * @brief Reads an `std::vector` object from this parcel.
744 *
745 * @tparam T1 Indicates the class type for the vector.
746 * @tparam T2 Indicates the class type for the read method of this parcel.
747 * @param val Indicates the pointer to the vector.
748 * @param Write Indicates the `Parcel::Read(T2 value)` method.
749 * @return Returns `true` if the operation is successful;
750 * returns `false` otherwise.
751 */
752 template <typename T>
753 bool ReadVector(std::vector<T> *val, bool (Parcel::*Read)(T &));
754 template <typename Type, typename T1, typename T2>
755 bool ReadFixedAlignVector(std::vector<T1> *val, bool (Parcel::*SpecialRead)(T2 &));
756 bool ReadBoolVector(std::vector<bool> *val);
757 bool ReadInt8Vector(std::vector<int8_t> *val);
758 bool ReadInt16Vector(std::vector<int16_t> *val);
759 bool ReadInt32Vector(std::vector<int32_t> *val);
760 bool ReadInt64Vector(std::vector<int64_t> *val);
761 bool ReadUInt8Vector(std::vector<uint8_t> *val);
762 bool ReadUInt16Vector(std::vector<uint16_t> *val);
763 bool ReadUInt32Vector(std::vector<uint32_t> *val);
764 bool ReadUInt64Vector(std::vector<uint64_t> *val);
765 bool ReadFloatVector(std::vector<float> *val);
766 bool ReadDoubleVector(std::vector<double> *val);
767 bool ReadStringVector(std::vector<std::string> *val);
768 bool ReadString16Vector(std::vector<std::u16string> *val);
769
770 // write raw primitive type(i.e. 1byte for bool, 4byte for `int16_t`, etc.)
771 bool WriteBoolUnaligned(bool value);
772 bool WriteInt8Unaligned(int8_t value);
773 bool WriteInt16Unaligned(int16_t value);
774 bool WriteUint8Unaligned(uint8_t value);
775 bool WriteUint16Unaligned(uint16_t value);
776 // read raw primitive type(i.e. 1byte for bool, 4byte for `int16_t`, etc.)
777 bool ReadBoolUnaligned();
778 bool ReadInt8Unaligned(int8_t &value);
779 bool ReadInt16Unaligned(int16_t &value);
780 bool ReadUint8Unaligned(uint8_t &value);
781 bool ReadUint16Unaligned(uint16_t &value);
782
783 protected:
784 /**
785 * @brief Records the position of the written object, which is represented
786 * by the offset from the beginning of the data region.
787 *
788 * @param offset Indicates the position.
789 * @return Returns `true` if the operation is successful;
790 * returns `false` otherwise.
791 */
792 bool WriteObjectOffset(binder_size_t offset);
793
794 /**
795 * @brief Ensures that the number of written objects is less than
796 * the capacity of objects.
797 *
798 * If the data region is full, the capacity will be expanded.
799 *
800 * @return Returns `true` if the operation is successful;
801 * returns `false` otherwise.
802 */
803 bool EnsureObjectsCapacity();
804
805 private:
806 DISALLOW_COPY_AND_MOVE(Parcel);
807 template <typename T>
808 bool Write(T value);
809
810 template <typename T>
811 bool Read(T &value);
812
813 template <typename T>
814 T Read();
815
816 template <typename T>
817 bool ReadPadded(T &value);
818
GetPadSize(size_t size)819 inline size_t GetPadSize(size_t size)
820 {
821 const size_t SIZE_OFFSET = 3;
822 return (((size + SIZE_OFFSET) & (~SIZE_OFFSET)) - size);
823 }
824
825 size_t CalcNewCapacity(size_t minCapacity);
826
827 bool WriteDataBytes(const void *data, size_t size);
828
829 void WritePadBytes(size_t padded);
830
831 bool EnsureWritableCapacity(size_t desireCapacity);
832
833 bool WriteParcelableOffset(size_t offset);
834
835 const uint8_t *BasicReadBuffer(size_t length);
836
837 bool IsReadObjectData(const size_t nextObj, const size_t upperBound);
838
839 bool ValidateReadData(size_t upperBound);
840
841 void ClearObjects();
842
843 private:
844 uint8_t *data_;
845 size_t readCursor_;
846 size_t writeCursor_;
847 size_t dataSize_;
848 size_t dataCapacity_;
849 size_t maxDataCapacity_;
850 binder_size_t *objectOffsets_;
851 size_t nextObjectIdx_;
852 size_t objectCursor_;
853 size_t objectsCapacity_;
854 Allocator *allocator_;
855 std::vector<sptr<Parcelable>> objectHolder_;
856 bool writable_ = true;
857 };
858
859 template <typename T>
WriteObject(const sptr<T> & object)860 bool Parcel::WriteObject(const sptr<T> &object)
861 {
862 if (object == nullptr) {
863 return T::Marshalling(*this, object);
864 }
865 return WriteRemoteObject(object.GetRefPtr());
866 }
867
868 template <typename T>
ReadObject()869 sptr<T> Parcel::ReadObject()
870 {
871 if (!this->CheckOffsets()) {
872 return nullptr;
873 }
874 sptr<T> res(T::Unmarshalling(*this));
875 return res;
876 }
877
878 // Read data from the given parcel into this parcelable object.
879 template <typename T>
ReadParcelable()880 T *Parcel::ReadParcelable()
881 {
882 int32_t size = this->ReadInt32();
883 if (size == 0) {
884 return nullptr;
885 }
886 return T::Unmarshalling(*this);
887 }
888
889 // Read data from the given parcel into this parcelable object, and return sptr.
890 template <typename T>
ReadStrongParcelable()891 sptr<T> Parcel::ReadStrongParcelable()
892 {
893 int32_t size = this->ReadInt32();
894 if (size == 0) {
895 return nullptr;
896 }
897 sptr<T> res(T::Unmarshalling(*this));
898 return res;
899 }
900
901 } // namespace OHOS
902 #endif
903