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

Commit ac4728f8 authored by Christopher Wiley's avatar Christopher Wiley Committed by Gerrit Code Review
Browse files

Merge "Add support for decoding UTF16 to UTF8"

parents 7f9c122a 9a5e32f1
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#ifndef ANDROID_PARCEL_H
#define ANDROID_PARCEL_H

#include <string>
#include <vector>

#include <cutils/native_handle.h>
@@ -119,6 +120,10 @@ public:
    status_t            writeChar(char16_t val);
    status_t            writeByte(int8_t val);

    // Take a UTF8 encoded string, convert to UTF16, write it to the parcel.
    status_t            writeUtf8AsUtf16(const std::string& str);
    status_t            writeUtf8AsUtf16(const std::unique_ptr<std::string>& str);

    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);
@@ -136,6 +141,9 @@ public:
    status_t            writeString16Vector(
                            const std::unique_ptr<std::vector<std::unique_ptr<String16>>>& val);
    status_t            writeString16Vector(const std::vector<String16>& val);
    status_t            writeUtf8VectorAsUtf16Vector(
                            const std::unique_ptr<std::vector<std::unique_ptr<std::string>>>& val);
    status_t            writeUtf8VectorAsUtf16Vector(const std::vector<std::string>& val);

    status_t            writeStrongBinderVector(const std::unique_ptr<std::vector<sp<IBinder>>>& val);
    status_t            writeStrongBinderVector(const std::vector<sp<IBinder>>& val);
@@ -230,6 +238,10 @@ public:
    int8_t              readByte() const;
    status_t            readByte(int8_t *pArg) const;

    // Read a UTF16 encoded string, convert to UTF8
    status_t            readUtf8FromUtf16(std::string* str) const;
    status_t            readUtf8FromUtf16(std::unique_ptr<std::string>* str) const;

    const char*         readCString() const;
    String8             readString8() const;
    String16            readString16() const;
@@ -274,6 +286,9 @@ public:
    status_t            readString16Vector(
                            std::unique_ptr<std::vector<std::unique_ptr<String16>>>* val) const;
    status_t            readString16Vector(std::vector<String16>* val) const;
    status_t            readUtf8VectorFromUtf16Vector(
                            std::unique_ptr<std::vector<std::unique_ptr<std::string>>>* val) const;
    status_t            readUtf8VectorFromUtf16Vector(std::vector<std::string>* val) const;

    template<typename T>
    status_t            read(Flattenable<T>& val) const;
+88 −0
Original line number Diff line number Diff line
@@ -751,6 +751,37 @@ restart_write:
    return NULL;
}

status_t Parcel::writeUtf8AsUtf16(const std::string& str) {
    const uint8_t* strData = (uint8_t*)str.data();
    const size_t strLen= str.length();
    const ssize_t utf16Len = utf8_to_utf16_length(strData, strLen);
    if (utf16Len < 0 || utf16Len> std::numeric_limits<int32_t>::max()) {
        return BAD_VALUE;
    }

    status_t err = writeInt32(utf16Len);
    if (err) {
        return err;
    }

    // Allocate enough bytes to hold our converted string and its terminating NULL.
    void* dst = writeInplace((utf16Len + 1) * sizeof(char16_t));
    if (!dst) {
        return NO_MEMORY;
    }

    utf8_to_utf16(strData, strLen, (char16_t*)dst);

    return NO_ERROR;
}

status_t Parcel::writeUtf8AsUtf16(const std::unique_ptr<std::string>& str) {
  if (!str) {
    return writeInt32(-1);
  }
  return writeUtf8AsUtf16(*str);
}

status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<int8_t>>& val)
{
    if (!val) {
@@ -854,6 +885,15 @@ status_t Parcel::writeString16Vector(
    return writeNullableTypedVector(val, &Parcel::writeString16);
}

status_t Parcel::writeUtf8VectorAsUtf16Vector(
                        const std::unique_ptr<std::vector<std::unique_ptr<std::string>>>& val) {
    return writeNullableTypedVector(val, &Parcel::writeUtf8AsUtf16);
}

status_t Parcel::writeUtf8VectorAsUtf16Vector(const std::vector<std::string>& val) {
    return writeTypedVector(val, &Parcel::writeUtf8AsUtf16);
}

status_t Parcel::writeInt32(int32_t val)
{
    return writeAligned(val);
@@ -1493,6 +1533,14 @@ status_t Parcel::readString16Vector(std::vector<String16>* val) const {
    return readTypedVector(val, &Parcel::readString16);
}

status_t Parcel::readUtf8VectorFromUtf16Vector(
        std::unique_ptr<std::vector<std::unique_ptr<std::string>>>* val) const {
    return readNullableTypedVector(val, &Parcel::readUtf8FromUtf16);
}

status_t Parcel::readUtf8VectorFromUtf16Vector(std::vector<std::string>* val) const {
    return readTypedVector(val, &Parcel::readUtf8FromUtf16);
}

status_t Parcel::readInt32(int32_t *pArg) const
{
@@ -1651,6 +1699,46 @@ int8_t Parcel::readByte() const
    return int8_t(readInt32());
}

status_t Parcel::readUtf8FromUtf16(std::string* str) const {
    size_t utf16Size = 0;
    const char16_t* src = readString16Inplace(&utf16Size);
    if (!src) {
        return UNEXPECTED_NULL;
    }

    // Save ourselves the trouble, we're done.
    if (utf16Size == 0u) {
        str->clear();
       return NO_ERROR;
    }

    ssize_t utf8Size = utf16_to_utf8_length(src, utf16Size);
    if (utf8Size < 0) {
        return BAD_VALUE;
    }
    // Note that while it is probably safe to assume string::resize keeps a
    // spare byte around for the trailing null, we're going to be explicit.
    str->resize(utf8Size + 1);
    utf16_to_utf8(src, utf16Size, &((*str)[0]));
    str->resize(utf8Size);
    return NO_ERROR;
}

status_t Parcel::readUtf8FromUtf16(std::unique_ptr<std::string>* str) const {
    const int32_t start = dataPosition();
    int32_t size;
    status_t status = readInt32(&size);
    str->reset();

    if (status != OK || size < 0) {
        return status;
    }

    setDataPosition(start);
    str->reset(new std::string());
    return readUtf8FromUtf16(str->get());
}

const char* Parcel::readCString() const
{
    const size_t avail = mDataSize-mDataPos;