Index: runtime/vm/dart_api_message.cc |
diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc |
index 2759e099f1100d0a48823c8ccb92fcaaf26d43ab..b1cf807102d0963780b42c58c1a2914a45aa10fc 100644 |
--- a/runtime/vm/dart_api_message.cc |
+++ b/runtime/vm/dart_api_message.cc |
@@ -6,6 +6,7 @@ |
#include "vm/object.h" |
#include "vm/snapshot_ids.h" |
#include "vm/symbols.h" |
+#include "vm/unicode.h" |
namespace dart { |
@@ -355,9 +356,30 @@ Dart_CObject* ApiMessageReader::ReadInternalVMObject(intptr_t class_id, |
p[len] = '\0'; |
return object; |
} |
- case kTwoByteStringCid: |
- // Two byte strings not supported. |
- return AllocateDartCObjectUnsupported(); |
+ case kTwoByteStringCid: { |
+ intptr_t len = ReadSmiValue(); |
+ intptr_t hash = ReadSmiValue(); |
+ USE(hash); |
+ uint16_t *utf16 = |
+ reinterpret_cast<uint16_t*>(::malloc(len * sizeof(uint16_t))); |
+ intptr_t utf8_len = 0; |
+ for (intptr_t i = 0; i < len; i++) { |
+ utf16[i] = Read<uint16_t>(); |
+ // TODO(sgjesse): Check for surrogate pairs. |
+ utf8_len += Utf8::Length(utf16[i]); |
+ } |
+ Dart_CObject* object = AllocateDartCObjectString(utf8_len); |
+ AddBackRef(object_id, object, kIsDeserialized); |
+ char* p = object->value.as_string; |
+ for (intptr_t i = 0; i < len; i++) { |
+ // TODO(sgjesse): Check for surrogate pairs. |
+ p += Utf8::Encode(utf16[i], p); |
+ } |
+ *p = '\0'; |
+ ASSERT(p == object->value.as_string + utf8_len); |
+ ::free(utf16); |
+ return object; |
+ } |
case kUint8ArrayCid: { |
intptr_t len = ReadSmiValue(); |
Dart_CObject* object = AllocateDartCObjectUint8Array(len); |
@@ -734,18 +756,34 @@ void ApiMessageWriter::WriteCObjectInlined(Dart_CObject* object, |
Write<double>(object->value.as_double); |
break; |
case Dart_CObject::kString: { |
+ const uint8_t* utf8_str = |
+ reinterpret_cast<const uint8_t*>(object->value.as_string); |
+ intptr_t utf8_len = strlen(object->value.as_string); |
+ Utf8::Type type; |
+ intptr_t len = Utf8::CodePointCount(utf8_str, utf8_len, &type); |
+ |
// Write out the serialization header value for this object. |
WriteInlinedHeader(object); |
// Write out the class and tags information. |
- WriteIndexedObject(kOneByteStringCid); |
+ WriteIndexedObject(type == Utf8::kAscii ? kOneByteStringCid |
+ : kTwoByteStringCid); |
WriteIntptrValue(0); |
// Write string length, hash and content |
- char* str = object->value.as_string; |
- intptr_t len = strlen(str); |
WriteSmi(len); |
WriteSmi(0); // TODO(sgjesse): Hash - not written. |
- for (intptr_t i = 0; i < len; i++) { |
- Write<uint8_t>(str[i]); |
+ if (type == Utf8::kAscii) { |
+ for (intptr_t i = 0; i < len; i++) { |
+ Write<uint8_t>(utf8_str[i]); |
+ } |
+ } else { |
+ // TODO(sgjesse): Make sure surrogate pairs are handled. |
+ uint16_t* utf16_str = |
+ reinterpret_cast<uint16_t*>(::malloc(len * sizeof(uint16_t))); |
+ Utf8::DecodeToUTF16(utf8_str, utf8_len, utf16_str, len); |
+ for (intptr_t i = 0; i < len; i++) { |
+ Write<uint16_t>(utf16_str[i]); |
+ } |
+ ::free(utf16_str); |
} |
break; |
} |