From 48418c9ab51552354b77c96d4d8ce7c58c54f45b Mon Sep 17 00:00:00 2001 From: huangyuchen Date: Tue, 17 Jan 2023 16:56:52 +0800 Subject: [PATCH] Add doc comments for parcel.h Issue:I6B44U Test:NA Signed-off-by: huangyuchen Change-Id: I65442794b703be8fe406cd308741f6e2e1c4b149 --- base/include/parcel.h | 486 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 464 insertions(+), 22 deletions(-) diff --git a/base/include/parcel.h b/base/include/parcel.h index 93de825..3ce1b4d 100644 --- a/base/include/parcel.h +++ b/base/include/parcel.h @@ -13,6 +13,14 @@ * limitations under the License. */ + /** + * @file parcel.h + * + * @brief Provide classes for data container implemented in c_utils. + * + * Including class Parcel, Parcelable and related memory Allocator. + */ + #ifndef OHOS_UTILS_PARCEL_H #define OHOS_UTILS_PARCEL_H @@ -26,45 +34,87 @@ namespace OHOS { class Parcel; +/** + * @brief Interface for class whose Instance can be written into a Parcel. + * + * @note If this object is remote, its position intends to + * use in kernel data transaction. + */ class Parcelable : public virtual RefBase { public: virtual ~Parcelable() = default; Parcelable(); + /** + * @brief Construct a new Parcelable object. + * + * @param asRemote Specifies whether this object is remote. + */ explicit Parcelable(bool asRemote); - // Write a parcelable object to the given parcel. - // The object position is saved into Parcel if set asRemote_ to - // true, and this intends to use in kernel data transaction. - // Returns true being written on success or false if any error occur. + /** + * @brief Write a parcelable object to the given parcel. + * + * @param parcel Target parcel to write to. + * @return Return true being written on success or false if any error occur. + * @note If this object is remote, its position will be saved in the parcel. + * @note A static Unmarshalling function must also be implemented, so that + * you can get data from the given parcel into this parcelable object. + * See `static TestParcelable *Unmarshalling(Parcel &parcel)` as an example. + */ virtual bool Marshalling(Parcel &parcel) const = 0; - // NOTICE! A static Unmarshalling function must also be implemented, so - // that you can get data from the given parcel into this parcelable object. - // See "static TestParcelable *Unmarshalling(Parcel &parcel)" as an example. - + /** + * @brief Enum flag to describe behaviors of the Parcelable object. + * + * @var IPC Indicate the object can be used in IPC. + * @var RPC Indicate the object can be used in RPC. + * @var HOLD_OBJECT Indicate the object will ensure + * alive during data transaction. + * + */ enum BehaviorFlag { IPC = 0x01, RPC = 0x02, HOLD_OBJECT = 0x10 }; + /** + * @brief Enable specified behavior. + * + * @param b Specific flag value. + * @see BehaviorFlag. + */ inline void SetBehavior(BehaviorFlag b) const { behavior_ |= static_cast(b); } + /** + * @brief Disable specified behavior. + * + * @param b Specific flag value. See BehaviorFlag. + */ inline void ClearBehavior(BehaviorFlag b) const { behavior_ &= static_cast(~b); } + /** + * @brief Check whether specified behavior is enabled. + * + * @param b Specific flag value. + * @see BehaviorFlag. + */ inline bool TestBehavior(BehaviorFlag b) const { return behavior_ & (static_cast(b)); } public: - bool asRemote_; - mutable uint8_t behavior_; + bool asRemote_; // if the object is remote + mutable uint8_t behavior_; // value of flag of behaviors }; +/** + * @brief Interface for memory allocator of the data in Parcel. + */ class Allocator { public: virtual ~Allocator() = default; @@ -76,93 +126,308 @@ public: virtual void Dealloc(void *data) = 0; }; +/** + * @brief Default implement of Allocator. + * + * @note Allocator defined by user for a parcel need be specified manually. + */ class DefaultAllocator : public Allocator { public: + /** + * @brief Use `malloc()` to allocate memory for a parcel. + * + * @param size Size of desired memory region. + * @return Void-type pointer to the memory region. + */ void *Alloc(size_t size) override; + /** + * @brief Use `free()` to deallocate memory for a parcel. + * + * @param data Void-type pointer to the memory region. + */ void Dealloc(void *data) override; private: + /** + * @brief Use `realloc()` to reallocate memory for a parcel. + * + * @param data Void-type pointer to the existed memory region. + * @param newSize New desired size of memory region. + * @return Void-type pointer to the new memory region. + */ void *Realloc(void *data, size_t newSize) override; }; +/** + * @brief A data/message container. + * + * Contains interfaces for writing and reading data of various types, + * including primitives, Parcelable objects etc. + * + * @note Usually used in IPC, RPC. + */ class Parcel { public: Parcel(); + + /** + * @brief Construct a new Parcel object with specified Allocator. + * + * @param allocator Specified Allocator. + */ explicit Parcel(Allocator *allocator); virtual ~Parcel(); + /** + * @brief Get total size of existed data in this parcel. + * + * @return Value of the size in bytes. + */ size_t GetDataSize() const; + /** + * @brief Get the pointer to the beginning of data in this parcel. + * + * @return `uintptr_t`-type pointer. + */ uintptr_t GetData() const; + /** + * @brief Get position of every object written in this parcel. + * + * @return `binder_size_t`-type pointer to + * the first slot of the position array. + * @see flat_obj.h + */ binder_size_t GetObjectOffsets() const; + /** + * @brief Get total size of all of the current positions. + * + * @return Value of the size in bytes. + */ size_t GetOffsetsSize() const; + /** + * @brief Get total availiable bytes to write to this parcel. + * + * @return Amount of the availiable bytes. + */ size_t GetWritableBytes() const; + /** + * @brief Get total availiable bytes to read from this parcel. + * + * @return Amount of the availiable bytes. + */ size_t GetReadableBytes() const; + /** + * @brief Get total capacity of this parcel, + * i.e. size of current data region in parcel. + * + * @return Value of the capacity in bytes. + */ size_t GetDataCapacity() const; + /** + * @brief Get maximum capacity of this parcel. + * + * @return Value of the capacity in bytes. + */ size_t GetMaxCapacity() const; + /** + * @brief Set capacity of this parcel, + * i.e. size of current data region in parcel. + * + * @param newCapacity Desired new capacity. + * @return Return True on success, or false if any error occur. + * @note Corresponding Allocator will try to reallocate + * the data region with new capacity. + * + */ bool SetDataCapacity(size_t newCapacity); + /** + * @brief Set total size of existed data in this parcel. + * + * @param dataSize Desired value of size in bytes. + * @return Return True on success, or false if any error occur. + * @note Avoid using it independently, otherwise it may not + * represents the correct size of existed data. + */ bool SetDataSize(size_t dataSize); + /** + * @brief Set maximux capacity of this parcel. + * + * @param maxCapacity Desired value of maximum capacity. + * @return Return True on success, or false if any error occur. + */ bool SetMaxCapacity(size_t maxCapacity); + // write primitives in alignment bool WriteBool(bool value); - bool WriteInt8(int8_t value); - bool WriteInt16(int16_t value); - bool WriteInt32(int32_t value); - bool WriteInt64(int64_t value); - bool WriteUint8(uint8_t value); - bool WriteUint16(uint16_t value); - bool WriteUint32(uint32_t value); - bool WriteUint64(uint64_t value); - bool WriteFloat(float value); - bool WriteDouble(double value); - bool WritePointer(uintptr_t value); + /** + * @brief Write a data region(buffer) to this parcel. + * + * @param data Void-type pointer to the buffer. + * @param size Size of the buffer to be written. + * @return Return True on success, or false if any error occur. + */ bool WriteBuffer(const void *data, size_t size); + /** + * @brief Write a data region(buffer) to this parcel + * in alignment and with terminator replaced. + * + * @param data Void-type pointer to the buffer. + * @param size Size of the buffer to be written. + * @param typeSize Size of the terminator. + * @return Return True on success, or false if any error occur. + * @note The last several bytes specified by `typeSize` of the aligned data + * will be deemed as a terminator, and then will be replaced by + * '0b00000000'. + */ bool WriteBufferAddTerminator(const void *data, size_t size, size_t typeSize); + /** + * @brief Write a data region(buffer) to this parcel without padding. + * + * @param data Void-type pointer to the buffer. + * @param size Size of the buffer to be written. + * @return Return True on success, or false if any error occur. + */ bool WriteUnpadBuffer(const void *data, size_t size); + /** + * @brief Write a C-style string to this parcel. + * + * Default terminator `\0` of C-style string will also write. + * + * @param value A C-style string, i.e. char-type pointer. + * @return Return True on success, or false if any error occur. + */ bool WriteCString(const char *value); + /** + * @brief Write a C++ string(`std::u16string`) to this parcel. + * + * The exact length of the string will write first, then the string itself + * with an appended terminator `\0` will write. + * + * @param value An `std::string` object passed by reference. + * @return Return True on success, or false if any error occur. + */ bool WriteString(const std::string &value); + /** + * @brief Write a C++ UTF-16 encoded string(`std::string`) to this parcel. + * + * The exact length of the string will write first, then the string itself + * with an appended terminator `\0` will write. + * + * @param value An `std::u16string` object passed by reference. + * @return Return True on success, or false if any error occur. + */ bool WriteString16(const std::u16string &value); + /** + * @brief Write a UTF-16 encoded string + * with specified length to this parcel. + * + * An `std::u16string` object will be constructed by input `char16_t*` + * pointer and the length `len` first. Then the input length and the string + * data in `u16string` object with an appended terminator `\0` will write. + * + * @param value Pointer to the UTF-16 encoded string. + * @param len Exact length of the input string. + * @return Return True on success, or false if any error occur. + */ bool WriteString16WithLength(const char16_t *value, size_t len); + /** + * @brief Write a UTF-8 encoded string + * with specified length to this parcel. + * + * The input length `len` and the string data + * with an appended terminator `\0` will write. + * + * @param value Pointer to the UTF-8 encoded string. + * @param len Exact length of the input string. + * @return Return True on success, or false if any error occur. + */ bool WriteString8WithLength(const char *value, size_t len); + /** + * @brief Write a Parcelable object to this parcel. + * + * Remote object will be written by `WriteRemoteObject(const Parcelable *)`. + * Non-remote object will be written by its own + * `Marshalling(Parcel &parcel)`. + * + * @param object Pointer to the input Parcelable object. + * @return Return True on success, or false if any error occur. + * @note '0' of `Int32_t` will write if input pointer is `nullptr`. + */ bool WriteParcelable(const Parcelable *object); + /** + * @brief Write a Parcelable object to this parcel, + * and enable its behavior of `HOLD_OBJECT`. + * + * @param object Smart pointer to the input parcelable object. + * @return Return True on success, or false if any error occur. + */ bool WriteStrongParcelable(const sptr &object); + /** + * @brief Write a remote object to this parcel. + * + * @param object Pointer to a remote object. + * @return Return True on success, or false if any error occur. + * @note If `HOLD_OBJECT` is enabled for the input object, it will stay + * alive as long as this parcel is alive. + * + */ bool WriteRemoteObject(const Parcelable *object); + /** + * @brief Write an object to this parcel. + * + * Use its own `Marshalling(Parcel &parcel)` when `nullptr` as input, + * otherwise use `WriteRemoteObject(const Parcelable *)`. + * + * @tparam T Specific class type of the input object. + * @param object Smart pointer to the input object. + * @return Return True on success, or false if any error occur. + */ template bool WriteObject(const sptr &object); + /** + * @brief Parse input data by this parcel. + * + * @param data Pointer to input data. + * @param size Size of input data(Bytes). + * @return Return True on success, or false if any error occur. + * @note Only read operation from this parcel is permitted after successful + * calling this method. + */ bool ParseFrom(uintptr_t data, size_t size); bool ReadBool(); @@ -211,51 +476,202 @@ public: bool ReadDouble(double &value); + /** + * @brief Read a block of data(buffer data) from this parcel. + * + * @param length Size of the buffer(Bytes). + * @return A `uint8_t` pointer to the buffer. + */ const uint8_t *ReadBuffer(size_t length); + /** + * @brief Read a block of data(buffer data) without padding(alignment) from + * this parcel. + * + * This method will read the effective data whose length specified by + * `length` and discard bytes for padding. + * + * @param length Effective size of the buffer(Bytes). + * @return A `uint8_t` pointer to the buffer. + * + */ const uint8_t *ReadUnpadBuffer(size_t length); + /** + * @brief Skip the next several bytes specifed by `bytes` in read process. + * + * @param bytes Skipped number of bytes. + */ void SkipBytes(size_t bytes); + /** + * @brief Read a C-style string from this parcel. + * + * @return A C-style string, which is represented by a `char`-type pointer. + */ const char *ReadCString(); + /** + * @brief Read a C++ string(`std::string`) object from this parcel. + * + * @return An `std::string` object. + */ const std::string ReadString(); + /** + * @brief Read a C++ string(`std::string`) object from this parcel to input + * object. + * + * @param value Target receiver `std::string` object. + * @return Return True on success, or false if any error occur. + */ bool ReadString(std::string &value); + /** + * @brief Read a C++ UTF-16 encoded string(`std::string`) object from this + * parcel. + * + * @return An `std::u16string` object. + */ const std::u16string ReadString16(); + /** + * @brief Read a C++ UTF-16 string(`std::u16string`) object from this + * parcel to input object. + * + * @param value Target receiver `std::string` object. + * @return Return True on success, or false if any error occur. + */ bool ReadString16(std::u16string &value); + /** + * @brief Read a C++ UTF-16 string(`std::u16string`) object and its length + * from this parcel. + * + * @param len `int32_t`-type variable passed by reference to receive the + * length. + * @return An output `std::u16string` object. + */ const std::u16string ReadString16WithLength(int32_t &len); + /** + * @brief Read a C++ string(`std::string`) object and its length from this + * parcel. + * + * @param len `int32_t`-type variable passed by reference to receive the + * length. + * @return An output `std::u8string` object. + */ const std::string ReadString8WithLength(int32_t &len); + /** + * @brief Set the read cursor to specified position. + * + * @param newPosition Specified position represented by offsets relative to + * the beginning of the data region. + * @return Return True on success, or false if any error occur. + */ bool RewindRead(size_t newPosition); + /** + * @brief Set the write cursor to specified position. + * + * @param offsets Specified position represented by offsets(Bytes) relative + * to the beginning of the data region. + * @return Return True on success, or false if any error occur. + */ bool RewindWrite(size_t offsets); + /** + * @brief Get current position of read cursor. + * + * @return Position represented by offsets(Bytes) relative to the beginning + * of the data region. + */ size_t GetReadPosition(); + /** + * @brief Get current position of write cursor. + * + * @return Position represented by offsets(Bytes) relative to the beginning + * of the data region. + */ size_t GetWritePosition(); + /** + * @brief Read a Parcelable(and its subclass) object from this parcel. + * + * @tparam T Specific class type of the output object. + * @return Object of specific class. + * @note `nullptr` will return if a '0' is read. + */ template T *ReadParcelable(); + /** + * @brief Read a Parcelable object from this parcel, and manage it by a + * smart pointer. + * + * @tparam T Specific class type of the output object. + * @return Object managed by a smart pointer. + * @note `nullptr` will return if a '0' is read. + */ template sptr ReadStrongParcelable(); + /** + * @brief Check if it is valid to read an object from current cursor. + * + * @return Return true if valid, otherwise return false. + */ bool CheckOffsets(); + /** + * @brief Read an object from this parcel. + * + * `CheckOffsets()` will call first to check whether it is valid to read an + * object. + * + * @tparam T Specific class type of the output object. + * @return A smart pointer to the object. + * @note `nullptr` will return if `CheckOffsets()` fail. + */ template sptr ReadObject(); + /** + * @brief Set the Allocator object of this parcel. + * + * New Allocator will reallocate the data region to which has been written. + * + * @param allocator Specified Allocator object. + * @return Return True on success, or false if any error occur. + */ bool SetAllocator(Allocator *allocator); + /** + * @brief Record an array of offsets of the object. + * + * @param offsets A pointer to the input array. + * @param offsetSize Size of the input array. + * @note It will return directly if fail. + */ void InjectOffsets(binder_size_t offsets, size_t offsetSize); + /** + * @brief Deallocate the data region, and reset this parcel. + */ void FlushBuffer(); + /** + * @brief Write an `std::vector` object to this parcel. + * + * @tparam T1 Specific class type for input vector. + * @tparam T2 Specific class type for write method of this parcel. + * @param val Input vector object passed by reference. + * @param Write Specific `Parcel::Write(T2 value)` method. + * @return Return True on success, or false if any error occur. + */ template bool WriteVector(const std::vector &val, bool (Parcel::*Write)(T2)); bool WriteBoolVector(const std::vector &val); @@ -272,6 +688,15 @@ public: bool WriteStringVector(const std::vector &val); bool WriteString16Vector(const std::vector &val); + /** + * @brief Read an `std::vector` object from this parcel. + * + * @tparam T1 Specific class type for output vector. + * @tparam T2 Specific class type for read method of this parcel. + * @param val Pointer to the output vector object. + * @param Write Specific `Parcel::Read(T2 value)` method. + * @return Return True on success, or false if any error occur. + */ template bool ReadVector(std::vector *val, bool (Parcel::*Read)(T &)); bool ReadBoolVector(std::vector *val); @@ -288,12 +713,13 @@ public: bool ReadStringVector(std::vector *val); bool ReadString16Vector(std::vector *val); + // write raw primitive type(i.e. 1byte for bool, 4byte for `int16_t`, etc.) bool WriteBoolUnaligned(bool value); bool WriteInt8Unaligned(int8_t value); bool WriteInt16Unaligned(int16_t value); bool WriteUint8Unaligned(uint8_t value); bool WriteUint16Unaligned(uint16_t value); - + // read raw primitive type(i.e. 1byte for bool, 4byte for `int16_t`, etc.) bool ReadBoolUnaligned(); bool ReadInt8Unaligned(int8_t &value); bool ReadInt16Unaligned(int16_t &value); @@ -301,7 +727,23 @@ public: bool ReadUint16Unaligned(uint16_t &value); protected: + /** + * @brief Record position of the written object, which are represented by + * offset from the beginning of the data region. + * + * @param offset Specific position. + * @return Return True on success, or false if any error occur. + */ bool WriteObjectOffset(binder_size_t offset); + + /** + * @brief Ensure number of the written objects is lower than the capacity of + * objects. + * + * If it is full, the capacity will be expanded. + * + * @return Return True on success, or false if any error occur. + */ bool EnsureObjectsCapacity(); private: -- Gitee