blob: df5df13c199f4e7af39d94aeb6642db20014ee89 [file] [log] [blame]
Steven Moreland7b06f592018-10-03 19:25:32 -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/**
18 * @addtogroup NdkBinder
19 * @{
20 */
21
22/**
23 * @file binder_parcel_utils.h
24 * @brief A collection of helper wrappers for AParcel.
25 */
26
27#pragma once
28
Steven Morelandfe031c82018-11-16 10:47:35 -080029#include <android/binder_auto_utils.h>
Steven Moreland7b06f592018-10-03 19:25:32 -070030#include <android/binder_parcel.h>
31
Steven Morelandb4e14612018-11-14 17:25:45 -080032#include <optional>
Steven Moreland7b06f592018-10-03 19:25:32 -070033#include <string>
Steven Morelanda8845662018-10-12 11:53:03 -070034#include <vector>
Steven Moreland7b06f592018-10-03 19:25:32 -070035
Steven Moreland8b4f48a2018-10-08 14:30:42 -070036namespace ndk {
37
Steven Moreland7b06f592018-10-03 19:25:32 -070038/**
Steven Moreland07fb9c92018-11-01 17:14:29 -070039 * This retrieves and allocates a vector to size 'length' and returns the underlying buffer.
Steven Morelanda8845662018-10-12 11:53:03 -070040 */
41template <typename T>
Steven Moreland01ebcf72018-11-15 15:06:26 -080042static inline bool AParcel_stdVectorAllocator(void* vectorData, int32_t length, T** outBuffer) {
43 if (length < 0) return false;
Steven Morelanda8845662018-10-12 11:53:03 -070044
Steven Moreland07fb9c92018-11-01 17:14:29 -070045 std::vector<T>* vec = static_cast<std::vector<T>*>(vectorData);
Steven Morelandc92a2b12018-12-17 10:15:59 -080046 if (static_cast<size_t>(length) > vec->max_size()) return false;
Steven Moreland71872f82018-10-29 11:46:56 -070047
48 vec->resize(length);
Steven Moreland01ebcf72018-11-15 15:06:26 -080049 *outBuffer = vec->data();
50 return true;
51}
52
53/**
54 * This retrieves and allocates a vector to size 'length' and returns the underlying buffer.
55 */
56template <typename T>
57static inline bool AParcel_nullableStdVectorAllocator(void* vectorData, int32_t length,
58 T** outBuffer) {
59 std::optional<std::vector<T>>* vec = static_cast<std::optional<std::vector<T>>*>(vectorData);
60
61 if (length < 0) {
62 *vec = std::nullopt;
63 return true;
64 }
65
66 *vec = std::optional<std::vector<T>>(std::vector<T>{});
67
Steven Morelandc92a2b12018-12-17 10:15:59 -080068 if (static_cast<size_t>(length) > (*vec)->max_size()) return false;
Steven Moreland01ebcf72018-11-15 15:06:26 -080069 (*vec)->resize(length);
70
71 *outBuffer = (*vec)->data();
Steven Moreland71872f82018-10-29 11:46:56 -070072 return true;
Steven Morelanda8845662018-10-12 11:53:03 -070073}
74
75/**
Steven Morelandb4e14612018-11-14 17:25:45 -080076 * This allocates a vector to size 'length' and returns whether the allocation is successful.
77 *
78 * See also AParcel_stdVectorAllocator. Types used with this allocator have their sizes defined
79 * externally with respect to the NDK, and that size information is not passed into the NDK.
80 * Instead, it is used in cases where callbacks are used. Note that when this allocator is used,
81 * null arrays are not supported.
82 *
Steven Moreland01ebcf72018-11-15 15:06:26 -080083 * See AParcel_readVector(const AParcel* parcel, std::vector<bool>)
Steven Morelandb4e14612018-11-14 17:25:45 -080084 * See AParcel_readVector(const AParcel* parcel, std::vector<std::string>)
85 */
86template <typename T>
87static inline bool AParcel_stdVectorExternalAllocator(void* vectorData, int32_t length) {
88 if (length < 0) return false;
89
90 std::vector<T>* vec = static_cast<std::vector<T>*>(vectorData);
Steven Morelandc92a2b12018-12-17 10:15:59 -080091 if (static_cast<size_t>(length) > vec->max_size()) return false;
Steven Morelandb4e14612018-11-14 17:25:45 -080092
93 vec->resize(length);
94 return true;
95}
96
97/**
98 * This allocates a vector to size 'length' and returns whether the allocation is successful.
99 *
100 * See also AParcel_stdVectorAllocator. Types used with this allocator have their sizes defined
101 * externally with respect to the NDK, and that size information is not passed into the NDK.
102 * Instead, it is used in cases where callbacks are used. Note, when this allocator is used,
103 * the vector itself can be nullable.
104 *
105 * See AParcel_readVector(const AParcel* parcel,
106 * std::optional<std::vector<std::optional<std::string>>>)
107 */
108template <typename T>
109static inline bool AParcel_nullableStdVectorExternalAllocator(void* vectorData, int32_t length) {
110 std::optional<std::vector<T>>* vec = static_cast<std::optional<std::vector<T>>*>(vectorData);
111
112 if (length < 0) {
113 *vec = std::nullopt;
114 return true;
115 }
116
117 *vec = std::optional<std::vector<T>>(std::vector<T>{});
118
Steven Morelandc92a2b12018-12-17 10:15:59 -0800119 if (static_cast<size_t>(length) > (*vec)->max_size()) return false;
Steven Morelandb4e14612018-11-14 17:25:45 -0800120 (*vec)->resize(length);
121
122 return true;
123}
124
125/**
Steven Morelanda8845662018-10-12 11:53:03 -0700126 * This retrieves the underlying value in a vector which may not be contiguous at index from a
127 * corresponding vectorData.
128 */
129template <typename T>
130static inline T AParcel_stdVectorGetter(const void* vectorData, size_t index) {
131 const std::vector<T>* vec = static_cast<const std::vector<T>*>(vectorData);
132 return (*vec)[index];
133}
134
135/**
136 * This sets the underlying value in a corresponding vectorData which may not be contiguous at
137 * index.
138 */
139template <typename T>
140static inline void AParcel_stdVectorSetter(void* vectorData, size_t index, T value) {
141 std::vector<T>* vec = static_cast<std::vector<T>*>(vectorData);
142 (*vec)[index] = value;
143}
144
Steven Morelandc51b2c92018-11-14 10:12:02 -0800145/**
Steven Moreland01ebcf72018-11-15 15:06:26 -0800146 * This sets the underlying value in a corresponding vectorData which may not be contiguous at
147 * index.
148 */
149template <typename T>
150static inline void AParcel_nullableStdVectorSetter(void* vectorData, size_t index, T value) {
151 std::optional<std::vector<T>>* vec = static_cast<std::optional<std::vector<T>>*>(vectorData);
152 vec->value()[index] = value;
153}
154
155/**
Steven Morelandfe031c82018-11-16 10:47:35 -0800156 * Convenience method to write a nullable strong binder.
157 */
158static inline binder_status_t AParcel_writeNullableStrongBinder(AParcel* parcel,
159 const SpAIBinder& binder) {
160 return AParcel_writeStrongBinder(parcel, binder.get());
161}
162
163/**
164 * Convenience method to read a nullable strong binder.
165 */
166static inline binder_status_t AParcel_readNullableStrongBinder(const AParcel* parcel,
167 SpAIBinder* binder) {
168 AIBinder* readBinder;
169 binder_status_t status = AParcel_readStrongBinder(parcel, &readBinder);
170 if (status == STATUS_OK) {
171 binder->set(readBinder);
172 }
173 return status;
174}
175
176/**
Steven Moreland8356bb82018-11-14 12:55:27 -0800177 * Convenience method to write a strong binder but return an error if it is null.
178 */
Steven Morelandfe031c82018-11-16 10:47:35 -0800179static inline binder_status_t AParcel_writeRequiredStrongBinder(AParcel* parcel,
180 const SpAIBinder& binder) {
181 if (binder.get() == nullptr) {
Steven Moreland8356bb82018-11-14 12:55:27 -0800182 return STATUS_UNEXPECTED_NULL;
183 }
Steven Morelandfe031c82018-11-16 10:47:35 -0800184 return AParcel_writeStrongBinder(parcel, binder.get());
Steven Moreland8356bb82018-11-14 12:55:27 -0800185}
186
187/**
188 * Convenience method to read a strong binder but return an error if it is null.
189 */
190static inline binder_status_t AParcel_readRequiredStrongBinder(const AParcel* parcel,
Steven Morelandfe031c82018-11-16 10:47:35 -0800191 SpAIBinder* binder) {
192 AIBinder* readBinder;
193 binder_status_t ret = AParcel_readStrongBinder(parcel, &readBinder);
194 if (ret == STATUS_OK) {
195 if (readBinder == nullptr) {
196 return STATUS_UNEXPECTED_NULL;
197 }
198
199 binder->set(readBinder);
Steven Moreland8356bb82018-11-14 12:55:27 -0800200 }
201 return ret;
202}
203
204/**
Steven Moreland4ce59c72018-11-16 15:21:15 -0800205 * Convenience method to write a ParcelFileDescriptor where -1 represents a null value.
206 */
207static inline binder_status_t AParcel_writeNullableParcelFileDescriptor(
208 AParcel* parcel, const ScopedFileDescriptor& fd) {
209 return AParcel_writeParcelFileDescriptor(parcel, fd.get());
210}
211
212/**
213 * Convenience method to read a ParcelFileDescriptor where -1 represents a null value.
214 */
215static inline binder_status_t AParcel_readNullableParcelFileDescriptor(const AParcel* parcel,
216 ScopedFileDescriptor* fd) {
217 int readFd;
218 binder_status_t status = AParcel_readParcelFileDescriptor(parcel, &readFd);
219 if (status == STATUS_OK) {
220 fd->set(readFd);
221 }
222 return status;
223}
224
225/**
226 * Convenience method to write a valid ParcelFileDescriptor.
227 */
228static inline binder_status_t AParcel_writeRequiredParcelFileDescriptor(
229 AParcel* parcel, const ScopedFileDescriptor& fd) {
230 if (fd.get() < 0) {
231 return STATUS_UNEXPECTED_NULL;
232 }
233 return AParcel_writeParcelFileDescriptor(parcel, fd.get());
234}
235
236/**
237 * Convenience method to read a valid ParcelFileDescriptor.
238 */
239static inline binder_status_t AParcel_readRequiredParcelFileDescriptor(const AParcel* parcel,
240 ScopedFileDescriptor* fd) {
241 int readFd;
242 binder_status_t status = AParcel_readParcelFileDescriptor(parcel, &readFd);
243 if (status == STATUS_OK) {
244 if (readFd < 0) {
245 return STATUS_UNEXPECTED_NULL;
246 }
247 fd->set(readFd);
248 }
249 return status;
250}
251
252/**
Steven Morelandc51b2c92018-11-14 10:12:02 -0800253 * Allocates a std::string to length and returns the underlying buffer. For use with
254 * AParcel_readString. See use below in AParcel_readString(const AParcel*, std::string*).
255 */
Steven Morelandb4e14612018-11-14 17:25:45 -0800256static inline bool AParcel_stdStringAllocator(void* stringData, int32_t length, char** buffer) {
257 if (length <= 0) return false;
258
Steven Morelandc51b2c92018-11-14 10:12:02 -0800259 std::string* str = static_cast<std::string*>(stringData);
260 str->resize(length - 1);
Steven Morelandb4e14612018-11-14 17:25:45 -0800261 *buffer = &(*str)[0];
262 return true;
Steven Morelandc51b2c92018-11-14 10:12:02 -0800263}
264
265/**
Steven Morelandb4e14612018-11-14 17:25:45 -0800266 * Allocates a string in a std::optional<std::string> to size 'length' (or to std::nullopt when
267 * length is -1) and returns the underlying buffer. For use with AParcel_readString. See use below
268 * in AParcel_readString(const AParcel*, std::optional<std::string>*).
Steven Morelandc51b2c92018-11-14 10:12:02 -0800269 */
Steven Morelandb4e14612018-11-14 17:25:45 -0800270static inline bool AParcel_nullableStdStringAllocator(void* stringData, int32_t length,
271 char** buffer) {
272 if (length == 0) return false;
Steven Morelandc51b2c92018-11-14 10:12:02 -0800273
Steven Morelandb4e14612018-11-14 17:25:45 -0800274 std::optional<std::string>* str = static_cast<std::optional<std::string>*>(stringData);
275
276 if (length < 0) {
277 *str = std::nullopt;
278 return true;
279 }
280
281 *str = std::optional<std::string>(std::string{});
282 (*str)->resize(length - 1);
283 *buffer = &(**str)[0];
284 return true;
285}
286
287/**
288 * Allocates a std::string inside of a std::vector<std::string> at index 'index' to size 'length'.
289 */
290static inline bool AParcel_stdVectorStringElementAllocator(void* vectorData, size_t index,
291 int32_t length, char** buffer) {
292 std::vector<std::string>* vec = static_cast<std::vector<std::string>*>(vectorData);
Steven Morelandc51b2c92018-11-14 10:12:02 -0800293 std::string& element = vec->at(index);
Steven Morelandb4e14612018-11-14 17:25:45 -0800294 return AParcel_stdStringAllocator(static_cast<void*>(&element), length, buffer);
Steven Morelandc51b2c92018-11-14 10:12:02 -0800295}
296
297/**
298 * This gets the length and buffer of a std::string inside of a std::vector<std::string> at index
299 * index.
300 */
301static inline const char* AParcel_stdVectorStringElementGetter(const void* vectorData, size_t index,
Steven Moreland763dc4c2018-12-12 11:30:06 -0800302 int32_t* outLength) {
Steven Morelandc51b2c92018-11-14 10:12:02 -0800303 const std::vector<std::string>* vec = static_cast<const std::vector<std::string>*>(vectorData);
Steven Morelandc51b2c92018-11-14 10:12:02 -0800304 const std::string& element = vec->at(index);
305
306 *outLength = element.size();
307 return element.c_str();
308}
309
310/**
Steven Morelandb4e14612018-11-14 17:25:45 -0800311 * Allocates a string in a std::optional<std::string> inside of a
312 * std::optional<std::vector<std::optional<std::string>>> at index 'index' to size 'length' (or to
313 * std::nullopt when length is -1).
314 */
315static inline bool AParcel_nullableStdVectorStringElementAllocator(void* vectorData, size_t index,
316 int32_t length, char** buffer) {
317 std::optional<std::vector<std::optional<std::string>>>* vec =
318 static_cast<std::optional<std::vector<std::optional<std::string>>>*>(vectorData);
319 std::optional<std::string>& element = vec->value().at(index);
320 return AParcel_nullableStdStringAllocator(static_cast<void*>(&element), length, buffer);
321}
322
323/**
324 * This gets the length and buffer of a std::optional<std::string> inside of a
325 * std::vector<std::string> at index index. If the string is null, then it returns null and a length
326 * of -1.
327 */
328static inline const char* AParcel_nullableStdVectorStringElementGetter(const void* vectorData,
329 size_t index,
Steven Moreland763dc4c2018-12-12 11:30:06 -0800330 int32_t* outLength) {
Steven Morelandb4e14612018-11-14 17:25:45 -0800331 const std::optional<std::vector<std::optional<std::string>>>* vec =
332 static_cast<const std::optional<std::vector<std::optional<std::string>>>*>(vectorData);
333 const std::optional<std::string>& element = vec->value().at(index);
334
335 if (!element) {
336 *outLength = -1;
337 return nullptr;
338 }
339
340 *outLength = element->size();
341 return element->c_str();
342}
343
344/**
Steven Morelandc51b2c92018-11-14 10:12:02 -0800345 * Convenience API for writing a std::string.
346 */
347static inline binder_status_t AParcel_writeString(AParcel* parcel, const std::string& str) {
348 return AParcel_writeString(parcel, str.c_str(), str.size());
349}
350
351/**
352 * Convenience API for reading a std::string.
353 */
354static inline binder_status_t AParcel_readString(const AParcel* parcel, std::string* str) {
355 void* stringData = static_cast<void*>(str);
356 return AParcel_readString(parcel, stringData, AParcel_stdStringAllocator);
357}
358
359/**
Steven Morelandb4e14612018-11-14 17:25:45 -0800360 * Convenience API for writing a std::optional<std::string>.
361 */
362static inline binder_status_t AParcel_writeString(AParcel* parcel,
363 const std::optional<std::string>& str) {
364 if (!str) {
365 return AParcel_writeString(parcel, nullptr, -1);
366 }
367
368 return AParcel_writeString(parcel, str->c_str(), str->size());
369}
370
371/**
372 * Convenience API for reading a std::optional<std::string>.
373 */
374static inline binder_status_t AParcel_readString(const AParcel* parcel,
375 std::optional<std::string>* str) {
376 void* stringData = static_cast<void*>(str);
377 return AParcel_readString(parcel, stringData, AParcel_nullableStdStringAllocator);
378}
379
380/**
Steven Morelandc51b2c92018-11-14 10:12:02 -0800381 * Convenience API for writing a std::vector<std::string>
382 */
383static inline binder_status_t AParcel_writeVector(AParcel* parcel,
384 const std::vector<std::string>& vec) {
385 const void* vectorData = static_cast<const void*>(&vec);
386 return AParcel_writeStringArray(parcel, vectorData, vec.size(),
387 AParcel_stdVectorStringElementGetter);
388}
389
390/**
391 * Convenience API for reading a std::vector<std::string>
392 */
393static inline binder_status_t AParcel_readVector(const AParcel* parcel,
394 std::vector<std::string>* vec) {
395 void* vectorData = static_cast<void*>(vec);
396 return AParcel_readStringArray(parcel, vectorData,
397 AParcel_stdVectorExternalAllocator<std::string>,
398 AParcel_stdVectorStringElementAllocator);
399}
400
Steven Morelandb4e14612018-11-14 17:25:45 -0800401/**
402 * Convenience API for writing a std::optional<std::vector<std::optional<std::string>>>
403 */
404static inline binder_status_t AParcel_writeVector(
405 AParcel* parcel, const std::optional<std::vector<std::optional<std::string>>>& vec) {
406 const void* vectorData = static_cast<const void*>(&vec);
407 return AParcel_writeStringArray(parcel, vectorData, (vec ? vec->size() : -1),
408 AParcel_nullableStdVectorStringElementGetter);
409}
410
411/**
412 * Convenience API for reading a std::optional<std::vector<std::optional<std::string>>>
413 */
414static inline binder_status_t AParcel_readVector(
415 const AParcel* parcel, std::optional<std::vector<std::optional<std::string>>>* vec) {
416 void* vectorData = static_cast<void*>(vec);
417 return AParcel_readStringArray(
418 parcel, vectorData,
419 AParcel_nullableStdVectorExternalAllocator<std::optional<std::string>>,
420 AParcel_nullableStdVectorStringElementAllocator);
421}
422
Steven Morelande22a9942018-12-11 18:57:05 -0800423/**
Steven Moreland10ae93b2019-12-16 16:38:01 -0800424 * Convenience API for writing a non-null parcelable.
425 */
426template <typename P>
427static inline binder_status_t AParcel_writeParcelable(AParcel* parcel, const P& p) {
428 binder_status_t status = AParcel_writeInt32(parcel, 1); // non-null
429 if (status != STATUS_OK) {
430 return status;
431 }
432 return p.writeToParcel(parcel);
433}
434
435/**
436 * Convenience API for reading a non-null parcelable.
437 */
438template <typename P>
439static inline binder_status_t AParcel_readParcelable(const AParcel* parcel, P* p) {
440 int32_t null;
441 binder_status_t status = AParcel_readInt32(parcel, &null);
442 if (status != STATUS_OK) {
443 return status;
444 }
445 if (null == 0) {
446 return STATUS_UNEXPECTED_NULL;
447 }
448 return p->readFromParcel(parcel);
449}
450
451/**
Steven Moreland15e12e32019-12-19 16:59:16 -0800452 * Convenience API for writing a nullable parcelable.
453 */
454template <typename P>
455static inline binder_status_t AParcel_writeNullableParcelable(AParcel* parcel,
456 const std::optional<P>& p) {
457 if (p == std::nullopt) {
458 return AParcel_writeInt32(parcel, 0); // null
459 }
460 binder_status_t status = AParcel_writeInt32(parcel, 1); // non-null
461 if (status != STATUS_OK) {
462 return status;
463 }
464 return p->writeToParcel(parcel);
465}
466
467/**
468 * Convenience API for reading a nullable parcelable.
469 */
470template <typename P>
471static inline binder_status_t AParcel_readNullableParcelable(const AParcel* parcel,
472 std::optional<P>* p) {
473 int32_t null;
474 binder_status_t status = AParcel_readInt32(parcel, &null);
475 if (status != STATUS_OK) {
476 return status;
477 }
478 if (null == 0) {
479 *p = std::nullopt;
480 return STATUS_OK;
481 }
482 *p = std::optional<P>(P{});
483 return (*p)->readFromParcel(parcel);
484}
485
486/**
Steven Morelande22a9942018-12-11 18:57:05 -0800487 * Writes a parcelable object of type P inside a std::vector<P> at index 'index' to 'parcel'.
488 */
489template <typename P>
490binder_status_t AParcel_writeStdVectorParcelableElement(AParcel* parcel, const void* vectorData,
491 size_t index) {
492 const std::vector<P>* vector = static_cast<const std::vector<P>*>(vectorData);
Steven Moreland10ae93b2019-12-16 16:38:01 -0800493 return AParcel_writeParcelable(parcel, vector->at(index));
Steven Morelande22a9942018-12-11 18:57:05 -0800494}
495
496/**
497 * Reads a parcelable object of type P inside a std::vector<P> at index 'index' from 'parcel'.
498 */
499template <typename P>
500binder_status_t AParcel_readStdVectorParcelableElement(const AParcel* parcel, void* vectorData,
501 size_t index) {
502 std::vector<P>* vector = static_cast<std::vector<P>*>(vectorData);
Steven Moreland10ae93b2019-12-16 16:38:01 -0800503 return AParcel_readParcelable(parcel, &vector->at(index));
Steven Morelande22a9942018-12-11 18:57:05 -0800504}
505
506/**
Jeongik Cha9af82102019-11-14 10:23:44 +0900507 * Writes a ScopedFileDescriptor object inside a std::vector<ScopedFileDescriptor> at index 'index'
508 * to 'parcel'.
509 */
510template <>
511inline binder_status_t AParcel_writeStdVectorParcelableElement<ScopedFileDescriptor>(
512 AParcel* parcel, const void* vectorData, size_t index) {
513 const std::vector<ScopedFileDescriptor>* vector =
514 static_cast<const std::vector<ScopedFileDescriptor>*>(vectorData);
515 int writeFd = vector->at(index).get();
516 if (writeFd < 0) {
517 return STATUS_UNEXPECTED_NULL;
518 }
519 return AParcel_writeParcelFileDescriptor(parcel, writeFd);
520}
521
522/**
523 * Reads a ScopedFileDescriptor object inside a std::vector<ScopedFileDescriptor> at index 'index'
524 * from 'parcel'.
525 */
526template <>
527inline binder_status_t AParcel_readStdVectorParcelableElement<ScopedFileDescriptor>(
528 const AParcel* parcel, void* vectorData, size_t index) {
529 std::vector<ScopedFileDescriptor>* vector =
530 static_cast<std::vector<ScopedFileDescriptor>*>(vectorData);
531 int readFd;
532 binder_status_t status = AParcel_readParcelFileDescriptor(parcel, &readFd);
533 if (status == STATUS_OK) {
534 if (readFd < 0) {
535 return STATUS_UNEXPECTED_NULL;
536 }
537 vector->at(index).set(readFd);
538 }
539 return status;
540}
541
542/**
Steven Morelande22a9942018-12-11 18:57:05 -0800543 * Convenience API for writing a std::vector<P>
544 */
545template <typename P>
546static inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<P>& vec) {
547 const void* vectorData = static_cast<const void*>(&vec);
548 return AParcel_writeParcelableArray(parcel, vectorData, vec.size(),
549 AParcel_writeStdVectorParcelableElement<P>);
550}
551
552/**
553 * Convenience API for reading a std::vector<P>
554 */
555template <typename P>
556static inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<P>* vec) {
557 void* vectorData = static_cast<void*>(vec);
558 return AParcel_readParcelableArray(parcel, vectorData, AParcel_stdVectorExternalAllocator<P>,
559 AParcel_readStdVectorParcelableElement<P>);
560}
561
Steven Morelanda8845662018-10-12 11:53:03 -0700562// @START
563/**
564 * Writes a vector of int32_t to the next location in a non-null parcel.
565 */
Steven Morelandc298ecd2018-10-25 16:18:37 -0700566inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<int32_t>& vec) {
Steven Morelanda8845662018-10-12 11:53:03 -0700567 return AParcel_writeInt32Array(parcel, vec.data(), vec.size());
568}
569
570/**
Steven Moreland01ebcf72018-11-15 15:06:26 -0800571 * Writes an optional vector of int32_t to the next location in a non-null parcel.
572 */
573inline binder_status_t AParcel_writeVector(AParcel* parcel,
574 const std::optional<std::vector<int32_t>>& vec) {
575 if (!vec) return AParcel_writeInt32Array(parcel, nullptr, -1);
576 return AParcel_writeVector(parcel, *vec);
577}
578
579/**
Steven Morelanda8845662018-10-12 11:53:03 -0700580 * Reads a vector of int32_t from the next location in a non-null parcel.
581 */
Steven Morelandc298ecd2018-10-25 16:18:37 -0700582inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<int32_t>* vec) {
Steven Morelanda8845662018-10-12 11:53:03 -0700583 void* vectorData = static_cast<void*>(vec);
Steven Moreland71872f82018-10-29 11:46:56 -0700584 return AParcel_readInt32Array(parcel, vectorData, AParcel_stdVectorAllocator<int32_t>);
Steven Morelanda8845662018-10-12 11:53:03 -0700585}
586
587/**
Steven Moreland01ebcf72018-11-15 15:06:26 -0800588 * Reads an optional vector of int32_t from the next location in a non-null parcel.
589 */
590inline binder_status_t AParcel_readVector(const AParcel* parcel,
591 std::optional<std::vector<int32_t>>* vec) {
592 void* vectorData = static_cast<void*>(vec);
593 return AParcel_readInt32Array(parcel, vectorData, AParcel_nullableStdVectorAllocator<int32_t>);
594}
595
596/**
Steven Morelanda8845662018-10-12 11:53:03 -0700597 * Writes a vector of uint32_t to the next location in a non-null parcel.
598 */
Steven Morelandc298ecd2018-10-25 16:18:37 -0700599inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<uint32_t>& vec) {
Steven Morelanda8845662018-10-12 11:53:03 -0700600 return AParcel_writeUint32Array(parcel, vec.data(), vec.size());
601}
602
603/**
Steven Moreland01ebcf72018-11-15 15:06:26 -0800604 * Writes an optional vector of uint32_t to the next location in a non-null parcel.
605 */
606inline binder_status_t AParcel_writeVector(AParcel* parcel,
607 const std::optional<std::vector<uint32_t>>& vec) {
608 if (!vec) return AParcel_writeUint32Array(parcel, nullptr, -1);
609 return AParcel_writeVector(parcel, *vec);
610}
611
612/**
Steven Morelanda8845662018-10-12 11:53:03 -0700613 * Reads a vector of uint32_t from the next location in a non-null parcel.
614 */
Steven Morelandc298ecd2018-10-25 16:18:37 -0700615inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<uint32_t>* vec) {
Steven Morelanda8845662018-10-12 11:53:03 -0700616 void* vectorData = static_cast<void*>(vec);
Steven Moreland71872f82018-10-29 11:46:56 -0700617 return AParcel_readUint32Array(parcel, vectorData, AParcel_stdVectorAllocator<uint32_t>);
Steven Morelanda8845662018-10-12 11:53:03 -0700618}
619
620/**
Steven Moreland01ebcf72018-11-15 15:06:26 -0800621 * Reads an optional vector of uint32_t from the next location in a non-null parcel.
622 */
623inline binder_status_t AParcel_readVector(const AParcel* parcel,
624 std::optional<std::vector<uint32_t>>* vec) {
625 void* vectorData = static_cast<void*>(vec);
626 return AParcel_readUint32Array(parcel, vectorData,
627 AParcel_nullableStdVectorAllocator<uint32_t>);
628}
629
630/**
Steven Morelanda8845662018-10-12 11:53:03 -0700631 * Writes a vector of int64_t to the next location in a non-null parcel.
632 */
Steven Morelandc298ecd2018-10-25 16:18:37 -0700633inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<int64_t>& vec) {
Steven Morelanda8845662018-10-12 11:53:03 -0700634 return AParcel_writeInt64Array(parcel, vec.data(), vec.size());
635}
636
637/**
Steven Moreland01ebcf72018-11-15 15:06:26 -0800638 * Writes an optional vector of int64_t to the next location in a non-null parcel.
639 */
640inline binder_status_t AParcel_writeVector(AParcel* parcel,
641 const std::optional<std::vector<int64_t>>& vec) {
642 if (!vec) return AParcel_writeInt64Array(parcel, nullptr, -1);
643 return AParcel_writeVector(parcel, *vec);
644}
645
646/**
Steven Morelanda8845662018-10-12 11:53:03 -0700647 * Reads a vector of int64_t from the next location in a non-null parcel.
648 */
Steven Morelandc298ecd2018-10-25 16:18:37 -0700649inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<int64_t>* vec) {
Steven Morelanda8845662018-10-12 11:53:03 -0700650 void* vectorData = static_cast<void*>(vec);
Steven Moreland71872f82018-10-29 11:46:56 -0700651 return AParcel_readInt64Array(parcel, vectorData, AParcel_stdVectorAllocator<int64_t>);
Steven Morelanda8845662018-10-12 11:53:03 -0700652}
653
654/**
Steven Moreland01ebcf72018-11-15 15:06:26 -0800655 * Reads an optional vector of int64_t from the next location in a non-null parcel.
656 */
657inline binder_status_t AParcel_readVector(const AParcel* parcel,
658 std::optional<std::vector<int64_t>>* vec) {
659 void* vectorData = static_cast<void*>(vec);
660 return AParcel_readInt64Array(parcel, vectorData, AParcel_nullableStdVectorAllocator<int64_t>);
661}
662
663/**
Steven Morelanda8845662018-10-12 11:53:03 -0700664 * Writes a vector of uint64_t to the next location in a non-null parcel.
665 */
Steven Morelandc298ecd2018-10-25 16:18:37 -0700666inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<uint64_t>& vec) {
Steven Morelanda8845662018-10-12 11:53:03 -0700667 return AParcel_writeUint64Array(parcel, vec.data(), vec.size());
668}
669
670/**
Steven Moreland01ebcf72018-11-15 15:06:26 -0800671 * Writes an optional vector of uint64_t to the next location in a non-null parcel.
672 */
673inline binder_status_t AParcel_writeVector(AParcel* parcel,
674 const std::optional<std::vector<uint64_t>>& vec) {
675 if (!vec) return AParcel_writeUint64Array(parcel, nullptr, -1);
676 return AParcel_writeVector(parcel, *vec);
677}
678
679/**
Steven Morelanda8845662018-10-12 11:53:03 -0700680 * Reads a vector of uint64_t from the next location in a non-null parcel.
681 */
Steven Morelandc298ecd2018-10-25 16:18:37 -0700682inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<uint64_t>* vec) {
Steven Morelanda8845662018-10-12 11:53:03 -0700683 void* vectorData = static_cast<void*>(vec);
Steven Moreland71872f82018-10-29 11:46:56 -0700684 return AParcel_readUint64Array(parcel, vectorData, AParcel_stdVectorAllocator<uint64_t>);
Steven Morelanda8845662018-10-12 11:53:03 -0700685}
686
687/**
Steven Moreland01ebcf72018-11-15 15:06:26 -0800688 * Reads an optional vector of uint64_t from the next location in a non-null parcel.
689 */
690inline binder_status_t AParcel_readVector(const AParcel* parcel,
691 std::optional<std::vector<uint64_t>>* vec) {
692 void* vectorData = static_cast<void*>(vec);
693 return AParcel_readUint64Array(parcel, vectorData,
694 AParcel_nullableStdVectorAllocator<uint64_t>);
695}
696
697/**
Steven Morelanda8845662018-10-12 11:53:03 -0700698 * Writes a vector of float to the next location in a non-null parcel.
699 */
Steven Morelandc298ecd2018-10-25 16:18:37 -0700700inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<float>& vec) {
Steven Morelanda8845662018-10-12 11:53:03 -0700701 return AParcel_writeFloatArray(parcel, vec.data(), vec.size());
702}
703
704/**
Steven Moreland01ebcf72018-11-15 15:06:26 -0800705 * Writes an optional vector of float to the next location in a non-null parcel.
706 */
707inline binder_status_t AParcel_writeVector(AParcel* parcel,
708 const std::optional<std::vector<float>>& vec) {
709 if (!vec) return AParcel_writeFloatArray(parcel, nullptr, -1);
710 return AParcel_writeVector(parcel, *vec);
711}
712
713/**
Steven Morelanda8845662018-10-12 11:53:03 -0700714 * Reads a vector of float from the next location in a non-null parcel.
715 */
Steven Morelandc298ecd2018-10-25 16:18:37 -0700716inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<float>* vec) {
Steven Morelanda8845662018-10-12 11:53:03 -0700717 void* vectorData = static_cast<void*>(vec);
Steven Moreland71872f82018-10-29 11:46:56 -0700718 return AParcel_readFloatArray(parcel, vectorData, AParcel_stdVectorAllocator<float>);
Steven Morelanda8845662018-10-12 11:53:03 -0700719}
720
721/**
Steven Moreland01ebcf72018-11-15 15:06:26 -0800722 * Reads an optional vector of float from the next location in a non-null parcel.
723 */
724inline binder_status_t AParcel_readVector(const AParcel* parcel,
725 std::optional<std::vector<float>>* vec) {
726 void* vectorData = static_cast<void*>(vec);
727 return AParcel_readFloatArray(parcel, vectorData, AParcel_nullableStdVectorAllocator<float>);
728}
729
730/**
Steven Morelanda8845662018-10-12 11:53:03 -0700731 * Writes a vector of double to the next location in a non-null parcel.
732 */
Steven Morelandc298ecd2018-10-25 16:18:37 -0700733inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<double>& vec) {
Steven Morelanda8845662018-10-12 11:53:03 -0700734 return AParcel_writeDoubleArray(parcel, vec.data(), vec.size());
735}
736
737/**
Steven Moreland01ebcf72018-11-15 15:06:26 -0800738 * Writes an optional vector of double to the next location in a non-null parcel.
739 */
740inline binder_status_t AParcel_writeVector(AParcel* parcel,
741 const std::optional<std::vector<double>>& vec) {
742 if (!vec) return AParcel_writeDoubleArray(parcel, nullptr, -1);
743 return AParcel_writeVector(parcel, *vec);
744}
745
746/**
Steven Morelanda8845662018-10-12 11:53:03 -0700747 * Reads a vector of double from the next location in a non-null parcel.
748 */
Steven Morelandc298ecd2018-10-25 16:18:37 -0700749inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<double>* vec) {
Steven Morelanda8845662018-10-12 11:53:03 -0700750 void* vectorData = static_cast<void*>(vec);
Steven Moreland71872f82018-10-29 11:46:56 -0700751 return AParcel_readDoubleArray(parcel, vectorData, AParcel_stdVectorAllocator<double>);
Steven Morelanda8845662018-10-12 11:53:03 -0700752}
753
754/**
Steven Moreland01ebcf72018-11-15 15:06:26 -0800755 * Reads an optional vector of double from the next location in a non-null parcel.
756 */
757inline binder_status_t AParcel_readVector(const AParcel* parcel,
758 std::optional<std::vector<double>>* vec) {
759 void* vectorData = static_cast<void*>(vec);
760 return AParcel_readDoubleArray(parcel, vectorData, AParcel_nullableStdVectorAllocator<double>);
761}
762
763/**
Steven Morelanda8845662018-10-12 11:53:03 -0700764 * Writes a vector of bool to the next location in a non-null parcel.
765 */
Steven Morelandc298ecd2018-10-25 16:18:37 -0700766inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<bool>& vec) {
Steven Moreland16e1eae2018-11-01 09:51:53 -0700767 return AParcel_writeBoolArray(parcel, static_cast<const void*>(&vec), vec.size(),
768 AParcel_stdVectorGetter<bool>);
Steven Morelanda8845662018-10-12 11:53:03 -0700769}
770
771/**
Steven Moreland01ebcf72018-11-15 15:06:26 -0800772 * Writes an optional vector of bool to the next location in a non-null parcel.
773 */
774inline binder_status_t AParcel_writeVector(AParcel* parcel,
775 const std::optional<std::vector<bool>>& vec) {
776 if (!vec) return AParcel_writeBoolArray(parcel, nullptr, -1, AParcel_stdVectorGetter<bool>);
777 return AParcel_writeVector(parcel, *vec);
778}
779
780/**
Steven Morelanda8845662018-10-12 11:53:03 -0700781 * Reads a vector of bool from the next location in a non-null parcel.
782 */
Steven Morelandc298ecd2018-10-25 16:18:37 -0700783inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<bool>* vec) {
Steven Morelanda8845662018-10-12 11:53:03 -0700784 void* vectorData = static_cast<void*>(vec);
Steven Moreland07fb9c92018-11-01 17:14:29 -0700785 return AParcel_readBoolArray(parcel, vectorData, AParcel_stdVectorExternalAllocator<bool>,
Steven Morelanda8845662018-10-12 11:53:03 -0700786 AParcel_stdVectorSetter<bool>);
787}
788
789/**
Steven Moreland01ebcf72018-11-15 15:06:26 -0800790 * Reads an optional vector of bool from the next location in a non-null parcel.
791 */
792inline binder_status_t AParcel_readVector(const AParcel* parcel,
793 std::optional<std::vector<bool>>* vec) {
794 void* vectorData = static_cast<void*>(vec);
795 return AParcel_readBoolArray(parcel, vectorData,
796 AParcel_nullableStdVectorExternalAllocator<bool>,
797 AParcel_nullableStdVectorSetter<bool>);
798}
799
800/**
Steven Morelanda8845662018-10-12 11:53:03 -0700801 * Writes a vector of char16_t to the next location in a non-null parcel.
802 */
Steven Morelandc298ecd2018-10-25 16:18:37 -0700803inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<char16_t>& vec) {
Steven Morelanda8845662018-10-12 11:53:03 -0700804 return AParcel_writeCharArray(parcel, vec.data(), vec.size());
805}
806
807/**
Steven Moreland01ebcf72018-11-15 15:06:26 -0800808 * Writes an optional vector of char16_t to the next location in a non-null parcel.
809 */
810inline binder_status_t AParcel_writeVector(AParcel* parcel,
811 const std::optional<std::vector<char16_t>>& vec) {
812 if (!vec) return AParcel_writeCharArray(parcel, nullptr, -1);
813 return AParcel_writeVector(parcel, *vec);
814}
815
816/**
Steven Morelanda8845662018-10-12 11:53:03 -0700817 * Reads a vector of char16_t from the next location in a non-null parcel.
818 */
Steven Morelandc298ecd2018-10-25 16:18:37 -0700819inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<char16_t>* vec) {
Steven Morelanda8845662018-10-12 11:53:03 -0700820 void* vectorData = static_cast<void*>(vec);
Steven Moreland71872f82018-10-29 11:46:56 -0700821 return AParcel_readCharArray(parcel, vectorData, AParcel_stdVectorAllocator<char16_t>);
Steven Morelanda8845662018-10-12 11:53:03 -0700822}
823
824/**
Steven Moreland01ebcf72018-11-15 15:06:26 -0800825 * Reads an optional vector of char16_t from the next location in a non-null parcel.
826 */
827inline binder_status_t AParcel_readVector(const AParcel* parcel,
828 std::optional<std::vector<char16_t>>* vec) {
829 void* vectorData = static_cast<void*>(vec);
830 return AParcel_readCharArray(parcel, vectorData, AParcel_nullableStdVectorAllocator<char16_t>);
831}
832
833/**
Steven Morelanda8845662018-10-12 11:53:03 -0700834 * Writes a vector of int8_t to the next location in a non-null parcel.
835 */
Steven Morelandc298ecd2018-10-25 16:18:37 -0700836inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<int8_t>& vec) {
Steven Morelanda8845662018-10-12 11:53:03 -0700837 return AParcel_writeByteArray(parcel, vec.data(), vec.size());
838}
839
840/**
Steven Moreland01ebcf72018-11-15 15:06:26 -0800841 * Writes an optional vector of int8_t to the next location in a non-null parcel.
842 */
843inline binder_status_t AParcel_writeVector(AParcel* parcel,
844 const std::optional<std::vector<int8_t>>& vec) {
845 if (!vec) return AParcel_writeByteArray(parcel, nullptr, -1);
846 return AParcel_writeVector(parcel, *vec);
847}
848
849/**
Steven Morelanda8845662018-10-12 11:53:03 -0700850 * Reads a vector of int8_t from the next location in a non-null parcel.
851 */
Steven Morelandc298ecd2018-10-25 16:18:37 -0700852inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<int8_t>* vec) {
Steven Morelanda8845662018-10-12 11:53:03 -0700853 void* vectorData = static_cast<void*>(vec);
Steven Moreland71872f82018-10-29 11:46:56 -0700854 return AParcel_readByteArray(parcel, vectorData, AParcel_stdVectorAllocator<int8_t>);
Steven Morelanda8845662018-10-12 11:53:03 -0700855}
856
Steven Moreland01ebcf72018-11-15 15:06:26 -0800857/**
858 * Reads an optional vector of int8_t from the next location in a non-null parcel.
859 */
860inline binder_status_t AParcel_readVector(const AParcel* parcel,
861 std::optional<std::vector<int8_t>>* vec) {
862 void* vectorData = static_cast<void*>(vec);
863 return AParcel_readByteArray(parcel, vectorData, AParcel_nullableStdVectorAllocator<int8_t>);
864}
865
Steven Morelanda8845662018-10-12 11:53:03 -0700866// @END
867
868/**
Steven Morelande3d09582018-11-02 19:29:36 -0700869 * Convenience API for writing the size of a vector.
870 */
Steven Morelanda8845662018-10-12 11:53:03 -0700871template <typename T>
872static inline binder_status_t AParcel_writeVectorSize(AParcel* parcel, const std::vector<T>& vec) {
873 if (vec.size() > INT32_MAX) {
874 return STATUS_BAD_VALUE;
875 }
876
877 return AParcel_writeInt32(parcel, static_cast<int32_t>(vec.size()));
878}
879
Steven Morelande3d09582018-11-02 19:29:36 -0700880/**
Steven Morelandb4e14612018-11-14 17:25:45 -0800881 * Convenience API for writing the size of a vector.
882 */
883template <typename T>
884static inline binder_status_t AParcel_writeVectorSize(AParcel* parcel,
885 const std::optional<std::vector<T>>& vec) {
886 if (!vec) {
887 return AParcel_writeInt32(parcel, -1);
888 }
889
890 if (vec->size() > INT32_MAX) {
891 return STATUS_BAD_VALUE;
892 }
893
894 return AParcel_writeInt32(parcel, static_cast<int32_t>(vec->size()));
895}
896
897/**
Steven Morelande3d09582018-11-02 19:29:36 -0700898 * Convenience API for resizing a vector.
899 */
Steven Morelanda8845662018-10-12 11:53:03 -0700900template <typename T>
901static inline binder_status_t AParcel_resizeVector(const AParcel* parcel, std::vector<T>* vec) {
902 int32_t size;
903 binder_status_t err = AParcel_readInt32(parcel, &size);
904
905 if (err != STATUS_OK) return err;
906 if (size < 0) return STATUS_UNEXPECTED_NULL;
907
908 vec->resize(static_cast<size_t>(size));
909 return STATUS_OK;
910}
911
Steven Morelandb4e14612018-11-14 17:25:45 -0800912/**
913 * Convenience API for resizing a vector.
914 */
915template <typename T>
916static inline binder_status_t AParcel_resizeVector(const AParcel* parcel,
917 std::optional<std::vector<T>>* vec) {
918 int32_t size;
919 binder_status_t err = AParcel_readInt32(parcel, &size);
920
921 if (err != STATUS_OK) return err;
922 if (size < -1) return STATUS_UNEXPECTED_NULL;
923
924 if (size == -1) {
925 *vec = std::nullopt;
926 return STATUS_OK;
927 }
928
929 *vec = std::optional<std::vector<T>>(std::vector<T>{});
930 (*vec)->resize(static_cast<size_t>(size));
931 return STATUS_OK;
932}
933
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700934} // namespace ndk
Steven Moreland8b4f48a2018-10-08 14:30:42 -0700935
Steven Moreland7b06f592018-10-03 19:25:32 -0700936/** @} */