libbinder_ndk: read/write parcelable array
Bug: 111445392
Test: atest android.binder.cts
Change-Id: Ib7e7634b32611e26e6bd7e359ab4d9e9764e1cbc
diff --git a/libs/binder/ndk/parcel.cpp b/libs/binder/ndk/parcel.cpp
index 2d68559..3976855 100644
--- a/libs/binder/ndk/parcel.cpp
+++ b/libs/binder/ndk/parcel.cpp
@@ -377,11 +377,11 @@
if (length <= 0) return STATUS_OK;
for (size_t i = 0; i < length; i++) {
- size_t length = 0;
- const char* str = getter(arrayData, i, &length);
- if (str == nullptr && length != -1) return STATUS_BAD_VALUE;
+ size_t elementLength = 0;
+ const char* str = getter(arrayData, i, &elementLength);
+ if (str == nullptr && elementLength != -1) return STATUS_BAD_VALUE;
- binder_status_t status = AParcel_writeString(parcel, str, length);
+ binder_status_t status = AParcel_writeString(parcel, str, elementLength);
if (status != STATUS_OK) return status;
}
@@ -433,6 +433,45 @@
return STATUS_OK;
}
+binder_status_t AParcel_writeParcelableArray(AParcel* parcel, const void* arrayData, int32_t length,
+ AParcel_writeParcelableElement elementWriter) {
+ // we have no clue if arrayData represents a null object or not, we can only infer from length
+ bool arrayIsNull = length < 0;
+ binder_status_t status = WriteAndValidateArraySize(parcel, arrayIsNull, length);
+ if (status != STATUS_OK) return status;
+ if (length <= 0) return STATUS_OK;
+
+ for (size_t i = 0; i < length; i++) {
+ binder_status_t status = elementWriter(parcel, arrayData, i);
+ if (status != STATUS_OK) return status;
+ }
+
+ return STATUS_OK;
+}
+
+binder_status_t AParcel_readParcelableArray(const AParcel* parcel, void* arrayData,
+ AParcel_parcelableArrayAllocator allocator,
+ AParcel_readParcelableElement elementReader) {
+ const Parcel* rawParcel = parcel->get();
+
+ int32_t length;
+ status_t status = rawParcel->readInt32(&length);
+
+ if (status != STATUS_OK) return PruneStatusT(status);
+ if (length < -1) return STATUS_BAD_VALUE;
+
+ if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;
+
+ if (length == -1) return STATUS_OK; // null array
+
+ for (size_t i = 0; i < length; i++) {
+ binder_status_t status = elementReader(parcel, arrayData, i);
+ if (status != STATUS_OK) return status;
+ }
+
+ return STATUS_OK;
+}
+
// See gen_parcel_helper.py. These auto-generated read/write methods use the same types for
// libbinder and this library.
// @START