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

Commit 2a0fb94b authored by Daniel Norman's avatar Daniel Norman Committed by android-build-merger
Browse files

Merge "Adds read and write methods for Enum vectors." am: 126c6b74 am: 294a32f4 am: 2a5ad5db

am: b071702b

Change-Id: I41cfa5d471e1d14e6bbab197c19325e67ef00cd5
parents 05e4badb b071702b
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)