blob: cfe0f460e5437816bdae42b034b21d8f86f6b3f9 [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 Moreland2e87adc2018-08-20 19:47:00 -070026#include <binder/Parcel.h>
Steven Moreland7b06f592018-10-03 19:25:32 -070027#include <utils/Unicode.h>
Steven Moreland2e87adc2018-08-20 19:47:00 -070028
29using ::android::IBinder;
30using ::android::Parcel;
31using ::android::sp;
Steven Moreland5d62e442018-09-13 15:01:02 -070032using ::android::status_t;
Steven Moreland2e87adc2018-08-20 19:47:00 -070033
Steven Morelanda8845662018-10-12 11:53:03 -070034template <typename T>
Steven Moreland71872f82018-10-29 11:46:56 -070035using ContiguousArrayAllocator = T* (*)(void* arrayData, size_t length);
36
37template <typename T>
38using ArrayAllocator = bool (*)(void* arrayData, size_t length);
Steven Morelanda8845662018-10-12 11:53:03 -070039template <typename T>
40using ArrayGetter = T (*)(const void* arrayData, size_t index);
41template <typename T>
42using ArraySetter = void (*)(void* arrayData, size_t index, T value);
43
44template <typename T>
45binder_status_t WriteArray(AParcel* parcel, const T* array, size_t length) {
46 if (length > std::numeric_limits<int32_t>::max()) return STATUS_BAD_VALUE;
47
48 Parcel* rawParcel = parcel->get();
49
50 status_t status = rawParcel->writeInt32(static_cast<int32_t>(length));
51 if (status != STATUS_OK) return PruneStatusT(status);
52
53 int32_t size = 0;
54 if (__builtin_smul_overflow(sizeof(T), length, &size)) return STATUS_NO_MEMORY;
55
56 void* const data = rawParcel->writeInplace(size);
57 if (data == nullptr) return STATUS_NO_MEMORY;
58
59 memcpy(data, array, size);
60
61 return STATUS_OK;
62}
63
64// Each element in a char16_t array is converted to an int32_t (not packed).
65template <>
66binder_status_t WriteArray<char16_t>(AParcel* parcel, const char16_t* array, size_t length) {
67 if (length > std::numeric_limits<int32_t>::max()) return STATUS_BAD_VALUE;
68
69 Parcel* rawParcel = parcel->get();
70
71 status_t status = rawParcel->writeInt32(static_cast<int32_t>(length));
72 if (status != STATUS_OK) return PruneStatusT(status);
73
74 int32_t size = 0;
75 if (__builtin_smul_overflow(sizeof(char16_t), length, &size)) return STATUS_NO_MEMORY;
76
77 for (int32_t i = 0; i < length; i++) {
78 status = rawParcel->writeChar(array[i]);
79
80 if (status != STATUS_OK) return PruneStatusT(status);
81 }
82
83 return STATUS_OK;
84}
85
86template <typename T>
Steven Moreland71872f82018-10-29 11:46:56 -070087binder_status_t ReadArray(const AParcel* parcel, void* arrayData,
88 ContiguousArrayAllocator<T> allocator) {
Steven Morelanda8845662018-10-12 11:53:03 -070089 const Parcel* rawParcel = parcel->get();
90
91 int32_t length;
92 status_t status = rawParcel->readInt32(&length);
93
94 if (status != STATUS_OK) return PruneStatusT(status);
95 if (length < 0) return STATUS_UNEXPECTED_NULL;
96
Steven Moreland71872f82018-10-29 11:46:56 -070097 T* array = allocator(arrayData, length);
Steven Morelanda8845662018-10-12 11:53:03 -070098 if (length == 0) return STATUS_OK;
Steven Morelanda8845662018-10-12 11:53:03 -070099 if (array == nullptr) return STATUS_NO_MEMORY;
100
101 int32_t size = 0;
102 if (__builtin_smul_overflow(sizeof(T), length, &size)) return STATUS_NO_MEMORY;
103
104 const void* data = rawParcel->readInplace(size);
105 if (data == nullptr) return STATUS_NO_MEMORY;
106
107 memcpy(array, data, size);
108
109 return STATUS_OK;
110}
111
112// Each element in a char16_t array is converted to an int32_t (not packed)
113template <>
Steven Moreland71872f82018-10-29 11:46:56 -0700114binder_status_t ReadArray<char16_t>(const AParcel* parcel, void* arrayData,
115 ContiguousArrayAllocator<char16_t> allocator) {
Steven Morelanda8845662018-10-12 11:53:03 -0700116 const Parcel* rawParcel = parcel->get();
117
118 int32_t length;
119 status_t status = rawParcel->readInt32(&length);
120
121 if (status != STATUS_OK) return PruneStatusT(status);
122 if (length < 0) return STATUS_UNEXPECTED_NULL;
123
Steven Moreland71872f82018-10-29 11:46:56 -0700124 char16_t* array = allocator(arrayData, length);
Steven Morelanda8845662018-10-12 11:53:03 -0700125 if (length == 0) return STATUS_OK;
Steven Morelanda8845662018-10-12 11:53:03 -0700126 if (array == nullptr) return STATUS_NO_MEMORY;
127
128 int32_t size = 0;
129 if (__builtin_smul_overflow(sizeof(char16_t), length, &size)) return STATUS_NO_MEMORY;
130
131 for (int32_t i = 0; i < length; i++) {
132 status = rawParcel->readChar(array + i);
133
134 if (status != STATUS_OK) return PruneStatusT(status);
135 }
136
137 return STATUS_OK;
138}
139
140template <typename T>
141binder_status_t WriteArray(AParcel* parcel, const void* arrayData, ArrayGetter<T> getter,
142 size_t length, status_t (Parcel::*write)(T)) {
143 if (length > std::numeric_limits<int32_t>::max()) return STATUS_BAD_VALUE;
144
145 Parcel* rawParcel = parcel->get();
146
147 status_t status = rawParcel->writeInt32(static_cast<int32_t>(length));
148 if (status != STATUS_OK) return PruneStatusT(status);
149
150 for (size_t i = 0; i < length; i++) {
151 status = (rawParcel->*write)(getter(arrayData, i));
152
153 if (status != STATUS_OK) return PruneStatusT(status);
154 }
155
156 return STATUS_OK;
157}
158
159template <typename T>
Steven Moreland71872f82018-10-29 11:46:56 -0700160binder_status_t ReadArray(const AParcel* parcel, void* arrayData, ArrayAllocator<T> allocator,
161 ArraySetter<T> setter, status_t (Parcel::*read)(T*) const) {
Steven Morelanda8845662018-10-12 11:53:03 -0700162 const Parcel* rawParcel = parcel->get();
163
164 int32_t length;
165 status_t status = rawParcel->readInt32(&length);
166
167 if (status != STATUS_OK) return PruneStatusT(status);
168 if (length < 0) return STATUS_UNEXPECTED_NULL;
169
Steven Moreland71872f82018-10-29 11:46:56 -0700170 if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;
Steven Morelanda8845662018-10-12 11:53:03 -0700171
172 for (size_t i = 0; i < length; i++) {
173 T readTarget;
174 status = (rawParcel->*read)(&readTarget);
175 if (status != STATUS_OK) return PruneStatusT(status);
176
Steven Moreland71872f82018-10-29 11:46:56 -0700177 setter(arrayData, i, readTarget);
Steven Morelanda8845662018-10-12 11:53:03 -0700178 }
179
180 return STATUS_OK;
181}
182
Steven Moreland9b80e282018-09-19 13:57:23 -0700183void AParcel_delete(AParcel* parcel) {
184 delete parcel;
Steven Morelandcaa776c2018-09-04 13:48:11 -0700185}
186
Steven Moreland2e87adc2018-08-20 19:47:00 -0700187binder_status_t AParcel_writeStrongBinder(AParcel* parcel, AIBinder* binder) {
Steven Morelandc0e46d32018-09-12 15:40:49 -0700188 sp<IBinder> writeBinder = binder != nullptr ? binder->getBinder() : nullptr;
Steven Morelandf18615b2018-09-14 11:43:06 -0700189 return parcel->get()->writeStrongBinder(writeBinder);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700190}
191binder_status_t AParcel_readStrongBinder(const AParcel* parcel, AIBinder** binder) {
192 sp<IBinder> readBinder = nullptr;
Steven Morelandf18615b2018-09-14 11:43:06 -0700193 status_t status = parcel->get()->readStrongBinder(&readBinder);
Steven Moreland5d62e442018-09-13 15:01:02 -0700194 if (status != STATUS_OK) {
195 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700196 }
Steven Moreland94968952018-09-05 14:42:59 -0700197 sp<AIBinder> ret = ABpBinder::lookupOrCreateFromBinder(readBinder);
Steven Moreland71cddc32018-08-30 23:39:22 -0700198 AIBinder_incStrong(ret.get());
199 *binder = ret.get();
Steven Moreland5d62e442018-09-13 15:01:02 -0700200 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700201}
202binder_status_t AParcel_readNullableStrongBinder(const AParcel* parcel, AIBinder** binder) {
203 sp<IBinder> readBinder = nullptr;
Steven Morelandf18615b2018-09-14 11:43:06 -0700204 status_t status = parcel->get()->readNullableStrongBinder(&readBinder);
Steven Moreland5d62e442018-09-13 15:01:02 -0700205 if (status != STATUS_OK) {
206 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700207 }
Steven Moreland94968952018-09-05 14:42:59 -0700208 sp<AIBinder> ret = ABpBinder::lookupOrCreateFromBinder(readBinder);
Steven Moreland71cddc32018-08-30 23:39:22 -0700209 AIBinder_incStrong(ret.get());
210 *binder = ret.get();
Steven Moreland5d62e442018-09-13 15:01:02 -0700211 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700212}
Steven Moreland9a51db82018-09-14 10:59:35 -0700213binder_status_t AParcel_writeStatusHeader(AParcel* parcel, const AStatus* status) {
214 return PruneStatusT(status->get()->writeToParcel(parcel->get()));
215}
216binder_status_t AParcel_readStatusHeader(const AParcel* parcel, AStatus** status) {
217 ::android::binder::Status bstatus;
218 binder_status_t ret = PruneStatusT(bstatus.readFromParcel(*parcel->get()));
219 if (ret == EX_NONE) {
220 *status = new AStatus(std::move(bstatus));
221 }
222 return ret;
223}
Steven Moreland2e87adc2018-08-20 19:47:00 -0700224
Steven Moreland7b06f592018-10-03 19:25:32 -0700225binder_status_t AParcel_writeString(AParcel* parcel, const char* string, size_t length) {
226 const uint8_t* str8 = (uint8_t*)string;
227
228 const ssize_t len16 = utf8_to_utf16_length(str8, length);
229
230 if (len16 < 0 || len16 >= std::numeric_limits<int32_t>::max()) {
231 LOG(WARNING) << __func__ << ": Invalid string length: " << len16;
232 return STATUS_BAD_VALUE;
233 }
234
235 status_t err = parcel->get()->writeInt32(len16);
236 if (err) {
237 return PruneStatusT(err);
238 }
239
240 void* str16 = parcel->get()->writeInplace((len16 + 1) * sizeof(char16_t));
241 if (str16 == nullptr) {
242 return STATUS_NO_MEMORY;
243 }
244
245 utf8_to_utf16(str8, length, (char16_t*)str16, (size_t)len16 + 1);
246
247 return STATUS_OK;
248}
249
Steven Moreland71872f82018-10-29 11:46:56 -0700250binder_status_t AParcel_readString(const AParcel* parcel, AParcel_stringAllocator allocator,
251 void* stringData) {
Steven Moreland7b06f592018-10-03 19:25:32 -0700252 size_t len16;
253 const char16_t* str16 = parcel->get()->readString16Inplace(&len16);
254
255 if (str16 == nullptr) {
256 LOG(WARNING) << __func__ << ": Failed to read string in place.";
257 return STATUS_UNEXPECTED_NULL;
258 }
259
260 ssize_t len8;
261
262 if (len16 == 0) {
263 len8 = 1;
264 } else {
265 len8 = utf16_to_utf8_length(str16, len16) + 1;
266 }
267
268 if (len8 <= 0 || len8 >= std::numeric_limits<int32_t>::max()) {
269 LOG(WARNING) << __func__ << ": Invalid string length: " << len8;
270 return STATUS_BAD_VALUE;
271 }
272
Steven Moreland71872f82018-10-29 11:46:56 -0700273 char* str8 = allocator(stringData, len8);
Steven Moreland7b06f592018-10-03 19:25:32 -0700274
275 if (str8 == nullptr) {
Steven Moreland71872f82018-10-29 11:46:56 -0700276 LOG(WARNING) << __func__ << ": AParcel_stringAllocator failed to allocate.";
Steven Moreland7b06f592018-10-03 19:25:32 -0700277 return STATUS_NO_MEMORY;
278 }
279
280 utf16_to_utf8(str16, len16, str8, len8);
281
282 return STATUS_OK;
283}
284
Steven Moreland2e87adc2018-08-20 19:47:00 -0700285// See gen_parcel_helper.py. These auto-generated read/write methods use the same types for
286// libbinder and this library.
287// @START
288binder_status_t AParcel_writeInt32(AParcel* parcel, int32_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700289 status_t status = parcel->get()->writeInt32(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700290 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700291}
292
293binder_status_t AParcel_writeUint32(AParcel* parcel, uint32_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700294 status_t status = parcel->get()->writeUint32(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700295 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700296}
297
298binder_status_t AParcel_writeInt64(AParcel* parcel, int64_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700299 status_t status = parcel->get()->writeInt64(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700300 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700301}
302
303binder_status_t AParcel_writeUint64(AParcel* parcel, uint64_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700304 status_t status = parcel->get()->writeUint64(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700305 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700306}
307
308binder_status_t AParcel_writeFloat(AParcel* parcel, float value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700309 status_t status = parcel->get()->writeFloat(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700310 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700311}
312
313binder_status_t AParcel_writeDouble(AParcel* parcel, double value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700314 status_t status = parcel->get()->writeDouble(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700315 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700316}
317
318binder_status_t AParcel_writeBool(AParcel* parcel, bool value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700319 status_t status = parcel->get()->writeBool(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700320 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700321}
322
323binder_status_t AParcel_writeChar(AParcel* parcel, char16_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700324 status_t status = parcel->get()->writeChar(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700325 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700326}
327
328binder_status_t AParcel_writeByte(AParcel* parcel, int8_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700329 status_t status = parcel->get()->writeByte(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_readInt32(const AParcel* parcel, int32_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700334 status_t status = parcel->get()->readInt32(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_readUint32(const AParcel* parcel, uint32_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700339 status_t status = parcel->get()->readUint32(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_readInt64(const AParcel* parcel, int64_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700344 status_t status = parcel->get()->readInt64(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_readUint64(const AParcel* parcel, uint64_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700349 status_t status = parcel->get()->readUint64(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_readFloat(const AParcel* parcel, float* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700354 status_t status = parcel->get()->readFloat(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_readDouble(const AParcel* parcel, double* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700359 status_t status = parcel->get()->readDouble(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_readBool(const AParcel* parcel, bool* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700364 status_t status = parcel->get()->readBool(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_readChar(const AParcel* parcel, char16_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700369 status_t status = parcel->get()->readChar(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_readByte(const AParcel* parcel, int8_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700374 status_t status = parcel->get()->readByte(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700375 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700376}
377
Steven Morelanda8845662018-10-12 11:53:03 -0700378binder_status_t AParcel_writeInt32Array(AParcel* parcel, const int32_t* value, size_t length) {
379 return WriteArray<int32_t>(parcel, value, length);
380}
381
382binder_status_t AParcel_writeUint32Array(AParcel* parcel, const uint32_t* value, size_t length) {
383 return WriteArray<uint32_t>(parcel, value, length);
384}
385
386binder_status_t AParcel_writeInt64Array(AParcel* parcel, const int64_t* value, size_t length) {
387 return WriteArray<int64_t>(parcel, value, length);
388}
389
390binder_status_t AParcel_writeUint64Array(AParcel* parcel, const uint64_t* value, size_t length) {
391 return WriteArray<uint64_t>(parcel, value, length);
392}
393
394binder_status_t AParcel_writeFloatArray(AParcel* parcel, const float* value, size_t length) {
395 return WriteArray<float>(parcel, value, length);
396}
397
398binder_status_t AParcel_writeDoubleArray(AParcel* parcel, const double* value, size_t length) {
399 return WriteArray<double>(parcel, value, length);
400}
401
402binder_status_t AParcel_writeBoolArray(AParcel* parcel, const void* arrayData,
403 AParcel_boolArrayGetter getter, size_t length) {
404 return WriteArray<bool>(parcel, arrayData, getter, length, &Parcel::writeBool);
405}
406
407binder_status_t AParcel_writeCharArray(AParcel* parcel, const char16_t* value, size_t length) {
408 return WriteArray<char16_t>(parcel, value, length);
409}
410
411binder_status_t AParcel_writeByteArray(AParcel* parcel, const int8_t* value, size_t length) {
412 return WriteArray<int8_t>(parcel, value, length);
413}
414
Steven Moreland71872f82018-10-29 11:46:56 -0700415binder_status_t AParcel_readInt32Array(const AParcel* parcel, void* arrayData,
416 AParcel_int32Allocator allocator) {
417 return ReadArray<int32_t>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700418}
419
Steven Moreland71872f82018-10-29 11:46:56 -0700420binder_status_t AParcel_readUint32Array(const AParcel* parcel, void* arrayData,
421 AParcel_uint32Allocator allocator) {
422 return ReadArray<uint32_t>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700423}
424
Steven Moreland71872f82018-10-29 11:46:56 -0700425binder_status_t AParcel_readInt64Array(const AParcel* parcel, void* arrayData,
426 AParcel_int64Allocator allocator) {
427 return ReadArray<int64_t>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700428}
429
Steven Moreland71872f82018-10-29 11:46:56 -0700430binder_status_t AParcel_readUint64Array(const AParcel* parcel, void* arrayData,
431 AParcel_uint64Allocator allocator) {
432 return ReadArray<uint64_t>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700433}
434
Steven Moreland71872f82018-10-29 11:46:56 -0700435binder_status_t AParcel_readFloatArray(const AParcel* parcel, void* arrayData,
436 AParcel_floatAllocator allocator) {
437 return ReadArray<float>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700438}
439
Steven Moreland71872f82018-10-29 11:46:56 -0700440binder_status_t AParcel_readDoubleArray(const AParcel* parcel, void* arrayData,
441 AParcel_doubleAllocator allocator) {
442 return ReadArray<double>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700443}
444
Steven Moreland71872f82018-10-29 11:46:56 -0700445binder_status_t AParcel_readBoolArray(const AParcel* parcel, void* arrayData,
446 AParcel_boolAllocator allocator,
Steven Morelanda8845662018-10-12 11:53:03 -0700447 AParcel_boolArraySetter setter) {
Steven Moreland71872f82018-10-29 11:46:56 -0700448 return ReadArray<bool>(parcel, arrayData, allocator, setter, &Parcel::readBool);
Steven Morelanda8845662018-10-12 11:53:03 -0700449}
450
Steven Moreland71872f82018-10-29 11:46:56 -0700451binder_status_t AParcel_readCharArray(const AParcel* parcel, void* arrayData,
452 AParcel_charAllocator allocator) {
453 return ReadArray<char16_t>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700454}
455
Steven Moreland71872f82018-10-29 11:46:56 -0700456binder_status_t AParcel_readByteArray(const AParcel* parcel, void* arrayData,
457 AParcel_byteAllocator allocator) {
458 return ReadArray<int8_t>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700459}
460
Steven Moreland2e87adc2018-08-20 19:47:00 -0700461// @END