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