Merge "[DevTools] Support UTF16 strings with binary protocol (ip)."
diff --git a/lib/Values_cpp.template b/lib/Values_cpp.template
index 4b4ba99..bf31bab 100644
--- a/lib/Values_cpp.template
+++ b/lib/Values_cpp.template
@@ -130,13 +130,19 @@
}
case CBORTokenTag::STRING8: {
span<uint8_t> str = tokenizer->GetString8();
- std::unique_ptr<Value> value = StringValue::create(StringUtil::fromUTF8(str.data(), str.size()));
+ std::unique_ptr<Value> value =
+ StringValue::create(StringUtil::fromUTF8(str.data(), str.size()));
tokenizer->Next();
return value;
}
- case CBORTokenTag::STRING16:
- // NOT SUPPORTED YET.
- return nullptr;
+ case CBORTokenTag::STRING16: {
+ span<uint8_t> wire = tokenizer->GetString16WireRep();
+ DCHECK_EQ(wire.size() & 1, 0);
+ std::unique_ptr<Value> value = StringValue::create(StringUtil::fromUTF16(
+ reinterpret_cast<const uint16_t*>(wire.data()), wire.size() / 2));
+ tokenizer->Next();
+ return value;
+ }
case CBORTokenTag::BINARY: {
span<uint8_t> payload = tokenizer->GetBinary();
tokenizer->Next();
@@ -363,10 +369,37 @@
StringUtil::builderAppendQuotedString(*output, m_stringValue);
}
+namespace {
+// This routine distinguishes between the current encoding for a given
+// string |s|, and calls encoding routines that will
+// - Ensure that all ASCII strings end up being encoded as UTF8 in
+// the wire format - e.g., EncodeFromUTF16 will detect ASCII and
+// do the (trivial) transcode to STRING8 on the wire, but if it's
+// not ASCII it'll do STRING16.
+// - Select a format that's cheap to convert to. E.g., we don't
+// have LATIN1 on the wire, so we call EncodeFromLatin1 which
+// transcodes to UTF8 if needed.
+void EncodeString(const String& s, std::vector<uint8_t>* out) {
+ if (StringUtil::CharactersLatin1(s)) {
+ EncodeFromLatin1(span<uint8_t>(StringUtil::CharactersLatin1(s),
+ StringUtil::CharacterCount(s)),
+ out);
+ } else if (StringUtil::CharactersUTF16(s)) {
+ EncodeFromUTF16(span<uint16_t>(StringUtil::CharactersUTF16(s),
+ StringUtil::CharacterCount(s)),
+ out);
+ } else if (StringUtil::CharactersUTF8(s)) {
+ EncodeString8(span<uint8_t>(StringUtil::CharactersUTF8(s),
+ StringUtil::CharacterCount(s)),
+ out);
+ } else {
+ EncodeString8(span<uint8_t>(nullptr, 0), out); // Empty string.
+ }
+}
+} // namespace
+
void StringValue::writeBinary(std::vector<uint8_t>* bytes) const {
- StringUTF8Adapter utf8(m_stringValue);
- EncodeString8(span<uint8_t>(reinterpret_cast<const uint8_t*>(utf8.Data()),
- utf8.length()), bytes);
+ EncodeString(m_stringValue, bytes);
}
std::unique_ptr<Value> StringValue::clone() const
@@ -557,9 +590,7 @@
const String& key = m_order[i];
Dictionary::const_iterator value = m_data.find(key);
DCHECK(value != m_data.cend() && value->second);
- StringUTF8Adapter utf8(key);
- EncodeString8(span<uint8_t>(reinterpret_cast<const uint8_t*>(utf8.Data()),
- utf8.length()), bytes);
+ EncodeString(key, bytes);
value->second->writeBinary(bytes);
}
bytes->push_back(EncodeStop());
diff --git a/lib/base_string_adapter_cc.template b/lib/base_string_adapter_cc.template
index ed33164..24855d4 100644
--- a/lib/base_string_adapter_cc.template
+++ b/lib/base_string_adapter_cc.template
@@ -136,7 +136,7 @@
reinterpret_cast<const uint8_t*>(message.data()),
message.length());
}
- std::unique_ptr<base::Value> value = base::JSONReader::Read(message);
+ std::unique_ptr<base::Value> value = base::JSONReader::ReadDeprecated(message);
return toProtocolValue(value.get(), 1000);
}
@@ -185,6 +185,13 @@
string_.reserve(capacity);
}
+// static
+String StringUtil::fromUTF16(const uint16_t* data, size_t length) {
+ std::string utf8;
+ base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(data), length, &utf8);
+ return utf8;
+}
+
Binary::Binary() : bytes_(new base::RefCountedBytes) {}
Binary::Binary(const Binary& binary) : bytes_(binary.bytes_) {}
Binary::Binary(scoped_refptr<base::RefCountedMemory> bytes) : bytes_(bytes) {}
diff --git a/lib/base_string_adapter_h.template b/lib/base_string_adapter_h.template
index b0215e0..082c7c0 100644
--- a/lib/base_string_adapter_h.template
+++ b/lib/base_string_adapter_h.template
@@ -32,16 +32,6 @@
using String = std::string;
using ProtocolMessage = std::string;
-class {{config.lib.export_macro}} StringUTF8Adapter {
- public:
- StringUTF8Adapter(const std::string& string) : string_(string) { }
- const char* Data() const { return string_.data(); }
- size_t length() const { return string_.length(); }
-
- private:
- const std::string& string_;
-};
-
class {{config.lib.export_macro}} StringBuilder {
public:
StringBuilder();
@@ -109,6 +99,15 @@
static String fromUTF8(const uint8_t* data, size_t length) {
return std::string(reinterpret_cast<const char*>(data), length);
}
+
+ static String fromUTF16(const uint16_t* data, size_t length);
+
+ static const uint8_t* CharactersLatin1(const String& s) { return nullptr; }
+ static const uint8_t* CharactersUTF8(const String& s) {
+ return reinterpret_cast<const uint8_t*>(s.data());
+ }
+ static const uint16_t* CharactersUTF16(const String& s) { return nullptr; }
+ static size_t CharacterCount(const String& s) { return s.size(); }
};
// A read-only sequence of uninterpreted bytes with reference-counted storage.