Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 126c6b74 authored by Daniel Norman's avatar Daniel Norman Committed by Gerrit Code Review
Browse files

Merge "Adds read and write methods for Enum vectors."

parents 3453a37f d0337ef5
Loading
Loading
Loading
Loading
+33 −97
Original line number Diff line number Diff line
@@ -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)
@@ -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 {
+99 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@

#include <map> // for legacy reasons
#include <string>
#include <type_traits>
#include <vector>

#include <android-base/unique_fd.h>
@@ -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>
@@ -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;
@@ -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;
@@ -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)