blob: ffa5caedba50f7a33ffb1839e5c4abf20e6ae23e [file] [log] [blame]
Steven Moreland2e87adc2018-08-20 19:47:00 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <android/binder_parcel.h>
Steven Moreland4d5ad492018-09-13 12:49:16 -070018#include "parcel_internal.h"
Steven Moreland2e87adc2018-08-20 19:47:00 -070019
Steven Moreland4d5ad492018-09-13 12:49:16 -070020#include "ibinder_internal.h"
Steven Moreland5d62e442018-09-13 15:01:02 -070021#include "status_internal.h"
Steven Moreland2e87adc2018-08-20 19:47:00 -070022
Steven Moreland7b06f592018-10-03 19:25:32 -070023#include <limits>
24
25#include <android-base/logging.h>
Steven Moreland063f2362018-10-18 12:49:11 -070026#include <android-base/unique_fd.h>
Steven Moreland2e87adc2018-08-20 19:47:00 -070027#include <binder/Parcel.h>
Steven Moreland063f2362018-10-18 12:49:11 -070028#include <binder/ParcelFileDescriptor.h>
Steven Moreland7b06f592018-10-03 19:25:32 -070029#include <utils/Unicode.h>
Steven Moreland2e87adc2018-08-20 19:47:00 -070030
31using ::android::IBinder;
32using ::android::Parcel;
33using ::android::sp;
Steven Moreland5d62e442018-09-13 15:01:02 -070034using ::android::status_t;
Steven Moreland063f2362018-10-18 12:49:11 -070035using ::android::base::unique_fd;
36using ::android::os::ParcelFileDescriptor;
Steven Moreland2e87adc2018-08-20 19:47:00 -070037
Steven Morelanda8845662018-10-12 11:53:03 -070038template <typename T>
39using ContiguousArrayGetter = T* (*)(void* arrayData);
40template <typename T>
41using ArrayGetter = T (*)(const void* arrayData, size_t index);
42template <typename T>
43using ArraySetter = void (*)(void* arrayData, size_t index, T value);
44
45template <typename T>
46binder_status_t WriteArray(AParcel* parcel, const T* array, size_t length) {
47 if (length > std::numeric_limits<int32_t>::max()) return STATUS_BAD_VALUE;
48
49 Parcel* rawParcel = parcel->get();
50
51 status_t status = rawParcel->writeInt32(static_cast<int32_t>(length));
52 if (status != STATUS_OK) return PruneStatusT(status);
53
54 int32_t size = 0;
55 if (__builtin_smul_overflow(sizeof(T), length, &size)) return STATUS_NO_MEMORY;
56
57 void* const data = rawParcel->writeInplace(size);
58 if (data == nullptr) return STATUS_NO_MEMORY;
59
60 memcpy(data, array, size);
61
62 return STATUS_OK;
63}
64
65// Each element in a char16_t array is converted to an int32_t (not packed).
66template <>
67binder_status_t WriteArray<char16_t>(AParcel* parcel, const char16_t* array, size_t length) {
68 if (length > std::numeric_limits<int32_t>::max()) return STATUS_BAD_VALUE;
69
70 Parcel* rawParcel = parcel->get();
71
72 status_t status = rawParcel->writeInt32(static_cast<int32_t>(length));
73 if (status != STATUS_OK) return PruneStatusT(status);
74
75 int32_t size = 0;
76 if (__builtin_smul_overflow(sizeof(char16_t), length, &size)) return STATUS_NO_MEMORY;
77
78 for (int32_t i = 0; i < length; i++) {
79 status = rawParcel->writeChar(array[i]);
80
81 if (status != STATUS_OK) return PruneStatusT(status);
82 }
83
84 return STATUS_OK;
85}
86
87template <typename T>
88binder_status_t ReadArray(const AParcel* parcel, void** arrayData,
89 AParcel_arrayReallocator reallocator, ContiguousArrayGetter<T> getter) {
90 const Parcel* rawParcel = parcel->get();
91
92 int32_t length;
93 status_t status = rawParcel->readInt32(&length);
94
95 if (status != STATUS_OK) return PruneStatusT(status);
96 if (length < 0) return STATUS_UNEXPECTED_NULL;
97
98 *arrayData = reallocator(*arrayData, length);
99 if (*arrayData == nullptr) return STATUS_NO_MEMORY;
100
101 if (length == 0) return STATUS_OK;
102
103 T* array = getter(*arrayData);
104 if (array == nullptr) return STATUS_NO_MEMORY;
105
106 int32_t size = 0;
107 if (__builtin_smul_overflow(sizeof(T), length, &size)) return STATUS_NO_MEMORY;
108
109 const void* data = rawParcel->readInplace(size);
110 if (data == nullptr) return STATUS_NO_MEMORY;
111
112 memcpy(array, data, size);
113
114 return STATUS_OK;
115}
116
117// Each element in a char16_t array is converted to an int32_t (not packed)
118template <>
119binder_status_t ReadArray<char16_t>(const AParcel* parcel, void** arrayData,
120 AParcel_arrayReallocator reallocator,
121 ContiguousArrayGetter<char16_t> getter) {
122 const Parcel* rawParcel = parcel->get();
123
124 int32_t length;
125 status_t status = rawParcel->readInt32(&length);
126
127 if (status != STATUS_OK) return PruneStatusT(status);
128 if (length < 0) return STATUS_UNEXPECTED_NULL;
129
130 *arrayData = reallocator(*arrayData, length);
131 if (*arrayData == nullptr) return STATUS_NO_MEMORY;
132
133 if (length == 0) return STATUS_OK;
134
135 char16_t* array = getter(*arrayData);
136 if (array == nullptr) return STATUS_NO_MEMORY;
137
138 int32_t size = 0;
139 if (__builtin_smul_overflow(sizeof(char16_t), length, &size)) return STATUS_NO_MEMORY;
140
141 for (int32_t i = 0; i < length; i++) {
142 status = rawParcel->readChar(array + i);
143
144 if (status != STATUS_OK) return PruneStatusT(status);
145 }
146
147 return STATUS_OK;
148}
149
150template <typename T>
151binder_status_t WriteArray(AParcel* parcel, const void* arrayData, ArrayGetter<T> getter,
152 size_t length, status_t (Parcel::*write)(T)) {
153 if (length > std::numeric_limits<int32_t>::max()) return STATUS_BAD_VALUE;
154
155 Parcel* rawParcel = parcel->get();
156
157 status_t status = rawParcel->writeInt32(static_cast<int32_t>(length));
158 if (status != STATUS_OK) return PruneStatusT(status);
159
160 for (size_t i = 0; i < length; i++) {
161 status = (rawParcel->*write)(getter(arrayData, i));
162
163 if (status != STATUS_OK) return PruneStatusT(status);
164 }
165
166 return STATUS_OK;
167}
168
169template <typename T>
170binder_status_t ReadArray(const AParcel* parcel, void** arrayData,
171 AParcel_arrayReallocator reallocator, ArraySetter<T> setter,
172 status_t (Parcel::*read)(T*) const) {
173 const Parcel* rawParcel = parcel->get();
174
175 int32_t length;
176 status_t status = rawParcel->readInt32(&length);
177
178 if (status != STATUS_OK) return PruneStatusT(status);
179 if (length < 0) return STATUS_UNEXPECTED_NULL;
180
181 *arrayData = reallocator(*arrayData, length);
182 if (*arrayData == nullptr) return STATUS_NO_MEMORY;
183
184 for (size_t i = 0; i < length; i++) {
185 T readTarget;
186 status = (rawParcel->*read)(&readTarget);
187 if (status != STATUS_OK) return PruneStatusT(status);
188
189 setter(*arrayData, i, readTarget);
190 }
191
192 return STATUS_OK;
193}
194
Steven Moreland9b80e282018-09-19 13:57:23 -0700195void AParcel_delete(AParcel* parcel) {
196 delete parcel;
Steven Morelandcaa776c2018-09-04 13:48:11 -0700197}
198
Steven Moreland2e87adc2018-08-20 19:47:00 -0700199binder_status_t AParcel_writeStrongBinder(AParcel* parcel, AIBinder* binder) {
Steven Morelandc0e46d32018-09-12 15:40:49 -0700200 sp<IBinder> writeBinder = binder != nullptr ? binder->getBinder() : nullptr;
Steven Morelandf18615b2018-09-14 11:43:06 -0700201 return parcel->get()->writeStrongBinder(writeBinder);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700202}
203binder_status_t AParcel_readStrongBinder(const AParcel* parcel, AIBinder** binder) {
204 sp<IBinder> readBinder = nullptr;
Steven Morelandf18615b2018-09-14 11:43:06 -0700205 status_t status = parcel->get()->readStrongBinder(&readBinder);
Steven Moreland5d62e442018-09-13 15:01:02 -0700206 if (status != STATUS_OK) {
207 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700208 }
Steven Moreland94968952018-09-05 14:42:59 -0700209 sp<AIBinder> ret = ABpBinder::lookupOrCreateFromBinder(readBinder);
Steven Moreland71cddc32018-08-30 23:39:22 -0700210 AIBinder_incStrong(ret.get());
211 *binder = ret.get();
Steven Moreland5d62e442018-09-13 15:01:02 -0700212 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700213}
214binder_status_t AParcel_readNullableStrongBinder(const AParcel* parcel, AIBinder** binder) {
215 sp<IBinder> readBinder = nullptr;
Steven Morelandf18615b2018-09-14 11:43:06 -0700216 status_t status = parcel->get()->readNullableStrongBinder(&readBinder);
Steven Moreland5d62e442018-09-13 15:01:02 -0700217 if (status != STATUS_OK) {
218 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700219 }
Steven Moreland94968952018-09-05 14:42:59 -0700220 sp<AIBinder> ret = ABpBinder::lookupOrCreateFromBinder(readBinder);
Steven Moreland71cddc32018-08-30 23:39:22 -0700221 AIBinder_incStrong(ret.get());
222 *binder = ret.get();
Steven Moreland5d62e442018-09-13 15:01:02 -0700223 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700224}
Steven Moreland063f2362018-10-18 12:49:11 -0700225
226binder_status_t AParcel_writeParcelFileDescriptor(AParcel* parcel, int fd) {
227 ParcelFileDescriptor parcelFd((unique_fd(fd)));
228
229 status_t status = parcel->get()->writeParcelable(parcelFd);
230
231 // ownership is retained by caller
232 (void)parcelFd.release().release();
233
234 return PruneStatusT(status);
235}
236
237binder_status_t AParcel_readParcelFileDescriptor(const AParcel* parcel, int* fd) {
238 ParcelFileDescriptor parcelFd;
239 // status_t status = parcelFd.readFromParcel(parcel->get());
240 status_t status = parcel->get()->readParcelable(&parcelFd);
241 if (status != STATUS_OK) return PruneStatusT(status);
242
243 *fd = parcelFd.release().release();
244 return STATUS_OK;
245}
246
Steven Moreland9a51db82018-09-14 10:59:35 -0700247binder_status_t AParcel_writeStatusHeader(AParcel* parcel, const AStatus* status) {
248 return PruneStatusT(status->get()->writeToParcel(parcel->get()));
249}
250binder_status_t AParcel_readStatusHeader(const AParcel* parcel, AStatus** status) {
251 ::android::binder::Status bstatus;
252 binder_status_t ret = PruneStatusT(bstatus.readFromParcel(*parcel->get()));
253 if (ret == EX_NONE) {
254 *status = new AStatus(std::move(bstatus));
255 }
256 return ret;
257}
Steven Moreland2e87adc2018-08-20 19:47:00 -0700258
Steven Moreland7b06f592018-10-03 19:25:32 -0700259binder_status_t AParcel_writeString(AParcel* parcel, const char* string, size_t length) {
260 const uint8_t* str8 = (uint8_t*)string;
261
262 const ssize_t len16 = utf8_to_utf16_length(str8, length);
263
264 if (len16 < 0 || len16 >= std::numeric_limits<int32_t>::max()) {
265 LOG(WARNING) << __func__ << ": Invalid string length: " << len16;
266 return STATUS_BAD_VALUE;
267 }
268
269 status_t err = parcel->get()->writeInt32(len16);
270 if (err) {
271 return PruneStatusT(err);
272 }
273
274 void* str16 = parcel->get()->writeInplace((len16 + 1) * sizeof(char16_t));
275 if (str16 == nullptr) {
276 return STATUS_NO_MEMORY;
277 }
278
279 utf8_to_utf16(str8, length, (char16_t*)str16, (size_t)len16 + 1);
280
281 return STATUS_OK;
282}
283
Steven Moreland01ee4932018-10-18 10:27:20 -0700284binder_status_t AParcel_readString(const AParcel* parcel, AParcel_stringReallocator reallocator,
285 AParcel_stringGetter getter, void** stringData) {
Steven Moreland7b06f592018-10-03 19:25:32 -0700286 size_t len16;
287 const char16_t* str16 = parcel->get()->readString16Inplace(&len16);
288
289 if (str16 == nullptr) {
290 LOG(WARNING) << __func__ << ": Failed to read string in place.";
291 return STATUS_UNEXPECTED_NULL;
292 }
293
294 ssize_t len8;
295
296 if (len16 == 0) {
297 len8 = 1;
298 } else {
299 len8 = utf16_to_utf8_length(str16, len16) + 1;
300 }
301
302 if (len8 <= 0 || len8 >= std::numeric_limits<int32_t>::max()) {
303 LOG(WARNING) << __func__ << ": Invalid string length: " << len8;
304 return STATUS_BAD_VALUE;
305 }
306
307 *stringData = reallocator(*stringData, len8);
Steven Morelanda8845662018-10-12 11:53:03 -0700308
309 if (*stringData == nullptr) {
310 return STATUS_NO_MEMORY;
311 }
312
Steven Moreland7b06f592018-10-03 19:25:32 -0700313 char* str8 = getter(*stringData);
314
315 if (str8 == nullptr) {
Steven Moreland01ee4932018-10-18 10:27:20 -0700316 LOG(WARNING) << __func__ << ": AParcel_stringReallocator failed to allocate.";
Steven Moreland7b06f592018-10-03 19:25:32 -0700317 return STATUS_NO_MEMORY;
318 }
319
320 utf16_to_utf8(str16, len16, str8, len8);
321
322 return STATUS_OK;
323}
324
Steven Moreland2e87adc2018-08-20 19:47:00 -0700325// See gen_parcel_helper.py. These auto-generated read/write methods use the same types for
326// libbinder and this library.
327// @START
328binder_status_t AParcel_writeInt32(AParcel* parcel, int32_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700329 status_t status = parcel->get()->writeInt32(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700330 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700331}
332
333binder_status_t AParcel_writeUint32(AParcel* parcel, uint32_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700334 status_t status = parcel->get()->writeUint32(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700335 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700336}
337
338binder_status_t AParcel_writeInt64(AParcel* parcel, int64_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700339 status_t status = parcel->get()->writeInt64(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700340 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700341}
342
343binder_status_t AParcel_writeUint64(AParcel* parcel, uint64_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700344 status_t status = parcel->get()->writeUint64(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700345 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700346}
347
348binder_status_t AParcel_writeFloat(AParcel* parcel, float value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700349 status_t status = parcel->get()->writeFloat(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700350 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700351}
352
353binder_status_t AParcel_writeDouble(AParcel* parcel, double value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700354 status_t status = parcel->get()->writeDouble(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700355 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700356}
357
358binder_status_t AParcel_writeBool(AParcel* parcel, bool value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700359 status_t status = parcel->get()->writeBool(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700360 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700361}
362
363binder_status_t AParcel_writeChar(AParcel* parcel, char16_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700364 status_t status = parcel->get()->writeChar(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700365 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700366}
367
368binder_status_t AParcel_writeByte(AParcel* parcel, int8_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700369 status_t status = parcel->get()->writeByte(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700370 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700371}
372
373binder_status_t AParcel_readInt32(const AParcel* parcel, int32_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700374 status_t status = parcel->get()->readInt32(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700375 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700376}
377
378binder_status_t AParcel_readUint32(const AParcel* parcel, uint32_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700379 status_t status = parcel->get()->readUint32(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700380 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700381}
382
383binder_status_t AParcel_readInt64(const AParcel* parcel, int64_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700384 status_t status = parcel->get()->readInt64(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700385 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700386}
387
388binder_status_t AParcel_readUint64(const AParcel* parcel, uint64_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700389 status_t status = parcel->get()->readUint64(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700390 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700391}
392
393binder_status_t AParcel_readFloat(const AParcel* parcel, float* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700394 status_t status = parcel->get()->readFloat(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700395 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700396}
397
398binder_status_t AParcel_readDouble(const AParcel* parcel, double* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700399 status_t status = parcel->get()->readDouble(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700400 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700401}
402
403binder_status_t AParcel_readBool(const AParcel* parcel, bool* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700404 status_t status = parcel->get()->readBool(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700405 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700406}
407
408binder_status_t AParcel_readChar(const AParcel* parcel, char16_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700409 status_t status = parcel->get()->readChar(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700410 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700411}
412
413binder_status_t AParcel_readByte(const AParcel* parcel, int8_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700414 status_t status = parcel->get()->readByte(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700415 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700416}
417
Steven Morelanda8845662018-10-12 11:53:03 -0700418binder_status_t AParcel_writeInt32Array(AParcel* parcel, const int32_t* value, size_t length) {
419 return WriteArray<int32_t>(parcel, value, length);
420}
421
422binder_status_t AParcel_writeUint32Array(AParcel* parcel, const uint32_t* value, size_t length) {
423 return WriteArray<uint32_t>(parcel, value, length);
424}
425
426binder_status_t AParcel_writeInt64Array(AParcel* parcel, const int64_t* value, size_t length) {
427 return WriteArray<int64_t>(parcel, value, length);
428}
429
430binder_status_t AParcel_writeUint64Array(AParcel* parcel, const uint64_t* value, size_t length) {
431 return WriteArray<uint64_t>(parcel, value, length);
432}
433
434binder_status_t AParcel_writeFloatArray(AParcel* parcel, const float* value, size_t length) {
435 return WriteArray<float>(parcel, value, length);
436}
437
438binder_status_t AParcel_writeDoubleArray(AParcel* parcel, const double* value, size_t length) {
439 return WriteArray<double>(parcel, value, length);
440}
441
442binder_status_t AParcel_writeBoolArray(AParcel* parcel, const void* arrayData,
443 AParcel_boolArrayGetter getter, size_t length) {
444 return WriteArray<bool>(parcel, arrayData, getter, length, &Parcel::writeBool);
445}
446
447binder_status_t AParcel_writeCharArray(AParcel* parcel, const char16_t* value, size_t length) {
448 return WriteArray<char16_t>(parcel, value, length);
449}
450
451binder_status_t AParcel_writeByteArray(AParcel* parcel, const int8_t* value, size_t length) {
452 return WriteArray<int8_t>(parcel, value, length);
453}
454
455binder_status_t AParcel_readInt32Array(const AParcel* parcel, void** arrayData,
456 AParcel_arrayReallocator reallocator,
457 AParcel_int32ArrayGetter getter) {
458 return ReadArray<int32_t>(parcel, arrayData, reallocator, getter);
459}
460
461binder_status_t AParcel_readUint32Array(const AParcel* parcel, void** arrayData,
462 AParcel_arrayReallocator reallocator,
463 AParcel_uint32ArrayGetter getter) {
464 return ReadArray<uint32_t>(parcel, arrayData, reallocator, getter);
465}
466
467binder_status_t AParcel_readInt64Array(const AParcel* parcel, void** arrayData,
468 AParcel_arrayReallocator reallocator,
469 AParcel_int64ArrayGetter getter) {
470 return ReadArray<int64_t>(parcel, arrayData, reallocator, getter);
471}
472
473binder_status_t AParcel_readUint64Array(const AParcel* parcel, void** arrayData,
474 AParcel_arrayReallocator reallocator,
475 AParcel_uint64ArrayGetter getter) {
476 return ReadArray<uint64_t>(parcel, arrayData, reallocator, getter);
477}
478
479binder_status_t AParcel_readFloatArray(const AParcel* parcel, void** arrayData,
480 AParcel_arrayReallocator reallocator,
481 AParcel_floatArrayGetter getter) {
482 return ReadArray<float>(parcel, arrayData, reallocator, getter);
483}
484
485binder_status_t AParcel_readDoubleArray(const AParcel* parcel, void** arrayData,
486 AParcel_arrayReallocator reallocator,
487 AParcel_doubleArrayGetter getter) {
488 return ReadArray<double>(parcel, arrayData, reallocator, getter);
489}
490
491binder_status_t AParcel_readBoolArray(const AParcel* parcel, void** arrayData,
492 AParcel_arrayReallocator reallocator,
493 AParcel_boolArraySetter setter) {
494 return ReadArray<bool>(parcel, arrayData, reallocator, setter, &Parcel::readBool);
495}
496
497binder_status_t AParcel_readCharArray(const AParcel* parcel, void** arrayData,
498 AParcel_arrayReallocator reallocator,
499 AParcel_charArrayGetter getter) {
500 return ReadArray<char16_t>(parcel, arrayData, reallocator, getter);
501}
502
503binder_status_t AParcel_readByteArray(const AParcel* parcel, void** arrayData,
504 AParcel_arrayReallocator reallocator,
505 AParcel_byteArrayGetter getter) {
506 return ReadArray<int8_t>(parcel, arrayData, reallocator, getter);
507}
508
Steven Moreland2e87adc2018-08-20 19:47:00 -0700509// @END