libbinder: Support reading/writing out T[] lengths
T[] types are special: the length of the out array is written
into the inbound parcel to signal the expected length to the
server.
Bug: 30836680
Change-Id: I4f2f39fd7b1a6b94a25bd7f6c3baed430fd567bc
Test: integration tests pass with this change.
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index fe3aed6..7ee25dd 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -166,6 +166,10 @@
template<typename T>
status_t write(const LightFlattenable<T>& val);
+ template<typename T>
+ status_t writeVectorSize(const std::vector<T>& val);
+ template<typename T>
+ status_t writeVectorSize(const std::unique_ptr<std::vector<T>>& val);
// Place a native_handle into the parcel (the native_handle's file-
// descriptors are dup'ed, so it is safe to delete the native_handle
@@ -305,6 +309,11 @@
template<typename T>
status_t read(LightFlattenable<T>& val) const;
+ template<typename T>
+ status_t resizeOutVector(std::vector<T>* val) const;
+ template<typename T>
+ status_t resizeOutVector(std::unique_ptr<std::vector<T>>* val) const;
+
// Like Parcel.java's readExceptionCode(). Reads the first int32
// off of a Parcel's header, returning 0 or the negative error
// code on exceptions, but also deals with skipping over rich
@@ -564,6 +573,54 @@
}
template<typename T>
+status_t Parcel::writeVectorSize(const std::vector<T>& val) {
+ if (val.size() > INT32_MAX) {
+ return BAD_VALUE;
+ }
+ return writeInt32(val.size());
+}
+
+template<typename T>
+status_t Parcel::writeVectorSize(const std::unique_ptr<std::vector<T>>& val) {
+ if (!val) {
+ return writeInt32(-1);
+ }
+
+ return writeVectorSize(*val);
+}
+
+template<typename T>
+status_t Parcel::resizeOutVector(std::vector<T>* val) const {
+ int32_t size;
+ status_t err = readInt32(&size);
+ if (err != NO_ERROR) {
+ return err;
+ }
+
+ if (size < 0) {
+ return UNEXPECTED_NULL;
+ }
+ val->resize(size_t(size));
+ return OK;
+}
+
+template<typename T>
+status_t Parcel::resizeOutVector(std::unique_ptr<std::vector<T>>* val) const {
+ int32_t size;
+ status_t err = readInt32(&size);
+ if (err != NO_ERROR) {
+ return err;
+ }
+
+ val->reset();
+ if (size >= 0) {
+ val->reset(new std::vector<T>(size_t(size)));
+ }
+
+ return OK;
+}
+
+template<typename T>
status_t Parcel::readStrongBinder(sp<T>* val) const {
sp<IBinder> tmp;
status_t ret = readStrongBinder(&tmp);