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