Loading libs/binder/Parcel.cpp +33 −97 Original line number Diff line number Diff line Loading @@ -750,61 +750,37 @@ status_t Parcel::writeUtf8AsUtf16(const std::unique_ptr<std::string>& str) { return writeUtf8AsUtf16(*str); } namespace { template<typename T> status_t writeByteVectorInternal(Parcel* parcel, const std::vector<T>& val) { status_t status; if (val.size() > std::numeric_limits<int32_t>::max()) { status = BAD_VALUE; return status; status_t Parcel::writeByteVectorInternal(const int8_t* data, size_t size) { if (size > std::numeric_limits<int32_t>::max()) { return BAD_VALUE; } status = parcel->writeInt32(val.size()); status_t status = writeInt32(size); if (status != OK) { return status; } void* data = parcel->writeInplace(val.size()); if (!data) { status = BAD_VALUE; return status; return write(data, size); } memcpy(data, val.data(), val.size()); return status; } template<typename T> status_t writeByteVectorInternalPtr(Parcel* parcel, const std::unique_ptr<std::vector<T>>& val) { if (!val) { return parcel->writeInt32(-1); } return writeByteVectorInternal(parcel, *val); } } // namespace status_t Parcel::writeByteVector(const std::vector<int8_t>& val) { return writeByteVectorInternal(this, val); return writeByteVectorInternal(val.data(), val.size()); } status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<int8_t>>& val) { return writeByteVectorInternalPtr(this, val); if (!val) return writeInt32(-1); return writeByteVectorInternal(val->data(), val->size()); } status_t Parcel::writeByteVector(const std::vector<uint8_t>& val) { return writeByteVectorInternal(this, val); return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val.data()), val.size()); } status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<uint8_t>>& val) { return writeByteVectorInternalPtr(this, val); if (!val) return writeInt32(-1); return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val->data()), val->size()); } status_t Parcel::writeInt32Vector(const std::vector<int32_t>& val) Loading Loading @@ -1477,81 +1453,41 @@ restart_write: return err; } namespace { template<typename T> status_t readByteVectorInternal(const Parcel* parcel, std::vector<T>* val) { val->clear(); int32_t size; status_t status = parcel->readInt32(&size); if (status != OK) { return status; } if (size < 0) { status = UNEXPECTED_NULL; return status; } if (size_t(size) > parcel->dataAvail()) { status = BAD_VALUE; return status; } T* data = const_cast<T*>(reinterpret_cast<const T*>(parcel->readInplace(size))); if (!data) { status = BAD_VALUE; return status; } val->reserve(size); val->insert(val->end(), data, data + size); return status; } template<typename T> status_t readByteVectorInternalPtr( const Parcel* parcel, std::unique_ptr<std::vector<T>>* val) { const int32_t start = parcel->dataPosition(); int32_t size; status_t status = parcel->readInt32(&size); val->reset(); if (status != OK || size < 0) { return status; } parcel->setDataPosition(start); val->reset(new (std::nothrow) std::vector<T>()); status = readByteVectorInternal(parcel, val->get()); if (status != OK) { val->reset(); status_t Parcel::readByteVectorInternal(int8_t* data, size_t size) const { if (size_t(size) > dataAvail()) { return BAD_VALUE; } return status; return read(data, size); } } // namespace status_t Parcel::readByteVector(std::vector<int8_t>* val) const { return readByteVectorInternal(this, val); if (status_t status = resizeOutVector(val); status != OK) return status; return readByteVectorInternal(val->data(), val->size()); } status_t Parcel::readByteVector(std::vector<uint8_t>* val) const { return readByteVectorInternal(this, val); if (status_t status = resizeOutVector(val); status != OK) return status; return readByteVectorInternal(reinterpret_cast<int8_t*>(val->data()), val->size()); } status_t Parcel::readByteVector(std::unique_ptr<std::vector<int8_t>>* val) const { return readByteVectorInternalPtr(this, val); if (status_t status = resizeOutVector(val); status != OK) return status; if (val->get() == nullptr) { // resizeOutVector does not create the out vector if size is < 0. // This occurs when writing a null byte vector. return OK; } return readByteVectorInternal((*val)->data(), (*val)->size()); } status_t Parcel::readByteVector(std::unique_ptr<std::vector<uint8_t>>* val) const { return readByteVectorInternalPtr(this, val); if (status_t status = resizeOutVector(val); status != OK) return status; if (val->get() == nullptr) { // resizeOutVector does not create the out vector if size is < 0. // This occurs when writing a null byte vector. return OK; } return readByteVectorInternal(reinterpret_cast<int8_t*>((*val)->data()), (*val)->size()); } status_t Parcel::readInt32Vector(std::unique_ptr<std::vector<int32_t>>* val) const { Loading libs/binder/include/binder/Parcel.h +99 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <map> // for legacy reasons #include <string> #include <type_traits> #include <vector> #include <android-base/unique_fd.h> Loading Loading @@ -157,6 +158,18 @@ public: status_t writeStrongBinderVector(const std::unique_ptr<std::vector<sp<IBinder>>>& val); status_t writeStrongBinderVector(const std::vector<sp<IBinder>>& val); // Write an Enum vector with underlying type int8_t. // Does not use padding; each byte is contiguous. template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0> status_t writeEnumVector(const std::vector<T>& val); template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0> status_t writeEnumVector(const std::unique_ptr<std::vector<T>>& val); // Write an Enum vector with underlying type != int8_t. template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0> status_t writeEnumVector(const std::vector<T>& val); template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0> status_t writeEnumVector(const std::unique_ptr<std::vector<T>>& val); template<typename T> status_t writeParcelableVector(const std::unique_ptr<std::vector<std::unique_ptr<T>>>& val); template<typename T> Loading Loading @@ -275,6 +288,19 @@ public: status_t readStrongBinder(sp<IBinder>* val) const; status_t readNullableStrongBinder(sp<IBinder>* val) const; // Read an Enum vector with underlying type int8_t. // Does not use padding; each byte is contiguous. template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0> status_t readEnumVector(std::vector<T>* val) const; template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0> status_t readEnumVector(std::unique_ptr<std::vector<T>>* val) const; // Read an Enum vector with underlying type != int8_t. template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0> status_t readEnumVector(std::vector<T>* val) const; template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0> status_t readEnumVector(std::unique_ptr<std::vector<T>>* val) const; template<typename T> status_t readParcelableVector( std::unique_ptr<std::vector<std::unique_ptr<T>>>* val) const; Loading Loading @@ -438,6 +464,19 @@ private: status_t writeRawNullableParcelable(const Parcelable* parcelable); template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int32_t>, bool> = 0> status_t writeEnum(const T& val); template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int64_t>, bool> = 0> status_t writeEnum(const T& val); template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int32_t>, bool> = 0> status_t readEnum(T* pArg) const; template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int64_t>, bool> = 0> status_t readEnum(T* pArg) const; status_t writeByteVectorInternal(const int8_t* data, size_t size); status_t readByteVectorInternal(int8_t* data, size_t size) const; template<typename T, typename U> status_t unsafeReadTypedVector(std::vector<T>* val, status_t(Parcel::*read_func)(U*) const) const; Loading Loading @@ -913,6 +952,66 @@ status_t Parcel::writeParcelableVector(const std::shared_ptr<std::vector<std::un return unsafeWriteTypedVector(*val, &Parcel::writeNullableParcelable<T>); } template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int32_t>, bool>> status_t Parcel::writeEnum(const T& val) { return writeInt32(static_cast<int32_t>(val)); } template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int64_t>, bool>> status_t Parcel::writeEnum(const T& val) { return writeInt64(static_cast<int64_t>(val)); } template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>> status_t Parcel::writeEnumVector(const std::vector<T>& val) { return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val.data()), val.size()); } template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>> status_t Parcel::writeEnumVector(const std::unique_ptr<std::vector<T>>& val) { if (!val) return writeInt32(-1); return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val->data()), val->size()); } template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>> status_t Parcel::writeEnumVector(const std::vector<T>& val) { return writeTypedVector(val, &Parcel::writeEnum); } template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>> status_t Parcel::writeEnumVector(const std::unique_ptr<std::vector<T>>& val) { return writeNullableTypedVector(val, &Parcel::writeEnum); } template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int32_t>, bool>> status_t Parcel::readEnum(T* pArg) const { return readInt32(reinterpret_cast<int32_t *>(pArg)); } template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int64_t>, bool>> status_t Parcel::readEnum(T* pArg) const { return readInt64(reinterpret_cast<int64_t *>(pArg)); } template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>> status_t Parcel::readEnumVector(std::vector<T>* val) const { if (status_t status = resizeOutVector(val); status != OK) return status; return readByteVectorInternal(reinterpret_cast<int8_t*>(val->data()), val->size()); } template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>> status_t Parcel::readEnumVector(std::unique_ptr<std::vector<T>>* val) const { if (status_t status = resizeOutVector(val); status != OK) return status; if (val->get() == nullptr) { // resizeOutVector does not create the out vector if size is < 0. // This occurs when writing a null Enum vector. return OK; } return readByteVectorInternal(reinterpret_cast<int8_t*>((*val)->data()), (*val)->size()); } template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>> status_t Parcel::readEnumVector(std::vector<T>* val) const { return readTypedVector(val, &Parcel::readEnum); } template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>> status_t Parcel::readEnumVector(std::unique_ptr<std::vector<T>>* val) const { return readNullableTypedVector(val, &Parcel::readEnum); } // --------------------------------------------------------------------------- inline TextOutput& operator<<(TextOutput& to, const Parcel& parcel) Loading Loading
libs/binder/Parcel.cpp +33 −97 Original line number Diff line number Diff line Loading @@ -750,61 +750,37 @@ status_t Parcel::writeUtf8AsUtf16(const std::unique_ptr<std::string>& str) { return writeUtf8AsUtf16(*str); } namespace { template<typename T> status_t writeByteVectorInternal(Parcel* parcel, const std::vector<T>& val) { status_t status; if (val.size() > std::numeric_limits<int32_t>::max()) { status = BAD_VALUE; return status; status_t Parcel::writeByteVectorInternal(const int8_t* data, size_t size) { if (size > std::numeric_limits<int32_t>::max()) { return BAD_VALUE; } status = parcel->writeInt32(val.size()); status_t status = writeInt32(size); if (status != OK) { return status; } void* data = parcel->writeInplace(val.size()); if (!data) { status = BAD_VALUE; return status; return write(data, size); } memcpy(data, val.data(), val.size()); return status; } template<typename T> status_t writeByteVectorInternalPtr(Parcel* parcel, const std::unique_ptr<std::vector<T>>& val) { if (!val) { return parcel->writeInt32(-1); } return writeByteVectorInternal(parcel, *val); } } // namespace status_t Parcel::writeByteVector(const std::vector<int8_t>& val) { return writeByteVectorInternal(this, val); return writeByteVectorInternal(val.data(), val.size()); } status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<int8_t>>& val) { return writeByteVectorInternalPtr(this, val); if (!val) return writeInt32(-1); return writeByteVectorInternal(val->data(), val->size()); } status_t Parcel::writeByteVector(const std::vector<uint8_t>& val) { return writeByteVectorInternal(this, val); return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val.data()), val.size()); } status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<uint8_t>>& val) { return writeByteVectorInternalPtr(this, val); if (!val) return writeInt32(-1); return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val->data()), val->size()); } status_t Parcel::writeInt32Vector(const std::vector<int32_t>& val) Loading Loading @@ -1477,81 +1453,41 @@ restart_write: return err; } namespace { template<typename T> status_t readByteVectorInternal(const Parcel* parcel, std::vector<T>* val) { val->clear(); int32_t size; status_t status = parcel->readInt32(&size); if (status != OK) { return status; } if (size < 0) { status = UNEXPECTED_NULL; return status; } if (size_t(size) > parcel->dataAvail()) { status = BAD_VALUE; return status; } T* data = const_cast<T*>(reinterpret_cast<const T*>(parcel->readInplace(size))); if (!data) { status = BAD_VALUE; return status; } val->reserve(size); val->insert(val->end(), data, data + size); return status; } template<typename T> status_t readByteVectorInternalPtr( const Parcel* parcel, std::unique_ptr<std::vector<T>>* val) { const int32_t start = parcel->dataPosition(); int32_t size; status_t status = parcel->readInt32(&size); val->reset(); if (status != OK || size < 0) { return status; } parcel->setDataPosition(start); val->reset(new (std::nothrow) std::vector<T>()); status = readByteVectorInternal(parcel, val->get()); if (status != OK) { val->reset(); status_t Parcel::readByteVectorInternal(int8_t* data, size_t size) const { if (size_t(size) > dataAvail()) { return BAD_VALUE; } return status; return read(data, size); } } // namespace status_t Parcel::readByteVector(std::vector<int8_t>* val) const { return readByteVectorInternal(this, val); if (status_t status = resizeOutVector(val); status != OK) return status; return readByteVectorInternal(val->data(), val->size()); } status_t Parcel::readByteVector(std::vector<uint8_t>* val) const { return readByteVectorInternal(this, val); if (status_t status = resizeOutVector(val); status != OK) return status; return readByteVectorInternal(reinterpret_cast<int8_t*>(val->data()), val->size()); } status_t Parcel::readByteVector(std::unique_ptr<std::vector<int8_t>>* val) const { return readByteVectorInternalPtr(this, val); if (status_t status = resizeOutVector(val); status != OK) return status; if (val->get() == nullptr) { // resizeOutVector does not create the out vector if size is < 0. // This occurs when writing a null byte vector. return OK; } return readByteVectorInternal((*val)->data(), (*val)->size()); } status_t Parcel::readByteVector(std::unique_ptr<std::vector<uint8_t>>* val) const { return readByteVectorInternalPtr(this, val); if (status_t status = resizeOutVector(val); status != OK) return status; if (val->get() == nullptr) { // resizeOutVector does not create the out vector if size is < 0. // This occurs when writing a null byte vector. return OK; } return readByteVectorInternal(reinterpret_cast<int8_t*>((*val)->data()), (*val)->size()); } status_t Parcel::readInt32Vector(std::unique_ptr<std::vector<int32_t>>* val) const { Loading
libs/binder/include/binder/Parcel.h +99 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <map> // for legacy reasons #include <string> #include <type_traits> #include <vector> #include <android-base/unique_fd.h> Loading Loading @@ -157,6 +158,18 @@ public: status_t writeStrongBinderVector(const std::unique_ptr<std::vector<sp<IBinder>>>& val); status_t writeStrongBinderVector(const std::vector<sp<IBinder>>& val); // Write an Enum vector with underlying type int8_t. // Does not use padding; each byte is contiguous. template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0> status_t writeEnumVector(const std::vector<T>& val); template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0> status_t writeEnumVector(const std::unique_ptr<std::vector<T>>& val); // Write an Enum vector with underlying type != int8_t. template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0> status_t writeEnumVector(const std::vector<T>& val); template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0> status_t writeEnumVector(const std::unique_ptr<std::vector<T>>& val); template<typename T> status_t writeParcelableVector(const std::unique_ptr<std::vector<std::unique_ptr<T>>>& val); template<typename T> Loading Loading @@ -275,6 +288,19 @@ public: status_t readStrongBinder(sp<IBinder>* val) const; status_t readNullableStrongBinder(sp<IBinder>* val) const; // Read an Enum vector with underlying type int8_t. // Does not use padding; each byte is contiguous. template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0> status_t readEnumVector(std::vector<T>* val) const; template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0> status_t readEnumVector(std::unique_ptr<std::vector<T>>* val) const; // Read an Enum vector with underlying type != int8_t. template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0> status_t readEnumVector(std::vector<T>* val) const; template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0> status_t readEnumVector(std::unique_ptr<std::vector<T>>* val) const; template<typename T> status_t readParcelableVector( std::unique_ptr<std::vector<std::unique_ptr<T>>>* val) const; Loading Loading @@ -438,6 +464,19 @@ private: status_t writeRawNullableParcelable(const Parcelable* parcelable); template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int32_t>, bool> = 0> status_t writeEnum(const T& val); template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int64_t>, bool> = 0> status_t writeEnum(const T& val); template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int32_t>, bool> = 0> status_t readEnum(T* pArg) const; template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int64_t>, bool> = 0> status_t readEnum(T* pArg) const; status_t writeByteVectorInternal(const int8_t* data, size_t size); status_t readByteVectorInternal(int8_t* data, size_t size) const; template<typename T, typename U> status_t unsafeReadTypedVector(std::vector<T>* val, status_t(Parcel::*read_func)(U*) const) const; Loading Loading @@ -913,6 +952,66 @@ status_t Parcel::writeParcelableVector(const std::shared_ptr<std::vector<std::un return unsafeWriteTypedVector(*val, &Parcel::writeNullableParcelable<T>); } template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int32_t>, bool>> status_t Parcel::writeEnum(const T& val) { return writeInt32(static_cast<int32_t>(val)); } template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int64_t>, bool>> status_t Parcel::writeEnum(const T& val) { return writeInt64(static_cast<int64_t>(val)); } template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>> status_t Parcel::writeEnumVector(const std::vector<T>& val) { return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val.data()), val.size()); } template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>> status_t Parcel::writeEnumVector(const std::unique_ptr<std::vector<T>>& val) { if (!val) return writeInt32(-1); return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val->data()), val->size()); } template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>> status_t Parcel::writeEnumVector(const std::vector<T>& val) { return writeTypedVector(val, &Parcel::writeEnum); } template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>> status_t Parcel::writeEnumVector(const std::unique_ptr<std::vector<T>>& val) { return writeNullableTypedVector(val, &Parcel::writeEnum); } template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int32_t>, bool>> status_t Parcel::readEnum(T* pArg) const { return readInt32(reinterpret_cast<int32_t *>(pArg)); } template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int64_t>, bool>> status_t Parcel::readEnum(T* pArg) const { return readInt64(reinterpret_cast<int64_t *>(pArg)); } template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>> status_t Parcel::readEnumVector(std::vector<T>* val) const { if (status_t status = resizeOutVector(val); status != OK) return status; return readByteVectorInternal(reinterpret_cast<int8_t*>(val->data()), val->size()); } template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>> status_t Parcel::readEnumVector(std::unique_ptr<std::vector<T>>* val) const { if (status_t status = resizeOutVector(val); status != OK) return status; if (val->get() == nullptr) { // resizeOutVector does not create the out vector if size is < 0. // This occurs when writing a null Enum vector. return OK; } return readByteVectorInternal(reinterpret_cast<int8_t*>((*val)->data()), (*val)->size()); } template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>> status_t Parcel::readEnumVector(std::vector<T>* val) const { return readTypedVector(val, &Parcel::readEnum); } template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>> status_t Parcel::readEnumVector(std::unique_ptr<std::vector<T>>* val) const { return readNullableTypedVector(val, &Parcel::readEnum); } // --------------------------------------------------------------------------- inline TextOutput& operator<<(TextOutput& to, const Parcel& parcel) Loading