// This file is generated by DispatcherBase_cpp.template. // Copyright 2019 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include {{format_include(config.protocol.package, "base_string_adapter")}} #include {{format_include(config.protocol.package, "Protocol")}} #include #include "base/base64.h" #include "base/json/json_reader.h" #include "base/memory/ptr_util.h" #include "base/strings/string16.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" {% for namespace in config.protocol.namespace %} namespace {{namespace}} { {% endfor %} std::unique_ptr toProtocolValue( const base::Value* value, int depth) { if (!value || !depth) return nullptr; if (value->is_none()) return protocol::Value::null(); if (value->is_bool()) { bool inner; value->GetAsBoolean(&inner); return protocol::FundamentalValue::create(inner); } if (value->is_int()) { int inner; value->GetAsInteger(&inner); return protocol::FundamentalValue::create(inner); } if (value->is_double()) { double inner; value->GetAsDouble(&inner); return protocol::FundamentalValue::create(inner); } if (value->is_string()) { std::string inner; value->GetAsString(&inner); return protocol::StringValue::create(inner); } if (value->is_list()) { const base::ListValue* list = nullptr; value->GetAsList(&list); std::unique_ptr result = protocol::ListValue::create(); for (size_t i = 0; i < list->GetSize(); i++) { const base::Value* item = nullptr; list->Get(i, &item); std::unique_ptr converted = toProtocolValue(item, depth - 1); if (converted) result->pushValue(std::move(converted)); } return std::move(result); } if (value->is_dict()) { const base::DictionaryValue* dictionary = nullptr; value->GetAsDictionary(&dictionary); std::unique_ptr result = protocol::DictionaryValue::create(); for (base::DictionaryValue::Iterator it(*dictionary); !it.IsAtEnd(); it.Advance()) { std::unique_ptr converted = toProtocolValue(&it.value(), depth - 1); if (converted) result->setValue(it.key(), std::move(converted)); } return std::move(result); } return nullptr; } std::unique_ptr toBaseValue(Value* value, int depth) { if (!value || !depth) return nullptr; if (value->type() == Value::TypeNull) return std::make_unique(); if (value->type() == Value::TypeBoolean) { bool inner; value->asBoolean(&inner); return base::WrapUnique(new base::Value(inner)); } if (value->type() == Value::TypeInteger) { int inner; value->asInteger(&inner); return base::WrapUnique(new base::Value(inner)); } if (value->type() == Value::TypeDouble) { double inner; value->asDouble(&inner); return base::WrapUnique(new base::Value(inner)); } if (value->type() == Value::TypeString) { std::string inner; value->asString(&inner); return base::WrapUnique(new base::Value(inner)); } if (value->type() == Value::TypeArray) { ListValue* list = ListValue::cast(value); std::unique_ptr result(new base::ListValue()); for (size_t i = 0; i < list->size(); i++) { std::unique_ptr converted = toBaseValue(list->at(i), depth - 1); if (converted) result->Append(std::move(converted)); } return std::move(result); } if (value->type() == Value::TypeObject) { DictionaryValue* dict = DictionaryValue::cast(value); std::unique_ptr result(new base::DictionaryValue()); for (size_t i = 0; i < dict->size(); i++) { DictionaryValue::Entry entry = dict->at(i); std::unique_ptr converted = toBaseValue(entry.second, depth - 1); if (converted) result->SetWithoutPathExpansion(entry.first, std::move(converted)); } return std::move(result); } return nullptr; } // static std::unique_ptr StringUtil::parseMessage( const std::string& message, bool binary) { if (binary) { return Value::parseBinary( reinterpret_cast(message.data()), message.length()); } std::unique_ptr value = base::JSONReader::Read(message); return toProtocolValue(value.get(), 1000); } // static ProtocolMessage StringUtil::jsonToMessage(String message) { return message; } // static ProtocolMessage StringUtil::binaryToMessage(std::vector message) { // TODO(pfeldman): figure out what to do with this copy. return std::string(reinterpret_cast(message.data()), message.size()); } StringBuilder::StringBuilder() {} StringBuilder::~StringBuilder() {} void StringBuilder::append(const std::string& s) { string_ += s; } void StringBuilder::append(char c) { string_ += c; } void StringBuilder::append(const char* characters, size_t length) { string_.append(characters, length); } // static void StringUtil::builderAppendQuotedString(StringBuilder& builder, const String& str) { builder.append('"'); base::string16 str16 = base::UTF8ToUTF16(str); escapeWideStringForJSON(reinterpret_cast(&str16[0]), str16.length(), &builder); builder.append('"'); } std::string StringBuilder::toString() { return string_; } void StringBuilder::reserveCapacity(size_t capacity) { string_.reserve(capacity); } Binary::Binary() : bytes_(new base::RefCountedBytes) {} Binary::Binary(const Binary& binary) : bytes_(binary.bytes_) {} Binary::Binary(scoped_refptr bytes) : bytes_(bytes) {} Binary::~Binary() {} String Binary::toBase64() const { std::string encoded; base::Base64Encode( base::StringPiece(reinterpret_cast(bytes_->front()), bytes_->size()), &encoded); return encoded; } // static Binary Binary::fromBase64(const String& base64, bool* success) { std::string decoded; *success = base::Base64Decode(base::StringPiece(base64), &decoded); if (*success) { return Binary::fromString(std::move(decoded)); } return Binary(); } // static Binary Binary::fromRefCounted(scoped_refptr memory) { return Binary(memory); } // static Binary Binary::fromVector(std::vector data) { return Binary(base::RefCountedBytes::TakeVector(&data)); } // static Binary Binary::fromString(std::string data) { return Binary(base::RefCountedString::TakeString(&data)); } // static Binary Binary::fromSpan(const uint8_t* data, size_t size) { return Binary(scoped_refptr( new base::RefCountedBytes(data, size))); } namespace { int32_t ReadEnvelopeSize(const uint8_t* in) { return (in[0] << 24) + (in[1] << 16) + (in[2] << 8) + in[3]; } void WriteEnvelopeSize(uint32_t value, uint8_t* out) { *(out++) = (value >> 24) & 0xFF; *(out++) = (value >> 16) & 0xFF; *(out++) = (value >> 8) & 0xFF; *(out++) = (value) & 0xFF; } } bool AppendStringValueToMapBinary(base::StringPiece in, base::StringPiece key, base::StringPiece value, std::string* out) { if (in.size() < 1 + 1 + 4 + 1 + 1) return false; const uint8_t* envelope = reinterpret_cast(in.data()); if (cbor::kInitialByteForEnvelope != envelope[0]) return false; if (cbor::kInitialByteFor32BitLengthByteString != envelope[1]) return false; if (cbor::kInitialByteIndefiniteLengthMap != envelope[6]) return false; uint32_t envelope_size = ReadEnvelopeSize(envelope + 2); if (envelope_size + 2 + 4 != in.size()) return false; if (cbor::kStopByte != static_cast(*in.rbegin())) return false; std::vector encoded_entry; encoded_entry.reserve(1 + 4 + key.size() + 1 + 4 + value.size()); span key_span( reinterpret_cast(key.data()), key.size()); EncodeString8(key_span, &encoded_entry); span value_span( reinterpret_cast(value.data()), value.size()); EncodeString8(value_span, &encoded_entry); out->clear(); out->reserve(in.size() + encoded_entry.size()); out->append(in.begin(), in.end() - 1); out->append(reinterpret_cast(encoded_entry.data()), encoded_entry.size()); out->append(1, static_cast(cbor::kStopByte)); std::size_t new_size = envelope_size + out->size() - in.size(); if (new_size > static_cast( std::numeric_limits::max())) { return false; } WriteEnvelopeSize(new_size, reinterpret_cast(&*out->begin() + 2)); return true; } bool AppendStringValueToMapJSON(base::StringPiece in, base::StringPiece key, base::StringPiece value, std::string* out) { if (!in.length() || *in.rbegin() != '}') return false; std::string suffix = base::StringPrintf(", \"%s\": \"%s\"}", key.begin(), value.begin()); out->clear(); out->reserve(in.length() + suffix.length() - 1); out->append(in.data(), in.length() - 1); out->append(suffix); return true; } {% for namespace in config.protocol.namespace %} } // namespace {{namespace}} {% endfor %}