Commit fa3aada5 authored by Johannes Henkel's avatar Johannes Henkel Committed by Commit Bot

[DevTools] Roll inspector_protocol (V8)

Upstream PR:
"Introduce a crdtp/dispatch.{h,cc} library."
https://chromium-review.googlesource.com/c/deps/inspector_protocol/+/1974680
"For the shallow parse of a DevTools message, allow "params": null."
https://chromium-review.googlesource.com/c/deps/inspector_protocol/+/2109466

New Revision: c69cdc36200992d21a17bf4e5c2f3a95b8860ddf

Change-Id: Icc447ff9ce408b24f5245c643dd2f1843da9255f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2076215
Commit-Queue: Johannes Henkel <johannes@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66813}
parent 1e40c682
...@@ -116,7 +116,7 @@ bool substituteObjectTags(int sessionId, const String16& groupName, ...@@ -116,7 +116,7 @@ bool substituteObjectTags(int sessionId, const String16& groupName,
protocol::Response response = protocol::Response response =
injectedScript->wrapObject(originValue, groupName, WrapMode::kNoPreview, injectedScript->wrapObject(originValue, groupName, WrapMode::kNoPreview,
configValue, maxDepth - 1, &wrapper); configValue, maxDepth - 1, &wrapper);
if (!response.isSuccess() || !wrapper) { if (!response.IsSuccess() || !wrapper) {
reportError(context, tryCatch, "cannot wrap value"); reportError(context, tryCatch, "cannot wrap value");
return false; return false;
} }
......
This diff is collapsed.
...@@ -38,12 +38,12 @@ Response RemoteObjectId::parse(const String16& objectId, ...@@ -38,12 +38,12 @@ Response RemoteObjectId::parse(const String16& objectId,
std::unique_ptr<RemoteObjectId> remoteObjectId(new RemoteObjectId()); std::unique_ptr<RemoteObjectId> remoteObjectId(new RemoteObjectId());
std::unique_ptr<protocol::DictionaryValue> parsedObjectId = std::unique_ptr<protocol::DictionaryValue> parsedObjectId =
remoteObjectId->parseInjectedScriptId(objectId); remoteObjectId->parseInjectedScriptId(objectId);
if (!parsedObjectId) return Response::Error("Invalid remote object id"); if (!parsedObjectId) return Response::ServerError("Invalid remote object id");
bool success = parsedObjectId->getInteger("id", &remoteObjectId->m_id); bool success = parsedObjectId->getInteger("id", &remoteObjectId->m_id);
if (!success) return Response::Error("Invalid remote object id"); if (!success) return Response::ServerError("Invalid remote object id");
*result = std::move(remoteObjectId); *result = std::move(remoteObjectId);
return Response::OK(); return Response::Success();
} }
RemoteCallFrameId::RemoteCallFrameId() RemoteCallFrameId::RemoteCallFrameId()
...@@ -54,13 +54,13 @@ Response RemoteCallFrameId::parse(const String16& objectId, ...@@ -54,13 +54,13 @@ Response RemoteCallFrameId::parse(const String16& objectId,
std::unique_ptr<RemoteCallFrameId> remoteCallFrameId(new RemoteCallFrameId()); std::unique_ptr<RemoteCallFrameId> remoteCallFrameId(new RemoteCallFrameId());
std::unique_ptr<protocol::DictionaryValue> parsedObjectId = std::unique_ptr<protocol::DictionaryValue> parsedObjectId =
remoteCallFrameId->parseInjectedScriptId(objectId); remoteCallFrameId->parseInjectedScriptId(objectId);
if (!parsedObjectId) return Response::Error("Invalid call frame id"); if (!parsedObjectId) return Response::ServerError("Invalid call frame id");
bool success = bool success =
parsedObjectId->getInteger("ordinal", &remoteCallFrameId->m_frameOrdinal); parsedObjectId->getInteger("ordinal", &remoteCallFrameId->m_frameOrdinal);
if (!success) return Response::Error("Invalid call frame id"); if (!success) return Response::ServerError("Invalid call frame id");
*result = std::move(remoteCallFrameId); *result = std::move(remoteCallFrameId);
return Response::OK(); return Response::Success();
} }
String16 RemoteCallFrameId::serialize(int injectedScriptId, int frameOrdinal) { String16 RemoteCallFrameId::serialize(int injectedScriptId, int frameOrdinal) {
......
...@@ -161,3 +161,10 @@ String16 stackTraceIdToString(uintptr_t id) { ...@@ -161,3 +161,10 @@ String16 stackTraceIdToString(uintptr_t id) {
} }
} // namespace v8_inspector } // namespace v8_inspector
namespace v8_crdtp {
void SerializerTraits<v8_inspector::protocol::Binary>::Serialize(
const v8_inspector::protocol::Binary& binary, std::vector<uint8_t>* out) {
cbor::EncodeBinary(span<uint8_t>(binary.data(), binary.size()), out);
}
} // namespace v8_crdtp
...@@ -24,17 +24,6 @@ using String = v8_inspector::String16; ...@@ -24,17 +24,6 @@ using String = v8_inspector::String16;
class StringUtil { class StringUtil {
public: public:
static String substring(const String& s, size_t pos, size_t len) {
return s.substring(pos, len);
}
static size_t find(const String& s, const char* needle) {
return s.find(needle);
}
static size_t find(const String& s, const String& needle) {
return s.find(needle);
}
static const size_t kNotFound = String::kNotFound;
static String fromUTF8(const uint8_t* data, size_t length) { static String fromUTF8(const uint8_t* data, size_t length) {
return String16::fromUTF8(reinterpret_cast<const char*>(data), length); return String16::fromUTF8(reinterpret_cast<const char*>(data), length);
} }
...@@ -100,4 +89,13 @@ String16 stackTraceIdToString(uintptr_t id); ...@@ -100,4 +89,13 @@ String16 stackTraceIdToString(uintptr_t id);
} // namespace v8_inspector } // namespace v8_inspector
// See third_party/inspector_protocol/crdtp/serializer_traits.h.
namespace v8_crdtp {
template <>
struct SerializerTraits<v8_inspector::protocol::Binary> {
static void Serialize(const v8_inspector::protocol::Binary& binary,
std::vector<uint8_t>* out);
};
} // namespace v8_crdtp
#endif // V8_INSPECTOR_STRING_UTIL_H_ #endif // V8_INSPECTOR_STRING_UTIL_H_
...@@ -27,23 +27,23 @@ V8ConsoleAgentImpl::V8ConsoleAgentImpl( ...@@ -27,23 +27,23 @@ V8ConsoleAgentImpl::V8ConsoleAgentImpl(
V8ConsoleAgentImpl::~V8ConsoleAgentImpl() = default; V8ConsoleAgentImpl::~V8ConsoleAgentImpl() = default;
Response V8ConsoleAgentImpl::enable() { Response V8ConsoleAgentImpl::enable() {
if (m_enabled) return Response::OK(); if (m_enabled) return Response::Success();
m_state->setBoolean(ConsoleAgentState::consoleEnabled, true); m_state->setBoolean(ConsoleAgentState::consoleEnabled, true);
m_enabled = true; m_enabled = true;
m_session->inspector()->enableStackCapturingIfNeeded(); m_session->inspector()->enableStackCapturingIfNeeded();
reportAllMessages(); reportAllMessages();
return Response::OK(); return Response::Success();
} }
Response V8ConsoleAgentImpl::disable() { Response V8ConsoleAgentImpl::disable() {
if (!m_enabled) return Response::OK(); if (!m_enabled) return Response::Success();
m_session->inspector()->disableStackCapturingIfNeeded(); m_session->inspector()->disableStackCapturingIfNeeded();
m_state->setBoolean(ConsoleAgentState::consoleEnabled, false); m_state->setBoolean(ConsoleAgentState::consoleEnabled, false);
m_enabled = false; m_enabled = false;
return Response::OK(); return Response::Success();
} }
Response V8ConsoleAgentImpl::clearMessages() { return Response::OK(); } Response V8ConsoleAgentImpl::clearMessages() { return Response::Success(); }
void V8ConsoleAgentImpl::restore() { void V8ConsoleAgentImpl::restore() {
if (!m_state->booleanProperty(ConsoleAgentState::consoleEnabled, false)) if (!m_state->booleanProperty(ConsoleAgentState::consoleEnabled, false))
......
...@@ -595,7 +595,7 @@ static void inspectImpl(const v8::FunctionCallbackInfo<v8::Value>& info, ...@@ -595,7 +595,7 @@ static void inspectImpl(const v8::FunctionCallbackInfo<v8::Value>& info,
std::unique_ptr<protocol::Runtime::RemoteObject> wrappedObject; std::unique_ptr<protocol::Runtime::RemoteObject> wrappedObject;
protocol::Response response = injectedScript->wrapObject( protocol::Response response = injectedScript->wrapObject(
value, "", WrapMode::kNoPreview, &wrappedObject); value, "", WrapMode::kNoPreview, &wrappedObject);
if (!response.isSuccess()) return; if (!response.IsSuccess()) return;
std::unique_ptr<protocol::DictionaryValue> hints = std::unique_ptr<protocol::DictionaryValue> hints =
protocol::DictionaryValue::create(); protocol::DictionaryValue::create();
......
This diff is collapsed.
...@@ -339,8 +339,8 @@ void V8Debugger::terminateExecution( ...@@ -339,8 +339,8 @@ void V8Debugger::terminateExecution(
std::unique_ptr<TerminateExecutionCallback> callback) { std::unique_ptr<TerminateExecutionCallback> callback) {
if (m_terminateExecutionCallback) { if (m_terminateExecutionCallback) {
if (callback) { if (callback) {
callback->sendFailure( callback->sendFailure(Response::ServerError(
Response::Error("There is current termination request in progress")); "There is current termination request in progress"));
} }
return; return;
} }
...@@ -394,9 +394,9 @@ Response V8Debugger::continueToLocation( ...@@ -394,9 +394,9 @@ Response V8Debugger::continueToLocation(
} }
continueProgram(targetContextGroupId); continueProgram(targetContextGroupId);
// TODO(kozyatinskiy): Return actual line and column number. // TODO(kozyatinskiy): Return actual line and column number.
return Response::OK(); return Response::Success();
} else { } else {
return Response::Error("Cannot continue to specified location"); return Response::ServerError("Cannot continue to specified location");
} }
} }
......
...@@ -173,7 +173,7 @@ void V8HeapProfilerAgentImpl::restore() { ...@@ -173,7 +173,7 @@ void V8HeapProfilerAgentImpl::restore() {
Response V8HeapProfilerAgentImpl::collectGarbage() { Response V8HeapProfilerAgentImpl::collectGarbage() {
m_isolate->LowMemoryNotification(); m_isolate->LowMemoryNotification();
return Response::OK(); return Response::Success();
} }
Response V8HeapProfilerAgentImpl::startTrackingHeapObjects( Response V8HeapProfilerAgentImpl::startTrackingHeapObjects(
...@@ -183,7 +183,7 @@ Response V8HeapProfilerAgentImpl::startTrackingHeapObjects( ...@@ -183,7 +183,7 @@ Response V8HeapProfilerAgentImpl::startTrackingHeapObjects(
m_state->setBoolean(HeapProfilerAgentState::allocationTrackingEnabled, m_state->setBoolean(HeapProfilerAgentState::allocationTrackingEnabled,
allocationTrackingEnabled); allocationTrackingEnabled);
startTrackingHeapObjectsInternal(allocationTrackingEnabled); startTrackingHeapObjectsInternal(allocationTrackingEnabled);
return Response::OK(); return Response::Success();
} }
Response V8HeapProfilerAgentImpl::stopTrackingHeapObjects( Response V8HeapProfilerAgentImpl::stopTrackingHeapObjects(
...@@ -192,12 +192,12 @@ Response V8HeapProfilerAgentImpl::stopTrackingHeapObjects( ...@@ -192,12 +192,12 @@ Response V8HeapProfilerAgentImpl::stopTrackingHeapObjects(
takeHeapSnapshot(std::move(reportProgress), takeHeapSnapshot(std::move(reportProgress),
std::move(treatGlobalObjectsAsRoots)); std::move(treatGlobalObjectsAsRoots));
stopTrackingHeapObjectsInternal(); stopTrackingHeapObjectsInternal();
return Response::OK(); return Response::Success();
} }
Response V8HeapProfilerAgentImpl::enable() { Response V8HeapProfilerAgentImpl::enable() {
m_state->setBoolean(HeapProfilerAgentState::heapProfilerEnabled, true); m_state->setBoolean(HeapProfilerAgentState::heapProfilerEnabled, true);
return Response::OK(); return Response::Success();
} }
Response V8HeapProfilerAgentImpl::disable() { Response V8HeapProfilerAgentImpl::disable() {
...@@ -209,13 +209,13 @@ Response V8HeapProfilerAgentImpl::disable() { ...@@ -209,13 +209,13 @@ Response V8HeapProfilerAgentImpl::disable() {
} }
m_isolate->GetHeapProfiler()->ClearObjectIds(); m_isolate->GetHeapProfiler()->ClearObjectIds();
m_state->setBoolean(HeapProfilerAgentState::heapProfilerEnabled, false); m_state->setBoolean(HeapProfilerAgentState::heapProfilerEnabled, false);
return Response::OK(); return Response::Success();
} }
Response V8HeapProfilerAgentImpl::takeHeapSnapshot( Response V8HeapProfilerAgentImpl::takeHeapSnapshot(
Maybe<bool> reportProgress, Maybe<bool> treatGlobalObjectsAsRoots) { Maybe<bool> reportProgress, Maybe<bool> treatGlobalObjectsAsRoots) {
v8::HeapProfiler* profiler = m_isolate->GetHeapProfiler(); v8::HeapProfiler* profiler = m_isolate->GetHeapProfiler();
if (!profiler) return Response::Error("Cannot access v8 heap profiler"); if (!profiler) return Response::ServerError("Cannot access v8 heap profiler");
std::unique_ptr<HeapSnapshotProgress> progress; std::unique_ptr<HeapSnapshotProgress> progress;
if (reportProgress.fromMaybe(false)) if (reportProgress.fromMaybe(false))
progress.reset(new HeapSnapshotProgress(&m_frontend)); progress.reset(new HeapSnapshotProgress(&m_frontend));
...@@ -223,11 +223,11 @@ Response V8HeapProfilerAgentImpl::takeHeapSnapshot( ...@@ -223,11 +223,11 @@ Response V8HeapProfilerAgentImpl::takeHeapSnapshot(
GlobalObjectNameResolver resolver(m_session); GlobalObjectNameResolver resolver(m_session);
const v8::HeapSnapshot* snapshot = profiler->TakeHeapSnapshot( const v8::HeapSnapshot* snapshot = profiler->TakeHeapSnapshot(
progress.get(), &resolver, treatGlobalObjectsAsRoots.fromMaybe(true)); progress.get(), &resolver, treatGlobalObjectsAsRoots.fromMaybe(true));
if (!snapshot) return Response::Error("Failed to take heap snapshot"); if (!snapshot) return Response::ServerError("Failed to take heap snapshot");
HeapSnapshotOutputStream stream(&m_frontend); HeapSnapshotOutputStream stream(&m_frontend);
snapshot->Serialize(&stream); snapshot->Serialize(&stream);
const_cast<v8::HeapSnapshot*>(snapshot)->Delete(); const_cast<v8::HeapSnapshot*>(snapshot)->Delete();
return Response::OK(); return Response::Success();
} }
Response V8HeapProfilerAgentImpl::getObjectByHeapObjectId( Response V8HeapProfilerAgentImpl::getObjectByHeapObjectId(
...@@ -235,36 +235,38 @@ Response V8HeapProfilerAgentImpl::getObjectByHeapObjectId( ...@@ -235,36 +235,38 @@ Response V8HeapProfilerAgentImpl::getObjectByHeapObjectId(
std::unique_ptr<protocol::Runtime::RemoteObject>* result) { std::unique_ptr<protocol::Runtime::RemoteObject>* result) {
bool ok; bool ok;
int id = heapSnapshotObjectId.toInteger(&ok); int id = heapSnapshotObjectId.toInteger(&ok);
if (!ok) return Response::Error("Invalid heap snapshot object id"); if (!ok) return Response::ServerError("Invalid heap snapshot object id");
v8::HandleScope handles(m_isolate); v8::HandleScope handles(m_isolate);
v8::Local<v8::Object> heapObject = objectByHeapObjectId(m_isolate, id); v8::Local<v8::Object> heapObject = objectByHeapObjectId(m_isolate, id);
if (heapObject.IsEmpty()) return Response::Error("Object is not available"); if (heapObject.IsEmpty())
return Response::ServerError("Object is not available");
if (!m_session->inspector()->client()->isInspectableHeapObject(heapObject)) if (!m_session->inspector()->client()->isInspectableHeapObject(heapObject))
return Response::Error("Object is not available"); return Response::ServerError("Object is not available");
*result = m_session->wrapObject(heapObject->CreationContext(), heapObject, *result = m_session->wrapObject(heapObject->CreationContext(), heapObject,
objectGroup.fromMaybe(""), false); objectGroup.fromMaybe(""), false);
if (!*result) return Response::Error("Object is not available"); if (!*result) return Response::ServerError("Object is not available");
return Response::OK(); return Response::Success();
} }
Response V8HeapProfilerAgentImpl::addInspectedHeapObject( Response V8HeapProfilerAgentImpl::addInspectedHeapObject(
const String16& inspectedHeapObjectId) { const String16& inspectedHeapObjectId) {
bool ok; bool ok;
int id = inspectedHeapObjectId.toInteger(&ok); int id = inspectedHeapObjectId.toInteger(&ok);
if (!ok) return Response::Error("Invalid heap snapshot object id"); if (!ok) return Response::ServerError("Invalid heap snapshot object id");
v8::HandleScope handles(m_isolate); v8::HandleScope handles(m_isolate);
v8::Local<v8::Object> heapObject = objectByHeapObjectId(m_isolate, id); v8::Local<v8::Object> heapObject = objectByHeapObjectId(m_isolate, id);
if (heapObject.IsEmpty()) return Response::Error("Object is not available"); if (heapObject.IsEmpty())
return Response::ServerError("Object is not available");
if (!m_session->inspector()->client()->isInspectableHeapObject(heapObject)) if (!m_session->inspector()->client()->isInspectableHeapObject(heapObject))
return Response::Error("Object is not available"); return Response::ServerError("Object is not available");
m_session->addInspectedObject( m_session->addInspectedObject(
std::unique_ptr<InspectableHeapObject>(new InspectableHeapObject(id))); std::unique_ptr<InspectableHeapObject>(new InspectableHeapObject(id)));
return Response::OK(); return Response::Success();
} }
Response V8HeapProfilerAgentImpl::getHeapObjectId( Response V8HeapProfilerAgentImpl::getHeapObjectId(
...@@ -274,12 +276,12 @@ Response V8HeapProfilerAgentImpl::getHeapObjectId( ...@@ -274,12 +276,12 @@ Response V8HeapProfilerAgentImpl::getHeapObjectId(
v8::Local<v8::Context> context; v8::Local<v8::Context> context;
Response response = Response response =
m_session->unwrapObject(objectId, &value, &context, nullptr); m_session->unwrapObject(objectId, &value, &context, nullptr);
if (!response.isSuccess()) return response; if (!response.IsSuccess()) return response;
if (value->IsUndefined()) return Response::InternalError(); if (value->IsUndefined()) return Response::InternalError();
v8::SnapshotObjectId id = m_isolate->GetHeapProfiler()->GetObjectId(value); v8::SnapshotObjectId id = m_isolate->GetHeapProfiler()->GetObjectId(value);
*heapSnapshotObjectId = String16::fromInteger(static_cast<size_t>(id)); *heapSnapshotObjectId = String16::fromInteger(static_cast<size_t>(id));
return Response::OK(); return Response::Success();
} }
void V8HeapProfilerAgentImpl::requestHeapStatsUpdate() { void V8HeapProfilerAgentImpl::requestHeapStatsUpdate() {
...@@ -320,7 +322,7 @@ void V8HeapProfilerAgentImpl::stopTrackingHeapObjectsInternal() { ...@@ -320,7 +322,7 @@ void V8HeapProfilerAgentImpl::stopTrackingHeapObjectsInternal() {
Response V8HeapProfilerAgentImpl::startSampling( Response V8HeapProfilerAgentImpl::startSampling(
Maybe<double> samplingInterval) { Maybe<double> samplingInterval) {
v8::HeapProfiler* profiler = m_isolate->GetHeapProfiler(); v8::HeapProfiler* profiler = m_isolate->GetHeapProfiler();
if (!profiler) return Response::Error("Cannot access v8 heap profiler"); if (!profiler) return Response::ServerError("Cannot access v8 heap profiler");
const unsigned defaultSamplingInterval = 1 << 15; const unsigned defaultSamplingInterval = 1 << 15;
double samplingIntervalValue = double samplingIntervalValue =
samplingInterval.fromMaybe(defaultSamplingInterval); samplingInterval.fromMaybe(defaultSamplingInterval);
...@@ -331,7 +333,7 @@ Response V8HeapProfilerAgentImpl::startSampling( ...@@ -331,7 +333,7 @@ Response V8HeapProfilerAgentImpl::startSampling(
profiler->StartSamplingHeapProfiler( profiler->StartSamplingHeapProfiler(
static_cast<uint64_t>(samplingIntervalValue), 128, static_cast<uint64_t>(samplingIntervalValue), 128,
v8::HeapProfiler::kSamplingForceGC); v8::HeapProfiler::kSamplingForceGC);
return Response::OK(); return Response::Success();
} }
namespace { namespace {
...@@ -367,7 +369,7 @@ buildSampingHeapProfileNode(v8::Isolate* isolate, ...@@ -367,7 +369,7 @@ buildSampingHeapProfileNode(v8::Isolate* isolate,
Response V8HeapProfilerAgentImpl::stopSampling( Response V8HeapProfilerAgentImpl::stopSampling(
std::unique_ptr<protocol::HeapProfiler::SamplingHeapProfile>* profile) { std::unique_ptr<protocol::HeapProfiler::SamplingHeapProfile>* profile) {
Response result = getSamplingProfile(profile); Response result = getSamplingProfile(profile);
if (result.isSuccess()) { if (result.IsSuccess()) {
m_isolate->GetHeapProfiler()->StopSamplingHeapProfiler(); m_isolate->GetHeapProfiler()->StopSamplingHeapProfiler();
m_state->setBoolean(HeapProfilerAgentState::samplingHeapProfilerEnabled, m_state->setBoolean(HeapProfilerAgentState::samplingHeapProfilerEnabled,
false); false);
...@@ -383,7 +385,7 @@ Response V8HeapProfilerAgentImpl::getSamplingProfile( ...@@ -383,7 +385,7 @@ Response V8HeapProfilerAgentImpl::getSamplingProfile(
std::unique_ptr<v8::AllocationProfile> v8Profile( std::unique_ptr<v8::AllocationProfile> v8Profile(
profiler->GetAllocationProfile()); profiler->GetAllocationProfile());
if (!v8Profile) if (!v8Profile)
return Response::Error("V8 sampling heap profiler was not started."); return Response::ServerError("V8 sampling heap profiler was not started.");
v8::AllocationProfile::Node* root = v8Profile->GetRootNode(); v8::AllocationProfile::Node* root = v8Profile->GetRootNode();
auto samples = std::make_unique< auto samples = std::make_unique<
protocol::Array<protocol::HeapProfiler::SamplingHeapProfileSample>>(); protocol::Array<protocol::HeapProfiler::SamplingHeapProfileSample>>();
...@@ -399,7 +401,7 @@ Response V8HeapProfilerAgentImpl::getSamplingProfile( ...@@ -399,7 +401,7 @@ Response V8HeapProfilerAgentImpl::getSamplingProfile(
.setHead(buildSampingHeapProfileNode(m_isolate, root)) .setHead(buildSampingHeapProfileNode(m_isolate, root))
.setSamples(std::move(samples)) .setSamples(std::move(samples))
.build(); .build();
return Response::OK(); return Response::Success();
} }
} // namespace v8_inspector } // namespace v8_inspector
...@@ -467,12 +467,12 @@ class V8InspectorImpl::EvaluateScope::TerminateTask : public v8::Task { ...@@ -467,12 +467,12 @@ class V8InspectorImpl::EvaluateScope::TerminateTask : public v8::Task {
protocol::Response V8InspectorImpl::EvaluateScope::setTimeout(double timeout) { protocol::Response V8InspectorImpl::EvaluateScope::setTimeout(double timeout) {
if (m_isolate->IsExecutionTerminating()) { if (m_isolate->IsExecutionTerminating()) {
return protocol::Response::Error("Execution was terminated"); return protocol::Response::ServerError("Execution was terminated");
} }
m_cancelToken.reset(new CancelToken()); m_cancelToken.reset(new CancelToken());
v8::debug::GetCurrentPlatform()->CallDelayedOnWorkerThread( v8::debug::GetCurrentPlatform()->CallDelayedOnWorkerThread(
std::make_unique<TerminateTask>(m_isolate, m_cancelToken), timeout); std::make_unique<TerminateTask>(m_isolate, m_cancelToken), timeout);
return protocol::Response::OK(); return protocol::Response::Success();
} }
} // namespace v8_inspector } // namespace v8_inspector
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "src/inspector/v8-inspector-session-impl.h" #include "src/inspector/v8-inspector-session-impl.h"
#include "../../third_party/inspector_protocol/crdtp/cbor.h" #include "../../third_party/inspector_protocol/crdtp/cbor.h"
#include "../../third_party/inspector_protocol/crdtp/dispatch.h"
#include "../../third_party/inspector_protocol/crdtp/json.h" #include "../../third_party/inspector_protocol/crdtp/json.h"
#include "src/base/logging.h" #include "src/base/logging.h"
#include "src/base/macros.h" #include "src/base/macros.h"
...@@ -184,23 +185,24 @@ std::unique_ptr<StringBuffer> V8InspectorSessionImpl::serializeForFrontend( ...@@ -184,23 +185,24 @@ std::unique_ptr<StringBuffer> V8InspectorSessionImpl::serializeForFrontend(
return StringBufferFrom(std::move(string16)); return StringBufferFrom(std::move(string16));
} }
void V8InspectorSessionImpl::sendProtocolResponse( void V8InspectorSessionImpl::SendProtocolResponse(
int callId, std::unique_ptr<protocol::Serializable> message) { int callId, std::unique_ptr<protocol::Serializable> message) {
m_channel->sendResponse(callId, serializeForFrontend(std::move(message))); m_channel->sendResponse(callId, serializeForFrontend(std::move(message)));
} }
void V8InspectorSessionImpl::sendProtocolNotification( void V8InspectorSessionImpl::SendProtocolNotification(
std::unique_ptr<protocol::Serializable> message) { std::unique_ptr<protocol::Serializable> message) {
m_channel->sendNotification(serializeForFrontend(std::move(message))); m_channel->sendNotification(serializeForFrontend(std::move(message)));
} }
void V8InspectorSessionImpl::fallThrough(int callId, const String16& method, void V8InspectorSessionImpl::FallThrough(int callId,
const v8_crdtp::span<uint8_t> method,
v8_crdtp::span<uint8_t> message) { v8_crdtp::span<uint8_t> message) {
// There's no other layer to handle the command. // There's no other layer to handle the command.
UNREACHABLE(); UNREACHABLE();
} }
void V8InspectorSessionImpl::flushProtocolNotifications() { void V8InspectorSessionImpl::FlushProtocolNotifications() {
m_channel->flushProtocolNotifications(); m_channel->flushProtocolNotifications();
} }
...@@ -224,14 +226,15 @@ Response V8InspectorSessionImpl::findInjectedScript( ...@@ -224,14 +226,15 @@ Response V8InspectorSessionImpl::findInjectedScript(
injectedScript = nullptr; injectedScript = nullptr;
InspectedContext* context = InspectedContext* context =
m_inspector->getContext(m_contextGroupId, contextId); m_inspector->getContext(m_contextGroupId, contextId);
if (!context) return Response::Error("Cannot find context with specified id"); if (!context)
return Response::ServerError("Cannot find context with specified id");
injectedScript = context->getInjectedScript(m_sessionId); injectedScript = context->getInjectedScript(m_sessionId);
if (!injectedScript) { if (!injectedScript) {
injectedScript = context->createInjectedScript(m_sessionId); injectedScript = context->createInjectedScript(m_sessionId);
if (m_customObjectFormatterEnabled) if (m_customObjectFormatterEnabled)
injectedScript->setCustomObjectFormatterEnabled(true); injectedScript->setCustomObjectFormatterEnabled(true);
} }
return Response::OK(); return Response::Success();
} }
Response V8InspectorSessionImpl::findInjectedScript( Response V8InspectorSessionImpl::findInjectedScript(
...@@ -259,8 +262,11 @@ bool V8InspectorSessionImpl::unwrapObject( ...@@ -259,8 +262,11 @@ bool V8InspectorSessionImpl::unwrapObject(
String16 objectGroupString; String16 objectGroupString;
Response response = unwrapObject(toString16(objectId), object, context, Response response = unwrapObject(toString16(objectId), object, context,
objectGroup ? &objectGroupString : nullptr); objectGroup ? &objectGroupString : nullptr);
if (!response.isSuccess()) { if (response.IsError()) {
if (error) *error = StringBufferFrom(response.errorMessage()); if (error) {
const std::string& msg = response.Message();
*error = StringBufferFrom(String16::fromUTF8(msg.data(), msg.size()));
}
return false; return false;
} }
if (objectGroup) if (objectGroup)
...@@ -274,15 +280,15 @@ Response V8InspectorSessionImpl::unwrapObject(const String16& objectId, ...@@ -274,15 +280,15 @@ Response V8InspectorSessionImpl::unwrapObject(const String16& objectId,
String16* objectGroup) { String16* objectGroup) {
std::unique_ptr<RemoteObjectId> remoteId; std::unique_ptr<RemoteObjectId> remoteId;
Response response = RemoteObjectId::parse(objectId, &remoteId); Response response = RemoteObjectId::parse(objectId, &remoteId);
if (!response.isSuccess()) return response; if (!response.IsSuccess()) return response;
InjectedScript* injectedScript = nullptr; InjectedScript* injectedScript = nullptr;
response = findInjectedScript(remoteId.get(), injectedScript); response = findInjectedScript(remoteId.get(), injectedScript);
if (!response.isSuccess()) return response; if (!response.IsSuccess()) return response;
response = injectedScript->findObject(*remoteId, object); response = injectedScript->findObject(*remoteId, object);
if (!response.isSuccess()) return response; if (!response.IsSuccess()) return response;
*context = injectedScript->context()->context(); *context = injectedScript->context()->context();
if (objectGroup) *objectGroup = injectedScript->objectGroupName(*remoteId); if (objectGroup) *objectGroup = injectedScript->objectGroupName(*remoteId);
return Response::OK(); return Response::Success();
} }
std::unique_ptr<protocol::Runtime::API::RemoteObject> std::unique_ptr<protocol::Runtime::API::RemoteObject>
...@@ -349,19 +355,29 @@ void V8InspectorSessionImpl::dispatchProtocolMessage( ...@@ -349,19 +355,29 @@ void V8InspectorSessionImpl::dispatchProtocolMessage(
} else { } else {
// We're ignoring the return value of the conversion function // We're ignoring the return value of the conversion function
// intentionally. It means the |parsed_message| below will be nullptr. // intentionally. It means the |parsed_message| below will be nullptr.
ConvertToCBOR(message, &converted_cbor); auto status = ConvertToCBOR(message, &converted_cbor);
if (!status.ok()) {
m_channel->sendNotification(
serializeForFrontend(v8_crdtp::CreateErrorNotification(
v8_crdtp::DispatchResponse::ParseError(status.ToASCIIString()))));
return;
}
cbor = SpanFrom(converted_cbor); cbor = SpanFrom(converted_cbor);
} }
int callId; v8_crdtp::Dispatchable dispatchable(cbor);
std::unique_ptr<protocol::Value> parsed_message = if (!dispatchable.ok()) {
protocol::Value::parseBinary(cbor.data(), cbor.size()); if (dispatchable.HasCallId()) {
String16 method; m_channel->sendNotification(serializeForFrontend(
if (m_dispatcher.parseCommand(parsed_message.get(), &callId, &method)) { v8_crdtp::CreateErrorNotification(dispatchable.DispatchError())));
// Pass empty string instead of the actual message to save on a conversion. } else {
// We're allowed to do so because fall-through is not implemented. m_channel->sendResponse(
m_dispatcher.dispatch(callId, method, std::move(parsed_message), dispatchable.CallId(),
v8_crdtp::span<uint8_t>()); serializeForFrontend(v8_crdtp::CreateErrorResponse(
dispatchable.CallId(), dispatchable.DispatchError())));
}
return;
} }
m_dispatcher.Dispatch(dispatchable).Run();
} }
std::vector<uint8_t> V8InspectorSessionImpl::state() { std::vector<uint8_t> V8InspectorSessionImpl::state() {
......
...@@ -100,13 +100,13 @@ class V8InspectorSessionImpl : public V8InspectorSession, ...@@ -100,13 +100,13 @@ class V8InspectorSessionImpl : public V8InspectorSession,
protocol::DictionaryValue* agentState(const String16& name); protocol::DictionaryValue* agentState(const String16& name);
// protocol::FrontendChannel implementation. // protocol::FrontendChannel implementation.
void sendProtocolResponse( void SendProtocolResponse(
int callId, std::unique_ptr<protocol::Serializable> message) override; int callId, std::unique_ptr<protocol::Serializable> message) override;
void sendProtocolNotification( void SendProtocolNotification(
std::unique_ptr<protocol::Serializable> message) override; std::unique_ptr<protocol::Serializable> message) override;
void fallThrough(int callId, const String16& method, void FallThrough(int callId, v8_crdtp::span<uint8_t> method,
v8_crdtp::span<uint8_t> message) override; v8_crdtp::span<uint8_t> message) override;
void flushProtocolNotifications() override; void FlushProtocolNotifications() override;
std::unique_ptr<StringBuffer> serializeForFrontend( std::unique_ptr<StringBuffer> serializeForFrontend(
std::unique_ptr<protocol::Serializable> message); std::unique_ptr<protocol::Serializable> message);
......
...@@ -220,14 +220,14 @@ void V8ProfilerAgentImpl::consoleProfileEnd(const String16& title) { ...@@ -220,14 +220,14 @@ void V8ProfilerAgentImpl::consoleProfileEnd(const String16& title) {
} }
Response V8ProfilerAgentImpl::enable() { Response V8ProfilerAgentImpl::enable() {
if (m_enabled) return Response::OK(); if (m_enabled) return Response::Success();
m_enabled = true; m_enabled = true;
m_state->setBoolean(ProfilerAgentState::profilerEnabled, true); m_state->setBoolean(ProfilerAgentState::profilerEnabled, true);
return Response::OK(); return Response::Success();
} }
Response V8ProfilerAgentImpl::disable() { Response V8ProfilerAgentImpl::disable() {
if (!m_enabled) return Response::OK(); if (!m_enabled) return Response::Success();
for (size_t i = m_startedProfiles.size(); i > 0; --i) for (size_t i = m_startedProfiles.size(); i > 0; --i)
stopProfiling(m_startedProfiles[i - 1].m_id, false); stopProfiling(m_startedProfiles[i - 1].m_id, false);
m_startedProfiles.clear(); m_startedProfiles.clear();
...@@ -236,15 +236,16 @@ Response V8ProfilerAgentImpl::disable() { ...@@ -236,15 +236,16 @@ Response V8ProfilerAgentImpl::disable() {
DCHECK(!m_profiler); DCHECK(!m_profiler);
m_enabled = false; m_enabled = false;
m_state->setBoolean(ProfilerAgentState::profilerEnabled, false); m_state->setBoolean(ProfilerAgentState::profilerEnabled, false);
return Response::OK(); return Response::Success();
} }
Response V8ProfilerAgentImpl::setSamplingInterval(int interval) { Response V8ProfilerAgentImpl::setSamplingInterval(int interval) {
if (m_profiler) { if (m_profiler) {
return Response::Error("Cannot change sampling interval when profiling."); return Response::ServerError(
"Cannot change sampling interval when profiling.");
} }
m_state->setInteger(ProfilerAgentState::samplingInterval, interval); m_state->setInteger(ProfilerAgentState::samplingInterval, interval);
return Response::OK(); return Response::Success();
} }
void V8ProfilerAgentImpl::restore() { void V8ProfilerAgentImpl::restore() {
...@@ -272,36 +273,36 @@ void V8ProfilerAgentImpl::restore() { ...@@ -272,36 +273,36 @@ void V8ProfilerAgentImpl::restore() {
} }
Response V8ProfilerAgentImpl::start() { Response V8ProfilerAgentImpl::start() {
if (m_recordingCPUProfile) return Response::OK(); if (m_recordingCPUProfile) return Response::Success();
if (!m_enabled) return Response::Error("Profiler is not enabled"); if (!m_enabled) return Response::ServerError("Profiler is not enabled");
m_recordingCPUProfile = true; m_recordingCPUProfile = true;
m_frontendInitiatedProfileId = nextProfileId(); m_frontendInitiatedProfileId = nextProfileId();
startProfiling(m_frontendInitiatedProfileId); startProfiling(m_frontendInitiatedProfileId);
m_state->setBoolean(ProfilerAgentState::userInitiatedProfiling, true); m_state->setBoolean(ProfilerAgentState::userInitiatedProfiling, true);
return Response::OK(); return Response::Success();
} }
Response V8ProfilerAgentImpl::stop( Response V8ProfilerAgentImpl::stop(
std::unique_ptr<protocol::Profiler::Profile>* profile) { std::unique_ptr<protocol::Profiler::Profile>* profile) {
if (!m_recordingCPUProfile) { if (!m_recordingCPUProfile) {
return Response::Error("No recording profiles found"); return Response::ServerError("No recording profiles found");
} }
m_recordingCPUProfile = false; m_recordingCPUProfile = false;
std::unique_ptr<protocol::Profiler::Profile> cpuProfile = std::unique_ptr<protocol::Profiler::Profile> cpuProfile =
stopProfiling(m_frontendInitiatedProfileId, !!profile); stopProfiling(m_frontendInitiatedProfileId, !!profile);
if (profile) { if (profile) {
*profile = std::move(cpuProfile); *profile = std::move(cpuProfile);
if (!profile->get()) return Response::Error("Profile is not found"); if (!profile->get()) return Response::ServerError("Profile is not found");
} }
m_frontendInitiatedProfileId = String16(); m_frontendInitiatedProfileId = String16();
m_state->setBoolean(ProfilerAgentState::userInitiatedProfiling, false); m_state->setBoolean(ProfilerAgentState::userInitiatedProfiling, false);
return Response::OK(); return Response::Success();
} }
Response V8ProfilerAgentImpl::startPreciseCoverage( Response V8ProfilerAgentImpl::startPreciseCoverage(
Maybe<bool> callCount, Maybe<bool> detailed, Maybe<bool> callCount, Maybe<bool> detailed,
Maybe<bool> allowTriggeredUpdates, double* out_timestamp) { Maybe<bool> allowTriggeredUpdates, double* out_timestamp) {
if (!m_enabled) return Response::Error("Profiler is not enabled"); if (!m_enabled) return Response::ServerError("Profiler is not enabled");
*out_timestamp = *out_timestamp =
v8::base::TimeTicks::HighResolutionNow().since_origin().InSecondsF(); v8::base::TimeTicks::HighResolutionNow().since_origin().InSecondsF();
bool callCountValue = callCount.fromMaybe(false); bool callCountValue = callCount.fromMaybe(false);
...@@ -324,17 +325,17 @@ Response V8ProfilerAgentImpl::startPreciseCoverage( ...@@ -324,17 +325,17 @@ Response V8ProfilerAgentImpl::startPreciseCoverage(
? (detailedValue ? Mode::kBlockCount : Mode::kPreciseCount) ? (detailedValue ? Mode::kBlockCount : Mode::kPreciseCount)
: (detailedValue ? Mode::kBlockBinary : Mode::kPreciseBinary); : (detailedValue ? Mode::kBlockBinary : Mode::kPreciseBinary);
C::SelectMode(m_isolate, mode); C::SelectMode(m_isolate, mode);
return Response::OK(); return Response::Success();
} }
Response V8ProfilerAgentImpl::stopPreciseCoverage() { Response V8ProfilerAgentImpl::stopPreciseCoverage() {
if (!m_enabled) return Response::Error("Profiler is not enabled"); if (!m_enabled) return Response::ServerError("Profiler is not enabled");
m_state->setBoolean(ProfilerAgentState::preciseCoverageStarted, false); m_state->setBoolean(ProfilerAgentState::preciseCoverageStarted, false);
m_state->setBoolean(ProfilerAgentState::preciseCoverageCallCount, false); m_state->setBoolean(ProfilerAgentState::preciseCoverageCallCount, false);
m_state->setBoolean(ProfilerAgentState::preciseCoverageDetailed, false); m_state->setBoolean(ProfilerAgentState::preciseCoverageDetailed, false);
v8::debug::Coverage::SelectMode(m_isolate, v8::debug::Coverage::SelectMode(m_isolate,
v8::debug::CoverageMode::kBestEffort); v8::debug::CoverageMode::kBestEffort);
return Response::OK(); return Response::Success();
} }
namespace { namespace {
...@@ -402,7 +403,7 @@ Response coverageToProtocol( ...@@ -402,7 +403,7 @@ Response coverageToProtocol(
.build()); .build());
} }
*out_result = std::move(result); *out_result = std::move(result);
return Response::OK(); return Response::Success();
} }
} // anonymous namespace } // anonymous namespace
...@@ -412,7 +413,7 @@ Response V8ProfilerAgentImpl::takePreciseCoverage( ...@@ -412,7 +413,7 @@ Response V8ProfilerAgentImpl::takePreciseCoverage(
double* out_timestamp) { double* out_timestamp) {
if (!m_state->booleanProperty(ProfilerAgentState::preciseCoverageStarted, if (!m_state->booleanProperty(ProfilerAgentState::preciseCoverageStarted,
false)) { false)) {
return Response::Error("Precise coverage has not been started."); return Response::ServerError("Precise coverage has not been started.");
} }
v8::HandleScope handle_scope(m_isolate); v8::HandleScope handle_scope(m_isolate);
v8::debug::Coverage coverage = v8::debug::Coverage::CollectPrecise(m_isolate); v8::debug::Coverage coverage = v8::debug::Coverage::CollectPrecise(m_isolate);
...@@ -500,14 +501,14 @@ Response V8ProfilerAgentImpl::startTypeProfile() { ...@@ -500,14 +501,14 @@ Response V8ProfilerAgentImpl::startTypeProfile() {
m_state->setBoolean(ProfilerAgentState::typeProfileStarted, true); m_state->setBoolean(ProfilerAgentState::typeProfileStarted, true);
v8::debug::TypeProfile::SelectMode(m_isolate, v8::debug::TypeProfile::SelectMode(m_isolate,
v8::debug::TypeProfileMode::kCollect); v8::debug::TypeProfileMode::kCollect);
return Response::OK(); return Response::Success();
} }
Response V8ProfilerAgentImpl::stopTypeProfile() { Response V8ProfilerAgentImpl::stopTypeProfile() {
m_state->setBoolean(ProfilerAgentState::typeProfileStarted, false); m_state->setBoolean(ProfilerAgentState::typeProfileStarted, false);
v8::debug::TypeProfile::SelectMode(m_isolate, v8::debug::TypeProfile::SelectMode(m_isolate,
v8::debug::TypeProfileMode::kNone); v8::debug::TypeProfileMode::kNone);
return Response::OK(); return Response::Success();
} }
Response V8ProfilerAgentImpl::takeTypeProfile( Response V8ProfilerAgentImpl::takeTypeProfile(
...@@ -515,37 +516,38 @@ Response V8ProfilerAgentImpl::takeTypeProfile( ...@@ -515,37 +516,38 @@ Response V8ProfilerAgentImpl::takeTypeProfile(
out_result) { out_result) {
if (!m_state->booleanProperty(ProfilerAgentState::typeProfileStarted, if (!m_state->booleanProperty(ProfilerAgentState::typeProfileStarted,
false)) { false)) {
return Response::Error("Type profile has not been started."); return Response::ServerError("Type profile has not been started.");
} }
v8::HandleScope handle_scope(m_isolate); v8::HandleScope handle_scope(m_isolate);
v8::debug::TypeProfile type_profile = v8::debug::TypeProfile type_profile =
v8::debug::TypeProfile::Collect(m_isolate); v8::debug::TypeProfile::Collect(m_isolate);
*out_result = typeProfileToProtocol(m_session->inspector(), type_profile); *out_result = typeProfileToProtocol(m_session->inspector(), type_profile);
return Response::OK(); return Response::Success();
} }
Response V8ProfilerAgentImpl::enableRuntimeCallStats() { Response V8ProfilerAgentImpl::enableRuntimeCallStats() {
if (m_counters) if (m_counters)
return Response::Error("RuntimeCallStats collection already enabled."); return Response::ServerError(
"RuntimeCallStats collection already enabled.");
if (V8Inspector* inspector = v8::debug::GetInspector(m_isolate)) if (V8Inspector* inspector = v8::debug::GetInspector(m_isolate))
m_counters = inspector->enableCounters(); m_counters = inspector->enableCounters();
else else
return Response::Error("No inspector found."); return Response::ServerError("No inspector found.");
return Response::OK(); return Response::Success();
} }
Response V8ProfilerAgentImpl::disableRuntimeCallStats() { Response V8ProfilerAgentImpl::disableRuntimeCallStats() {
if (m_counters) m_counters.reset(); if (m_counters) m_counters.reset();
return Response::OK(); return Response::Success();
} }
Response V8ProfilerAgentImpl::getRuntimeCallStats( Response V8ProfilerAgentImpl::getRuntimeCallStats(
std::unique_ptr<protocol::Array<protocol::Profiler::CounterInfo>>* std::unique_ptr<protocol::Array<protocol::Profiler::CounterInfo>>*
out_result) { out_result) {
if (!m_counters) if (!m_counters)
return Response::Error("RuntimeCallStats collection is not enabled."); return Response::ServerError("RuntimeCallStats collection is not enabled.");
*out_result = *out_result =
std::make_unique<protocol::Array<protocol::Profiler::CounterInfo>>(); std::make_unique<protocol::Array<protocol::Profiler::CounterInfo>>();
...@@ -559,7 +561,7 @@ Response V8ProfilerAgentImpl::getRuntimeCallStats( ...@@ -559,7 +561,7 @@ Response V8ProfilerAgentImpl::getRuntimeCallStats(
.build()); .build());
} }
return Response::OK(); return Response::Success();
} }
String16 V8ProfilerAgentImpl::nextProfileId() { String16 V8ProfilerAgentImpl::nextProfileId() {
......
This diff is collapsed.
...@@ -21,7 +21,7 @@ Response V8SchemaAgentImpl::getDomains( ...@@ -21,7 +21,7 @@ Response V8SchemaAgentImpl::getDomains(
*result = *result =
std::make_unique<std::vector<std::unique_ptr<protocol::Schema::Domain>>>( std::make_unique<std::vector<std::unique_ptr<protocol::Schema::Domain>>>(
m_session->supportedDomainsImpl()); m_session->supportedDomainsImpl());
return Response::OK(); return Response::Success();
} }
} // namespace v8_inspector } // namespace v8_inspector
...@@ -42,17 +42,18 @@ V8InternalValueType v8InternalValueTypeFrom(v8::Local<v8::Context> context, ...@@ -42,17 +42,18 @@ V8InternalValueType v8InternalValueTypeFrom(v8::Local<v8::Context> context,
Response toProtocolValue(v8::Local<v8::Context> context, Response toProtocolValue(v8::Local<v8::Context> context,
v8::Local<v8::Value> value, int maxDepth, v8::Local<v8::Value> value, int maxDepth,
std::unique_ptr<protocol::Value>* result) { std::unique_ptr<protocol::Value>* result) {
if (!maxDepth) return Response::Error("Object reference chain is too long"); if (!maxDepth)
return Response::ServerError("Object reference chain is too long");
maxDepth--; maxDepth--;
if (value->IsNull() || value->IsUndefined()) { if (value->IsNull() || value->IsUndefined()) {
*result = protocol::Value::null(); *result = protocol::Value::null();
return Response::OK(); return Response::Success();
} }
if (value->IsBoolean()) { if (value->IsBoolean()) {
*result = *result =
protocol::FundamentalValue::create(value.As<v8::Boolean>()->Value()); protocol::FundamentalValue::create(value.As<v8::Boolean>()->Value());
return Response::OK(); return Response::Success();
} }
if (value->IsNumber()) { if (value->IsNumber()) {
double doubleValue = value.As<v8::Number>()->Value(); double doubleValue = value.As<v8::Number>()->Value();
...@@ -62,16 +63,16 @@ Response toProtocolValue(v8::Local<v8::Context> context, ...@@ -62,16 +63,16 @@ Response toProtocolValue(v8::Local<v8::Context> context,
int intValue = static_cast<int>(doubleValue); int intValue = static_cast<int>(doubleValue);
if (intValue == doubleValue) { if (intValue == doubleValue) {
*result = protocol::FundamentalValue::create(intValue); *result = protocol::FundamentalValue::create(intValue);
return Response::OK(); return Response::Success();
} }
} }
*result = protocol::FundamentalValue::create(doubleValue); *result = protocol::FundamentalValue::create(doubleValue);
return Response::OK(); return Response::Success();
} }
if (value->IsString()) { if (value->IsString()) {
*result = protocol::StringValue::create( *result = protocol::StringValue::create(
toProtocolString(context->GetIsolate(), value.As<v8::String>())); toProtocolString(context->GetIsolate(), value.As<v8::String>()));
return Response::OK(); return Response::Success();
} }
if (value->IsArray()) { if (value->IsArray()) {
v8::Local<v8::Array> array = value.As<v8::Array>(); v8::Local<v8::Array> array = value.As<v8::Array>();
...@@ -84,11 +85,11 @@ Response toProtocolValue(v8::Local<v8::Context> context, ...@@ -84,11 +85,11 @@ Response toProtocolValue(v8::Local<v8::Context> context,
return Response::InternalError(); return Response::InternalError();
std::unique_ptr<protocol::Value> element; std::unique_ptr<protocol::Value> element;
Response response = toProtocolValue(context, value, maxDepth, &element); Response response = toProtocolValue(context, value, maxDepth, &element);
if (!response.isSuccess()) return response; if (!response.IsSuccess()) return response;
inspectorArray->pushValue(std::move(element)); inspectorArray->pushValue(std::move(element));
} }
*result = std::move(inspectorArray); *result = std::move(inspectorArray);
return Response::OK(); return Response::Success();
} }
if (value->IsObject()) { if (value->IsObject()) {
std::unique_ptr<protocol::DictionaryValue> jsonObject = std::unique_ptr<protocol::DictionaryValue> jsonObject =
...@@ -119,21 +120,21 @@ Response toProtocolValue(v8::Local<v8::Context> context, ...@@ -119,21 +120,21 @@ Response toProtocolValue(v8::Local<v8::Context> context,
std::unique_ptr<protocol::Value> propertyValue; std::unique_ptr<protocol::Value> propertyValue;
Response response = Response response =
toProtocolValue(context, property, maxDepth, &propertyValue); toProtocolValue(context, property, maxDepth, &propertyValue);
if (!response.isSuccess()) return response; if (!response.IsSuccess()) return response;
jsonObject->setValue( jsonObject->setValue(
toProtocolString(context->GetIsolate(), propertyName), toProtocolString(context->GetIsolate(), propertyName),
std::move(propertyValue)); std::move(propertyValue));
} }
*result = std::move(jsonObject); *result = std::move(jsonObject);
return Response::OK(); return Response::Success();
} }
return Response::Error("Object couldn't be returned by value"); return Response::ServerError("Object couldn't be returned by value");
} }
Response toProtocolValue(v8::Local<v8::Context> context, Response toProtocolValue(v8::Local<v8::Context> context,
v8::Local<v8::Value> value, v8::Local<v8::Value> value,
std::unique_ptr<protocol::Value>* result) { std::unique_ptr<protocol::Value>* result) {
if (value->IsUndefined()) return Response::OK(); if (value->IsUndefined()) return Response::Success();
return toProtocolValue(context, value, 1000, result); return toProtocolValue(context, value, 1000, result);
} }
...@@ -361,7 +362,7 @@ class PrimitiveValueMirror final : public ValueMirror { ...@@ -361,7 +362,7 @@ class PrimitiveValueMirror final : public ValueMirror {
.build(); .build();
if (m_value->IsNull()) if (m_value->IsNull())
(*result)->setSubtype(RemoteObject::SubtypeEnum::Null); (*result)->setSubtype(RemoteObject::SubtypeEnum::Null);
return Response::OK(); return Response::Success();
} }
void buildEntryPreview( void buildEntryPreview(
...@@ -416,7 +417,7 @@ class NumberMirror final : public ValueMirror { ...@@ -416,7 +417,7 @@ class NumberMirror final : public ValueMirror {
} else { } else {
(*result)->setValue(protocol::FundamentalValue::create(m_value->Value())); (*result)->setValue(protocol::FundamentalValue::create(m_value->Value()));
} }
return Response::OK(); return Response::Success();
} }
void buildPropertyPreview( void buildPropertyPreview(
v8::Local<v8::Context> context, const String16& name, v8::Local<v8::Context> context, const String16& name,
...@@ -470,7 +471,7 @@ class BigIntMirror final : public ValueMirror { ...@@ -470,7 +471,7 @@ class BigIntMirror final : public ValueMirror {
.setUnserializableValue(description) .setUnserializableValue(description)
.setDescription(description) .setDescription(description)
.build(); .build();
return Response::OK(); return Response::Success();
} }
void buildPropertyPreview(v8::Local<v8::Context> context, void buildPropertyPreview(v8::Local<v8::Context> context,
...@@ -513,13 +514,13 @@ class SymbolMirror final : public ValueMirror { ...@@ -513,13 +514,13 @@ class SymbolMirror final : public ValueMirror {
v8::Local<v8::Context> context, WrapMode mode, v8::Local<v8::Context> context, WrapMode mode,
std::unique_ptr<RemoteObject>* result) const override { std::unique_ptr<RemoteObject>* result) const override {
if (mode == WrapMode::kForceValue) { if (mode == WrapMode::kForceValue) {
return Response::Error("Object couldn't be returned by value"); return Response::ServerError("Object couldn't be returned by value");
} }
*result = RemoteObject::create() *result = RemoteObject::create()
.setType(RemoteObject::TypeEnum::Symbol) .setType(RemoteObject::TypeEnum::Symbol)
.setDescription(descriptionForSymbol(context, m_symbol)) .setDescription(descriptionForSymbol(context, m_symbol))
.build(); .build();
return Response::OK(); return Response::Success();
} }
void buildPropertyPreview(v8::Local<v8::Context> context, void buildPropertyPreview(v8::Local<v8::Context> context,
...@@ -576,7 +577,7 @@ class LocationMirror final : public ValueMirror { ...@@ -576,7 +577,7 @@ class LocationMirror final : public ValueMirror {
.setDescription("Object") .setDescription("Object")
.setValue(std::move(location)) .setValue(std::move(location))
.build(); .build();
return Response::OK(); return Response::Success();
} }
v8::Local<v8::Value> v8Value() const override { return m_value; } v8::Local<v8::Value> v8Value() const override { return m_value; }
...@@ -620,7 +621,7 @@ class FunctionMirror final : public ValueMirror { ...@@ -620,7 +621,7 @@ class FunctionMirror final : public ValueMirror {
if (mode == WrapMode::kForceValue) { if (mode == WrapMode::kForceValue) {
std::unique_ptr<protocol::Value> protocolValue; std::unique_ptr<protocol::Value> protocolValue;
Response response = toProtocolValue(context, m_value, &protocolValue); Response response = toProtocolValue(context, m_value, &protocolValue);
if (!response.isSuccess()) return response; if (!response.IsSuccess()) return response;
*result = RemoteObject::create() *result = RemoteObject::create()
.setType(RemoteObject::TypeEnum::Function) .setType(RemoteObject::TypeEnum::Function)
.setValue(std::move(protocolValue)) .setValue(std::move(protocolValue))
...@@ -633,7 +634,7 @@ class FunctionMirror final : public ValueMirror { ...@@ -633,7 +634,7 @@ class FunctionMirror final : public ValueMirror {
.setDescription(descriptionForFunction(context, m_value)) .setDescription(descriptionForFunction(context, m_value))
.build(); .build();
} }
return Response::OK(); return Response::Success();
} }
void buildPropertyPreview( void buildPropertyPreview(
...@@ -881,7 +882,7 @@ class ObjectMirror final : public ValueMirror { ...@@ -881,7 +882,7 @@ class ObjectMirror final : public ValueMirror {
if (mode == WrapMode::kForceValue) { if (mode == WrapMode::kForceValue) {
std::unique_ptr<protocol::Value> protocolValue; std::unique_ptr<protocol::Value> protocolValue;
Response response = toProtocolValue(context, m_value, &protocolValue); Response response = toProtocolValue(context, m_value, &protocolValue);
if (!response.isSuccess()) return response; if (!response.IsSuccess()) return response;
*result = RemoteObject::create() *result = RemoteObject::create()
.setType(RemoteObject::TypeEnum::Object) .setType(RemoteObject::TypeEnum::Object)
.setValue(std::move(protocolValue)) .setValue(std::move(protocolValue))
...@@ -904,7 +905,7 @@ class ObjectMirror final : public ValueMirror { ...@@ -904,7 +905,7 @@ class ObjectMirror final : public ValueMirror {
(*result)->setPreview(std::move(previewValue)); (*result)->setPreview(std::move(previewValue));
} }
} }
return Response::OK(); return Response::Success();
} }
void buildObjectPreview( void buildObjectPreview(
......
...@@ -14,9 +14,12 @@ v8_source_set("crdtp") { ...@@ -14,9 +14,12 @@ v8_source_set("crdtp") {
sources = [ sources = [
"crdtp/cbor.cc", "crdtp/cbor.cc",
"crdtp/cbor.h", "crdtp/cbor.h",
"crdtp/dispatch.cc",
"crdtp/dispatch.h",
"crdtp/error_support.cc", "crdtp/error_support.cc",
"crdtp/error_support.h", "crdtp/error_support.h",
"crdtp/export.h", "crdtp/export.h",
"crdtp/find_by_first.h",
"crdtp/glue.h", "crdtp/glue.h",
"crdtp/json.cc", "crdtp/json.cc",
"crdtp/json.h", "crdtp/json.h",
...@@ -24,6 +27,7 @@ v8_source_set("crdtp") { ...@@ -24,6 +27,7 @@ v8_source_set("crdtp") {
"crdtp/serializable.cc", "crdtp/serializable.cc",
"crdtp/serializable.h", "crdtp/serializable.h",
"crdtp/serializer_traits.h", "crdtp/serializer_traits.h",
"crdtp/span.cc",
"crdtp/span.h", "crdtp/span.h",
"crdtp/status.cc", "crdtp/status.cc",
"crdtp/status.h", "crdtp/status.h",
...@@ -47,7 +51,9 @@ v8_source_set("crdtp_platform") { ...@@ -47,7 +51,9 @@ v8_source_set("crdtp_platform") {
v8_source_set("crdtp_test") { v8_source_set("crdtp_test") {
sources = [ sources = [
"crdtp/cbor_test.cc", "crdtp/cbor_test.cc",
"crdtp/dispatch_test.cc",
"crdtp/error_support_test.cc", "crdtp/error_support_test.cc",
"crdtp/find_by_first_test.cc",
"crdtp/glue_test.cc", "crdtp/glue_test.cc",
"crdtp/json_test.cc", "crdtp/json_test.cc",
"crdtp/serializable_test.cc", "crdtp/serializable_test.cc",
......
...@@ -2,7 +2,7 @@ Name: inspector protocol ...@@ -2,7 +2,7 @@ Name: inspector protocol
Short Name: inspector_protocol Short Name: inspector_protocol
URL: https://chromium.googlesource.com/deps/inspector_protocol/ URL: https://chromium.googlesource.com/deps/inspector_protocol/
Version: 0 Version: 0
Revision: 81ef742ba3587767fc08652d299df9e9b7051407 Revision: c69cdc36200992d21a17bf4e5c2f3a95b8860ddf
License: BSD License: BSD
License File: LICENSE License File: LICENSE
Security Critical: no Security Critical: no
......
...@@ -658,19 +658,16 @@ def main(): ...@@ -658,19 +658,16 @@ def main():
"Values_h.template", "Values_h.template",
"Object_h.template", "Object_h.template",
"ValueConversions_h.template", "ValueConversions_h.template",
"DispatcherBase_h.template",
] ]
protocol_cpp_templates = [ protocol_cpp_templates = [
"Protocol_cpp.template", "Protocol_cpp.template",
"Values_cpp.template", "Values_cpp.template",
"Object_cpp.template", "Object_cpp.template",
"DispatcherBase_cpp.template",
] ]
forward_h_templates = [ forward_h_templates = [
"Forward_h.template", "Forward_h.template",
"FrontendChannel_h.template",
] ]
base_string_adapter_h_templates = [ base_string_adapter_h_templates = [
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <cstdint> #include <cstdint>
#include <string> #include <string>
#include <vector>
#include "export.h" #include "export.h"
#include "span.h" #include "span.h"
......
// Copyright 2020 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.
#ifndef V8_CRDTP_FIND_BY_FIRST_H_
#define V8_CRDTP_FIND_BY_FIRST_H_
#include <algorithm>
#include <cstdint>
#include <memory>
#include <vector>
#include "export.h"
#include "span.h"
namespace v8_crdtp {
// =============================================================================
// FindByFirst - Retrieval from a sorted vector that's keyed by span<uint8_t>.
// =============================================================================
// Given a vector of pairs sorted by the first element of each pair, find
// the corresponding value given a key to be compared to the first element.
// Together with std::inplace_merge and pre-sorting or std::sort, this can
// be used to implement a minimalistic equivalent of Chromium's flat_map.
// In this variant, the template parameter |T| is a value type and a
// |default_value| is provided.
template <typename T>
T FindByFirst(const std::vector<std::pair<span<uint8_t>, T>>& sorted_by_first,
span<uint8_t> key,
T default_value) {
auto it = std::lower_bound(
sorted_by_first.begin(), sorted_by_first.end(), key,
[](const std::pair<span<uint8_t>, T>& left, span<uint8_t> right) {
return SpanLessThan(left.first, right);
});
return (it != sorted_by_first.end() && SpanEquals(it->first, key))
? it->second
: default_value;
}
// In this variant, the template parameter |T| is a class or struct that's
// instantiated in std::unique_ptr, and we return either a T* or a nullptr.
template <typename T>
T* FindByFirst(const std::vector<std::pair<span<uint8_t>, std::unique_ptr<T>>>&
sorted_by_first,
span<uint8_t> key) {
auto it = std::lower_bound(
sorted_by_first.begin(), sorted_by_first.end(), key,
[](const std::pair<span<uint8_t>, std::unique_ptr<T>>& left,
span<uint8_t> right) { return SpanLessThan(left.first, right); });
return (it != sorted_by_first.end() && SpanEquals(it->first, key))
? it->second.get()
: nullptr;
}
} // namespace v8_crdtp
#endif // V8_CRDTP_FIND_BY_FIRST_H_
// Copyright 2020 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 <string>
#include "find_by_first.h"
#include "test_platform.h"
namespace v8_crdtp {
// =============================================================================
// FindByFirst - Efficient retrieval from a sorted vector.
// =============================================================================
TEST(FindByFirst, SpanBySpan) {
std::vector<std::pair<span<uint8_t>, span<uint8_t>>> sorted_span_by_span = {
{SpanFrom("foo1"), SpanFrom("bar1")},
{SpanFrom("foo2"), SpanFrom("bar2")},
{SpanFrom("foo3"), SpanFrom("bar3")},
};
{
auto result = FindByFirst(sorted_span_by_span, SpanFrom("foo1"),
SpanFrom("not_found"));
EXPECT_EQ("bar1", std::string(result.begin(), result.end()));
}
{
auto result = FindByFirst(sorted_span_by_span, SpanFrom("foo3"),
SpanFrom("not_found"));
EXPECT_EQ("bar3", std::string(result.begin(), result.end()));
}
{
auto result = FindByFirst(sorted_span_by_span, SpanFrom("baz"),
SpanFrom("not_found"));
EXPECT_EQ("not_found", std::string(result.begin(), result.end()));
}
}
namespace {
class TestObject {
public:
explicit TestObject(const std::string& message) : message_(message) {}
const std::string& message() const { return message_; }
private:
std::string message_;
};
} // namespace
TEST(FindByFirst, ObjectBySpan) {
std::vector<std::pair<span<uint8_t>, std::unique_ptr<TestObject>>>
sorted_object_by_span;
sorted_object_by_span.push_back(
std::make_pair(SpanFrom("foo1"), std::make_unique<TestObject>("bar1")));
sorted_object_by_span.push_back(
std::make_pair(SpanFrom("foo2"), std::make_unique<TestObject>("bar2")));
sorted_object_by_span.push_back(
std::make_pair(SpanFrom("foo3"), std::make_unique<TestObject>("bar3")));
{
TestObject* result =
FindByFirst<TestObject>(sorted_object_by_span, SpanFrom("foo1"));
ASSERT_TRUE(result);
ASSERT_EQ("bar1", result->message());
}
{
TestObject* result =
FindByFirst<TestObject>(sorted_object_by_span, SpanFrom("foo3"));
ASSERT_TRUE(result);
ASSERT_EQ("bar3", result->message());
}
{
TestObject* result =
FindByFirst<TestObject>(sorted_object_by_span, SpanFrom("baz"));
ASSERT_FALSE(result);
}
}
} // namespace v8_crdtp
// Copyright 2020 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.
#ifndef V8_CRDTP_FRONTEND_CHANNEL_H_
#define V8_CRDTP_FRONTEND_CHANNEL_H_
#include <cstdint>
#include <memory>
#include "export.h"
#include "serializable.h"
#include "span.h"
namespace v8_crdtp {
// =============================================================================
// FrontendChannel - For sending notifications and responses to protocol clients
// =============================================================================
class FrontendChannel {
public:
virtual ~FrontendChannel() = default;
// Sends protocol responses and notifications. The |call_id| parameter is
// seemingly redundant because it's also included in the message, but
// responses may be sent from an untrusted source to a trusted process (e.g.
// from Chromium's renderer (blink) to the browser process), which needs
// to be able to match the response to an earlier request without parsing the
// messsage.
virtual void SendProtocolResponse(int call_id,
std::unique_ptr<Serializable> message) = 0;
virtual void SendProtocolNotification(
std::unique_ptr<Serializable> message) = 0;
// FallThrough indicates that |message| should be handled in another layer.
// Usually this means the layer responding to the message didn't handle it,
// but in some cases messages are handled by multiple layers (e.g. both
// the embedder and the content layer in Chromium).
virtual void FallThrough(int call_id,
span<uint8_t> method,
span<uint8_t> message) = 0;
// Session implementations may queue notifications for performance or
// other considerations; this is a hook for domain handlers to manually flush.
virtual void FlushProtocolNotifications() = 0;
};
} // namespace v8_crdtp
#endif // V8_CRDTP_FRONTEND_CHANNEL_H_
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define V8_CRDTP_JSON_H_ #define V8_CRDTP_JSON_H_
#include <memory> #include <memory>
#include <vector>
#include "export.h" #include "export.h"
#include "parser_handler.h" #include "parser_handler.h"
......
...@@ -14,4 +14,23 @@ std::vector<uint8_t> Serializable::Serialize() const { ...@@ -14,4 +14,23 @@ std::vector<uint8_t> Serializable::Serialize() const {
AppendSerialized(&out); AppendSerialized(&out);
return out; return out;
} }
namespace {
class PreSerialized : public Serializable {
public:
explicit PreSerialized(std::vector<uint8_t> bytes) : bytes_(bytes) {}
void AppendSerialized(std::vector<uint8_t>* out) const override {
out->insert(out->end(), bytes_.begin(), bytes_.end());
}
private:
std::vector<uint8_t> bytes_;
};
} // namespace
// static
std::unique_ptr<Serializable> Serializable::From(std::vector<uint8_t> bytes) {
return std::make_unique<PreSerialized>(std::move(bytes));
}
} // namespace v8_crdtp } // namespace v8_crdtp
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define V8_CRDTP_SERIALIZABLE_H_ #define V8_CRDTP_SERIALIZABLE_H_
#include <cstdint> #include <cstdint>
#include <memory>
#include <vector> #include <vector>
#include "export.h" #include "export.h"
...@@ -13,7 +14,6 @@ namespace v8_crdtp { ...@@ -13,7 +14,6 @@ namespace v8_crdtp {
// ============================================================================= // =============================================================================
// Serializable - An object to be emitted as a sequence of bytes. // Serializable - An object to be emitted as a sequence of bytes.
// ============================================================================= // =============================================================================
class Serializable { class Serializable {
public: public:
// Convenience: Invokes |AppendSerialized| on an empty vector. // Convenience: Invokes |AppendSerialized| on an empty vector.
...@@ -22,6 +22,10 @@ class Serializable { ...@@ -22,6 +22,10 @@ class Serializable {
virtual void AppendSerialized(std::vector<uint8_t>* out) const = 0; virtual void AppendSerialized(std::vector<uint8_t>* out) const = 0;
virtual ~Serializable() = default; virtual ~Serializable() = default;
// Wraps a vector of |bytes| into a Serializable for situations in which we
// eagerly serialize a structure.
static std::unique_ptr<Serializable> From(std::vector<uint8_t> bytes);
}; };
} // namespace v8_crdtp } // namespace v8_crdtp
......
// Copyright 2020 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 "span.h"
#include <algorithm>
namespace v8_crdtp {
bool SpanLessThan(span<uint8_t> x, span<uint8_t> y) noexcept {
auto min_size = std::min(x.size(), y.size());
const int r = min_size == 0 ? 0 : memcmp(x.data(), y.data(), min_size);
return (r < 0) || (r == 0 && x.size() < y.size());
}
bool SpanEquals(span<uint8_t> x, span<uint8_t> y) noexcept {
auto len = x.size();
if (len != y.size())
return false;
return x.data() == y.data() || len == 0 ||
std::memcmp(x.data(), y.data(), len) == 0;
}
} // namespace v8_crdtp
...@@ -5,11 +5,11 @@ ...@@ -5,11 +5,11 @@
#ifndef V8_CRDTP_SPAN_H_ #ifndef V8_CRDTP_SPAN_H_
#define V8_CRDTP_SPAN_H_ #define V8_CRDTP_SPAN_H_
#include <algorithm>
#include <cstdint> #include <cstdint>
#include <cstring> #include <cstring>
#include <string> #include <string>
#include <vector>
#include "export.h"
namespace v8_crdtp { namespace v8_crdtp {
// ============================================================================= // =============================================================================
...@@ -76,19 +76,15 @@ inline span<typename C::value_type> SpanFrom(const C& v) { ...@@ -76,19 +76,15 @@ inline span<typename C::value_type> SpanFrom(const C& v) {
// Less than / equality comparison functions for sorting / searching for byte // Less than / equality comparison functions for sorting / searching for byte
// spans. These are similar to absl::string_view's < and == operators. // spans. These are similar to absl::string_view's < and == operators.
constexpr inline bool SpanLessThan(span<uint8_t> x, span<uint8_t> y) noexcept { bool SpanLessThan(span<uint8_t> x, span<uint8_t> y) noexcept;
auto min_size = std::min(x.size(), y.size());
const int r = min_size == 0 ? 0 : memcmp(x.data(), y.data(), min_size);
return (r < 0) || (r == 0 && x.size() < y.size());
}
constexpr inline bool SpanEquals(span<uint8_t> x, span<uint8_t> y) noexcept { bool SpanEquals(span<uint8_t> x, span<uint8_t> y) noexcept;
auto len = x.size();
if (len != y.size()) struct SpanLt {
return false; bool operator()(span<uint8_t> l, span<uint8_t> r) const {
return x.data() == y.data() || len == 0 || return SpanLessThan(l, r);
std::memcmp(x.data(), y.data(), len) == 0; }
} };
} // namespace v8_crdtp } // namespace v8_crdtp
#endif // V8_CRDTP_SPAN_H_ #endif // V8_CRDTP_SPAN_H_
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
#include <cstdlib> #include <cstdlib>
#include <string> #include <string>
#include <unordered_map>
#include "span.h" #include "span.h"
#include "test_platform.h" #include "test_platform.h"
...@@ -13,7 +12,6 @@ namespace v8_crdtp { ...@@ -13,7 +12,6 @@ namespace v8_crdtp {
// ============================================================================= // =============================================================================
// span - sequence of bytes // span - sequence of bytes
// ============================================================================= // =============================================================================
template <typename T> template <typename T>
class SpanTest : public ::testing::Test {}; class SpanTest : public ::testing::Test {};
...@@ -108,41 +106,4 @@ TEST(SpanComparisons, ByteWiseLexicographicalOrder) { ...@@ -108,41 +106,4 @@ TEST(SpanComparisons, ByteWiseLexicographicalOrder) {
EXPECT_FALSE(SpanLessThan(SpanFrom(msg), SpanFrom(lesser_msg))); EXPECT_FALSE(SpanLessThan(SpanFrom(msg), SpanFrom(lesser_msg)));
EXPECT_FALSE(SpanEquals(SpanFrom(msg), SpanFrom(lesser_msg))); EXPECT_FALSE(SpanEquals(SpanFrom(msg), SpanFrom(lesser_msg)));
} }
// TODO(johannes): The following shows how the span can be used in an
// std::unordered_map as a key. Once we have a production usage, we'll move
// SpanHash, SpanEq, SpanHasher into the header.
// A simple hash code, inspired by http://stackoverflow.com/q/1646807.
constexpr inline size_t SpanHash(span<uint8_t> s) noexcept {
size_t hash = 17;
for (uint8_t c : s)
hash = 31 * hash + c;
return hash;
}
// Structs for making std::unordered_map with std::span<uint8_t> keys.
struct SpanEq {
constexpr inline bool operator()(span<uint8_t> l, span<uint8_t> r) const {
return SpanEquals(l, r);
}
};
struct SpanHasher {
constexpr inline size_t operator()(span<uint8_t> s) const {
return SpanHash(s);
}
};
TEST(SpanHasherAndSpanEq, SpanAsKeyInUnorderedMap) {
// A very simple smoke test for unordered_map, storing three key/value pairs.
std::unordered_map<span<uint8_t>, int32_t, SpanHasher, SpanEq> a_map;
a_map[SpanFrom("foo")] = 1;
a_map[SpanFrom("bar")] = 2;
a_map[SpanFrom("baz")] = 3;
EXPECT_EQ(3u, a_map.size());
EXPECT_EQ(1, a_map[SpanFrom("foo")]);
EXPECT_EQ(2, a_map[SpanFrom("bar")]);
EXPECT_EQ(3, a_map[SpanFrom("baz")]);
}
} // namespace v8_crdtp } // namespace v8_crdtp
...@@ -9,100 +9,118 @@ namespace v8_crdtp { ...@@ -9,100 +9,118 @@ namespace v8_crdtp {
// Status and Error codes // Status and Error codes
// ============================================================================= // =============================================================================
std::string Status::ToASCIIString() const { std::string Status::Message() const {
switch (error) { switch (error) {
case Error::OK: case Error::OK:
return "OK"; return "OK";
case Error::JSON_PARSER_UNPROCESSED_INPUT_REMAINS: case Error::JSON_PARSER_UNPROCESSED_INPUT_REMAINS:
return ToASCIIString("JSON: unprocessed input remains"); return "JSON: unprocessed input remains";
case Error::JSON_PARSER_STACK_LIMIT_EXCEEDED: case Error::JSON_PARSER_STACK_LIMIT_EXCEEDED:
return ToASCIIString("JSON: stack limit exceeded"); return "JSON: stack limit exceeded";
case Error::JSON_PARSER_NO_INPUT: case Error::JSON_PARSER_NO_INPUT:
return ToASCIIString("JSON: no input"); return "JSON: no input";
case Error::JSON_PARSER_INVALID_TOKEN: case Error::JSON_PARSER_INVALID_TOKEN:
return ToASCIIString("JSON: invalid token"); return "JSON: invalid token";
case Error::JSON_PARSER_INVALID_NUMBER: case Error::JSON_PARSER_INVALID_NUMBER:
return ToASCIIString("JSON: invalid number"); return "JSON: invalid number";
case Error::JSON_PARSER_INVALID_STRING: case Error::JSON_PARSER_INVALID_STRING:
return ToASCIIString("JSON: invalid string"); return "JSON: invalid string";
case Error::JSON_PARSER_UNEXPECTED_ARRAY_END: case Error::JSON_PARSER_UNEXPECTED_ARRAY_END:
return ToASCIIString("JSON: unexpected array end"); return "JSON: unexpected array end";
case Error::JSON_PARSER_COMMA_OR_ARRAY_END_EXPECTED: case Error::JSON_PARSER_COMMA_OR_ARRAY_END_EXPECTED:
return ToASCIIString("JSON: comma or array end expected"); return "JSON: comma or array end expected";
case Error::JSON_PARSER_STRING_LITERAL_EXPECTED: case Error::JSON_PARSER_STRING_LITERAL_EXPECTED:
return ToASCIIString("JSON: string literal expected"); return "JSON: string literal expected";
case Error::JSON_PARSER_COLON_EXPECTED: case Error::JSON_PARSER_COLON_EXPECTED:
return ToASCIIString("JSON: colon expected"); return "JSON: colon expected";
case Error::JSON_PARSER_UNEXPECTED_MAP_END: case Error::JSON_PARSER_UNEXPECTED_MAP_END:
return ToASCIIString("JSON: unexpected map end"); return "JSON: unexpected map end";
case Error::JSON_PARSER_COMMA_OR_MAP_END_EXPECTED: case Error::JSON_PARSER_COMMA_OR_MAP_END_EXPECTED:
return ToASCIIString("JSON: comma or map end expected"); return "JSON: comma or map end expected";
case Error::JSON_PARSER_VALUE_EXPECTED: case Error::JSON_PARSER_VALUE_EXPECTED:
return ToASCIIString("JSON: value expected"); return "JSON: value expected";
case Error::CBOR_INVALID_INT32: case Error::CBOR_INVALID_INT32:
return ToASCIIString("CBOR: invalid int32"); return "CBOR: invalid int32";
case Error::CBOR_INVALID_DOUBLE: case Error::CBOR_INVALID_DOUBLE:
return ToASCIIString("CBOR: invalid double"); return "CBOR: invalid double";
case Error::CBOR_INVALID_ENVELOPE: case Error::CBOR_INVALID_ENVELOPE:
return ToASCIIString("CBOR: invalid envelope"); return "CBOR: invalid envelope";
case Error::CBOR_ENVELOPE_CONTENTS_LENGTH_MISMATCH: case Error::CBOR_ENVELOPE_CONTENTS_LENGTH_MISMATCH:
return ToASCIIString("CBOR: envelope contents length mismatch"); return "CBOR: envelope contents length mismatch";
case Error::CBOR_MAP_OR_ARRAY_EXPECTED_IN_ENVELOPE: case Error::CBOR_MAP_OR_ARRAY_EXPECTED_IN_ENVELOPE:
return ToASCIIString("CBOR: map or array expected in envelope"); return "CBOR: map or array expected in envelope";
case Error::CBOR_INVALID_STRING8: case Error::CBOR_INVALID_STRING8:
return ToASCIIString("CBOR: invalid string8"); return "CBOR: invalid string8";
case Error::CBOR_INVALID_STRING16: case Error::CBOR_INVALID_STRING16:
return ToASCIIString("CBOR: invalid string16"); return "CBOR: invalid string16";
case Error::CBOR_INVALID_BINARY: case Error::CBOR_INVALID_BINARY:
return ToASCIIString("CBOR: invalid binary"); return "CBOR: invalid binary";
case Error::CBOR_UNSUPPORTED_VALUE: case Error::CBOR_UNSUPPORTED_VALUE:
return ToASCIIString("CBOR: unsupported value"); return "CBOR: unsupported value";
case Error::CBOR_NO_INPUT: case Error::CBOR_NO_INPUT:
return ToASCIIString("CBOR: no input"); return "CBOR: no input";
case Error::CBOR_INVALID_START_BYTE: case Error::CBOR_INVALID_START_BYTE:
return ToASCIIString("CBOR: invalid start byte"); return "CBOR: invalid start byte";
case Error::CBOR_UNEXPECTED_EOF_EXPECTED_VALUE: case Error::CBOR_UNEXPECTED_EOF_EXPECTED_VALUE:
return ToASCIIString("CBOR: unexpected eof expected value"); return "CBOR: unexpected eof expected value";
case Error::CBOR_UNEXPECTED_EOF_IN_ARRAY: case Error::CBOR_UNEXPECTED_EOF_IN_ARRAY:
return ToASCIIString("CBOR: unexpected eof in array"); return "CBOR: unexpected eof in array";
case Error::CBOR_UNEXPECTED_EOF_IN_MAP: case Error::CBOR_UNEXPECTED_EOF_IN_MAP:
return ToASCIIString("CBOR: unexpected eof in map"); return "CBOR: unexpected eof in map";
case Error::CBOR_INVALID_MAP_KEY: case Error::CBOR_INVALID_MAP_KEY:
return ToASCIIString("CBOR: invalid map key"); return "CBOR: invalid map key";
case Error::CBOR_DUPLICATE_MAP_KEY:
return "CBOR: duplicate map key";
case Error::CBOR_STACK_LIMIT_EXCEEDED: case Error::CBOR_STACK_LIMIT_EXCEEDED:
return ToASCIIString("CBOR: stack limit exceeded"); return "CBOR: stack limit exceeded";
case Error::CBOR_TRAILING_JUNK: case Error::CBOR_TRAILING_JUNK:
return ToASCIIString("CBOR: trailing junk"); return "CBOR: trailing junk";
case Error::CBOR_MAP_START_EXPECTED: case Error::CBOR_MAP_START_EXPECTED:
return ToASCIIString("CBOR: map start expected"); return "CBOR: map start expected";
case Error::CBOR_MAP_STOP_EXPECTED: case Error::CBOR_MAP_STOP_EXPECTED:
return ToASCIIString("CBOR: map stop expected"); return "CBOR: map stop expected";
case Error::CBOR_ARRAY_START_EXPECTED: case Error::CBOR_ARRAY_START_EXPECTED:
return ToASCIIString("CBOR: array start expected"); return "CBOR: array start expected";
case Error::CBOR_ENVELOPE_SIZE_LIMIT_EXCEEDED: case Error::CBOR_ENVELOPE_SIZE_LIMIT_EXCEEDED:
return ToASCIIString("CBOR: envelope size limit exceeded"); return "CBOR: envelope size limit exceeded";
case Error::MESSAGE_MUST_BE_AN_OBJECT:
return "Message must be an object";
case Error::MESSAGE_MUST_HAVE_INTEGER_ID_PROPERTY:
return "Message must have integer 'id' property";
case Error::MESSAGE_MUST_HAVE_STRING_METHOD_PROPERTY:
return "Message must have string 'method' property";
case Error::MESSAGE_MAY_HAVE_STRING_SESSION_ID_PROPERTY:
return "Message may have string 'sessionId' property";
case Error::MESSAGE_MAY_HAVE_OBJECT_PARAMS_PROPERTY:
return "Message may have object 'params' property";
case Error::MESSAGE_HAS_UNKNOWN_PROPERTY:
return "Message has property other than "
"'id', 'method', 'sessionId', 'params'";
case Error::BINDINGS_MANDATORY_FIELD_MISSING: case Error::BINDINGS_MANDATORY_FIELD_MISSING:
return ToASCIIString("BINDINGS: mandatory field missing"); return "BINDINGS: mandatory field missing";
case Error::BINDINGS_BOOL_VALUE_EXPECTED: case Error::BINDINGS_BOOL_VALUE_EXPECTED:
return ToASCIIString("BINDINGS: bool value expected"); return "BINDINGS: bool value expected";
case Error::BINDINGS_INT32_VALUE_EXPECTED: case Error::BINDINGS_INT32_VALUE_EXPECTED:
return ToASCIIString("BINDINGS: int32 value expected"); return "BINDINGS: int32 value expected";
case Error::BINDINGS_DOUBLE_VALUE_EXPECTED: case Error::BINDINGS_DOUBLE_VALUE_EXPECTED:
return ToASCIIString("BINDINGS: double value expected"); return "BINDINGS: double value expected";
case Error::BINDINGS_STRING_VALUE_EXPECTED: case Error::BINDINGS_STRING_VALUE_EXPECTED:
return ToASCIIString("BINDINGS: string value expected"); return "BINDINGS: string value expected";
case Error::BINDINGS_STRING8_VALUE_EXPECTED: case Error::BINDINGS_STRING8_VALUE_EXPECTED:
return ToASCIIString("BINDINGS: string8 value expected"); return "BINDINGS: string8 value expected";
case Error::BINDINGS_BINARY_VALUE_EXPECTED: case Error::BINDINGS_BINARY_VALUE_EXPECTED:
return ToASCIIString("BINDINGS: binary value expected"); return "BINDINGS: binary value expected";
} }
// Some compilers can't figure out that we can't get here. // Some compilers can't figure out that we can't get here.
return "INVALID ERROR CODE"; return "INVALID ERROR CODE";
} }
std::string Status::ToASCIIString(const char* msg) const { std::string Status::ToASCIIString() const {
return std::string(msg) + " at position " + std::to_string(pos); if (ok())
return "OK";
return Message() + " at position " + std::to_string(pos);
} }
} // namespace v8_crdtp } // namespace v8_crdtp
...@@ -18,7 +18,9 @@ namespace v8_crdtp { ...@@ -18,7 +18,9 @@ namespace v8_crdtp {
enum class Error { enum class Error {
OK = 0, OK = 0,
// JSON parsing errors - json_parser.{h,cc}.
// JSON parsing errors; checked when parsing / converting from JSON.
// See json.{h,cc}.
JSON_PARSER_UNPROCESSED_INPUT_REMAINS = 0x01, JSON_PARSER_UNPROCESSED_INPUT_REMAINS = 0x01,
JSON_PARSER_STACK_LIMIT_EXCEEDED = 0x02, JSON_PARSER_STACK_LIMIT_EXCEEDED = 0x02,
JSON_PARSER_NO_INPUT = 0x03, JSON_PARSER_NO_INPUT = 0x03,
...@@ -33,6 +35,7 @@ enum class Error { ...@@ -33,6 +35,7 @@ enum class Error {
JSON_PARSER_COMMA_OR_MAP_END_EXPECTED = 0x0c, JSON_PARSER_COMMA_OR_MAP_END_EXPECTED = 0x0c,
JSON_PARSER_VALUE_EXPECTED = 0x0d, JSON_PARSER_VALUE_EXPECTED = 0x0d,
// CBOR parsing errors; checked when parsing / converting from CBOR.
CBOR_INVALID_INT32 = 0x0e, CBOR_INVALID_INT32 = 0x0e,
CBOR_INVALID_DOUBLE = 0x0f, CBOR_INVALID_DOUBLE = 0x0f,
CBOR_INVALID_ENVELOPE = 0x10, CBOR_INVALID_ENVELOPE = 0x10,
...@@ -48,20 +51,31 @@ enum class Error { ...@@ -48,20 +51,31 @@ enum class Error {
CBOR_UNEXPECTED_EOF_IN_ARRAY = 0x1a, CBOR_UNEXPECTED_EOF_IN_ARRAY = 0x1a,
CBOR_UNEXPECTED_EOF_IN_MAP = 0x1b, CBOR_UNEXPECTED_EOF_IN_MAP = 0x1b,
CBOR_INVALID_MAP_KEY = 0x1c, CBOR_INVALID_MAP_KEY = 0x1c,
CBOR_STACK_LIMIT_EXCEEDED = 0x1d, CBOR_DUPLICATE_MAP_KEY = 0x1d,
CBOR_TRAILING_JUNK = 0x1e, CBOR_STACK_LIMIT_EXCEEDED = 0x1e,
CBOR_MAP_START_EXPECTED = 0x1f, CBOR_TRAILING_JUNK = 0x1f,
CBOR_MAP_STOP_EXPECTED = 0x20, CBOR_MAP_START_EXPECTED = 0x20,
CBOR_ARRAY_START_EXPECTED = 0x21, CBOR_MAP_STOP_EXPECTED = 0x21,
CBOR_ENVELOPE_SIZE_LIMIT_EXCEEDED = 0x22, CBOR_ARRAY_START_EXPECTED = 0x22,
CBOR_ENVELOPE_SIZE_LIMIT_EXCEEDED = 0x23,
BINDINGS_MANDATORY_FIELD_MISSING = 0x23,
BINDINGS_BOOL_VALUE_EXPECTED = 0x24, // Message errors are constraints we place on protocol messages coming
BINDINGS_INT32_VALUE_EXPECTED = 0x25, // from a protocol client; these are checked in crdtp::Dispatchable
BINDINGS_DOUBLE_VALUE_EXPECTED = 0x26, // (see dispatch.h) as it performs a shallow parse.
BINDINGS_STRING_VALUE_EXPECTED = 0x27, MESSAGE_MUST_BE_AN_OBJECT = 0x24,
BINDINGS_STRING8_VALUE_EXPECTED = 0x28, MESSAGE_MUST_HAVE_INTEGER_ID_PROPERTY = 0x25,
BINDINGS_BINARY_VALUE_EXPECTED = 0x29, MESSAGE_MUST_HAVE_STRING_METHOD_PROPERTY = 0x26,
MESSAGE_MAY_HAVE_STRING_SESSION_ID_PROPERTY = 0x27,
MESSAGE_MAY_HAVE_OBJECT_PARAMS_PROPERTY = 0x28,
MESSAGE_HAS_UNKNOWN_PROPERTY = 0x29,
BINDINGS_MANDATORY_FIELD_MISSING = 0x30,
BINDINGS_BOOL_VALUE_EXPECTED = 0x31,
BINDINGS_INT32_VALUE_EXPECTED = 0x32,
BINDINGS_DOUBLE_VALUE_EXPECTED = 0x33,
BINDINGS_STRING_VALUE_EXPECTED = 0x34,
BINDINGS_STRING8_VALUE_EXPECTED = 0x35,
BINDINGS_BINARY_VALUE_EXPECTED = 0x36,
}; };
// A status value with position that can be copied. The default status // A status value with position that can be copied. The default status
...@@ -76,12 +90,18 @@ struct Status { ...@@ -76,12 +90,18 @@ struct Status {
Status(Error error, size_t pos) : error(error), pos(pos) {} Status(Error error, size_t pos) : error(error), pos(pos) {}
Status() = default; Status() = default;
// Returns a 7 bit US-ASCII string, either "OK" or an error message bool IsMessageError() const {
// that includes the position. return error >= Error::MESSAGE_MUST_BE_AN_OBJECT &&
std::string ToASCIIString() const; error <= Error::MESSAGE_HAS_UNKNOWN_PROPERTY;
}
// Returns 7 bit US-ASCII string, either "OK" or an error message without
// position.
std::string Message() const;
private: // Returns a 7 bit US-ASCII string, either "OK" or an error message that
std::string ToASCIIString(const char* msg) const; // includes the position.
std::string ToASCIIString() const;
}; };
} // namespace v8_crdtp } // namespace v8_crdtp
......
...@@ -33,10 +33,7 @@ template("inspector_protocol_generate") { ...@@ -33,10 +33,7 @@ template("inspector_protocol_generate") {
invoker.config_file, invoker.config_file,
"$inspector_protocol_dir/lib/base_string_adapter_cc.template", "$inspector_protocol_dir/lib/base_string_adapter_cc.template",
"$inspector_protocol_dir/lib/base_string_adapter_h.template", "$inspector_protocol_dir/lib/base_string_adapter_h.template",
"$inspector_protocol_dir/lib/DispatcherBase_cpp.template",
"$inspector_protocol_dir/lib/DispatcherBase_h.template",
"$inspector_protocol_dir/lib/Forward_h.template", "$inspector_protocol_dir/lib/Forward_h.template",
"$inspector_protocol_dir/lib/FrontendChannel_h.template",
"$inspector_protocol_dir/lib/Object_cpp.template", "$inspector_protocol_dir/lib/Object_cpp.template",
"$inspector_protocol_dir/lib/Object_h.template", "$inspector_protocol_dir/lib/Object_h.template",
"$inspector_protocol_dir/lib/Protocol_cpp.template", "$inspector_protocol_dir/lib/Protocol_cpp.template",
...@@ -56,6 +53,7 @@ template("inspector_protocol_generate") { ...@@ -56,6 +53,7 @@ template("inspector_protocol_generate") {
"--jinja_dir", "--jinja_dir",
rebase_path("//third_party/", root_build_dir), # jinja is in chromium's rebase_path("//third_party/", root_build_dir), # jinja is in chromium's
# third_party # third_party
"--output_base", "--output_base",
rebase_path(invoker.out_dir, root_build_dir), rebase_path(invoker.out_dir, root_build_dir),
"--config", "--config",
......
// This file is generated by DispatcherBase_h.template.
// Copyright 2016 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.
#ifndef {{"_".join(config.protocol.namespace)}}_DispatcherBase_h
#define {{"_".join(config.protocol.namespace)}}_DispatcherBase_h
//#include "Forward.h"
//#include "ErrorSupport.h"
//#include "Values.h"
#include "{{config.crdtp.dir}}/span.h"
{% for namespace in config.protocol.namespace %}
namespace {{namespace}} {
{% endfor %}
class WeakPtr;
class {{config.lib.export_macro}} DispatchResponse {
public:
enum Status {
kSuccess = 0,
kError = 1,
kFallThrough = 2,
};
// For historical reasons, these error codes correspond to commonly used
// XMLRPC codes (e.g. see METHOD_NOT_FOUND in
// https://github.com/python/cpython/blob/master/Lib/xmlrpc/client.py).
enum ErrorCode {
kParseError = -32700,
kInvalidRequest = -32600,
kMethodNotFound = -32601,
kInvalidParams = -32602,
kInternalError = -32603,
kServerError = -32000,
};
Status status() const { return m_status; }
const String& errorMessage() const { return m_errorMessage; }
ErrorCode errorCode() const { return m_errorCode; }
bool isSuccess() const { return m_status == kSuccess; }
static DispatchResponse OK();
static DispatchResponse Error(const String&);
static DispatchResponse InternalError();
static DispatchResponse InvalidParams(const String&);
static DispatchResponse FallThrough();
private:
Status m_status;
String m_errorMessage;
ErrorCode m_errorCode;
};
class {{config.lib.export_macro}} DispatcherBase {
PROTOCOL_DISALLOW_COPY(DispatcherBase);
public:
static const char kInvalidParamsString[];
class {{config.lib.export_macro}} WeakPtr {
public:
explicit WeakPtr(DispatcherBase*);
~WeakPtr();
DispatcherBase* get() { return m_dispatcher; }
void dispose() { m_dispatcher = nullptr; }
private:
DispatcherBase* m_dispatcher;
};
class {{config.lib.export_macro}} Callback {
public:
Callback(std::unique_ptr<WeakPtr> backendImpl, int callId, const String& method, {{config.crdtp.namespace}}::span<uint8_t> message);
virtual ~Callback();
void dispose();
protected:
void sendIfActive(std::unique_ptr<protocol::DictionaryValue> partialMessage, const DispatchResponse& response);
void fallThroughIfActive();
private:
std::unique_ptr<WeakPtr> m_backendImpl;
int m_callId;
String m_method;
std::vector<uint8_t> m_message;
};
explicit DispatcherBase(FrontendChannel*);
virtual ~DispatcherBase();
virtual bool canDispatch(const String& method) = 0;
virtual void dispatch(int callId, const String& method, {{config.crdtp.namespace}}::span<uint8_t> 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);
void sendResponse(int callId, const DispatchResponse&);
void reportProtocolError(int callId, DispatchResponse::ErrorCode, const String& errorMessage, ErrorSupport* errors);
void clearFrontend();
std::unique_ptr<WeakPtr> weakPtr();
private:
FrontendChannel* m_frontendChannel;
std::unordered_set<WeakPtr*> m_weakPtrs;
};
class {{config.lib.export_macro}} UberDispatcher {
PROTOCOL_DISALLOW_COPY(UberDispatcher);
public:
explicit UberDispatcher(FrontendChannel*);
void registerBackend(const String& name, std::unique_ptr<protocol::DispatcherBase>);
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, {{config.crdtp.namespace}}::span<uint8_t> rawMessage);
FrontendChannel* channel() { return m_frontendChannel; }
virtual ~UberDispatcher();
private:
protocol::DispatcherBase* findDispatcher(const String& method);
FrontendChannel* m_frontendChannel;
std::unordered_map<String, String> m_redirects;
std::unordered_map<String, std::unique_ptr<protocol::DispatcherBase>> m_dispatchers;
};
class InternalResponse : public Serializable {
PROTOCOL_DISALLOW_COPY(InternalResponse);
public:
static std::unique_ptr<Serializable> createResponse(int callId, std::unique_ptr<Serializable> params);
static std::unique_ptr<Serializable> createNotification(const char* method, std::unique_ptr<Serializable> params = nullptr);
static std::unique_ptr<Serializable> createErrorResponse(int callId, DispatchResponse::ErrorCode code, const String& message);
void AppendSerialized(std::vector<uint8_t>* out) const override;
~InternalResponse() override {}
private:
InternalResponse(int callId, const char* method, std::unique_ptr<Serializable> params);
int m_callId;
const char* m_method = nullptr;
std::unique_ptr<Serializable> m_params;
};
{% for namespace in config.protocol.namespace %}
} // namespace {{namespace}}
{% endfor %}
#endif // !defined({{"_".join(config.protocol.namespace)}}_DispatcherBase_h)
...@@ -19,6 +19,8 @@ ...@@ -19,6 +19,8 @@
#include <unordered_set> #include <unordered_set>
#include "{{config.crdtp.dir}}/error_support.h" #include "{{config.crdtp.dir}}/error_support.h"
#include "{{config.crdtp.dir}}/dispatch.h"
#include "{{config.crdtp.dir}}/frontend_channel.h"
#include "{{config.crdtp.dir}}/glue.h" #include "{{config.crdtp.dir}}/glue.h"
{% for namespace in config.protocol.namespace %} {% for namespace in config.protocol.namespace %}
...@@ -26,15 +28,18 @@ namespace {{namespace}} { ...@@ -26,15 +28,18 @@ namespace {{namespace}} {
{% endfor %} {% endfor %}
class DictionaryValue; class DictionaryValue;
class DispatchResponse; using DispatchResponse = {{config.crdtp.namespace}}::DispatchResponse;
using ErrorSupport = {{config.crdtp.namespace}}::ErrorSupport; using ErrorSupport = {{config.crdtp.namespace}}::ErrorSupport;
using Serializable = {{config.crdtp.namespace}}::Serializable;
using FrontendChannel = {{config.crdtp.namespace}}::FrontendChannel;
using DomainDispatcher = {{config.crdtp.namespace}}::DomainDispatcher;
using UberDispatcher = {{config.crdtp.namespace}}::UberDispatcher;
class FundamentalValue; class FundamentalValue;
class ListValue; class ListValue;
class Object; class Object;
using Response = DispatchResponse; using Response = DispatchResponse;
class SerializedValue; class SerializedValue;
class StringValue; class StringValue;
class UberDispatcher;
class Value; class Value;
namespace detail { namespace detail {
......
// This file is generated by FrontendChannel_h.template.
// Copyright 2016 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.
#ifndef {{"_".join(config.protocol.namespace)}}_FrontendChannel_h
#define {{"_".join(config.protocol.namespace)}}_FrontendChannel_h
#include "{{config.crdtp.dir}}/serializable.h"
#include "{{config.crdtp.dir}}/span.h"
{% for namespace in config.protocol.namespace %}
namespace {{namespace}} {
{% endfor %}
using {{config.crdtp.namespace}}::Serializable;
class {{config.lib.export_macro}} FrontendChannel {
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, {{config.crdtp.namespace}}::span<uint8_t> message) = 0;
virtual void flushProtocolNotifications() = 0;
};
{% for namespace in config.protocol.namespace %}
} // namespace {{namespace}}
{% endfor %}
#endif // !defined({{"_".join(config.protocol.namespace)}}_FrontendChannel_h)
...@@ -34,17 +34,6 @@ using String = std::string; ...@@ -34,17 +34,6 @@ using String = std::string;
class {{config.lib.export_macro}} StringUtil { class {{config.lib.export_macro}} StringUtil {
public: public:
static String substring(const String& s, unsigned pos, unsigned len) {
return s.substr(pos, len);
}
static size_t find(const String& s, const char* needle) {
return s.find(needle);
}
static size_t find(const String& s, const String& needle) {
return s.find(needle);
}
static const size_t kNotFound = static_cast<size_t>(-1);
static String fromUTF8(const uint8_t* data, size_t length) { static String fromUTF8(const uint8_t* data, size_t length) {
return std::string(reinterpret_cast<const char*>(data), length); return std::string(reinterpret_cast<const char*>(data), length);
} }
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment