Fix Unicode string handling
Linux uses UTF8 but java and MTP both
use UTF16. In a few places, this results
in the top byte of a UTF16 string being
truncated on conversion to UTF8.
Also, the hardcoded UTF to byte serialization
in MtpStringBuffer is incorrect.
Replace it with conversions from std, and
replace usages of MtpString with MtpStringBuffer.
Remove any remaining usages of libutils
and replace them with corresponding std
libraries.
Bug: 70546563
Test: Mtp works, tests pass
Test: file/folder names containing emoji can be transferred to/from
windows
Change-Id: Idbcb73f1beac17ce8a90843fa254e759dd1a6369
diff --git a/media/mtp/MtpProperty.cpp b/media/mtp/MtpProperty.cpp
index 039e4f5..5c02a0d 100644
--- a/media/mtp/MtpProperty.cpp
+++ b/media/mtp/MtpProperty.cpp
@@ -18,6 +18,10 @@
#include <inttypes.h>
#include <cutils/compiler.h>
+#include <iomanip>
+#include <sstream>
+#include <string>
+
#include "MtpDataPacket.h"
#include "MtpDebug.h"
#include "MtpProperty.h"
@@ -336,7 +340,7 @@
}
void MtpProperty::print() {
- MtpString buffer;
+ std::string buffer;
bool deviceProp = isDeviceProperty();
if (deviceProp)
ALOGI(" %s (%04X)", MtpDebug::getDevicePropCodeName(mCode), mCode);
@@ -346,11 +350,11 @@
ALOGI(" writeable %s", (mWriteable ? "true" : "false"));
buffer = " default value: ";
print(mDefaultValue, buffer);
- ALOGI("%s", (const char *)buffer);
+ ALOGI("%s", buffer.c_str());
if (deviceProp) {
buffer = " current value: ";
print(mCurrentValue, buffer);
- ALOGI("%s", (const char *)buffer);
+ ALOGI("%s", buffer.c_str());
}
switch (mFormFlag) {
case kFormNone:
@@ -363,7 +367,7 @@
buffer += ", ";
print(mStepSize, buffer);
buffer += ")";
- ALOGI("%s", (const char *)buffer);
+ ALOGI("%s", buffer.c_str());
break;
case kFormEnum:
buffer = " Enum { ";
@@ -372,7 +376,7 @@
buffer += " ";
}
buffer += "}";
- ALOGI("%s", (const char *)buffer);
+ ALOGI("%s", buffer.c_str());
break;
case kFormDateTime:
ALOGI(" DateTime\n");
@@ -383,42 +387,47 @@
}
}
-void MtpProperty::print(MtpPropertyValue& value, MtpString& buffer) {
+void MtpProperty::print(MtpPropertyValue& value, std::string& buffer) {
+ std::ostringstream s;
switch (mType) {
case MTP_TYPE_INT8:
- buffer.appendFormat("%d", value.u.i8);
+ buffer += std::to_string(value.u.i8);
break;
case MTP_TYPE_UINT8:
- buffer.appendFormat("%d", value.u.u8);
+ buffer += std::to_string(value.u.u8);
break;
case MTP_TYPE_INT16:
- buffer.appendFormat("%d", value.u.i16);
+ buffer += std::to_string(value.u.i16);
break;
case MTP_TYPE_UINT16:
- buffer.appendFormat("%d", value.u.u16);
+ buffer += std::to_string(value.u.u16);
break;
case MTP_TYPE_INT32:
- buffer.appendFormat("%d", value.u.i32);
+ buffer += std::to_string(value.u.i32);
break;
case MTP_TYPE_UINT32:
- buffer.appendFormat("%d", value.u.u32);
+ buffer += std::to_string(value.u.u32);
break;
case MTP_TYPE_INT64:
- buffer.appendFormat("%" PRId64, value.u.i64);
+ buffer += std::to_string(value.u.i64);
break;
case MTP_TYPE_UINT64:
- buffer.appendFormat("%" PRIu64, value.u.u64);
+ buffer += std::to_string(value.u.u64);
break;
case MTP_TYPE_INT128:
- buffer.appendFormat("%08X%08X%08X%08X", value.u.i128[0], value.u.i128[1],
- value.u.i128[2], value.u.i128[3]);
+ for (auto i : value.u.i128) {
+ s << std::hex << std::setfill('0') << std::uppercase << i;
+ }
+ buffer += s.str();
break;
case MTP_TYPE_UINT128:
- buffer.appendFormat("%08X%08X%08X%08X", value.u.u128[0], value.u.u128[1],
- value.u.u128[2], value.u.u128[3]);
+ for (auto i : value.u.u128) {
+ s << std::hex << std::setfill('0') << std::uppercase << i;
+ }
+ buffer += s.str();
break;
case MTP_TYPE_STR:
- buffer.appendFormat("%s", value.str);
+ buffer += value.str;
break;
default:
ALOGE("unsupported type for MtpProperty::print\n");