1 /*
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
29 #include <android/binder_auto_utils.h>
30 #include <android/binder_parcel.h>
31
32 #include <optional>
33 #include <string>
34 #include <vector>
35
36 namespace ndk {
37
38 /**
39 * This retrieves and allocates a vector to size 'length' and returns the underlying buffer.
40 */
41 template <typename T>
AParcel_stdVectorAllocator(void * vectorData,int32_t length,T ** outBuffer)42 static inline bool AParcel_stdVectorAllocator(void* vectorData, int32_t length, T** outBuffer) {
43 if (length < 0) return false;
44
45 std::vector<T>* vec = static_cast<std::vector<T>*>(vectorData);
46 if (static_cast<size_t>(length) > vec->max_size()) return false;
47
48 vec->resize(length);
49 *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 */
56 template <typename T>
AParcel_nullableStdVectorAllocator(void * vectorData,int32_t length,T ** outBuffer)57 static 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
68 if (static_cast<size_t>(length) > (*vec)->max_size()) return false;
69 (*vec)->resize(length);
70
71 *outBuffer = (*vec)->data();
72 return true;
73 }
74
75 /**
76 * 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 *
83 * See AParcel_readVector(const AParcel* parcel, std::vector<bool>)
84 * See AParcel_readVector(const AParcel* parcel, std::vector<std::string>)
85 */
86 template <typename T>
AParcel_stdVectorExternalAllocator(void * vectorData,int32_t length)87 static 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);
91 if (static_cast<size_t>(length) > vec->max_size()) return false;
92
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 */
108 template <typename T>
AParcel_nullableStdVectorExternalAllocator(void * vectorData,int32_t length)109 static 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
119 if (static_cast<size_t>(length) > (*vec)->max_size()) return false;
120 (*vec)->resize(length);
121
122 return true;
123 }
124
125 /**
126 * This retrieves the underlying value in a vector which may not be contiguous at index from a
127 * corresponding vectorData.
128 */
129 template <typename T>
AParcel_stdVectorGetter(const void * vectorData,size_t index)130 static 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 */
139 template <typename T>
AParcel_stdVectorSetter(void * vectorData,size_t index,T value)140 static 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
145 /**
146 * This sets the underlying value in a corresponding vectorData which may not be contiguous at
147 * index.
148 */
149 template <typename T>
AParcel_nullableStdVectorSetter(void * vectorData,size_t index,T value)150 static 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 /**
156 * Convenience method to write a nullable strong binder.
157 */
AParcel_writeNullableStrongBinder(AParcel * parcel,const SpAIBinder & binder)158 static 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 */
AParcel_readNullableStrongBinder(const AParcel * parcel,SpAIBinder * binder)166 static 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 /**
177 * Convenience method to write a strong binder but return an error if it is null.
178 */
AParcel_writeRequiredStrongBinder(AParcel * parcel,const SpAIBinder & binder)179 static inline binder_status_t AParcel_writeRequiredStrongBinder(AParcel* parcel,
180 const SpAIBinder& binder) {
181 if (binder.get() == nullptr) {
182 return STATUS_UNEXPECTED_NULL;
183 }
184 return AParcel_writeStrongBinder(parcel, binder.get());
185 }
186
187 /**
188 * Convenience method to read a strong binder but return an error if it is null.
189 */
AParcel_readRequiredStrongBinder(const AParcel * parcel,SpAIBinder * binder)190 static inline binder_status_t AParcel_readRequiredStrongBinder(const AParcel* parcel,
191 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);
200 }
201 return ret;
202 }
203
204 /**
205 * Convenience method to write a ParcelFileDescriptor where -1 represents a null value.
206 */
AParcel_writeNullableParcelFileDescriptor(AParcel * parcel,const ScopedFileDescriptor & fd)207 static 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 */
AParcel_readNullableParcelFileDescriptor(const AParcel * parcel,ScopedFileDescriptor * fd)215 static 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 */
AParcel_writeRequiredParcelFileDescriptor(AParcel * parcel,const ScopedFileDescriptor & fd)228 static 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 */
AParcel_readRequiredParcelFileDescriptor(const AParcel * parcel,ScopedFileDescriptor * fd)239 static 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 /**
253 * 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 */
AParcel_stdStringAllocator(void * stringData,int32_t length,char ** buffer)256 static inline bool AParcel_stdStringAllocator(void* stringData, int32_t length, char** buffer) {
257 if (length <= 0) return false;
258
259 std::string* str = static_cast<std::string*>(stringData);
260 str->resize(length - 1);
261 *buffer = &(*str)[0];
262 return true;
263 }
264
265 /**
266 * 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>*).
269 */
AParcel_nullableStdStringAllocator(void * stringData,int32_t length,char ** buffer)270 static inline bool AParcel_nullableStdStringAllocator(void* stringData, int32_t length,
271 char** buffer) {
272 if (length == 0) return false;
273
274 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 */
AParcel_stdVectorStringElementAllocator(void * vectorData,size_t index,int32_t length,char ** buffer)290 static 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);
293 std::string& element = vec->at(index);
294 return AParcel_stdStringAllocator(static_cast<void*>(&element), length, buffer);
295 }
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 */
AParcel_stdVectorStringElementGetter(const void * vectorData,size_t index,int32_t * outLength)301 static inline const char* AParcel_stdVectorStringElementGetter(const void* vectorData, size_t index,
302 int32_t* outLength) {
303 const std::vector<std::string>* vec = static_cast<const std::vector<std::string>*>(vectorData);
304 const std::string& element = vec->at(index);
305
306 *outLength = element.size();
307 return element.c_str();
308 }
309
310 /**
311 * 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 */
AParcel_nullableStdVectorStringElementAllocator(void * vectorData,size_t index,int32_t length,char ** buffer)315 static 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 */
AParcel_nullableStdVectorStringElementGetter(const void * vectorData,size_t index,int32_t * outLength)328 static inline const char* AParcel_nullableStdVectorStringElementGetter(const void* vectorData,
329 size_t index,
330 int32_t* outLength) {
331 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 /**
345 * Convenience API for writing a std::string.
346 */
AParcel_writeString(AParcel * parcel,const std::string & str)347 static 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 */
AParcel_readString(const AParcel * parcel,std::string * str)354 static 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 /**
360 * Convenience API for writing a std::optional<std::string>.
361 */
AParcel_writeString(AParcel * parcel,const std::optional<std::string> & str)362 static 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 */
AParcel_readString(const AParcel * parcel,std::optional<std::string> * str)374 static 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 /**
381 * Convenience API for writing a std::vector<std::string>
382 */
AParcel_writeVector(AParcel * parcel,const std::vector<std::string> & vec)383 static 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 */
AParcel_readVector(const AParcel * parcel,std::vector<std::string> * vec)393 static 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
401 /**
402 * Convenience API for writing a std::optional<std::vector<std::optional<std::string>>>
403 */
AParcel_writeVector(AParcel * parcel,const std::optional<std::vector<std::optional<std::string>>> & vec)404 static 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 */
AParcel_readVector(const AParcel * parcel,std::optional<std::vector<std::optional<std::string>>> * vec)414 static 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
423 /**
424 * Writes a parcelable object of type P inside a std::vector<P> at index 'index' to 'parcel'.
425 */
426 template <typename P>
AParcel_writeStdVectorParcelableElement(AParcel * parcel,const void * vectorData,size_t index)427 binder_status_t AParcel_writeStdVectorParcelableElement(AParcel* parcel, const void* vectorData,
428 size_t index) {
429 const std::vector<P>* vector = static_cast<const std::vector<P>*>(vectorData);
430 return vector->at(index).writeToParcel(parcel);
431 }
432
433 /**
434 * Reads a parcelable object of type P inside a std::vector<P> at index 'index' from 'parcel'.
435 */
436 template <typename P>
AParcel_readStdVectorParcelableElement(const AParcel * parcel,void * vectorData,size_t index)437 binder_status_t AParcel_readStdVectorParcelableElement(const AParcel* parcel, void* vectorData,
438 size_t index) {
439 std::vector<P>* vector = static_cast<std::vector<P>*>(vectorData);
440 return vector->at(index).readFromParcel(parcel);
441 }
442
443 /**
444 * Convenience API for writing a std::vector<P>
445 */
446 template <typename P>
AParcel_writeVector(AParcel * parcel,const std::vector<P> & vec)447 static inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<P>& vec) {
448 const void* vectorData = static_cast<const void*>(&vec);
449 return AParcel_writeParcelableArray(parcel, vectorData, vec.size(),
450 AParcel_writeStdVectorParcelableElement<P>);
451 }
452
453 /**
454 * Convenience API for reading a std::vector<P>
455 */
456 template <typename P>
AParcel_readVector(const AParcel * parcel,std::vector<P> * vec)457 static inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<P>* vec) {
458 void* vectorData = static_cast<void*>(vec);
459 return AParcel_readParcelableArray(parcel, vectorData, AParcel_stdVectorExternalAllocator<P>,
460 AParcel_readStdVectorParcelableElement<P>);
461 }
462
463 // @START
464 /**
465 * Writes a vector of int32_t to the next location in a non-null parcel.
466 */
AParcel_writeVector(AParcel * parcel,const std::vector<int32_t> & vec)467 inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<int32_t>& vec) {
468 return AParcel_writeInt32Array(parcel, vec.data(), vec.size());
469 }
470
471 /**
472 * Writes an optional vector of int32_t to the next location in a non-null parcel.
473 */
AParcel_writeVector(AParcel * parcel,const std::optional<std::vector<int32_t>> & vec)474 inline binder_status_t AParcel_writeVector(AParcel* parcel,
475 const std::optional<std::vector<int32_t>>& vec) {
476 if (!vec) return AParcel_writeInt32Array(parcel, nullptr, -1);
477 return AParcel_writeVector(parcel, *vec);
478 }
479
480 /**
481 * Reads a vector of int32_t from the next location in a non-null parcel.
482 */
AParcel_readVector(const AParcel * parcel,std::vector<int32_t> * vec)483 inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<int32_t>* vec) {
484 void* vectorData = static_cast<void*>(vec);
485 return AParcel_readInt32Array(parcel, vectorData, AParcel_stdVectorAllocator<int32_t>);
486 }
487
488 /**
489 * Reads an optional vector of int32_t from the next location in a non-null parcel.
490 */
AParcel_readVector(const AParcel * parcel,std::optional<std::vector<int32_t>> * vec)491 inline binder_status_t AParcel_readVector(const AParcel* parcel,
492 std::optional<std::vector<int32_t>>* vec) {
493 void* vectorData = static_cast<void*>(vec);
494 return AParcel_readInt32Array(parcel, vectorData, AParcel_nullableStdVectorAllocator<int32_t>);
495 }
496
497 /**
498 * Writes a vector of uint32_t to the next location in a non-null parcel.
499 */
AParcel_writeVector(AParcel * parcel,const std::vector<uint32_t> & vec)500 inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<uint32_t>& vec) {
501 return AParcel_writeUint32Array(parcel, vec.data(), vec.size());
502 }
503
504 /**
505 * Writes an optional vector of uint32_t to the next location in a non-null parcel.
506 */
AParcel_writeVector(AParcel * parcel,const std::optional<std::vector<uint32_t>> & vec)507 inline binder_status_t AParcel_writeVector(AParcel* parcel,
508 const std::optional<std::vector<uint32_t>>& vec) {
509 if (!vec) return AParcel_writeUint32Array(parcel, nullptr, -1);
510 return AParcel_writeVector(parcel, *vec);
511 }
512
513 /**
514 * Reads a vector of uint32_t from the next location in a non-null parcel.
515 */
AParcel_readVector(const AParcel * parcel,std::vector<uint32_t> * vec)516 inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<uint32_t>* vec) {
517 void* vectorData = static_cast<void*>(vec);
518 return AParcel_readUint32Array(parcel, vectorData, AParcel_stdVectorAllocator<uint32_t>);
519 }
520
521 /**
522 * Reads an optional vector of uint32_t from the next location in a non-null parcel.
523 */
AParcel_readVector(const AParcel * parcel,std::optional<std::vector<uint32_t>> * vec)524 inline binder_status_t AParcel_readVector(const AParcel* parcel,
525 std::optional<std::vector<uint32_t>>* vec) {
526 void* vectorData = static_cast<void*>(vec);
527 return AParcel_readUint32Array(parcel, vectorData,
528 AParcel_nullableStdVectorAllocator<uint32_t>);
529 }
530
531 /**
532 * Writes a vector of int64_t to the next location in a non-null parcel.
533 */
AParcel_writeVector(AParcel * parcel,const std::vector<int64_t> & vec)534 inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<int64_t>& vec) {
535 return AParcel_writeInt64Array(parcel, vec.data(), vec.size());
536 }
537
538 /**
539 * Writes an optional vector of int64_t to the next location in a non-null parcel.
540 */
AParcel_writeVector(AParcel * parcel,const std::optional<std::vector<int64_t>> & vec)541 inline binder_status_t AParcel_writeVector(AParcel* parcel,
542 const std::optional<std::vector<int64_t>>& vec) {
543 if (!vec) return AParcel_writeInt64Array(parcel, nullptr, -1);
544 return AParcel_writeVector(parcel, *vec);
545 }
546
547 /**
548 * Reads a vector of int64_t from the next location in a non-null parcel.
549 */
AParcel_readVector(const AParcel * parcel,std::vector<int64_t> * vec)550 inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<int64_t>* vec) {
551 void* vectorData = static_cast<void*>(vec);
552 return AParcel_readInt64Array(parcel, vectorData, AParcel_stdVectorAllocator<int64_t>);
553 }
554
555 /**
556 * Reads an optional vector of int64_t from the next location in a non-null parcel.
557 */
AParcel_readVector(const AParcel * parcel,std::optional<std::vector<int64_t>> * vec)558 inline binder_status_t AParcel_readVector(const AParcel* parcel,
559 std::optional<std::vector<int64_t>>* vec) {
560 void* vectorData = static_cast<void*>(vec);
561 return AParcel_readInt64Array(parcel, vectorData, AParcel_nullableStdVectorAllocator<int64_t>);
562 }
563
564 /**
565 * Writes a vector of uint64_t to the next location in a non-null parcel.
566 */
AParcel_writeVector(AParcel * parcel,const std::vector<uint64_t> & vec)567 inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<uint64_t>& vec) {
568 return AParcel_writeUint64Array(parcel, vec.data(), vec.size());
569 }
570
571 /**
572 * Writes an optional vector of uint64_t to the next location in a non-null parcel.
573 */
AParcel_writeVector(AParcel * parcel,const std::optional<std::vector<uint64_t>> & vec)574 inline binder_status_t AParcel_writeVector(AParcel* parcel,
575 const std::optional<std::vector<uint64_t>>& vec) {
576 if (!vec) return AParcel_writeUint64Array(parcel, nullptr, -1);
577 return AParcel_writeVector(parcel, *vec);
578 }
579
580 /**
581 * Reads a vector of uint64_t from the next location in a non-null parcel.
582 */
AParcel_readVector(const AParcel * parcel,std::vector<uint64_t> * vec)583 inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<uint64_t>* vec) {
584 void* vectorData = static_cast<void*>(vec);
585 return AParcel_readUint64Array(parcel, vectorData, AParcel_stdVectorAllocator<uint64_t>);
586 }
587
588 /**
589 * Reads an optional vector of uint64_t from the next location in a non-null parcel.
590 */
AParcel_readVector(const AParcel * parcel,std::optional<std::vector<uint64_t>> * vec)591 inline binder_status_t AParcel_readVector(const AParcel* parcel,
592 std::optional<std::vector<uint64_t>>* vec) {
593 void* vectorData = static_cast<void*>(vec);
594 return AParcel_readUint64Array(parcel, vectorData,
595 AParcel_nullableStdVectorAllocator<uint64_t>);
596 }
597
598 /**
599 * Writes a vector of float to the next location in a non-null parcel.
600 */
AParcel_writeVector(AParcel * parcel,const std::vector<float> & vec)601 inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<float>& vec) {
602 return AParcel_writeFloatArray(parcel, vec.data(), vec.size());
603 }
604
605 /**
606 * Writes an optional vector of float to the next location in a non-null parcel.
607 */
AParcel_writeVector(AParcel * parcel,const std::optional<std::vector<float>> & vec)608 inline binder_status_t AParcel_writeVector(AParcel* parcel,
609 const std::optional<std::vector<float>>& vec) {
610 if (!vec) return AParcel_writeFloatArray(parcel, nullptr, -1);
611 return AParcel_writeVector(parcel, *vec);
612 }
613
614 /**
615 * Reads a vector of float from the next location in a non-null parcel.
616 */
AParcel_readVector(const AParcel * parcel,std::vector<float> * vec)617 inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<float>* vec) {
618 void* vectorData = static_cast<void*>(vec);
619 return AParcel_readFloatArray(parcel, vectorData, AParcel_stdVectorAllocator<float>);
620 }
621
622 /**
623 * Reads an optional vector of float from the next location in a non-null parcel.
624 */
AParcel_readVector(const AParcel * parcel,std::optional<std::vector<float>> * vec)625 inline binder_status_t AParcel_readVector(const AParcel* parcel,
626 std::optional<std::vector<float>>* vec) {
627 void* vectorData = static_cast<void*>(vec);
628 return AParcel_readFloatArray(parcel, vectorData, AParcel_nullableStdVectorAllocator<float>);
629 }
630
631 /**
632 * Writes a vector of double to the next location in a non-null parcel.
633 */
AParcel_writeVector(AParcel * parcel,const std::vector<double> & vec)634 inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<double>& vec) {
635 return AParcel_writeDoubleArray(parcel, vec.data(), vec.size());
636 }
637
638 /**
639 * Writes an optional vector of double to the next location in a non-null parcel.
640 */
AParcel_writeVector(AParcel * parcel,const std::optional<std::vector<double>> & vec)641 inline binder_status_t AParcel_writeVector(AParcel* parcel,
642 const std::optional<std::vector<double>>& vec) {
643 if (!vec) return AParcel_writeDoubleArray(parcel, nullptr, -1);
644 return AParcel_writeVector(parcel, *vec);
645 }
646
647 /**
648 * Reads a vector of double from the next location in a non-null parcel.
649 */
AParcel_readVector(const AParcel * parcel,std::vector<double> * vec)650 inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<double>* vec) {
651 void* vectorData = static_cast<void*>(vec);
652 return AParcel_readDoubleArray(parcel, vectorData, AParcel_stdVectorAllocator<double>);
653 }
654
655 /**
656 * Reads an optional vector of double from the next location in a non-null parcel.
657 */
AParcel_readVector(const AParcel * parcel,std::optional<std::vector<double>> * vec)658 inline binder_status_t AParcel_readVector(const AParcel* parcel,
659 std::optional<std::vector<double>>* vec) {
660 void* vectorData = static_cast<void*>(vec);
661 return AParcel_readDoubleArray(parcel, vectorData, AParcel_nullableStdVectorAllocator<double>);
662 }
663
664 /**
665 * Writes a vector of bool to the next location in a non-null parcel.
666 */
AParcel_writeVector(AParcel * parcel,const std::vector<bool> & vec)667 inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<bool>& vec) {
668 return AParcel_writeBoolArray(parcel, static_cast<const void*>(&vec), vec.size(),
669 AParcel_stdVectorGetter<bool>);
670 }
671
672 /**
673 * Writes an optional vector of bool to the next location in a non-null parcel.
674 */
AParcel_writeVector(AParcel * parcel,const std::optional<std::vector<bool>> & vec)675 inline binder_status_t AParcel_writeVector(AParcel* parcel,
676 const std::optional<std::vector<bool>>& vec) {
677 if (!vec) return AParcel_writeBoolArray(parcel, nullptr, -1, AParcel_stdVectorGetter<bool>);
678 return AParcel_writeVector(parcel, *vec);
679 }
680
681 /**
682 * Reads a vector of bool from the next location in a non-null parcel.
683 */
AParcel_readVector(const AParcel * parcel,std::vector<bool> * vec)684 inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<bool>* vec) {
685 void* vectorData = static_cast<void*>(vec);
686 return AParcel_readBoolArray(parcel, vectorData, AParcel_stdVectorExternalAllocator<bool>,
687 AParcel_stdVectorSetter<bool>);
688 }
689
690 /**
691 * Reads an optional vector of bool from the next location in a non-null parcel.
692 */
AParcel_readVector(const AParcel * parcel,std::optional<std::vector<bool>> * vec)693 inline binder_status_t AParcel_readVector(const AParcel* parcel,
694 std::optional<std::vector<bool>>* vec) {
695 void* vectorData = static_cast<void*>(vec);
696 return AParcel_readBoolArray(parcel, vectorData,
697 AParcel_nullableStdVectorExternalAllocator<bool>,
698 AParcel_nullableStdVectorSetter<bool>);
699 }
700
701 /**
702 * Writes a vector of char16_t to the next location in a non-null parcel.
703 */
AParcel_writeVector(AParcel * parcel,const std::vector<char16_t> & vec)704 inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<char16_t>& vec) {
705 return AParcel_writeCharArray(parcel, vec.data(), vec.size());
706 }
707
708 /**
709 * Writes an optional vector of char16_t to the next location in a non-null parcel.
710 */
AParcel_writeVector(AParcel * parcel,const std::optional<std::vector<char16_t>> & vec)711 inline binder_status_t AParcel_writeVector(AParcel* parcel,
712 const std::optional<std::vector<char16_t>>& vec) {
713 if (!vec) return AParcel_writeCharArray(parcel, nullptr, -1);
714 return AParcel_writeVector(parcel, *vec);
715 }
716
717 /**
718 * Reads a vector of char16_t from the next location in a non-null parcel.
719 */
AParcel_readVector(const AParcel * parcel,std::vector<char16_t> * vec)720 inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<char16_t>* vec) {
721 void* vectorData = static_cast<void*>(vec);
722 return AParcel_readCharArray(parcel, vectorData, AParcel_stdVectorAllocator<char16_t>);
723 }
724
725 /**
726 * Reads an optional vector of char16_t from the next location in a non-null parcel.
727 */
AParcel_readVector(const AParcel * parcel,std::optional<std::vector<char16_t>> * vec)728 inline binder_status_t AParcel_readVector(const AParcel* parcel,
729 std::optional<std::vector<char16_t>>* vec) {
730 void* vectorData = static_cast<void*>(vec);
731 return AParcel_readCharArray(parcel, vectorData, AParcel_nullableStdVectorAllocator<char16_t>);
732 }
733
734 /**
735 * Writes a vector of int8_t to the next location in a non-null parcel.
736 */
AParcel_writeVector(AParcel * parcel,const std::vector<int8_t> & vec)737 inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<int8_t>& vec) {
738 return AParcel_writeByteArray(parcel, vec.data(), vec.size());
739 }
740
741 /**
742 * Writes an optional vector of int8_t to the next location in a non-null parcel.
743 */
AParcel_writeVector(AParcel * parcel,const std::optional<std::vector<int8_t>> & vec)744 inline binder_status_t AParcel_writeVector(AParcel* parcel,
745 const std::optional<std::vector<int8_t>>& vec) {
746 if (!vec) return AParcel_writeByteArray(parcel, nullptr, -1);
747 return AParcel_writeVector(parcel, *vec);
748 }
749
750 /**
751 * Reads a vector of int8_t from the next location in a non-null parcel.
752 */
AParcel_readVector(const AParcel * parcel,std::vector<int8_t> * vec)753 inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<int8_t>* vec) {
754 void* vectorData = static_cast<void*>(vec);
755 return AParcel_readByteArray(parcel, vectorData, AParcel_stdVectorAllocator<int8_t>);
756 }
757
758 /**
759 * Reads an optional vector of int8_t from the next location in a non-null parcel.
760 */
AParcel_readVector(const AParcel * parcel,std::optional<std::vector<int8_t>> * vec)761 inline binder_status_t AParcel_readVector(const AParcel* parcel,
762 std::optional<std::vector<int8_t>>* vec) {
763 void* vectorData = static_cast<void*>(vec);
764 return AParcel_readByteArray(parcel, vectorData, AParcel_nullableStdVectorAllocator<int8_t>);
765 }
766
767 // @END
768
769 /**
770 * Convenience API for writing the size of a vector.
771 */
772 template <typename T>
AParcel_writeVectorSize(AParcel * parcel,const std::vector<T> & vec)773 static inline binder_status_t AParcel_writeVectorSize(AParcel* parcel, const std::vector<T>& vec) {
774 if (vec.size() > INT32_MAX) {
775 return STATUS_BAD_VALUE;
776 }
777
778 return AParcel_writeInt32(parcel, static_cast<int32_t>(vec.size()));
779 }
780
781 /**
782 * Convenience API for writing the size of a vector.
783 */
784 template <typename T>
AParcel_writeVectorSize(AParcel * parcel,const std::optional<std::vector<T>> & vec)785 static inline binder_status_t AParcel_writeVectorSize(AParcel* parcel,
786 const std::optional<std::vector<T>>& vec) {
787 if (!vec) {
788 return AParcel_writeInt32(parcel, -1);
789 }
790
791 if (vec->size() > INT32_MAX) {
792 return STATUS_BAD_VALUE;
793 }
794
795 return AParcel_writeInt32(parcel, static_cast<int32_t>(vec->size()));
796 }
797
798 /**
799 * Convenience API for resizing a vector.
800 */
801 template <typename T>
AParcel_resizeVector(const AParcel * parcel,std::vector<T> * vec)802 static inline binder_status_t AParcel_resizeVector(const AParcel* parcel, std::vector<T>* vec) {
803 int32_t size;
804 binder_status_t err = AParcel_readInt32(parcel, &size);
805
806 if (err != STATUS_OK) return err;
807 if (size < 0) return STATUS_UNEXPECTED_NULL;
808
809 vec->resize(static_cast<size_t>(size));
810 return STATUS_OK;
811 }
812
813 /**
814 * Convenience API for resizing a vector.
815 */
816 template <typename T>
AParcel_resizeVector(const AParcel * parcel,std::optional<std::vector<T>> * vec)817 static inline binder_status_t AParcel_resizeVector(const AParcel* parcel,
818 std::optional<std::vector<T>>* vec) {
819 int32_t size;
820 binder_status_t err = AParcel_readInt32(parcel, &size);
821
822 if (err != STATUS_OK) return err;
823 if (size < -1) return STATUS_UNEXPECTED_NULL;
824
825 if (size == -1) {
826 *vec = std::nullopt;
827 return STATUS_OK;
828 }
829
830 *vec = std::optional<std::vector<T>>(std::vector<T>{});
831 (*vec)->resize(static_cast<size_t>(size));
832 return STATUS_OK;
833 }
834
835 } // namespace ndk
836
837 /** @} */
838