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

Commit d83a34d8 authored by Casey Dahlin's avatar Casey Dahlin Committed by Gerrit Code Review
Browse files

Merge "Add read/write methods for vectors"

parents 4e6d8c5b 451ff582
Loading
Loading
Loading
Loading
+22 −1
Original line number Diff line number Diff line
@@ -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);

@@ -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;

+423 −0
Original line number Diff line number Diff line
@@ -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();