Commit b9872623 authored by Casey Dahlin's avatar Casey Dahlin
Browse files

Allow null values for Parcel readers and writers


Test: AIDL integration tests pass
Bug: 25969194
Change-Id: Ib7023c8e02af49e08c9921f1d097e5967c1d378e
Signed-off-by: default avatarCasey Dahlin <sadmac@google.com>
parent 478259b5
......@@ -109,6 +109,7 @@ public:
status_t writeCString(const char* str);
status_t writeString8(const String8& str);
status_t writeString16(const String16& str);
status_t writeString16(const std::unique_ptr<String16>& str);
status_t writeString16(const char16_t* str, size_t len);
status_t writeStrongBinder(const sp<IBinder>& val);
status_t writeWeakBinder(const wp<IBinder>& val);
......@@ -118,19 +119,35 @@ public:
status_t writeChar(char16_t val);
status_t writeByte(int8_t val);
status_t writeByteVector(const std::unique_ptr<std::vector<int8_t>>& val);
status_t writeByteVector(const std::vector<int8_t>& val);
status_t writeInt32Vector(const std::unique_ptr<std::vector<int32_t>>& val);
status_t writeInt32Vector(const std::vector<int32_t>& val);
status_t writeInt64Vector(const std::unique_ptr<std::vector<int64_t>>& val);
status_t writeInt64Vector(const std::vector<int64_t>& val);
status_t writeFloatVector(const std::unique_ptr<std::vector<float>>& val);
status_t writeFloatVector(const std::vector<float>& val);
status_t writeDoubleVector(const std::unique_ptr<std::vector<double>>& val);
status_t writeDoubleVector(const std::vector<double>& val);
status_t writeBoolVector(const std::unique_ptr<std::vector<bool>>& val);
status_t writeBoolVector(const std::vector<bool>& val);
status_t writeCharVector(const std::unique_ptr<std::vector<char16_t>>& val);
status_t writeCharVector(const std::vector<char16_t>& val);
status_t writeString16Vector(
const std::unique_ptr<std::vector<std::unique_ptr<String16>>>& val);
status_t writeString16Vector(const std::vector<String16>& val);
status_t writeStrongBinderVector(const std::unique_ptr<std::vector<sp<IBinder>>>& val);
status_t writeStrongBinderVector(const std::vector<sp<IBinder>>& val);
template<typename T>
status_t writeParcelableVector(const std::unique_ptr<std::vector<std::unique_ptr<T>>>& val);
template<typename T>
status_t writeParcelableVector(const std::vector<T>& val);
template<typename T>
status_t writeNullableParcelable(const std::unique_ptr<T>& parcelable);
status_t writeParcelable(const Parcelable& parcelable);
template<typename T>
......@@ -163,6 +180,8 @@ public:
// Place a vector of file desciptors into the parcel. Each descriptor is
// dup'd as in writeDupFileDescriptor
status_t writeUniqueFileDescriptorVector(
const std::unique_ptr<std::vector<ScopedFd>>& val);
status_t writeUniqueFileDescriptorVector(
const std::vector<ScopedFd>& val);
......@@ -215,27 +234,45 @@ public:
String8 readString8() const;
String16 readString16() const;
status_t readString16(String16* pArg) const;
status_t readString16(std::unique_ptr<String16>* pArg) const;
const char16_t* readString16Inplace(size_t* outLen) const;
sp<IBinder> readStrongBinder() const;
status_t readStrongBinder(sp<IBinder>* val) const;
wp<IBinder> readWeakBinder() const;
template<typename T>
status_t readParcelableVector(
std::unique_ptr<std::vector<std::unique_ptr<T>>>* val) const;
template<typename T>
status_t readParcelableVector(std::vector<T>* val) const;
status_t readParcelable(Parcelable* parcelable) const;
template<typename T>
status_t readParcelable(std::unique_ptr<T>* parcelable) const;
template<typename T>
status_t readStrongBinder(sp<T>* val) const;
status_t readStrongBinderVector(std::unique_ptr<std::vector<sp<IBinder>>>* val) const;
status_t readStrongBinderVector(std::vector<sp<IBinder>>* val) const;
status_t readByteVector(std::unique_ptr<std::vector<int8_t>>* val) const;
status_t readByteVector(std::vector<int8_t>* val) const;
status_t readInt32Vector(std::unique_ptr<std::vector<int32_t>>* val) const;
status_t readInt32Vector(std::vector<int32_t>* val) const;
status_t readInt64Vector(std::unique_ptr<std::vector<int64_t>>* val) const;
status_t readInt64Vector(std::vector<int64_t>* val) const;
status_t readFloatVector(std::unique_ptr<std::vector<float>>* val) const;
status_t readFloatVector(std::vector<float>* val) const;
status_t readDoubleVector(std::unique_ptr<std::vector<double>>* val) const;
status_t readDoubleVector(std::vector<double>* val) const;
status_t readBoolVector(std::unique_ptr<std::vector<bool>>* val) const;
status_t readBoolVector(std::vector<bool>* val) const;
status_t readCharVector(std::unique_ptr<std::vector<char16_t>>* val) const;
status_t readCharVector(std::vector<char16_t>* val) const;
status_t readString16Vector(
std::unique_ptr<std::vector<std::unique_ptr<String16>>>* val) const;
status_t readString16Vector(std::vector<String16>* val) const;
template<typename T>
......@@ -268,6 +305,8 @@ public:
// Retrieve a vector of smart file descriptors from the parcel.
status_t readUniqueFileDescriptorVector(
std::unique_ptr<std::vector<ScopedFd>>* val) const;
status_t readUniqueFileDescriptorVector(
std::vector<ScopedFd>* val) const;
......@@ -326,16 +365,28 @@ private:
template<class T>
status_t writeAligned(T val);
status_t writeRawNullableParcelable(const Parcelable*
parcelable);
template<typename T, typename U>
status_t unsafeReadTypedVector(std::vector<T>* val,
status_t(Parcel::*read_func)(U*) const) const;
template<typename T>
status_t readNullableTypedVector(std::unique_ptr<std::vector<T>>* val,
status_t(Parcel::*read_func)(T*) const) const;
template<typename T>
status_t readTypedVector(std::vector<T>* val,
status_t(Parcel::*read_func)(T*) const) const;
template<typename T, typename U>
status_t unsafeWriteTypedVector(const std::vector<T>& val,
status_t(Parcel::*write_func)(U));
template<typename T>
status_t writeNullableTypedVector(const std::unique_ptr<std::vector<T>>& val,
status_t(Parcel::*write_func)(const T&));
template<typename T>
status_t writeNullableTypedVector(const std::unique_ptr<std::vector<T>>& val,
status_t(Parcel::*write_func)(T));
template<typename T>
status_t writeTypedVector(const std::vector<T>& val,
status_t(Parcel::*write_func)(const T&));
template<typename T>
......@@ -506,9 +557,8 @@ status_t Parcel::readStrongBinder(sp<T>* val) const {
template<typename T, typename U>
status_t Parcel::unsafeReadTypedVector(
std::vector<T>* val, status_t(Parcel::*read_func)(U*) const) const {
val->clear();
std::vector<T>* val,
status_t(Parcel::*read_func)(U*) const) const {
int32_t size;
status_t status = this->readInt32(&size);
......@@ -539,6 +589,30 @@ status_t Parcel::readTypedVector(std::vector<T>* val,
return unsafeReadTypedVector(val, read_func);
}
template<typename T>
status_t Parcel::readNullableTypedVector(std::unique_ptr<std::vector<T>>* val,
status_t(Parcel::*read_func)(T*) const) const {
const int32_t start = dataPosition();
int32_t size;
status_t status = readInt32(&size);
val->reset();
if (status != OK || size < 0) {
return status;
}
setDataPosition(start);
val->reset(new std::vector<T>());
status = unsafeReadTypedVector(val->get(), read_func);
if (status != OK) {
val->reset();
}
return status;
}
template<typename T, typename U>
status_t Parcel::unsafeWriteTypedVector(const std::vector<T>& val,
status_t(Parcel::*write_func)(U)) {
......@@ -565,24 +639,104 @@ status_t Parcel::unsafeWriteTypedVector(const std::vector<T>& val,
template<typename T>
status_t Parcel::writeTypedVector(const std::vector<T>& val,
status_t(Parcel::*write_func)(const T&)) {
status_t(Parcel::*write_func)(const T&)) {
return unsafeWriteTypedVector(val, write_func);
}
template<typename T>
status_t Parcel::writeTypedVector(const std::vector<T>& val,
status_t(Parcel::*write_func)(T)) {
status_t(Parcel::*write_func)(T)) {
return unsafeWriteTypedVector(val, write_func);
}
template<typename T>
status_t Parcel::writeNullableTypedVector(const std::unique_ptr<std::vector<T>>& val,
status_t(Parcel::*write_func)(const T&)) {
if (val.get() == nullptr) {
return this->writeInt32(-1);
}
return unsafeWriteTypedVector(*val, write_func);
}
template<typename T>
status_t Parcel::writeNullableTypedVector(const std::unique_ptr<std::vector<T>>& val,
status_t(Parcel::*write_func)(T)) {
if (val.get() == nullptr) {
return this->writeInt32(-1);
}
return unsafeWriteTypedVector(*val, write_func);
}
template<typename T>
status_t Parcel::readParcelableVector(std::vector<T>* val) const {
return unsafeReadTypedVector(val, &Parcel::readParcelable);
return unsafeReadTypedVector<T, Parcelable>(val, &Parcel::readParcelable);
}
template<typename T>
status_t Parcel::readParcelableVector(std::unique_ptr<std::vector<std::unique_ptr<T>>>* val) const {
const int32_t start = dataPosition();
int32_t size;
status_t status = readInt32(&size);
val->reset();
if (status != OK || size < 0) {
return status;
}
setDataPosition(start);
val->reset(new std::vector<T>());
status = unsafeReadTypedVector(val->get(), &Parcel::readParcelable);
if (status != OK) {
val->reset();
}
return status;
}
template<typename T>
status_t Parcel::readParcelable(std::unique_ptr<T>* parcelable) const {
const int32_t start = dataPosition();
int32_t present;
status_t status = readInt32(&present);
parcelable->reset();
if (status != OK || !present) {
return status;
}
setDataPosition(start);
parcelable->reset(new T());
status = readParcelable(parcelable->get());
if (status != OK) {
parcelable->reset();
}
return status;
}
template<typename T>
status_t Parcel::writeNullableParcelable(const std::unique_ptr<T>& parcelable) {
return writeRawNullableParcelable(parcelable.get());
}
template<typename T>
status_t Parcel::writeParcelableVector(const std::vector<T>& val) {
return unsafeWriteTypedVector(val, &Parcel::writeParcelable);
return unsafeWriteTypedVector<T,const Parcelable&>(val, &Parcel::writeParcelable);
}
template<typename T>
status_t Parcel::writeParcelableVector(const std::unique_ptr<std::vector<std::unique_ptr<T>>>& val) {
if (val.get() == nullptr) {
return this->writeInt32(-1);
}
return unsafeWriteTypedVector(*val, &Parcel::writeParcelable);
}
// ---------------------------------------------------------------------------
......
......@@ -743,6 +743,15 @@ restart_write:
return NULL;
}
status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<int8_t>>& val)
{
if (!val) {
return writeInt32(-1);
}
return writeByteVector(*val);
}
status_t Parcel::writeByteVector(const std::vector<int8_t>& val)
{
status_t status;
......@@ -771,36 +780,72 @@ status_t Parcel::writeInt32Vector(const std::vector<int32_t>& val)
return writeTypedVector(val, &Parcel::writeInt32);
}
status_t Parcel::writeInt32Vector(const std::unique_ptr<std::vector<int32_t>>& val)
{
return writeNullableTypedVector(val, &Parcel::writeInt32);
}
status_t Parcel::writeInt64Vector(const std::vector<int64_t>& val)
{
return writeTypedVector(val, &Parcel::writeInt64);
}
status_t Parcel::writeInt64Vector(const std::unique_ptr<std::vector<int64_t>>& val)
{
return writeNullableTypedVector(val, &Parcel::writeInt64);
}
status_t Parcel::writeFloatVector(const std::vector<float>& val)
{
return writeTypedVector(val, &Parcel::writeFloat);
}
status_t Parcel::writeFloatVector(const std::unique_ptr<std::vector<float>>& val)
{
return writeNullableTypedVector(val, &Parcel::writeFloat);
}
status_t Parcel::writeDoubleVector(const std::vector<double>& val)
{
return writeTypedVector(val, &Parcel::writeDouble);
}
status_t Parcel::writeDoubleVector(const std::unique_ptr<std::vector<double>>& val)
{
return writeNullableTypedVector(val, &Parcel::writeDouble);
}
status_t Parcel::writeBoolVector(const std::vector<bool>& val)
{
return writeTypedVector(val, &Parcel::writeBool);
}
status_t Parcel::writeBoolVector(const std::unique_ptr<std::vector<bool>>& val)
{
return writeNullableTypedVector(val, &Parcel::writeBool);
}
status_t Parcel::writeCharVector(const std::vector<char16_t>& val)
{
return writeTypedVector(val, &Parcel::writeChar);
}
status_t Parcel::writeCharVector(const std::unique_ptr<std::vector<char16_t>>& val)
{
return writeNullableTypedVector(val, &Parcel::writeChar);
}
status_t Parcel::writeString16Vector(const std::vector<String16>& val)
{
return writeTypedVector(val, &Parcel::writeString16);
}
status_t Parcel::writeString16Vector(
const std::unique_ptr<std::vector<std::unique_ptr<String16>>>& val)
{
return writeNullableTypedVector(val, &Parcel::writeString16);
}
status_t Parcel::writeInt32(int32_t val)
{
return writeAligned(val);
......@@ -917,6 +962,15 @@ status_t Parcel::writeString8(const String8& str)
return err;
}
status_t Parcel::writeString16(const std::unique_ptr<String16>& str)
{
if (!str) {
return writeInt32(-1);
}
return writeString16(*str);
}
status_t Parcel::writeString16(const String16& str)
{
return writeString16(str.string(), str.size());
......@@ -950,6 +1004,15 @@ status_t Parcel::writeStrongBinderVector(const std::vector<sp<IBinder>>& val)
return writeTypedVector(val, &Parcel::writeStrongBinder);
}
status_t Parcel::writeStrongBinderVector(const std::unique_ptr<std::vector<sp<IBinder>>>& val)
{
return writeNullableTypedVector(val, &Parcel::writeStrongBinder);
}
status_t Parcel::readStrongBinderVector(std::unique_ptr<std::vector<sp<IBinder>>>* val) const {
return readNullableTypedVector(val, &Parcel::readStrongBinder);
}
status_t Parcel::readStrongBinderVector(std::vector<sp<IBinder>>* val) const {
return readTypedVector(val, &Parcel::readStrongBinder);
}
......@@ -959,6 +1022,14 @@ status_t Parcel::writeWeakBinder(const wp<IBinder>& val)
return flatten_binder(ProcessState::self(), val, this);
}
status_t Parcel::writeRawNullableParcelable(const Parcelable* parcelable) {
if (!parcelable) {
return writeInt32(0);
}
return writeParcelable(*parcelable);
}
status_t Parcel::writeParcelable(const Parcelable& parcelable) {
status_t status = writeInt32(1); // parcelable is not null.
if (status != OK) {
......@@ -1022,6 +1093,10 @@ status_t Parcel::writeUniqueFileDescriptorVector(const std::vector<ScopedFd>& va
return writeTypedVector(val, &Parcel::writeUniqueFileDescriptor);
}
status_t Parcel::writeUniqueFileDescriptorVector(const std::unique_ptr<std::vector<ScopedFd>>& val) {
return writeNullableTypedVector(val, &Parcel::writeUniqueFileDescriptor);
}
status_t Parcel::writeBlob(size_t len, bool mutableCopy, WritableBlob* outBlob)
{
if (len > INT32_MAX) {
......@@ -1287,25 +1362,83 @@ status_t Parcel::readByteVector(std::vector<int8_t>* val) const {
return status;
}
status_t Parcel::readByteVector(std::unique_ptr<std::vector<int8_t>>* val) const {
const int32_t start = dataPosition();
int32_t size;
status_t status = readInt32(&size);
val->reset();
if (status != OK || size < 0) {
return status;
}
setDataPosition(start);
val->reset(new std::vector<int8_t>());
status = readByteVector(val->get());
if (status != OK) {
val->reset();
}
return status;
}
status_t Parcel::readInt32Vector(std::unique_ptr<std::vector<int32_t>>* val) const {
return readNullableTypedVector(val, &Parcel::readInt32);
}
status_t Parcel::readInt32Vector(std::vector<int32_t>* val) const {
return readTypedVector(val, &Parcel::readInt32);
}
status_t Parcel::readInt64Vector(std::unique_ptr<std::vector<int64_t>>* val) const {
return readNullableTypedVector(val, &Parcel::readInt64);
}
status_t Parcel::readInt64Vector(std::vector<int64_t>* val) const {
return readTypedVector(val, &Parcel::readInt64);
}
status_t Parcel::readFloatVector(std::unique_ptr<std::vector<float>>* val) const {
return readNullableTypedVector(val, &Parcel::readFloat);
}
status_t Parcel::readFloatVector(std::vector<float>* val) const {
return readTypedVector(val, &Parcel::readFloat);
}
status_t Parcel::readDoubleVector(std::unique_ptr<std::vector<double>>* val) const {
return readNullableTypedVector(val, &Parcel::readDouble);
}
status_t Parcel::readDoubleVector(std::vector<double>* val) const {
return readTypedVector(val, &Parcel::readDouble);
}
status_t Parcel::readBoolVector(std::vector<bool>* val) const {
val->clear();
status_t Parcel::readBoolVector(std::unique_ptr<std::vector<bool>>* val) const {
const int32_t start = dataPosition();
int32_t size;
status_t status = readInt32(&size);
val->reset();
if (status != OK || size < 0) {
return status;
}
setDataPosition(start);
val->reset(new std::vector<bool>());
status = readBoolVector(val->get());
if (status != OK) {
val->reset();
}
return status;
}
status_t Parcel::readBoolVector(std::vector<bool>* val) const {
int32_t size;
status_t status = readInt32(&size);
......@@ -1335,10 +1468,19 @@ status_t Parcel::readBoolVector(std::vector<bool>* val) const {
return OK;
}
status_t Parcel::readCharVector(std::unique_ptr<std::vector<char16_t>>* val) const {
return readNullableTypedVector(val, &Parcel::readChar);
}
status_t Parcel::readCharVector(std::vector<char16_t>* val) const {
return readTypedVector(val, &Parcel::readChar);
}
status_t Parcel::readString16Vector(
std::unique_ptr<std::vector<std::unique_ptr<String16>>>* val) const {
return readNullableTypedVector(val, &Parcel::readString16);
}
status_t Parcel::readString16Vector(std::vector<String16>* val) const {
return readTypedVector(val, &Parcel::readString16);
}
......@@ -1538,6 +1680,29 @@ String16 Parcel::readString16() const
return String16();
}
status_t Parcel::readString16(std::unique_ptr<String16>* pArg) const
{
const int32_t start = dataPosition();
int32_t size;
status_t status = readInt32(&size);
pArg->reset();
if (status != OK || size < 0) {
return status;
}
setDataPosition(start);
pArg->reset(new String16());
status = readString16(pArg->get());
if (status != OK) {
pArg->reset();
}
return status;
}
status_t Parcel::readString16(String16* pArg) const
{
size_t len;
......@@ -1661,6 +1826,10 @@ status_t Parcel::readUniqueFileDescriptor(ScopedFd* val) const
}
status_t Parcel::readUniqueFileDescriptorVector(std::unique_ptr<std::vector<ScopedFd>>* val) const {
return readNullableTypedVector(val, &Parcel::readUniqueFileDescriptor);
}
status_t Parcel::readUniqueFileDescriptorVector(std::vector<ScopedFd>* val) const {
return readTypedVector(val, &Parcel::readUniqueFileDescriptor);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment