2ce083de69b1102ac9356623cdd22ea4f1f4d021
[WebKit-https.git] / Source / WebKit2 / Platform / IPC / HandleMessage.h
1 #ifndef HandleMessage_h
2 #define HandleMessage_h
3
4 #include "Arguments.h"
5 #include "MessageDecoder.h"
6 #include "MessageEncoder.h"
7 #include <wtf/StdLibExtras.h>
8
9 namespace IPC {
10
11 // Dispatch functions with no reply arguments.
12
13 template <typename C, typename MF, typename ArgsTuple, size_t... ArgsIndex>
14 void callMemberFunctionImpl(C* object, MF function, ArgsTuple&& args, std::index_sequence<ArgsIndex...>)
15 {
16     (object->*function)(std::get<ArgsIndex>(std::forward<ArgsTuple>(args))...);
17 }
18
19 template<typename C, typename MF, typename ArgsTuple, typename ArgsIndicies = std::make_index_sequence<std::tuple_size<ArgsTuple>::value>>
20 void callMemberFunction(ArgsTuple&& args, C* object, MF function)
21 {
22     callMemberFunctionImpl(object, function, std::forward<ArgsTuple>(args), ArgsIndicies());
23 }
24
25 // Dispatch functions with reply arguments.
26
27 template <typename C, typename MF, typename ArgsTuple, size_t... ArgsIndex, typename ReplyArgsTuple, size_t... ReplyArgsIndex>
28 void callMemberFunctionImpl(C* object, MF function, ArgsTuple&& args, ReplyArgsTuple& replyArgs, std::index_sequence<ArgsIndex...>, std::index_sequence<ReplyArgsIndex...>)
29 {
30     (object->*function)(std::get<ArgsIndex>(std::forward<ArgsTuple>(args))..., std::get<ReplyArgsIndex>(replyArgs)...);
31 }
32
33 template <typename C, typename MF, typename ArgsTuple, typename ArgsIndicies = std::make_index_sequence<std::tuple_size<ArgsTuple>::value>, typename ReplyArgsTuple, typename ReplyArgsIndicies = std::make_index_sequence<std::tuple_size<ReplyArgsTuple>::value>>
34 void callMemberFunction(ArgsTuple&& args, ReplyArgsTuple& replyArgs, C* object, MF function)
35 {
36     callMemberFunctionImpl(object, function, std::forward<ArgsTuple>(args), replyArgs, ArgsIndicies(), ReplyArgsIndicies());
37 }
38
39 // Dispatch functions with delayed reply arguments.
40
41 template <typename C, typename MF, typename R, typename ArgsTuple, size_t... ArgsIndex>
42 void callMemberFunctionImpl(C* object, MF function, PassRefPtr<R> delayedReply, ArgsTuple&& args, std::index_sequence<ArgsIndex...>)
43 {
44     (object->*function)(std::get<ArgsIndex>(args)..., delayedReply);
45 }
46
47 template<typename C, typename MF, typename R, typename ArgsTuple, typename ArgsIndicies = std::make_index_sequence<std::tuple_size<ArgsTuple>::value>>
48 void callMemberFunction(ArgsTuple&& args, PassRefPtr<R> delayedReply, C* object, MF function)
49 {
50     callMemberFunctionImpl(object, function, delayedReply, std::forward<ArgsTuple>(args), ArgsIndicies());
51 }
52
53 // Dispatch functions with connection parameter with no reply arguments.
54
55 template <typename C, typename MF, typename ArgsTuple, size_t... ArgsIndex>
56 void callMemberFunctionImpl(C* object, MF function, Connection& connection, ArgsTuple&& args, std::index_sequence<ArgsIndex...>)
57 {
58     (object->*function)(connection, std::get<ArgsIndex>(args)...);
59 }
60
61 template<typename C, typename MF, typename ArgsTuple, typename ArgsIndicies = std::make_index_sequence<std::tuple_size<ArgsTuple>::value>>
62 void callMemberFunction(Connection& connection, ArgsTuple&& args, C* object, MF function)
63 {
64     callMemberFunctionImpl(object, function, connection, std::forward<ArgsTuple>(args), ArgsIndicies());
65 }
66
67 // Dispatch functions with connection parameter with reply arguments.
68
69 template <typename C, typename MF, typename ArgsTuple, size_t... ArgsIndex, typename ReplyArgsTuple, size_t... ReplyArgsIndex>
70 void callMemberFunctionImpl(C* object, MF function, Connection& connection, ArgsTuple&& args, ReplyArgsTuple& replyArgs, std::index_sequence<ArgsIndex...>, std::index_sequence<ReplyArgsIndex...>)
71 {
72     (object->*function)(connection, std::get<ArgsIndex>(std::forward<ArgsTuple>(args))..., std::get<ReplyArgsIndex>(replyArgs)...);
73 }
74
75 template <typename C, typename MF, typename ArgsTuple, typename ArgsIndicies = std::make_index_sequence<std::tuple_size<ArgsTuple>::value>, typename ReplyArgsTuple, typename ReplyArgsIndicies = std::make_index_sequence<std::tuple_size<ReplyArgsTuple>::value>>
76 void callMemberFunction(Connection& connection, ArgsTuple&& args, ReplyArgsTuple& replyArgs, C* object, MF function)
77 {
78     callMemberFunctionImpl(object, function, connection, std::forward<ArgsTuple>(args), replyArgs, ArgsIndicies(), ReplyArgsIndicies());
79 }
80
81 // Main dispatch functions
82
83 template<typename T, typename C, typename MF>
84 void handleMessage(MessageDecoder& decoder, C* object, MF function)
85 {
86     typename T::DecodeType arguments;
87     if (!decoder.decode(arguments)) {
88         ASSERT(decoder.isInvalid());
89         return;
90     }
91
92     callMemberFunction(WTFMove(arguments), object, function);
93 }
94
95 template<typename T, typename C, typename MF>
96 void handleMessage(MessageDecoder& decoder, MessageEncoder& replyEncoder, C* object, MF function)
97 {
98     typename T::DecodeType arguments;
99     if (!decoder.decode(arguments)) {
100         ASSERT(decoder.isInvalid());
101         return;
102     }
103
104     typename T::Reply::ValueType replyArguments;
105     callMemberFunction(WTFMove(arguments), replyArguments, object, function);
106     replyEncoder << replyArguments;
107 }
108
109 template<typename T, typename C, typename MF>
110 void handleMessage(Connection& connection, MessageDecoder& decoder, MessageEncoder& replyEncoder, C* object, MF function)
111 {
112     typename T::DecodeType arguments;
113     if (!decoder.decode(arguments)) {
114         ASSERT(decoder.isInvalid());
115         return;
116     }
117
118     typename T::Reply::ValueType replyArguments;
119     callMemberFunction(connection, WTFMove(arguments), replyArguments, object, function);
120     replyEncoder << replyArguments;
121 }
122
123 template<typename T, typename C, typename MF>
124 void handleMessage(Connection& connection, MessageDecoder& decoder, C* object, MF function)
125 {
126     typename T::DecodeType arguments;
127     if (!decoder.decode(arguments)) {
128         ASSERT(decoder.isInvalid());
129         return;
130     }
131     callMemberFunction(connection, WTFMove(arguments), object, function);
132 }
133
134 template<typename T, typename C, typename MF>
135 void handleMessageDelayed(Connection& connection, MessageDecoder& decoder, std::unique_ptr<MessageEncoder>& replyEncoder, C* object, MF function)
136 {
137     typename T::DecodeType arguments;
138     if (!decoder.decode(arguments)) {
139         ASSERT(decoder.isInvalid());
140         return;
141     }
142
143     RefPtr<typename T::DelayedReply> delayedReply = adoptRef(new typename T::DelayedReply(&connection, WTFMove(replyEncoder)));
144     callMemberFunction(WTFMove(arguments), delayedReply.release(), object, function);
145 }
146
147 } // namespace IPC
148
149 #endif // HandleMessage_h