#ifndef HandleMessage_h #define HandleMessage_h #include "Arguments.h" #include "MessageDecoder.h" #include "MessageEncoder.h" #include namespace IPC { // Dispatch functions with no reply arguments. template void callMemberFunctionImpl(C* object, MF function, ArgsTuple&& args, std::index_sequence) { (object->*function)(std::get(std::forward(args))...); } template::value>> void callMemberFunction(ArgsTuple&& args, C* object, MF function) { callMemberFunctionImpl(object, function, std::forward(args), ArgsIndicies()); } // Dispatch functions with reply arguments. template void callMemberFunctionImpl(C* object, MF function, ArgsTuple&& args, ReplyArgsTuple& replyArgs, std::index_sequence, std::index_sequence) { (object->*function)(std::get(std::forward(args))..., std::get(replyArgs)...); } template ::value>, typename ReplyArgsTuple, typename ReplyArgsIndicies = std::make_index_sequence::value>> void callMemberFunction(ArgsTuple&& args, ReplyArgsTuple& replyArgs, C* object, MF function) { callMemberFunctionImpl(object, function, std::forward(args), replyArgs, ArgsIndicies(), ReplyArgsIndicies()); } // Dispatch functions with delayed reply arguments. template void callMemberFunctionImpl(C* object, MF function, PassRefPtr delayedReply, ArgsTuple&& args, std::index_sequence) { (object->*function)(std::get(args)..., delayedReply); } template::value>> void callMemberFunction(ArgsTuple&& args, PassRefPtr delayedReply, C* object, MF function) { callMemberFunctionImpl(object, function, delayedReply, std::forward(args), ArgsIndicies()); } // Dispatch functions with connection parameter with no reply arguments. template void callMemberFunctionImpl(C* object, MF function, Connection& connection, ArgsTuple&& args, std::index_sequence) { (object->*function)(connection, std::get(args)...); } template::value>> void callMemberFunction(Connection& connection, ArgsTuple&& args, C* object, MF function) { callMemberFunctionImpl(object, function, connection, std::forward(args), ArgsIndicies()); } // Dispatch functions with connection parameter with reply arguments. template void callMemberFunctionImpl(C* object, MF function, Connection& connection, ArgsTuple&& args, ReplyArgsTuple& replyArgs, std::index_sequence, std::index_sequence) { (object->*function)(connection, std::get(std::forward(args))..., std::get(replyArgs)...); } template ::value>, typename ReplyArgsTuple, typename ReplyArgsIndicies = std::make_index_sequence::value>> void callMemberFunction(Connection& connection, ArgsTuple&& args, ReplyArgsTuple& replyArgs, C* object, MF function) { callMemberFunctionImpl(object, function, connection, std::forward(args), replyArgs, ArgsIndicies(), ReplyArgsIndicies()); } // Main dispatch functions template void handleMessage(MessageDecoder& decoder, C* object, MF function) { typename T::DecodeType arguments; if (!decoder.decode(arguments)) { ASSERT(decoder.isInvalid()); return; } callMemberFunction(WTFMove(arguments), object, function); } template void handleMessage(MessageDecoder& decoder, MessageEncoder& replyEncoder, C* object, MF function) { typename T::DecodeType arguments; if (!decoder.decode(arguments)) { ASSERT(decoder.isInvalid()); return; } typename T::Reply::ValueType replyArguments; callMemberFunction(WTFMove(arguments), replyArguments, object, function); replyEncoder << replyArguments; } template void handleMessage(Connection& connection, MessageDecoder& decoder, MessageEncoder& replyEncoder, C* object, MF function) { typename T::DecodeType arguments; if (!decoder.decode(arguments)) { ASSERT(decoder.isInvalid()); return; } typename T::Reply::ValueType replyArguments; callMemberFunction(connection, WTFMove(arguments), replyArguments, object, function); replyEncoder << replyArguments; } template void handleMessage(Connection& connection, MessageDecoder& decoder, C* object, MF function) { typename T::DecodeType arguments; if (!decoder.decode(arguments)) { ASSERT(decoder.isInvalid()); return; } callMemberFunction(connection, WTFMove(arguments), object, function); } template void handleMessageDelayed(Connection& connection, MessageDecoder& decoder, std::unique_ptr& replyEncoder, C* object, MF function) { typename T::DecodeType arguments; if (!decoder.decode(arguments)) { ASSERT(decoder.isInvalid()); return; } RefPtr delayedReply = adoptRef(new typename T::DelayedReply(&connection, WTFMove(replyEncoder))); callMemberFunction(WTFMove(arguments), delayedReply.release(), object, function); } } // namespace IPC #endif // HandleMessage_h