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