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