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