DevTools: roll third_party/inspector_protocol, wire binary operation.
Bug: chromium:929862 Change-Id: I8c23be1d22f70d1143d570050514c36ecfb30fc7 Reviewed-on: https://chromium-review.googlesource.com/c/1466003 Reviewed-by: Alexei Filippov <alph@chromium.org> Commit-Queue: Pavel Feldman <pfeldman@chromium.org> Commit-Queue: Alexei Filippov <alph@chromium.org> Cr-Commit-Position: refs/heads/master@{#59541}
This commit is contained in:
parent
ba78fef1f2
commit
5dffb59630
@ -120,7 +120,7 @@ bool substituteObjectTags(int sessionId, const String16& groupName,
|
||||
return false;
|
||||
}
|
||||
v8::Local<v8::Value> jsonWrapper;
|
||||
String16 serialized = wrapper->serialize();
|
||||
String16 serialized = wrapper->toJSON();
|
||||
if (!v8::JSON::Parse(context, toV8String(isolate, serialized))
|
||||
.ToLocal(&jsonWrapper)) {
|
||||
reportError(context, tryCatch, "cannot wrap value");
|
||||
|
@ -585,7 +585,7 @@ Response InjectedScript::resolveCallArgument(
|
||||
if (callArgument->hasValue() || callArgument->hasUnserializableValue()) {
|
||||
String16 value;
|
||||
if (callArgument->hasValue()) {
|
||||
value = "(" + callArgument->getValue(nullptr)->serialize() + ")";
|
||||
value = "(" + callArgument->getValue(nullptr)->toJSONString() + ")";
|
||||
} else {
|
||||
String16 unserializableValue = callArgument->getUnserializableValue("");
|
||||
// Protect against potential identifier resolution for NaN and Infinity.
|
||||
|
@ -122,6 +122,26 @@ std::unique_ptr<protocol::Value> StringUtil::parseJSON(const String16& string) {
|
||||
static_cast<int>(string.length()));
|
||||
}
|
||||
|
||||
// static
|
||||
std::unique_ptr<protocol::Value> StringUtil::parseProtocolMessage(
|
||||
const ProtocolMessage& message) {
|
||||
return parseJSON(message.json);
|
||||
}
|
||||
|
||||
// static
|
||||
ProtocolMessage StringUtil::jsonToMessage(String message) {
|
||||
ProtocolMessage result;
|
||||
result.json = std::move(message);
|
||||
return result;
|
||||
}
|
||||
|
||||
// static
|
||||
ProtocolMessage StringUtil::binaryToMessage(std::vector<uint8_t> message) {
|
||||
ProtocolMessage result;
|
||||
result.binary = std::move(message);
|
||||
return result;
|
||||
}
|
||||
|
||||
// static
|
||||
void StringUtil::builderAppendQuotedString(StringBuilder& builder,
|
||||
const String& str) {
|
||||
|
@ -22,6 +22,10 @@ class Value;
|
||||
|
||||
using String = v8_inspector::String16;
|
||||
using StringBuilder = v8_inspector::String16Builder;
|
||||
struct ProtocolMessage {
|
||||
String json;
|
||||
std::vector<uint8_t> binary;
|
||||
};
|
||||
|
||||
class StringUtil {
|
||||
public:
|
||||
@ -59,6 +63,10 @@ class StringUtil {
|
||||
}
|
||||
static std::unique_ptr<protocol::Value> parseJSON(const String16& json);
|
||||
static std::unique_ptr<protocol::Value> parseJSON(const StringView& json);
|
||||
static std::unique_ptr<protocol::Value> parseProtocolMessage(
|
||||
const ProtocolMessage&);
|
||||
static ProtocolMessage jsonToMessage(String message);
|
||||
static ProtocolMessage binaryToMessage(std::vector<uint8_t> message);
|
||||
};
|
||||
|
||||
// A read-only sequence of uninterpreted bytes with reference-counted storage.
|
||||
@ -101,6 +109,19 @@ class StringBufferImpl : public StringBuffer {
|
||||
DISALLOW_COPY_AND_ASSIGN(StringBufferImpl);
|
||||
};
|
||||
|
||||
class BinaryStringBuffer : public StringBuffer {
|
||||
public:
|
||||
explicit BinaryStringBuffer(std::vector<uint8_t> data)
|
||||
: m_data(std::move(data)), m_string(m_data.data(), m_data.size()) {}
|
||||
const StringView& string() override { return m_string; }
|
||||
|
||||
private:
|
||||
std::vector<uint8_t> m_data;
|
||||
StringView m_string;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(BinaryStringBuffer);
|
||||
};
|
||||
|
||||
String16 debuggerIdToString(const std::pair<int64_t, int64_t>& debuggerId);
|
||||
String16 stackTraceIdToString(uintptr_t id);
|
||||
|
||||
|
@ -137,41 +137,53 @@ namespace {
|
||||
class MessageBuffer : public StringBuffer {
|
||||
public:
|
||||
static std::unique_ptr<MessageBuffer> create(
|
||||
std::unique_ptr<protocol::Serializable> message) {
|
||||
std::unique_ptr<protocol::Serializable> message, bool binary) {
|
||||
return std::unique_ptr<MessageBuffer>(
|
||||
new MessageBuffer(std::move(message)));
|
||||
new MessageBuffer(std::move(message), binary));
|
||||
}
|
||||
|
||||
const StringView& string() override {
|
||||
if (!m_serialized) {
|
||||
m_serialized = StringBuffer::create(toStringView(m_message->serialize()));
|
||||
if (m_binary) {
|
||||
// Encode binary response as an 8bit string buffer.
|
||||
m_serialized.reset(
|
||||
new BinaryStringBuffer(m_message->serializeToBinary()));
|
||||
} else {
|
||||
m_serialized =
|
||||
StringBuffer::create(toStringView(m_message->serializeToJSON()));
|
||||
}
|
||||
m_message.reset(nullptr);
|
||||
}
|
||||
return m_serialized->string();
|
||||
}
|
||||
|
||||
private:
|
||||
explicit MessageBuffer(std::unique_ptr<protocol::Serializable> message)
|
||||
: m_message(std::move(message)) {}
|
||||
explicit MessageBuffer(std::unique_ptr<protocol::Serializable> message,
|
||||
bool binary)
|
||||
: m_message(std::move(message)), m_binary(binary) {}
|
||||
|
||||
std::unique_ptr<protocol::Serializable> m_message;
|
||||
std::unique_ptr<StringBuffer> m_serialized;
|
||||
bool m_binary;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
void V8InspectorSessionImpl::sendProtocolResponse(
|
||||
int callId, std::unique_ptr<protocol::Serializable> message) {
|
||||
m_channel->sendResponse(callId, MessageBuffer::create(std::move(message)));
|
||||
m_channel->sendResponse(
|
||||
callId, MessageBuffer::create(std::move(message), use_binary_protocol_));
|
||||
}
|
||||
|
||||
void V8InspectorSessionImpl::sendProtocolNotification(
|
||||
std::unique_ptr<protocol::Serializable> message) {
|
||||
m_channel->sendNotification(MessageBuffer::create(std::move(message)));
|
||||
m_channel->sendNotification(
|
||||
MessageBuffer::create(std::move(message), use_binary_protocol_));
|
||||
}
|
||||
|
||||
void V8InspectorSessionImpl::fallThrough(int callId, const String16& method,
|
||||
const String16& message) {
|
||||
void V8InspectorSessionImpl::fallThrough(
|
||||
int callId, const String16& method,
|
||||
const protocol::ProtocolMessage& message) {
|
||||
// There's no other layer to handle the command.
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -316,19 +328,28 @@ void V8InspectorSessionImpl::reportAllContexts(V8RuntimeAgentImpl* agent) {
|
||||
|
||||
void V8InspectorSessionImpl::dispatchProtocolMessage(
|
||||
const StringView& message) {
|
||||
bool binary_protocol =
|
||||
message.is8Bit() && message.length() && message.characters8()[0] == 0xDA;
|
||||
if (binary_protocol) use_binary_protocol_ = true;
|
||||
int callId;
|
||||
std::unique_ptr<protocol::Value> parsed_message;
|
||||
if (binary_protocol) {
|
||||
parsed_message = protocol::Value::parseBinary(
|
||||
message.characters8(), static_cast<unsigned>(message.length()));
|
||||
} else {
|
||||
parsed_message = protocol::StringUtil::parseJSON(message);
|
||||
}
|
||||
String16 method;
|
||||
std::unique_ptr<protocol::Value> parsedMessage =
|
||||
protocol::StringUtil::parseJSON(message);
|
||||
if (m_dispatcher.parseCommand(parsedMessage.get(), &callId, &method)) {
|
||||
if (m_dispatcher.parseCommand(parsed_message.get(), &callId, &method)) {
|
||||
// Pass empty string instead of the actual message to save on a conversion.
|
||||
// We're allowed to do so because fall-through is not implemented.
|
||||
m_dispatcher.dispatch(callId, method, std::move(parsedMessage), "");
|
||||
m_dispatcher.dispatch(callId, method, std::move(parsed_message),
|
||||
protocol::ProtocolMessage());
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<StringBuffer> V8InspectorSessionImpl::stateJSON() {
|
||||
String16 json = m_state->serialize();
|
||||
String16 json = m_state->toJSONString();
|
||||
return StringBufferImpl::adopt(json);
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,7 @@ class V8InspectorSessionImpl : public V8InspectorSession,
|
||||
void sendProtocolNotification(
|
||||
std::unique_ptr<protocol::Serializable> message) override;
|
||||
void fallThrough(int callId, const String16& method,
|
||||
const String16& message) override;
|
||||
const protocol::ProtocolMessage& message) override;
|
||||
void flushProtocolNotifications() override;
|
||||
|
||||
int m_contextGroupId;
|
||||
@ -122,6 +122,7 @@ class V8InspectorSessionImpl : public V8InspectorSession,
|
||||
std::unique_ptr<V8SchemaAgentImpl> m_schemaAgent;
|
||||
std::vector<std::unique_ptr<V8InspectorSession::Inspectable>>
|
||||
m_inspectedObjects;
|
||||
bool use_binary_protocol_ = false;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(V8InspectorSessionImpl);
|
||||
};
|
||||
|
2
third_party/inspector_protocol/README.v8
vendored
2
third_party/inspector_protocol/README.v8
vendored
@ -2,7 +2,7 @@ Name: inspector protocol
|
||||
Short Name: inspector_protocol
|
||||
URL: https://chromium.googlesource.com/deps/inspector_protocol/
|
||||
Version: 0
|
||||
Revision: 8515c2a1c5c016646b61221586cd4e5839f425ee
|
||||
Revision: e8a0de7351b5d72aadde777e2ad9b412d1431ffa
|
||||
License: BSD
|
||||
License File: LICENSE
|
||||
Security Critical: no
|
||||
|
@ -70,7 +70,7 @@ DispatcherBase::WeakPtr::~WeakPtr()
|
||||
m_dispatcher->m_weakPtrs.erase(this);
|
||||
}
|
||||
|
||||
DispatcherBase::Callback::Callback(std::unique_ptr<DispatcherBase::WeakPtr> backendImpl, int callId, const String& method, const String& message)
|
||||
DispatcherBase::Callback::Callback(std::unique_ptr<DispatcherBase::WeakPtr> backendImpl, int callId, const String& method, const ProtocolMessage& message)
|
||||
: m_backendImpl(std::move(backendImpl))
|
||||
, m_callId(callId)
|
||||
, m_method(method)
|
||||
@ -142,18 +142,14 @@ public:
|
||||
return std::unique_ptr<ProtocolError>(new ProtocolError(code, errorMessage));
|
||||
}
|
||||
|
||||
String serialize() override
|
||||
String serializeToJSON() override
|
||||
{
|
||||
std::unique_ptr<protocol::DictionaryValue> error = DictionaryValue::create();
|
||||
error->setInteger("code", m_code);
|
||||
error->setString("message", m_errorMessage);
|
||||
if (m_data.length())
|
||||
error->setString("data", m_data);
|
||||
std::unique_ptr<protocol::DictionaryValue> message = DictionaryValue::create();
|
||||
message->setObject("error", std::move(error));
|
||||
if (m_hasCallId)
|
||||
message->setInteger("id", m_callId);
|
||||
return message->serialize();
|
||||
return serialize()->serializeToJSON();
|
||||
}
|
||||
|
||||
std::vector<uint8_t> serializeToBinary() override
|
||||
{
|
||||
return serialize()->serializeToBinary();
|
||||
}
|
||||
|
||||
~ProtocolError() override {}
|
||||
@ -165,6 +161,19 @@ private:
|
||||
{
|
||||
}
|
||||
|
||||
std::unique_ptr<DictionaryValue> serialize() {
|
||||
std::unique_ptr<protocol::DictionaryValue> error = DictionaryValue::create();
|
||||
error->setInteger("code", m_code);
|
||||
error->setString("message", m_errorMessage);
|
||||
if (m_data.length())
|
||||
error->setString("data", m_data);
|
||||
std::unique_ptr<protocol::DictionaryValue> message = DictionaryValue::create();
|
||||
message->setObject("error", std::move(error));
|
||||
if (m_hasCallId)
|
||||
message->setInteger("id", m_callId);
|
||||
return message;
|
||||
}
|
||||
|
||||
DispatchResponse::ErrorCode m_code;
|
||||
String m_errorMessage;
|
||||
String m_data;
|
||||
@ -275,7 +284,7 @@ bool UberDispatcher::canDispatch(const String& in_method)
|
||||
return !!findDispatcher(method);
|
||||
}
|
||||
|
||||
void UberDispatcher::dispatch(int callId, const String& in_method, std::unique_ptr<Value> parsedMessage, const String& rawMessage)
|
||||
void UberDispatcher::dispatch(int callId, const String& in_method, std::unique_ptr<Value> parsedMessage, const ProtocolMessage& rawMessage)
|
||||
{
|
||||
String method = in_method;
|
||||
auto redirectIt = m_redirects.find(method);
|
||||
@ -304,18 +313,32 @@ std::unique_ptr<InternalResponse> InternalResponse::createNotification(const Str
|
||||
return std::unique_ptr<InternalResponse>(new InternalResponse(0, notification, std::move(params)));
|
||||
}
|
||||
|
||||
String InternalResponse::serialize()
|
||||
String InternalResponse::serializeToJSON()
|
||||
{
|
||||
std::unique_ptr<DictionaryValue> result = DictionaryValue::create();
|
||||
std::unique_ptr<Serializable> params(m_params ? std::move(m_params) : DictionaryValue::create());
|
||||
if (m_notification.length()) {
|
||||
result->setString("method", m_notification);
|
||||
result->setValue("params", SerializedValue::create(params->serialize()));
|
||||
result->setValue("params", SerializedValue::fromJSON(params->serializeToJSON()));
|
||||
} else {
|
||||
result->setInteger("id", m_callId);
|
||||
result->setValue("result", SerializedValue::create(params->serialize()));
|
||||
result->setValue("result", SerializedValue::fromJSON(params->serializeToJSON()));
|
||||
}
|
||||
return result->serialize();
|
||||
return result->serializeToJSON();
|
||||
}
|
||||
|
||||
std::vector<uint8_t> InternalResponse::serializeToBinary()
|
||||
{
|
||||
std::unique_ptr<DictionaryValue> result = DictionaryValue::create();
|
||||
std::unique_ptr<Serializable> params(m_params ? std::move(m_params) : DictionaryValue::create());
|
||||
if (m_notification.length()) {
|
||||
result->setString("method", m_notification);
|
||||
result->setValue("params", SerializedValue::fromBinary(params->serializeToBinary()));
|
||||
} else {
|
||||
result->setInteger("id", m_callId);
|
||||
result->setValue("result", SerializedValue::fromBinary(params->serializeToBinary()));
|
||||
}
|
||||
return result->serializeToBinary();
|
||||
}
|
||||
|
||||
InternalResponse::InternalResponse(int callId, const String& notification, std::unique_ptr<Serializable> params)
|
||||
|
@ -68,7 +68,7 @@ public:
|
||||
|
||||
class {{config.lib.export_macro}} Callback {
|
||||
public:
|
||||
Callback(std::unique_ptr<WeakPtr> backendImpl, int callId, const String& method, const String& message);
|
||||
Callback(std::unique_ptr<WeakPtr> backendImpl, int callId, const String& method, const ProtocolMessage& message);
|
||||
virtual ~Callback();
|
||||
void dispose();
|
||||
|
||||
@ -80,14 +80,14 @@ public:
|
||||
std::unique_ptr<WeakPtr> m_backendImpl;
|
||||
int m_callId;
|
||||
String m_method;
|
||||
String m_message;
|
||||
ProtocolMessage m_message;
|
||||
};
|
||||
|
||||
explicit DispatcherBase(FrontendChannel*);
|
||||
virtual ~DispatcherBase();
|
||||
|
||||
virtual bool canDispatch(const String& method) = 0;
|
||||
virtual void dispatch(int callId, const String& method, const String& rawMessage, std::unique_ptr<protocol::DictionaryValue> messageObject) = 0;
|
||||
virtual void dispatch(int callId, const String& method, const ProtocolMessage& rawMessage, std::unique_ptr<protocol::DictionaryValue> messageObject) = 0;
|
||||
FrontendChannel* channel() { return m_frontendChannel; }
|
||||
|
||||
void sendResponse(int callId, const DispatchResponse&, std::unique_ptr<protocol::DictionaryValue> result);
|
||||
@ -111,7 +111,7 @@ public:
|
||||
void setupRedirects(const std::unordered_map<String, String>&);
|
||||
bool parseCommand(Value* message, int* callId, String* method);
|
||||
bool canDispatch(const String& method);
|
||||
void dispatch(int callId, const String& method, std::unique_ptr<Value> message, const String& rawMessage);
|
||||
void dispatch(int callId, const String& method, std::unique_ptr<Value> message, const ProtocolMessage& rawMessage);
|
||||
FrontendChannel* channel() { return m_frontendChannel; }
|
||||
virtual ~UberDispatcher();
|
||||
|
||||
@ -128,7 +128,8 @@ public:
|
||||
static std::unique_ptr<InternalResponse> createResponse(int callId, std::unique_ptr<Serializable> params);
|
||||
static std::unique_ptr<InternalResponse> createNotification(const String& notification, std::unique_ptr<Serializable> params = nullptr);
|
||||
|
||||
String serialize() override;
|
||||
String serializeToJSON() override;
|
||||
std::vector<uint8_t> serializeToBinary() override;
|
||||
|
||||
~InternalResponse() override {}
|
||||
|
||||
@ -142,24 +143,36 @@ private:
|
||||
|
||||
class InternalRawNotification : public Serializable {
|
||||
public:
|
||||
static std::unique_ptr<InternalRawNotification> create(const String& notification)
|
||||
static std::unique_ptr<InternalRawNotification> fromJSON(String notification)
|
||||
{
|
||||
return std::unique_ptr<InternalRawNotification>(new InternalRawNotification(notification));
|
||||
return std::unique_ptr<InternalRawNotification>(new InternalRawNotification(std::move(notification)));
|
||||
}
|
||||
|
||||
static std::unique_ptr<InternalRawNotification> fromBinary(std::vector<uint8_t> notification)
|
||||
{
|
||||
return std::unique_ptr<InternalRawNotification>(new InternalRawNotification(std::move(notification)));
|
||||
}
|
||||
|
||||
~InternalRawNotification() override {}
|
||||
|
||||
String serialize() override
|
||||
String serializeToJSON() override
|
||||
{
|
||||
return m_notification;
|
||||
return std::move(m_jsonNotification);
|
||||
}
|
||||
|
||||
std::vector<uint8_t> serializeToBinary() override
|
||||
{
|
||||
return std::move(m_binaryNotification);
|
||||
}
|
||||
|
||||
private:
|
||||
explicit InternalRawNotification(const String& notification)
|
||||
: m_notification(notification)
|
||||
{
|
||||
}
|
||||
explicit InternalRawNotification(String notification)
|
||||
: m_jsonNotification(std::move(notification)) { }
|
||||
explicit InternalRawNotification(std::vector<uint8_t> notification)
|
||||
: m_binaryNotification(std::move(notification)) { }
|
||||
|
||||
String m_notification;
|
||||
String m_jsonNotification;
|
||||
std::vector<uint8_t> m_binaryNotification;
|
||||
};
|
||||
|
||||
{% for namespace in config.protocol.namespace %}
|
||||
|
@ -13,7 +13,14 @@ namespace {{namespace}} {
|
||||
|
||||
class {{config.lib.export_macro}} Serializable {
|
||||
public:
|
||||
virtual String serialize() = 0;
|
||||
ProtocolMessage serialize(bool binary) {
|
||||
if (binary)
|
||||
return StringUtil::binaryToMessage(serializeToBinary());
|
||||
else
|
||||
return StringUtil::jsonToMessage(serializeToJSON());
|
||||
}
|
||||
virtual String serializeToJSON() = 0;
|
||||
virtual std::vector<uint8_t> serializeToBinary() = 0;
|
||||
virtual ~Serializable() = default;
|
||||
};
|
||||
|
||||
@ -22,7 +29,7 @@ public:
|
||||
virtual ~FrontendChannel() { }
|
||||
virtual void sendProtocolResponse(int callId, std::unique_ptr<Serializable> message) = 0;
|
||||
virtual void sendProtocolNotification(std::unique_ptr<Serializable> message) = 0;
|
||||
virtual void fallThrough(int callId, const String& method, const String& message) = 0;
|
||||
virtual void fallThrough(int callId, const String& method, const ProtocolMessage& message) = 0;
|
||||
virtual void flushProtocolNotifications() = 0;
|
||||
};
|
||||
|
||||
|
@ -62,6 +62,11 @@ void escapeStringForJSONInternal(const Char* str, unsigned len,
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// static
|
||||
std::unique_ptr<Value> Value::parseBinary(const uint8_t* data, unsigned size) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Value::asBoolean(bool*) const
|
||||
{
|
||||
return false;
|
||||
@ -82,11 +87,6 @@ bool Value::asString(String*) const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Value::asSerialized(String*) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void Value::writeJSON(StringBuilder* output) const
|
||||
{
|
||||
DCHECK(m_type == TypeNull);
|
||||
@ -98,7 +98,7 @@ std::unique_ptr<Value> Value::clone() const
|
||||
return Value::null();
|
||||
}
|
||||
|
||||
String Value::serialize()
|
||||
String Value::toJSONString() const
|
||||
{
|
||||
StringBuilder result;
|
||||
StringUtil::builderReserve(result, 512);
|
||||
@ -106,6 +106,14 @@ String Value::serialize()
|
||||
return StringUtil::builderToString(result);
|
||||
}
|
||||
|
||||
String Value::serializeToJSON() {
|
||||
return toJSONString();
|
||||
}
|
||||
|
||||
std::vector<uint8_t> Value::serializeToBinary() {
|
||||
return std::vector<uint8_t>();
|
||||
}
|
||||
|
||||
bool FundamentalValue::asBoolean(bool* output) const
|
||||
{
|
||||
if (type() != TypeBoolean)
|
||||
@ -183,21 +191,15 @@ std::unique_ptr<Value> StringValue::clone() const
|
||||
return StringValue::create(m_stringValue);
|
||||
}
|
||||
|
||||
bool SerializedValue::asSerialized(String* output) const
|
||||
{
|
||||
*output = m_serializedValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
void SerializedValue::writeJSON(StringBuilder* output) const
|
||||
{
|
||||
DCHECK(type() == TypeSerialized);
|
||||
StringUtil::builderAppend(*output, m_serializedValue);
|
||||
StringUtil::builderAppend(*output, m_serializedJSON);
|
||||
}
|
||||
|
||||
std::unique_ptr<Value> SerializedValue::clone() const
|
||||
{
|
||||
return SerializedValue::create(m_serializedValue);
|
||||
return std::unique_ptr<SerializedValue>(new SerializedValue(m_serializedJSON, m_serializedBinary));
|
||||
}
|
||||
|
||||
DictionaryValue::~DictionaryValue()
|
||||
|
@ -28,6 +28,8 @@ public:
|
||||
return std::unique_ptr<Value>(new Value());
|
||||
}
|
||||
|
||||
static std::unique_ptr<Value> parseBinary(const uint8_t*data, unsigned size);
|
||||
|
||||
enum ValueType {
|
||||
TypeNull = 0,
|
||||
TypeBoolean,
|
||||
@ -47,11 +49,13 @@ public:
|
||||
virtual bool asDouble(double* output) const;
|
||||
virtual bool asInteger(int* output) const;
|
||||
virtual bool asString(String* output) const;
|
||||
virtual bool asSerialized(String* output) const;
|
||||
|
||||
virtual void writeJSON(StringBuilder* output) const;
|
||||
virtual std::unique_ptr<Value> clone() const;
|
||||
String serialize() override;
|
||||
String toJSONString() const;
|
||||
String serializeToJSON() override;
|
||||
std::vector<uint8_t> serializeToBinary() override;
|
||||
|
||||
|
||||
protected:
|
||||
Value() : m_type(TypeNull) { }
|
||||
@ -124,19 +128,26 @@ private:
|
||||
|
||||
class {{config.lib.export_macro}} SerializedValue : public Value {
|
||||
public:
|
||||
static std::unique_ptr<SerializedValue> create(const String& value)
|
||||
static std::unique_ptr<SerializedValue> fromJSON(const String& value)
|
||||
{
|
||||
return std::unique_ptr<SerializedValue>(new SerializedValue(value));
|
||||
}
|
||||
|
||||
bool asSerialized(String* output) const override;
|
||||
static std::unique_ptr<SerializedValue> fromBinary(std::vector<uint8_t> value)
|
||||
{
|
||||
return std::unique_ptr<SerializedValue>(new SerializedValue(std::move(value)));
|
||||
}
|
||||
|
||||
void writeJSON(StringBuilder* output) const override;
|
||||
std::unique_ptr<Value> clone() const override;
|
||||
|
||||
private:
|
||||
explicit SerializedValue(const String& value) : Value(TypeSerialized), m_serializedValue(value) { }
|
||||
|
||||
String m_serializedValue;
|
||||
explicit SerializedValue(const String& json) : Value(TypeSerialized), m_serializedJSON(json) { }
|
||||
explicit SerializedValue(std::vector<uint8_t> binary) : Value(TypeSerialized), m_serializedBinary(std::move(binary)) { }
|
||||
SerializedValue(const String& json, const std::vector<uint8_t>& binary)
|
||||
: Value(TypeSerialized), m_serializedJSON(json), m_serializedBinary(binary) { }
|
||||
String m_serializedJSON;
|
||||
std::vector<uint8_t> m_serializedBinary;
|
||||
};
|
||||
|
||||
class {{config.lib.export_macro}} DictionaryValue : public Value {
|
||||
|
@ -128,12 +128,28 @@ std::unique_ptr<base::Value> toBaseValue(Value* value, int depth) {
|
||||
}
|
||||
|
||||
// static
|
||||
std::unique_ptr<Value> StringUtil::parseJSON(
|
||||
const std::string& json) {
|
||||
std::unique_ptr<base::Value> value = base::JSONReader::Read(json);
|
||||
std::unique_ptr<Value> StringUtil::parseMessage(
|
||||
const std::string& message, bool binary) {
|
||||
if (binary) {
|
||||
return Value::parseBinary(
|
||||
reinterpret_cast<const uint8_t*>(message.data()),
|
||||
message.length());
|
||||
}
|
||||
std::unique_ptr<base::Value> value = base::JSONReader::Read(message);
|
||||
return toProtocolValue(value.get(), 1000);
|
||||
}
|
||||
|
||||
// static
|
||||
ProtocolMessage StringUtil::jsonToMessage(String message) {
|
||||
return message;
|
||||
}
|
||||
|
||||
// static
|
||||
ProtocolMessage StringUtil::binaryToMessage(std::vector<uint8_t> message) {
|
||||
// TODO(pfeldman): figure out what to do with this copy.
|
||||
return std::string(reinterpret_cast<const char*>(message.data()), message.size());
|
||||
}
|
||||
|
||||
StringBuilder::StringBuilder() {}
|
||||
|
||||
StringBuilder::~StringBuilder() {}
|
||||
|
@ -30,6 +30,7 @@ namespace {{namespace}} {
|
||||
class Value;
|
||||
|
||||
using String = std::string;
|
||||
using ProtocolMessage = std::string;
|
||||
|
||||
class {{config.lib.export_macro}} StringBuilder {
|
||||
public:
|
||||
@ -90,7 +91,9 @@ class {{config.lib.export_macro}} StringUtil {
|
||||
return std::vector<uint8_t>(str.begin(), str.end());
|
||||
}
|
||||
|
||||
static std::unique_ptr<Value> parseJSON(const String&);
|
||||
static std::unique_ptr<Value> parseMessage(const std::string& message, bool binary);
|
||||
static ProtocolMessage jsonToMessage(String message);
|
||||
static ProtocolMessage binaryToMessage(std::vector<uint8_t> message);
|
||||
};
|
||||
|
||||
// A read-only sequence of uninterpreted bytes with reference-counted storage.
|
||||
|
@ -51,8 +51,10 @@ namespace {{param.name | to_title_case}}Enum {
|
||||
class {{config.exported.export_macro}} {{type.id}} {
|
||||
public:
|
||||
virtual {{config.exported.string_out}} toJSONString() const = 0;
|
||||
virtual std::vector<uint8_t> toBinary() const = 0;
|
||||
virtual ~{{type.id}}() { }
|
||||
static std::unique_ptr<protocol::{{domain.domain}}::API::{{type.id}}> fromJSONString(const {{config.exported.string_in}}& json);
|
||||
static std::unique_ptr<protocol::{{domain.domain}}::API::{{type.id}}> fromBinary(std::vector<uint8_t> binary);
|
||||
};
|
||||
{% endfor %}
|
||||
|
||||
|
@ -28,8 +28,17 @@ struct ValueConversions<{{"::".join(config.imported.namespace)}}::{{domain.domai
|
||||
errors->addError("value expected");
|
||||
return nullptr;
|
||||
}
|
||||
String json = value->serialize();
|
||||
auto result = {{"::".join(config.imported.namespace)}}::{{domain.domain}}::API::{{type.id}}::fromJSONString({{config.imported.to_imported_string % "json"}});
|
||||
|
||||
// TODO(pfeldman): toggle to true and delete the json branch when binary is ready.
|
||||
bool binary_protocol = false;
|
||||
std::unique_ptr<{{"::".join(config.imported.namespace)}}::{{domain.domain}}::API::{{type.id}}> result;
|
||||
if (binary_protocol) {
|
||||
std::vector<uint8_t> binary = value->serializeToBinary();
|
||||
result = {{"::".join(config.imported.namespace)}}::{{domain.domain}}::API::{{type.id}}::fromBinary(std::move(binary));
|
||||
} else {
|
||||
String json = value->serializeToJSON();
|
||||
result = {{"::".join(config.imported.namespace)}}::{{domain.domain}}::API::{{type.id}}::fromJSONString({{config.imported.to_imported_string % "json"}});
|
||||
}
|
||||
if (!result)
|
||||
errors->addError("cannot parse");
|
||||
return result;
|
||||
@ -37,8 +46,15 @@ struct ValueConversions<{{"::".join(config.imported.namespace)}}::{{domain.domai
|
||||
|
||||
static std::unique_ptr<protocol::Value> toValue(const {{"::".join(config.imported.namespace)}}::{{domain.domain}}::API::{{type.id}}* value)
|
||||
{
|
||||
// TODO(pfeldman): toggle to true and delete the json branch when binary is ready.
|
||||
bool binary_protocol = false;
|
||||
if (binary_protocol) {
|
||||
return SerializedValue::fromBinary(value->toBinary());
|
||||
} else {
|
||||
auto json = value->toJSONString();
|
||||
return SerializedValue::create({{config.imported.from_imported_string % "std::move(json)"}});
|
||||
String local_json = ({{config.imported.from_imported_string % "std::move(json)"}});
|
||||
return SerializedValue::fromJSON(local_json);
|
||||
}
|
||||
}
|
||||
|
||||
static std::unique_ptr<protocol::Value> toValue(const std::unique_ptr<{{"::".join(config.imported.namespace)}}::{{domain.domain}}::API::{{type.id}}>& value)
|
||||
|
@ -101,10 +101,15 @@ std::unique_ptr<{{type.id}}> {{type.id}}::clone() const
|
||||
|
||||
{{config.exported.string_out}} {{type.id}}::toJSONString() const
|
||||
{
|
||||
String json = toValue()->serialize();
|
||||
String json = toValue()->serializeToJSON();
|
||||
return {{config.exported.to_string_out % "json"}};
|
||||
}
|
||||
|
||||
std::vector<uint8_t> {{type.id}}::toBinary() const
|
||||
{
|
||||
return toValue()->serializeToBinary();
|
||||
}
|
||||
|
||||
// static
|
||||
std::unique_ptr<API::{{type.id}}> API::{{type.id}}::fromJSONString(const {{config.exported.string_in}}& json)
|
||||
{
|
||||
@ -114,6 +119,7 @@ std::unique_ptr<API::{{type.id}}> API::{{type.id}}::fromJSONString(const {{confi
|
||||
return nullptr;
|
||||
return protocol::{{domain.domain}}::{{type.id}}::fromValue(value.get(), &errors);
|
||||
}
|
||||
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
@ -187,9 +193,14 @@ void Frontend::flush()
|
||||
m_frontendChannel->flushProtocolNotifications();
|
||||
}
|
||||
|
||||
void Frontend::sendRawNotification(const String& notification)
|
||||
void Frontend::sendRawNotification(String notification)
|
||||
{
|
||||
m_frontendChannel->sendProtocolNotification(InternalRawNotification::create(notification));
|
||||
m_frontendChannel->sendProtocolNotification(InternalRawNotification::fromJSON(std::move(notification)));
|
||||
}
|
||||
|
||||
void Frontend::sendRawNotification(std::vector<uint8_t> notification)
|
||||
{
|
||||
m_frontendChannel->sendProtocolNotification(InternalRawNotification::fromBinary(std::move(notification)));
|
||||
}
|
||||
|
||||
// --------------------- Dispatcher.
|
||||
@ -210,11 +221,11 @@ public:
|
||||
}
|
||||
~DispatcherImpl() override { }
|
||||
bool canDispatch(const String& method) override;
|
||||
void dispatch(int callId, const String& method, const String& message, std::unique_ptr<protocol::DictionaryValue> messageObject) override;
|
||||
void dispatch(int callId, const String& method, const ProtocolMessage& message, std::unique_ptr<protocol::DictionaryValue> messageObject) override;
|
||||
std::unordered_map<String, String>& redirects() { return m_redirects; }
|
||||
|
||||
protected:
|
||||
using CallHandler = void (DispatcherImpl::*)(int callId, const String& method, const String& message, std::unique_ptr<DictionaryValue> messageObject, ErrorSupport* errors);
|
||||
using CallHandler = void (DispatcherImpl::*)(int callId, const String& method, const ProtocolMessage& message, std::unique_ptr<DictionaryValue> messageObject, ErrorSupport* errors);
|
||||
using DispatchMap = std::unordered_map<String, CallHandler>;
|
||||
DispatchMap m_dispatchMap;
|
||||
std::unordered_map<String, String> m_redirects;
|
||||
@ -222,7 +233,7 @@ protected:
|
||||
{% for command in domain.commands %}
|
||||
{% if "redirect" in command %}{% continue %}{% endif %}
|
||||
{% if not protocol.generate_command(domain.domain, command.name) %}{% continue %}{% endif %}
|
||||
void {{command.name}}(int callId, const String& method, const String& message, std::unique_ptr<DictionaryValue> requestMessageObject, ErrorSupport*);
|
||||
void {{command.name}}(int callId, const String& method, const ProtocolMessage& message, std::unique_ptr<DictionaryValue> requestMessageObject, ErrorSupport*);
|
||||
{% endfor %}
|
||||
|
||||
Backend* m_backend;
|
||||
@ -232,7 +243,7 @@ bool DispatcherImpl::canDispatch(const String& method) {
|
||||
return m_dispatchMap.find(method) != m_dispatchMap.end();
|
||||
}
|
||||
|
||||
void DispatcherImpl::dispatch(int callId, const String& method, const String& message, std::unique_ptr<protocol::DictionaryValue> messageObject)
|
||||
void DispatcherImpl::dispatch(int callId, const String& method, const ProtocolMessage& message, std::unique_ptr<protocol::DictionaryValue> messageObject)
|
||||
{
|
||||
std::unordered_map<String, CallHandler>::iterator it = m_dispatchMap.find(method);
|
||||
DCHECK(it != m_dispatchMap.end());
|
||||
@ -248,7 +259,7 @@ void DispatcherImpl::dispatch(int callId, const String& method, const String& me
|
||||
|
||||
class {{command_name_title}}CallbackImpl : public Backend::{{command_name_title}}Callback, public DispatcherBase::Callback {
|
||||
public:
|
||||
{{command_name_title}}CallbackImpl(std::unique_ptr<DispatcherBase::WeakPtr> backendImpl, int callId, const String& method, const String& message)
|
||||
{{command_name_title}}CallbackImpl(std::unique_ptr<DispatcherBase::WeakPtr> backendImpl, int callId, const String& method, const ProtocolMessage& message)
|
||||
: DispatcherBase::Callback(std::move(backendImpl), callId, method, message) { }
|
||||
|
||||
void sendSuccess(
|
||||
@ -286,7 +297,7 @@ public:
|
||||
};
|
||||
{% endif %}
|
||||
|
||||
void DispatcherImpl::{{command.name}}(int callId, const String& method, const String& message, std::unique_ptr<DictionaryValue> requestMessageObject, ErrorSupport* errors)
|
||||
void DispatcherImpl::{{command.name}}(int callId, const String& method, const ProtocolMessage& message, std::unique_ptr<DictionaryValue> requestMessageObject, ErrorSupport* errors)
|
||||
{
|
||||
{% if "parameters" in command %}
|
||||
// Prepare input parameters.
|
||||
|
@ -100,10 +100,13 @@ public:
|
||||
{% endfor %}
|
||||
|
||||
std::unique_ptr<protocol::DictionaryValue> toValue() const;
|
||||
String serialize() override { return toValue()->serialize(); }
|
||||
String serializeToJSON() override { return toValue()->serializeToJSON(); }
|
||||
std::vector<uint8_t> serializeToBinary() override { return toValue()->serializeToBinary(); }
|
||||
String toJSON() const { return toValue()->toJSONString(); }
|
||||
std::unique_ptr<{{type.id}}> clone() const;
|
||||
{% if protocol.is_exported(domain.domain, type.id) %}
|
||||
{{config.exported.string_out}} toJSONString() const override;
|
||||
std::vector<uint8_t> toBinary() const override;
|
||||
{% endif %}
|
||||
|
||||
template<int STATE>
|
||||
@ -266,7 +269,8 @@ public:
|
||||
{% endfor %}
|
||||
|
||||
void flush();
|
||||
void sendRawNotification(const String&);
|
||||
void sendRawNotification(String);
|
||||
void sendRawNotification(std::vector<uint8_t>);
|
||||
private:
|
||||
FrontendChannel* m_frontendChannel;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user