diff options
-rw-r--r-- | include/binder/Parcel.h | 23 | ||||
-rw-r--r-- | libs/binder/Parcel.cpp | 423 |
2 files changed, 445 insertions, 1 deletions
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h index 9bf62a3a8e..5a37e6a408 100644 --- a/include/binder/Parcel.h +++ b/include/binder/Parcel.h @@ -17,6 +17,8 @@ #ifndef ANDROID_PARCEL_H #define ANDROID_PARCEL_H +#include <vector> + #include <cutils/native_handle.h> #include <utils/Errors.h> #include <utils/RefBase.h> @@ -112,6 +114,15 @@ public: status_t writeChar(char16_t val); status_t writeByte(int8_t val); + status_t writeByteVector(const std::vector<int8_t>& val); + status_t writeInt32Vector(const std::vector<int32_t>& val); + status_t writeInt64Vector(const std::vector<int64_t>& val); + status_t writeFloatVector(const std::vector<float>& val); + status_t writeDoubleVector(const std::vector<double>& val); + status_t writeBoolVector(const std::vector<bool>& val); + status_t writeCharVector(const std::vector<char16_t>& val); + status_t writeString16Vector(const std::vector<String16>& val); + template<typename T> status_t write(const Flattenable<T>& val); @@ -121,7 +132,7 @@ public: // 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 - // when this function returns). + // when this function returns). // Doesn't take ownership of the native_handle. status_t writeNativeHandle(const native_handle* handle); @@ -182,10 +193,20 @@ public: const char* readCString() const; String8 readString8() const; String16 readString16() const; + status_t readString16(String16* pArg) const; const char16_t* readString16Inplace(size_t* outLen) const; sp<IBinder> readStrongBinder() const; wp<IBinder> readWeakBinder() const; + status_t readByteVector(std::vector<int8_t>* val) const; + status_t readInt32Vector(std::vector<int32_t>* val) const; + status_t readInt64Vector(std::vector<int64_t>* val) const; + status_t readFloatVector(std::vector<float>* val) const; + status_t readDoubleVector(std::vector<double>* val) const; + status_t readBoolVector(std::vector<bool>* val) const; + status_t readCharVector(std::vector<char16_t>* val) const; + status_t readString16Vector(std::vector<String16>* val) const; + template<typename T> status_t read(Flattenable<T>& val) const; diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index 95385db9d9..dd3f068e01 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -717,6 +717,190 @@ restart_write: return NULL; } +status_t Parcel::writeByteVector(const std::vector<int8_t>& val) +{ + if (val.size() > std::numeric_limits<int32_t>::max()) { + return BAD_VALUE; + } + + status_t status = writeInt32(val.size()); + + if (status != OK) { + return status; + } + + for (const auto& item : val) { + status = writeByte(item); + + if (status != OK) { + return status; + } + } + + return OK; +} + +status_t Parcel::writeInt32Vector(const std::vector<int32_t>& val) +{ + if (val.size() > std::numeric_limits<int32_t>::max()) { + return BAD_VALUE; + } + + status_t status = writeInt32(val.size()); + + if (status != OK) { + return status; + } + + for (const auto& item : val) { + status = writeInt32(item); + + if (status != OK) { + return status; + } + } + + return OK; +} + +status_t Parcel::writeInt64Vector(const std::vector<int64_t>& val) +{ + if (val.size() > std::numeric_limits<int32_t>::max()) { + return BAD_VALUE; + } + + status_t status = writeInt32(val.size()); + + if (status != OK) { + return status; + } + + for (const auto& item : val) { + status = writeInt64(item); + + if (status != OK) { + return status; + } + } + + return OK; +} + +status_t Parcel::writeFloatVector(const std::vector<float>& val) +{ + if (val.size() > std::numeric_limits<int32_t>::max()) { + return BAD_VALUE; + } + + status_t status = writeInt32(val.size()); + + if (status != OK) { + return status; + } + + for (const auto& item : val) { + status = writeFloat(item); + + if (status != OK) { + return status; + } + } + + return OK; +} + +status_t Parcel::writeDoubleVector(const std::vector<double>& val) +{ + if (val.size() > std::numeric_limits<int32_t>::max()) { + return BAD_VALUE; + } + + status_t status = writeInt32(val.size()); + + if (status != OK) { + return status; + } + + for (const auto& item : val) { + status = writeDouble(item); + + if (status != OK) { + return status; + } + } + + return OK; +} + +status_t Parcel::writeBoolVector(const std::vector<bool>& val) +{ + if (val.size() > std::numeric_limits<int32_t>::max()) { + return BAD_VALUE; + } + + status_t status = writeInt32(val.size()); + + if (status != OK) { + return status; + } + + for (const auto& item : val) { + status = writeBool(item); + + if (status != OK) { + return status; + } + } + + return OK; +} + +status_t Parcel::writeCharVector(const std::vector<char16_t>& val) +{ + if (val.size() > std::numeric_limits<int32_t>::max()) { + return BAD_VALUE; + } + + status_t status = writeInt32(val.size()); + + if (status != OK) { + return status; + } + + for (const auto& item : val) { + status = writeChar(item); + + if (status != OK) { + return status; + } + } + + return OK; +} + +status_t Parcel::writeString16Vector(const std::vector<String16>& val) +{ + if (val.size() > std::numeric_limits<int32_t>::max()) { + return BAD_VALUE; + } + + status_t status = writeInt32(val.size()); + + if (status != OK) { + return status; + } + + for (const auto& item : val) { + status = writeString16(item); + + if (status != OK) { + return status; + } + } + + return OK; +} + status_t Parcel::writeInt32(int32_t val) { return writeAligned(val); @@ -1149,6 +1333,232 @@ restart_write: return err; } +status_t Parcel::readByteVector(std::vector<int8_t>* val) const { + val->clear(); + + int32_t size; + status_t status = readInt32(&size); + + if (status != OK) { + return status; + } + + if (size < 0) { + return BAD_VALUE; + } + + val->resize(size); + + for (auto& v : *val) { + status = readByte(&v); + + if (status != OK) { + return status; + } + } + + return OK; +} + +status_t Parcel::readInt32Vector(std::vector<int32_t>* val) const { + val->clear(); + + int32_t size; + status_t status = readInt32(&size); + + if (status != OK) { + return status; + } + + if (size < 0) { + return BAD_VALUE; + } + + val->resize(size); + + for (auto& v: *val) { + status = readInt32(&v); + + if (status != OK) { + return status; + } + } + + return OK; +} + +status_t Parcel::readInt64Vector(std::vector<int64_t>* val) const { + val->clear(); + + int32_t size; + status_t status = readInt32(&size); + + if (status != OK) { + return status; + } + + if (size < 0) { + return BAD_VALUE; + } + + val->resize(size); + + for (auto& v : *val) { + status = readInt64(&v); + + if (status != OK) { + return status; + } + } + + return OK; +} + +status_t Parcel::readFloatVector(std::vector<float>* val) const { + val->clear(); + + int32_t size; + status_t status = readInt32(&size); + + if (status != OK) { + return status; + } + + if (size < 0) { + return BAD_VALUE; + } + + val->resize(size); + + for (auto& v : *val) { + status = readFloat(&v); + + if (status != OK) { + return status; + } + } + + return OK; +} + +status_t Parcel::readDoubleVector(std::vector<double>* val) const { + val->clear(); + + int32_t size; + status_t status = readInt32(&size); + + if (status != OK) { + return status; + } + + if (size < 0) { + return BAD_VALUE; + } + + val->resize(size); + + for (auto& v : *val) { + status = readDouble(&v); + + if (status != OK) { + return status; + } + } + + return OK; +} + +status_t Parcel::readBoolVector(std::vector<bool>* val) const { + val->clear(); + + int32_t size; + status_t status = readInt32(&size); + + if (status != OK) { + return status; + } + + if (size < 0) { + return BAD_VALUE; + } + + val->resize(size); + + /* C++ bool handling means a vector of bools isn't necessarily addressable + * (we might use individual bits) + */ + for (int32_t i = 0; i < size; size++) { + bool data; + status = readBool(&data); + (*val)[i] = data; + + if (status != OK) { + return status; + } + } + + return OK; +} + +status_t Parcel::readCharVector(std::vector<char16_t>* val) const { + val->clear(); + + int32_t size; + status_t status = readInt32(&size); + + if (status != OK) { + return status; + } + + if (size < 0) { + return BAD_VALUE; + } + + val->resize(size); + + for (auto& v : *val) { + status = readChar(&v); + + if (status != OK) { + return status; + } + } + + return OK; +} + +status_t Parcel::readString16Vector(std::vector<String16>* val) const { + val->clear(); + + int32_t size; + status_t status = readInt32(&size); + + if (status != OK) { + return status; + } + + if (size < 0) { + return BAD_VALUE; + } + + val->reserve(size); + + while (size-- > 0) { + const char16_t *data; + size_t size; + data = readString16Inplace(&size); + + if (data == nullptr) { + return UNKNOWN_ERROR; + } + + val->emplace_back(data, size); + } + + return OK; +} + + status_t Parcel::readInt32(int32_t *pArg) const { return readAligned(pArg); @@ -1343,6 +1753,19 @@ String16 Parcel::readString16() const return String16(); } +status_t Parcel::readString16(String16* pArg) const +{ + size_t len; + const char16_t* str = readString16Inplace(&len); + if (str) { + *pArg->setTo(str, len); + return 0; + } else { + *pArg = String16(); + return UNKNOWN_ERROR; + } +} + const char16_t* Parcel::readString16Inplace(size_t* outLen) const { int32_t size = readInt32(); |