• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 Reads a block of data (buffer data) without padding (alignment)
518      * from this parcel.
519      *
520      * This method will read the effective data with the specified
521      * `length` and discard the bytes used for padding.
522      *
523      * @param length Indicates the effective size of the buffer, in bytes.
524      * @return Returns a pointer of the `uint8_t` type to the buffer.
525      *
526      */
527     const uint8_t *ReadUnpadBuffer(size_t length);
528 
529     /**
530      * @brief Skips the next several bytes specified by `bytes` in the read
531      * operation.
532      *
533      * @param bytes Indicates the number of bytes to skip.
534      */
535     void SkipBytes(size_t bytes);
536 
537     /**
538      * @brief Reads a C-style string from this parcel.
539      *
540      * @return Returns a pointer of the `char` type to the C-style string.
541      */
542     const char *ReadCString();
543 
544     /**
545      * @brief Reads a C++ string (`std::string`) object from this parcel.
546      *
547      * @return Returns a pointer of the `std::string` type to the C-style
548      * string.
549      */
550     const std::string ReadString();
551 
552     /**
553      * @brief Reads a C++ string (`std::string`) object from this parcel to
554      * an object.
555      *
556      * @param value Indicates the `std::string` object to hold the data read.
557      * @return Returns `true` if the operation is successful;
558      * returns `false` otherwise.
559      */
560     bool ReadString(std::string &value);
561 
562     /**
563      * @brief Reads a C++ UTF-16 encoded string (`std::u16string`) object
564      * from this parcel.
565      *
566      * @return Returns a pointer of the `std::u16string` type to the C-style
567      * string.
568      */
569     const std::u16string ReadString16();
570 
571     /**
572      * @brief Reads a C++ UTF-16 string (`std::u16string`) object from this
573      * parcel to an object.
574      *
575      * @param value Indicates the `std::u16string` object to hold the data read.
576      * @return Returns `true` if the operation is successful;
577      * returns `false` otherwise.
578      */
579     bool ReadString16(std::u16string &value);
580 
581     /**
582      * @brief Reads a C++ UTF-16 string (`std::u16string`) object and its length
583      * from this parcel.
584      *
585      * @param len Indicates the reference to a variable of the `int32_t` type
586      * to receive the length.
587      * @return Returns an `std::u16string` object.
588      */
589     const std::u16string ReadString16WithLength(int32_t &len);
590 
591     /**
592      * @brief Reads a C++ string (`std::string`) object and its length from
593      * this parcel.
594      *
595      * @param len Indicates the reference to a variable of the `int32_t` type
596      * to receive the length.
597      * @return Returns an `std::string` object.
598      */
599     const std::string ReadString8WithLength(int32_t &len);
600 
601     /**
602      * @brief Sets the read cursor to the specified position.
603      *
604      * @param newPosition Indicates the position, represented by the offset
605      * (in bytes) from the beginning of the data region.
606      * @return Returns `true` if the operation is successful;
607      * returns `false` otherwise.
608      */
609     bool RewindRead(size_t newPosition);
610 
611     /**
612      * @brief Sets the write cursor to the specified position.
613      *
614      * @param offsets Indicates the position, represented by the offset
615      * (in bytes) from the beginning of the data region.
616      * @return Returns `true` if the operation is successful;
617      * returns `false` otherwise.
618      */
619     bool RewindWrite(size_t offsets);
620 
621     /**
622      * @brief Obtains the current position of the read cursor.
623      *
624      * @return Returns the position, represented by the offset (in bytes)
625      * from the beginning of the data region.
626      */
627     size_t GetReadPosition();
628 
629     /**
630      * @brief Obtains the current position of the write 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 GetWritePosition();
636 
637     /**
638      * @brief Reads a `Parcelable` object and its child class objects
639      * from this parcel.
640      *
641      * @tparam T Indicates the class type of the output object.
642      * @return Returns the object read.
643      * @note A null pointer will be returned if '0' is read.
644      */
645     template <typename T>
646     T *ReadParcelable();
647 
648     /**
649      * @brief Reads a `Parcelable` object from this parcel and manages it by a
650      * smart pointer.
651      *
652      * @tparam T Indicates the class type of the output object.
653      * @return Returns the object managed by a smart pointer.
654      * @note A null pointer will be returned if '0' is read.
655      */
656     template <typename T>
657     sptr<T> ReadStrongParcelable();
658 
659     /**
660      * @brief Checks whether it is valid to read an object from the current
661      * cursor.
662      *
663      * @return Returns `true` if valid; returns `false` otherwise.
664      */
665     bool CheckOffsets();
666 
667     /**
668      * @brief Reads an object from this parcel.
669      *
670      * Call `CheckOffsets()` first to check whether it is valid to read an
671      * object.
672      *
673      * @tparam T Indicates the class type of the output object.
674      * @return Returns the smart pointer to the object.
675      * @note A null pointer will be returned if `CheckOffsets()` fails
676      * to be called.
677      */
678     template<typename T>
679     sptr<T> ReadObject();
680 
681     /**
682      * @brief Sets a memory allocator for this parcel.
683      *
684      * The new allocator will reallocate the data region that has been written.
685      *
686      * @param allocator Indicates the pointer to an `Allocator` object.
687      * @return Returns `true` if the operation is successful;
688      * returns `false` otherwise.
689      */
690     bool SetAllocator(Allocator *allocator);
691 
692     /**
693      * @brief Records an array of positions of this parcel.
694      *
695      * @param offsets Indicates the pointer to the position array.
696      * @param offsetSize Indicates the size of the position array.
697      * @note The method returns directly if the call fail.
698      */
699     void InjectOffsets(binder_size_t offsets, size_t offsetSize);
700 
701     /**
702      * @brief Deallocates the data region and resets this parcel.
703      */
704     void FlushBuffer();
705 
706     /**
707      * @brief Writes an `std::vector` object to this parcel.
708      *
709      * @tparam T1 Indicates the class type for the vector.
710      * @tparam T2 Indicates the class type for the write method of this parcel.
711      * @param val Indicates the reference to the vector.
712      * @param Write Indicates the `Parcel::Write(T2 value)` method.
713      * @return Returns `true` if the operation is successful;
714      * returns `false` otherwise.
715      */
716     template <typename T1, typename T2>
717     bool WriteVector(const std::vector<T1> &val, bool (Parcel::*Write)(T2));
718     template <typename Type, typename T1, typename T2>
719     bool WriteFixedAlignVector(const std::vector<T1> &originVal, bool (Parcel::*SpecialWrite)(T2));
720     bool WriteBoolVector(const std::vector<bool> &val);
721     bool WriteInt8Vector(const std::vector<int8_t> &val);
722     bool WriteInt16Vector(const std::vector<int16_t> &val);
723     bool WriteInt32Vector(const std::vector<int32_t> &val);
724     bool WriteInt64Vector(const std::vector<int64_t> &val);
725     bool WriteUInt8Vector(const std::vector<uint8_t> &val);
726     bool WriteUInt16Vector(const std::vector<uint16_t> &val);
727     bool WriteUInt32Vector(const std::vector<uint32_t> &val);
728     bool WriteUInt64Vector(const std::vector<uint64_t> &val);
729     bool WriteFloatVector(const std::vector<float> &val);
730     bool WriteDoubleVector(const std::vector<double> &val);
731     bool WriteStringVector(const std::vector<std::string> &val);
732     bool WriteString16Vector(const std::vector<std::u16string> &val);
733 
734     /**
735      * @brief Reads an `std::vector` object from this parcel.
736      *
737      * @tparam T1 Indicates the class type for the vector.
738      * @tparam T2 Indicates the class type for the read method of this parcel.
739      * @param val Indicates the pointer to the vector.
740      * @param Write Indicates the `Parcel::Read(T2 value)` method.
741      * @return Returns `true` if the operation is successful;
742      * returns `false` otherwise.
743      */
744     template <typename T>
745     bool ReadVector(std::vector<T> *val, bool (Parcel::*Read)(T &));
746     bool ReadBoolVector(std::vector<bool> *val);
747     bool ReadInt8Vector(std::vector<int8_t> *val);
748     bool ReadInt16Vector(std::vector<int16_t> *val);
749     bool ReadInt32Vector(std::vector<int32_t> *val);
750     bool ReadInt64Vector(std::vector<int64_t> *val);
751     bool ReadUInt8Vector(std::vector<uint8_t> *val);
752     bool ReadUInt16Vector(std::vector<uint16_t> *val);
753     bool ReadUInt32Vector(std::vector<uint32_t> *val);
754     bool ReadUInt64Vector(std::vector<uint64_t> *val);
755     bool ReadFloatVector(std::vector<float> *val);
756     bool ReadDoubleVector(std::vector<double> *val);
757     bool ReadStringVector(std::vector<std::string> *val);
758     bool ReadString16Vector(std::vector<std::u16string> *val);
759 
760     // write raw primitive type(i.e. 1byte for bool, 4byte for `int16_t`, etc.)
761     bool WriteBoolUnaligned(bool value);
762     bool WriteInt8Unaligned(int8_t value);
763     bool WriteInt16Unaligned(int16_t value);
764     bool WriteUint8Unaligned(uint8_t value);
765     bool WriteUint16Unaligned(uint16_t value);
766     // read raw primitive type(i.e. 1byte for bool, 4byte for `int16_t`, etc.)
767     bool ReadBoolUnaligned();
768     bool ReadInt8Unaligned(int8_t &value);
769     bool ReadInt16Unaligned(int16_t &value);
770     bool ReadUint8Unaligned(uint8_t &value);
771     bool ReadUint16Unaligned(uint16_t &value);
772 
773 protected:
774     /**
775      * @brief Records the position of the written object, which is represented
776      * by the offset from the beginning of the data region.
777      *
778      * @param offset Indicates the position.
779      * @return Returns `true` if the operation is successful;
780      * returns `false` otherwise.
781      */
782     bool WriteObjectOffset(binder_size_t offset);
783 
784     /**
785      * @brief Ensures that the number of written objects is less than
786      * the capacity of objects.
787      *
788      * If the data region is full, the capacity will be expanded.
789      *
790      * @return Returns `true` if the operation is successful;
791      * returns `false` otherwise.
792      */
793     bool EnsureObjectsCapacity();
794 
795 private:
796     DISALLOW_COPY_AND_MOVE(Parcel);
797     template <typename T>
798     bool Write(T value);
799 
800     template <typename T>
801     bool Read(T &value);
802 
803     template <typename T>
804     T Read();
805 
806     template <typename T>
807     bool ReadPadded(T &value);
808 
GetPadSize(size_t size)809     inline size_t GetPadSize(size_t size)
810     {
811         const size_t SIZE_OFFSET = 3;
812         return (((size + SIZE_OFFSET) & (~SIZE_OFFSET)) - size);
813     }
814 
815     size_t CalcNewCapacity(size_t minCapacity);
816 
817     bool WriteDataBytes(const void *data, size_t size);
818 
819     void WritePadBytes(size_t padded);
820 
821     bool EnsureWritableCapacity(size_t desireCapacity);
822 
823     bool WriteParcelableOffset(size_t offset);
824 
825     const uint8_t *BasicReadBuffer(size_t length);
826 
827     bool ValidateReadData(size_t upperBound);
828 
829     void ClearObjects();
830 
831 private:
832     uint8_t *data_;
833     size_t readCursor_;
834     size_t writeCursor_;
835     size_t dataSize_;
836     size_t dataCapacity_;
837     size_t maxDataCapacity_;
838     binder_size_t *objectOffsets_;
839     size_t nextObjectIdx_;
840     size_t objectCursor_;
841     size_t objectsCapacity_;
842     Allocator *allocator_;
843     std::vector<sptr<Parcelable>> objectHolder_;
844     bool writable_ = true;
845 };
846 
847 template <typename T>
WriteObject(const sptr<T> & object)848 bool Parcel::WriteObject(const sptr<T> &object)
849 {
850     if (object == nullptr) {
851         return T::Marshalling(*this, object);
852     }
853     return WriteRemoteObject(object.GetRefPtr());
854 }
855 
856 template <typename T>
ReadObject()857 sptr<T> Parcel::ReadObject()
858 {
859     if (!this->CheckOffsets()) {
860         return nullptr;
861     }
862     sptr<T> res(T::Unmarshalling(*this));
863     return res;
864 }
865 
866 // Read data from the given parcel into this parcelable object.
867 template <typename T>
ReadParcelable()868 T *Parcel::ReadParcelable()
869 {
870     int32_t size = this->ReadInt32();
871     if (size == 0) {
872         return nullptr;
873     }
874     return T::Unmarshalling(*this);
875 }
876 
877 // Read data from the given parcel into this parcelable object, and return sptr.
878 template <typename T>
ReadStrongParcelable()879 sptr<T> Parcel::ReadStrongParcelable()
880 {
881     int32_t size = this->ReadInt32();
882     if (size == 0) {
883         return nullptr;
884     }
885     sptr<T> res(T::Unmarshalling(*this));
886     return res;
887 }
888 
889 } // namespace OHOS
890 #endif
891