#ifndef DevToolsRPC_h
#define DevToolsRPC_h
#include "PlatformString.h"
#include "Vector.h"
#include "WebDevToolsMessageData.h"
#include <wtf/Noncopyable.h>
namespace WebCore {
class String;
}
using WebCore::String;
using WTF::Vector;
namespace WebKit {
template<typename T>
struct RpcTypeTrait {
typedef T ApiType;
};
template<>
struct RpcTypeTrait<bool> {
typedef bool ApiType;
static bool parse(const WebCore::String& t)
{
return t == "true";
}
static WebCore::String toString(bool b)
{
return b ? "true" : "false";
}
};
template<>
struct RpcTypeTrait<int> {
typedef int ApiType;
static int parse(const WebCore::String& t)
{
bool success;
int i = t.toIntStrict(&success);
ASSERT(success);
return i;
}
static WebCore::String toString(int i)
{
return WebCore::String::number(i);
}
};
template<>
struct RpcTypeTrait<String> {
typedef const String& ApiType;
static String parse(const WebCore::String& t)
{
return t;
}
static WebCore::String toString(const String& t)
{
return t;
}
};
#define TOOLS_RPC_API_METHOD0(Method) \
virtual void Method() = 0;
#define TOOLS_RPC_API_METHOD1(Method, T1) \
virtual void Method(RpcTypeTrait<T1>::ApiType t1) = 0;
#define TOOLS_RPC_API_METHOD2(Method, T1, T2) \
virtual void Method(RpcTypeTrait<T1>::ApiType t1, \
RpcTypeTrait<T2>::ApiType t2) = 0;
#define TOOLS_RPC_API_METHOD3(Method, T1, T2, T3) \
virtual void Method(RpcTypeTrait<T1>::ApiType t1, \
RpcTypeTrait<T2>::ApiType t2, \
RpcTypeTrait<T3>::ApiType t3) = 0;
#define TOOLS_RPC_API_METHOD4(Method, T1, T2, T3, T4) \
virtual void Method(RpcTypeTrait<T1>::ApiType t1, \
RpcTypeTrait<T2>::ApiType t2, \
RpcTypeTrait<T3>::ApiType t3, \
RpcTypeTrait<T4>::ApiType t4) = 0;
#define TOOLS_RPC_API_METHOD5(Method, T1, T2, T3, T4, T5) \
virtual void Method(RpcTypeTrait<T1>::ApiType t1, \
RpcTypeTrait<T2>::ApiType t2, \
RpcTypeTrait<T3>::ApiType t3, \
RpcTypeTrait<T4>::ApiType t4, \
RpcTypeTrait<T5>::ApiType t5) = 0;
#define TOOLS_RPC_STUB_METHOD0(Method) \
virtual void Method() { \
Vector<String> args; \
this->sendRpcMessage(m_className, #Method, args); \
}
#define TOOLS_RPC_STUB_METHOD1(Method, T1) \
virtual void Method(RpcTypeTrait<T1>::ApiType t1) { \
Vector<String> args(1); \
args[0] = RpcTypeTrait<T1>::toString(t1); \
this->sendRpcMessage(m_className, #Method, args); \
}
#define TOOLS_RPC_STUB_METHOD2(Method, T1, T2) \
virtual void Method(RpcTypeTrait<T1>::ApiType t1, \
RpcTypeTrait<T2>::ApiType t2) { \
Vector<String> args(2); \
args[0] = RpcTypeTrait<T1>::toString(t1); \
args[1] = RpcTypeTrait<T2>::toString(t2); \
this->sendRpcMessage(m_className, #Method, args); \
}
#define TOOLS_RPC_STUB_METHOD3(Method, T1, T2, T3) \
virtual void Method(RpcTypeTrait<T1>::ApiType t1, \
RpcTypeTrait<T2>::ApiType t2, \
RpcTypeTrait<T3>::ApiType t3) { \
Vector<String> args(3); \
args[0] = RpcTypeTrait<T1>::toString(t1); \
args[1] = RpcTypeTrait<T2>::toString(t2); \
args[2] = RpcTypeTrait<T3>::toString(t3); \
this->sendRpcMessage(m_className, #Method, args); \
}
#define TOOLS_RPC_STUB_METHOD4(Method, T1, T2, T3, T4) \
virtual void Method(RpcTypeTrait<T1>::ApiType t1, \
RpcTypeTrait<T2>::ApiType t2, \
RpcTypeTrait<T3>::ApiType t3, \
RpcTypeTrait<T4>::ApiType t4) { \
Vector<String> args(4); \
args[0] = RpcTypeTrait<T1>::toString(t1); \
args[1] = RpcTypeTrait<T2>::toString(t2); \
args[2] = RpcTypeTrait<T3>::toString(t3); \
args[3] = RpcTypeTrait<T4>::toString(t4); \
this->sendRpcMessage(m_className, #Method, args); \
}
#define TOOLS_RPC_STUB_METHOD5(Method, T1, T2, T3, T4, T5) \
virtual void Method(RpcTypeTrait<T1>::ApiType t1, \
RpcTypeTrait<T2>::ApiType t2, \
RpcTypeTrait<T3>::ApiType t3, \
RpcTypeTrait<T4>::ApiType t4, \
RpcTypeTrait<T5>::ApiType t5) { \
Vector<String> args(5); \
args[0] = RpcTypeTrait<T1>::toString(t1); \
args[1] = RpcTypeTrait<T2>::toString(t2); \
args[2] = RpcTypeTrait<T3>::toString(t3); \
args[3] = RpcTypeTrait<T4>::toString(t4); \
args[4] = RpcTypeTrait<T5>::toString(t5); \
this->sendRpcMessage(m_className, #Method, args); \
}
#define TOOLS_RPC_DISPATCH0(Method) \
if (methodName == #Method) { \
delegate->Method(); \
return true; \
}
#define TOOLS_RPC_DISPATCH1(Method, T1) \
if (methodName == #Method) { \
delegate->Method(RpcTypeTrait<T1>::parse(args[0])); \
return true; \
}
#define TOOLS_RPC_DISPATCH2(Method, T1, T2) \
if (methodName == #Method) { \
delegate->Method( \
RpcTypeTrait<T1>::parse(args[0]), \
RpcTypeTrait<T2>::parse(args[1]) \
); \
return true; \
}
#define TOOLS_RPC_DISPATCH3(Method, T1, T2, T3) \
if (methodName == #Method) { \
delegate->Method( \
RpcTypeTrait<T1>::parse(args[0]), \
RpcTypeTrait<T2>::parse(args[1]), \
RpcTypeTrait<T3>::parse(args[2]) \
); \
return true; \
}
#define TOOLS_RPC_DISPATCH4(Method, T1, T2, T3, T4) \
if (methodName == #Method) { \
delegate->Method( \
RpcTypeTrait<T1>::parse(args[0]), \
RpcTypeTrait<T2>::parse(args[1]), \
RpcTypeTrait<T3>::parse(args[2]), \
RpcTypeTrait<T4>::parse(args[3]) \
); \
return true; \
}
#define TOOLS_RPC_DISPATCH5(Method, T1, T2, T3, T4, T5) \
if (methodName == #Method) { \
delegate->Method( \
RpcTypeTrait<T1>::parse(args[0]), \
RpcTypeTrait<T2>::parse(args[1]), \
RpcTypeTrait<T3>::parse(args[2]), \
RpcTypeTrait<T4>::parse(args[3]), \
RpcTypeTrait<T5>::parse(args[4]) \
); \
return true; \
}
#define TOOLS_END_RPC_DISPATCH() \
}
#define DEFINE_RPC_CLASS(Class, STRUCT) \
class Class : public Noncopyable {\
public: \
Class() \
{ \
m_className = #Class; \
} \
virtual ~Class() { } \
\
STRUCT( \
TOOLS_RPC_API_METHOD0, \
TOOLS_RPC_API_METHOD1, \
TOOLS_RPC_API_METHOD2, \
TOOLS_RPC_API_METHOD3, \
TOOLS_RPC_API_METHOD4, \
TOOLS_RPC_API_METHOD5) \
WebCore::String m_className; \
}; \
\
class Class##Stub \
: public Class \
, public DevToolsRPC { \
public: \
explicit Class##Stub(Delegate* delegate) : DevToolsRPC(delegate) { } \
virtual ~Class##Stub() { } \
typedef Class CLASS; \
STRUCT( \
TOOLS_RPC_STUB_METHOD0, \
TOOLS_RPC_STUB_METHOD1, \
TOOLS_RPC_STUB_METHOD2, \
TOOLS_RPC_STUB_METHOD3, \
TOOLS_RPC_STUB_METHOD4, \
TOOLS_RPC_STUB_METHOD5) \
}; \
\
class Class##Dispatch : public Noncopyable { \
public: \
Class##Dispatch() { } \
virtual ~Class##Dispatch() { } \
\
static bool dispatch(Class* delegate, \
const WebKit::WebDevToolsMessageData& data) { \
String className = data.className; \
if (className != #Class) \
return false; \
String methodName = data.methodName; \
Vector<String> args; \
for (size_t i = 0; i < data.arguments.size(); i++) \
args.append(data.arguments[i]); \
typedef Class CLASS; \
STRUCT( \
TOOLS_RPC_DISPATCH0, \
TOOLS_RPC_DISPATCH1, \
TOOLS_RPC_DISPATCH2, \
TOOLS_RPC_DISPATCH3, \
TOOLS_RPC_DISPATCH4, \
TOOLS_RPC_DISPATCH5) \
return false; \
} \
};
class DevToolsRPC {
public:
class Delegate {
public:
Delegate() { }
virtual ~Delegate() { }
virtual void sendRpcMessage(const WebKit::WebDevToolsMessageData& data) = 0;
};
explicit DevToolsRPC(Delegate* delegate) : m_delegate(delegate) { }
virtual ~DevToolsRPC() { };
protected:
void sendRpcMessage(const String& className,
const String& methodName,
const Vector<String>& args) {
WebKit::WebVector<WebKit::WebString> webArgs(args.size());
for (size_t i = 0; i < args.size(); i++)
webArgs[i] = args[i];
WebKit::WebDevToolsMessageData data;
data.className = className;
data.methodName = methodName;
data.arguments.swap(webArgs);
this->m_delegate->sendRpcMessage(data);
}
Delegate* m_delegate;
};
}
#endif