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