diff options
| author | 2016-02-01 21:41:56 +0000 | |
|---|---|---|
| committer | 2016-02-01 21:41:56 +0000 | |
| commit | 7b0c8479ae68c6596df21879c6470ff21560ea03 (patch) | |
| tree | e59125fd2421b81b5d8a2e12228dc004e8b5ad46 | |
| parent | 3fa6da13b307ce74d8778a4a1d6180043fd28b5a (diff) | |
| parent | ac4728f8ba54e5f25466efeaf65a1dbda179ca97 (diff) | |
Merge "Add support for decoding UTF16 to UTF8"
am: ac4728f8ba
* commit 'ac4728f8ba54e5f25466efeaf65a1dbda179ca97':
Add support for decoding UTF16 to UTF8
| -rw-r--r-- | include/binder/Parcel.h | 15 | ||||
| -rw-r--r-- | libs/binder/Parcel.cpp | 88 |
2 files changed, 103 insertions, 0 deletions
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h index 0abf8f3483..5956e133b0 100644 --- a/include/binder/Parcel.h +++ b/include/binder/Parcel.h @@ -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; diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index 3acd86955b..2e9e658fd9 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -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; |