Index: third_party/inspector_protocol/lib/DispatcherBase_cpp.template |
diff --git a/third_party/inspector_protocol/lib/DispatcherBase_cpp.template b/third_party/inspector_protocol/lib/DispatcherBase_cpp.template |
new file mode 100644 |
index 0000000000000000000000000000000000000000..76f77aae7ece7871d2db5e64aa626ea8f308a208 |
--- /dev/null |
+++ b/third_party/inspector_protocol/lib/DispatcherBase_cpp.template |
@@ -0,0 +1,173 @@ |
+// 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. |
+ |
+//#include "DispatcherBase.h" |
+//#include "Parser.h" |
+ |
+{% for namespace in config.protocol.namespace %} |
+namespace {{namespace}} { |
+{% endfor %} |
+ |
+// static |
+const char DispatcherBase::kInvalidRequest[] = "Invalid request"; |
+ |
+DispatcherBase::WeakPtr::WeakPtr(DispatcherBase* dispatcher) : m_dispatcher(dispatcher) { } |
+ |
+DispatcherBase::WeakPtr::~WeakPtr() |
+{ |
+ if (m_dispatcher) |
+ m_dispatcher->m_weakPtrs.erase(this); |
+} |
+ |
+DispatcherBase::Callback::Callback(std::unique_ptr<DispatcherBase::WeakPtr> backendImpl, int callId) |
+ : m_backendImpl(std::move(backendImpl)) |
+ , m_callId(callId) { } |
+ |
+DispatcherBase::Callback::~Callback() = default; |
+ |
+void DispatcherBase::Callback::dispose() |
+{ |
+ m_backendImpl = nullptr; |
+} |
+ |
+void DispatcherBase::Callback::sendIfActive(std::unique_ptr<protocol::DictionaryValue> partialMessage, const ErrorString& invocationError) |
+{ |
+ if (!m_backendImpl || !m_backendImpl->get()) |
+ return; |
+ m_backendImpl->get()->sendResponse(m_callId, invocationError, nullptr, std::move(partialMessage)); |
+ m_backendImpl = nullptr; |
+} |
+ |
+DispatcherBase::DispatcherBase(FrontendChannel* frontendChannel) |
+ : m_frontendChannel(frontendChannel) { } |
+ |
+DispatcherBase::~DispatcherBase() |
+{ |
+ clearFrontend(); |
+} |
+ |
+// static |
+bool DispatcherBase::getCommandName(const String& message, String* result) |
+{ |
+ std::unique_ptr<protocol::Value> value = parseJSON(message); |
+ if (!value) |
+ return false; |
+ |
+ protocol::DictionaryValue* object = DictionaryValue::cast(value.get()); |
+ if (!object) |
+ return false; |
+ |
+ if (!object->getString("method", result)) |
+ return false; |
+ |
+ return true; |
+} |
+ |
+void DispatcherBase::sendResponse(int callId, const ErrorString& invocationError, ErrorSupport* errors, std::unique_ptr<protocol::DictionaryValue> result) |
+{ |
+ if (invocationError.length() || (errors && errors->hasErrors())) { |
+ reportProtocolError(callId, ServerError, invocationError, errors); |
+ return; |
+ } |
+ |
+ std::unique_ptr<protocol::DictionaryValue> responseMessage = DictionaryValue::create(); |
+ responseMessage->setInteger("id", callId); |
+ responseMessage->setObject("result", std::move(result)); |
+ if (m_frontendChannel) |
+ m_frontendChannel->sendProtocolResponse(callId, responseMessage->toJSONString()); |
+} |
+ |
+void DispatcherBase::sendResponse(int callId, const ErrorString& invocationError, std::unique_ptr<protocol::DictionaryValue> result) |
+{ |
+ sendResponse(callId, invocationError, nullptr, std::move(result)); |
+} |
+ |
+void DispatcherBase::sendResponse(int callId, const ErrorString& invocationError) |
+{ |
+ sendResponse(callId, invocationError, nullptr, DictionaryValue::create()); |
+} |
+ |
+static void reportProtocolErrorTo(FrontendChannel* frontendChannel, int callId, DispatcherBase::CommonErrorCode code, const String& errorMessage, ErrorSupport* errors) |
+{ |
+ if (!frontendChannel) |
+ return; |
+ std::unique_ptr<protocol::DictionaryValue> error = DictionaryValue::create(); |
+ error->setInteger("code", code); |
+ error->setString("message", errorMessage); |
+ DCHECK(error); |
+ if (errors && errors->hasErrors()) |
+ error->setString("data", errors->errors()); |
+ std::unique_ptr<protocol::DictionaryValue> message = DictionaryValue::create(); |
+ message->setObject("error", std::move(error)); |
+ message->setInteger("id", callId); |
+ frontendChannel->sendProtocolResponse(callId, message->toJSONString()); |
+} |
+ |
+void DispatcherBase::reportProtocolError(int callId, CommonErrorCode code, const String& errorMessage, ErrorSupport* errors) |
+{ |
+ reportProtocolErrorTo(m_frontendChannel, callId, code, errorMessage, errors); |
+} |
+ |
+void DispatcherBase::clearFrontend() |
+{ |
+ m_frontendChannel = nullptr; |
+ for (auto& weak : m_weakPtrs) |
+ weak->dispose(); |
+ m_weakPtrs.clear(); |
+} |
+ |
+std::unique_ptr<DispatcherBase::WeakPtr> DispatcherBase::weakPtr() |
+{ |
+ std::unique_ptr<DispatcherBase::WeakPtr> weak(new DispatcherBase::WeakPtr(this)); |
+ m_weakPtrs.insert(weak.get()); |
+ return weak; |
+} |
+ |
+UberDispatcher::UberDispatcher(FrontendChannel* frontendChannel) |
+ : m_frontendChannel(frontendChannel) { } |
+ |
+void UberDispatcher::registerBackend(const String& name, std::unique_ptr<protocol::DispatcherBase> dispatcher) |
+{ |
+ m_dispatchers[name] = std::move(dispatcher); |
+} |
+ |
+void UberDispatcher::dispatch(std::unique_ptr<Value> parsedMessage) |
+{ |
+ if (!parsedMessage) |
+ return; |
+ std::unique_ptr<protocol::DictionaryValue> messageObject = DictionaryValue::cast(std::move(parsedMessage)); |
+ if (!messageObject) |
+ return; |
+ |
+ int callId = 0; |
+ protocol::Value* callIdValue = messageObject->get("id"); |
+ bool success = callIdValue && callIdValue->asInteger(&callId); |
+ if (!success) |
+ return; |
+ |
+ protocol::Value* methodValue = messageObject->get("method"); |
+ String method; |
+ success = methodValue && methodValue->asString(&method); |
+ if (!success) |
+ return; |
+ |
+ size_t dotIndex = method.find("."); |
+ if (dotIndex == StringUtil::kNotFound) { |
+ reportProtocolErrorTo(m_frontendChannel, callId, DispatcherBase::MethodNotFound, "'" + method + "' wasn't found", nullptr); |
+ return; |
+ } |
+ String domain = StringUtil::substring(method, 0, dotIndex); |
+ auto it = m_dispatchers.find(domain); |
+ if (it == m_dispatchers.end()) { |
+ reportProtocolErrorTo(m_frontendChannel, callId, DispatcherBase::MethodNotFound, "'" + method + "' wasn't found", nullptr); |
+ return; |
+ } |
+ it->second->dispatch(callId, method, std::move(messageObject)); |
+} |
+ |
+UberDispatcher::~UberDispatcher() = default; |
+ |
+{% for namespace in config.protocol.namespace %} |
+} // namespace {{namespace}} |
+{% endfor %} |