• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 Provide classes for data container implemented in c_utils.
20   *
21   * Including class Parcel, Parcelable and related memory Allocator.
22   */
23 
24 #ifndef OHOS_UTILS_PARCEL_H
25 #define OHOS_UTILS_PARCEL_H
26 
27 #include <string>
28 #include <vector>
29 #include "gmock/gmock.h"
30 #include "nocopyable.h"
31 #include "refbase.h"
32 #include "flat_obj.h"
33 
34 namespace OHOS {
35 const uint32_t NUM_TEST = 4;
36 class Parcel;
37 
38 /**
39  * @brief Interface for class whose Instance can be written into a Parcel.
40  *
41  * @note If this object is remote, its position intends to
42  * use in kernel data transaction.
43  */
44 class Parcelable : public virtual RefBase {
45 public:
46     virtual ~Parcelable() = default;
47 
48     Parcelable();
49     /**
50      * @brief Construct a new Parcelable object.
51      *
52      * @param asRemote Specifies whether this object is remote.
53      */
54     explicit Parcelable(bool asRemote);
55 
56     /**
57      * @brief Write a parcelable object to the given parcel.
58      *
59      * @param parcel Target parcel to write to.
60      * @return Return true being written on success or false if any error occur.
61      * @note If this object is remote, its position will be saved in the parcel.
62      * @note A static Unmarshalling function must also be implemented, so that
63      * you can get data from the given parcel into this parcelable object.
64      * See `static TestParcelable *Unmarshalling(Parcel &parcel)` as an example.
65      */
66     virtual bool Marshalling(Parcel &parcel) const = 0;
67 
68     /**
69      * @brief Enum flag to describe behaviors of the Parcelable object.
70      *
71      * @var IPC Indicate the object can be used in IPC.
72      * @var RPC Indicate the object can be used in RPC.
73      * @var HOLD_OBJECT Indicate the object will ensure
74      * alive during data transaction.
75      *
76      */
77     enum BehaviorFlag { IPC = 0x01, RPC = 0x02, HOLD_OBJECT = 0x10 };
78 
79     /**
80      * @brief Enable specified behavior.
81      *
82      * @param b Specific flag value.
83      * @see BehaviorFlag.
84      */
SetBehavior(BehaviorFlag b)85     inline void SetBehavior(BehaviorFlag b) const
86     {
87         behavior_ |= static_cast<uint8_t>(b);
88     }
89 
90     /**
91      * @brief Disable specified behavior.
92      *
93      * @param b Specific flag value. See BehaviorFlag.
94      */
ClearBehavior(BehaviorFlag b)95     inline void ClearBehavior(BehaviorFlag b) const
96     {
97         behavior_ &= static_cast<uint8_t>(~b);
98     }
99 
100     /**
101      * @brief Check whether specified behavior is enabled.
102      *
103      * @param b Specific flag value.
104      * @see BehaviorFlag.
105      */
TestBehavior(BehaviorFlag b)106     inline bool TestBehavior(BehaviorFlag b) const
107     {
108         return behavior_ & (static_cast<uint8_t>(b));
109     }
110 
111 public:
112     bool asRemote_; // if the object is remote
113     mutable uint8_t behavior_; // value of flag of behaviors
114 };
115 
116 /**
117  * @brief Interface for memory allocator of the data in Parcel.
118  */
119 class Allocator {
120 public:
121     virtual ~Allocator() = default;
122 
123     virtual void *Realloc(void *data, size_t newSize) = 0;
124 
125     virtual void *Alloc(size_t size) = 0;
126 
127     virtual void Dealloc(void *data) = 0;
128 };
129 
130 /**
131  * @brief Default implement of Allocator.
132  *
133  * @note Allocator defined by user for a parcel need be specified manually.
134  */
135 class DefaultAllocator : public Allocator {
136 public:
137     /**
138      * @brief Use `malloc()` to allocate memory for a parcel.
139      *
140      * @param size Size of desired memory region.
141      * @return Void-type pointer to the memory region.
142      */
143     void *Alloc(size_t size) override;
144 
145     /**
146      * @brief Use `free()` to deallocate memory for a parcel.
147      *
148      * @param data Void-type pointer to the memory region.
149      */
150     void Dealloc(void *data) override;
151 private:
152     /**
153      * @brief Use `realloc()` to reallocate memory for a parcel.
154      *
155      * @param data Void-type pointer to the existed memory region.
156      * @param newSize New desired size of memory region.
157      * @return Void-type pointer to the new memory region.
158      */
159     void *Realloc(void *data, size_t newSize) override;
160 };
161 
162 /**
163  * @brief A data/message container.
164  *
165  * Contains interfaces for writing and reading data of various types,
166  * including primitives, Parcelable objects etc.
167  *
168  * @note Usually used in IPC, RPC.
169  */
170 class Parcel {
171 public:
Parcel()172     Parcel() {}
173 
174     /**
175      * @brief Construct a new Parcel object with specified Allocator.
176      *
177      * @param allocator Specified Allocator.
178      */
Parcel(Allocator * allocator)179     explicit Parcel(Allocator *allocator)
180     {
181         (void)allocator;
182     }
183 
184     ~Parcel();
185     size_t GetDataSize() const;
186     uintptr_t GetData() const;
187     binder_size_t GetObjectOffsets() const;
188     size_t GetOffsetsSize() const;
189     size_t GetWritableBytes() const;
190     size_t GetReadableBytes() const;
191     size_t GetDataCapacity() const;
192     size_t GetMaxCapacity() const;
193     bool SetDataCapacity(size_t newCapacity);
194     bool SetDataSize(size_t dataSize);
195     bool SetMaxCapacity(size_t maxCapacity);
196     bool WriteBool(bool value);
197     bool WriteInt8(int8_t value);
198     bool WriteInt16(int16_t value);
199     bool WriteInt32(int32_t value);
200     bool WriteInt64(int64_t value);
201     bool WriteUint8(uint8_t value);
202     bool WriteUint16(uint16_t value);
203     bool WriteUint32(uint32_t value);
204     bool WriteUint64(uint64_t value);
205     bool WriteFloat(float value);
206     bool WriteDouble(double value);
207     bool WritePointer(uintptr_t value);
208     bool WriteBuffer(const void *data, size_t size);
209     bool WriteBufferAddTerminator(const void *data, size_t size, size_t typeSize);
210     bool WriteUnpadBuffer(const void *data, size_t size);
211     bool WriteCString(const char *value);
212     bool WriteString(const std::string &value);
213     bool WriteString16(const std::u16string &value);
214     bool WriteString16WithLength(const char16_t *value, size_t len);
215     bool WriteString8WithLength(const char *value, size_t len);
216     bool WriteParcelable(const Parcelable *object);
217     bool WriteStrongParcelable(const sptr<Parcelable> &object);
218     bool WriteRemoteObject(const Parcelable *object);
219     template<typename T>
220     bool WriteObject(const sptr<T> &object);
221     bool ParseFrom(uintptr_t data, size_t size);
222     bool ReadBool();
223     int8_t ReadInt8();
224     int16_t ReadInt16();
225     int32_t ReadInt32();
226     int64_t ReadInt64();
ReadUint8()227     uint8_t ReadUint8()
228     {
229         if (writable_ == true) {
230             return 0;
231         }
232         return NUM_TEST;
233     }
234     uint16_t ReadUint16();
235     uint32_t ReadUint32();
236     uint64_t ReadUint64();
237     float ReadFloat();
238     double ReadDouble();
239     uintptr_t ReadPointer();
240     bool ReadBool(bool &value);
241     bool ReadInt8(int8_t &value);
242     bool ReadInt16(int16_t &value);
243     bool ReadInt32(int32_t &value);
244     bool ReadInt64(int64_t &value);
245     bool ReadUint8(uint8_t &value);
246     bool ReadUint16(uint16_t &value);
247     bool ReadUint32(uint32_t &value);
248     bool ReadUint64(uint64_t &value);
249     bool ReadFloat(float &value);
250     bool ReadDouble(double &value);
251     const uint8_t *ReadBuffer(size_t length);
252     const uint8_t *ReadUnpadBuffer(size_t length);
253     void SkipBytes(size_t bytes);
254     const char *ReadCString();
255     const std::string ReadString();
256     bool ReadString(std::string &value);
257     const std::u16string ReadString16();
258     bool ReadString16(std::u16string &value);
259     const std::u16string ReadString16WithLength(int32_t &len);
260     const std::string ReadString8WithLength(int32_t &len);
261     bool RewindRead(size_t newPosition);
262     bool RewindWrite(size_t offsets);
263     size_t GetReadPosition();
264     size_t GetWritePosition();
265     template <typename T>
266     T *ReadParcelable();
267 
268     template <typename T>
269     sptr<T> ReadStrongParcelable();
270 
271     bool CheckOffsets();
272 
273     template<typename T>
274     sptr<T> ReadObject();
275 
276     bool SetAllocator(Allocator *allocator);
277 
278     void InjectOffsets(binder_size_t offsets, size_t offsetSize);
279     void FlushBuffer();
280     template <typename T1, typename T2>
281     bool WriteVector(const std::vector<T1> &val, bool (Parcel::*write)(T2));
282     bool WriteBoolVector(const std::vector<bool> &val);
283     bool WriteInt8Vector(const std::vector<int8_t> &val);
284     bool WriteInt16Vector(const std::vector<int16_t> &val);
285     bool WriteInt32Vector(const std::vector<int32_t> &val);
286     bool WriteInt64Vector(const std::vector<int64_t> &val);
287     bool WriteUInt8Vector(const std::vector<uint8_t> &val);
288     bool WriteUInt16Vector(const std::vector<uint16_t> &val);
289     bool WriteUInt32Vector(const std::vector<uint32_t> &val);
290     bool WriteUInt64Vector(const std::vector<uint64_t> &val);
291     bool WriteFloatVector(const std::vector<float> &val);
292     bool WriteDoubleVector(const std::vector<double> &val);
293     bool WriteStringVector(const std::vector<std::string> &val);
294     bool WriteString16Vector(const std::vector<std::u16string> &val);
295     template <typename T>
296     bool ReadVector(std::vector<T> *val, bool (Parcel::*read)(T &));
297     bool ReadBoolVector(std::vector<bool> *val);
298     bool ReadInt8Vector(std::vector<int8_t> *val);
299     bool ReadInt16Vector(std::vector<int16_t> *val);
300     bool ReadInt32Vector(std::vector<int32_t> *val);
301     bool ReadInt64Vector(std::vector<int64_t> *val);
302     bool ReadUInt8Vector(std::vector<uint8_t> *val);
303     bool ReadUInt16Vector(std::vector<uint16_t> *val);
304     bool ReadUInt32Vector(std::vector<uint32_t> *val);
305     bool ReadUInt64Vector(std::vector<uint64_t> *val);
306     bool ReadFloatVector(std::vector<float> *val);
307     bool ReadDoubleVector(std::vector<double> *val);
308     bool ReadStringVector(std::vector<std::string> *val);
309     bool ReadString16Vector(std::vector<std::u16string> *val);
310     bool WriteBoolUnaligned(bool value);
311     bool WriteInt8Unaligned(int8_t value);
312     bool WriteInt16Unaligned(int16_t value);
313     bool WriteUint8Unaligned(uint8_t value);
314     bool WriteUint16Unaligned(uint16_t value);
315     bool ReadBoolUnaligned();
316     bool ReadInt8Unaligned(int8_t &value);
317     bool ReadInt16Unaligned(int16_t &value);
318     bool ReadUint8Unaligned(uint8_t &value);
319     bool ReadUint16Unaligned(uint16_t &value);
320 
321 protected:
322     bool WriteObjectOffset(binder_size_t offset);
323     bool EnsureObjectsCapacity();
324 private:
325     DISALLOW_COPY_AND_MOVE(Parcel);
326     template <typename T>
327     bool Write(T value);
328 
329     template <typename T>
330     bool Read(T &value);
331 
332     template <typename T>
333     T Read();
334 
335     template <typename T>
336     bool ReadPadded(T &value);
337 
GetPadSize(size_t size)338     inline size_t GetPadSize(size_t size)
339     {
340         const size_t sizeOffset = 3;
341         return (((size + sizeOffset) & (~sizeOffset)) - size);
342     }
343 
344     size_t CalcNewCapacity(size_t minCapacity);
345 
346     bool WriteDataBytes(const void *data, size_t size);
347 
348     void WritePadBytes(size_t padded);
349 
350     bool EnsureWritableCapacity(size_t desireCapacity);
351 
352     bool WriteParcelableOffset(size_t offset);
353 
354 private:
355     uint8_t *data_;
356     size_t readCursor_;
357     size_t writeCursor_;
358     size_t dataSize_;
359     size_t dataCapacity_;
360     size_t maxDataCapacity_;
361     binder_size_t *objectOffsets_;
362     size_t objectCursor_;
363     size_t objectsCapacity_;
364     Allocator *allocator_;
365     std::vector<sptr<Parcelable>> objectHolder_;
366     bool writable_ = true;
367 };
368 
369 template <typename T>
WriteObject(const sptr<T> & object)370 bool Parcel::WriteObject(const sptr<T> &object)
371 {
372     if (object == nullptr) {
373         return T::Marshalling(*this, object);
374     }
375     return WriteRemoteObject(object.GetRefPtr());
376 }
377 
378 template <typename T>
ReadObject()379 sptr<T> Parcel::ReadObject()
380 {
381     if (!this->CheckOffsets()) {
382         return nullptr;
383     }
384     sptr<T> res(T::Unmarshalling(*this));
385     return res;
386 }
387 
388 // Read data from the given parcel into this parcelable object.
389 template <typename T>
ReadParcelable()390 T *Parcel::ReadParcelable()
391 {
392     int32_t size = this->ReadInt32();
393     if (size == 0) {
394         return nullptr;
395     }
396     return T::Unmarshalling(*this);
397 }
398 
399 // Read data from the given parcel into this parcelable object, return sptr.
400 template <typename T>
ReadStrongParcelable()401 sptr<T> Parcel::ReadStrongParcelable()
402 {
403     int32_t size = this->ReadInt32();
404     if (size == 0) {
405         return nullptr;
406     }
407     sptr<T> res(T::Unmarshalling(*this));
408     return res;
409 }
410 
411 } // namespace OHOS
412 #endif
413