xref: /commonlibrary/c_utils/base/include/parcel.h (revision 3f4cbf05)
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
34namespace OHOS {
35
36class 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 */
44class Parcelable : public virtual RefBase {
45public:
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     */
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     */
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     */
112    inline bool TestBehavior(BehaviorFlag b) const
113    {
114        return behavior_ & (static_cast<uint8_t>(b));
115    }
116
117public:
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 */
125class Allocator {
126public:
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 */
141class DefaultAllocator : public Allocator {
142public:
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;
157private:
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 */
176class Parcel {
177public:
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
783protected:
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
805private:
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
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
843private:
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
859template <typename T>
860bool 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
868template <typename T>
869sptr<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.
879template <typename T>
880T *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.
890template <typename T>
891sptr<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