OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef IPC_IPC_MESSAGE_UTILS_H_ | 5 #ifndef IPC_IPC_MESSAGE_UTILS_H_ |
6 #define IPC_IPC_MESSAGE_UTILS_H_ | 6 #define IPC_IPC_MESSAGE_UTILS_H_ |
7 #pragma once | 7 #pragma once |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <map> | 10 #include <map> |
(...skipping 926 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
937 l->append(", "); | 937 l->append(", "); |
938 LogParam(p.e, l); | 938 LogParam(p.e, l); |
939 } | 939 } |
940 }; | 940 }; |
941 | 941 |
942 //----------------------------------------------------------------------------- | 942 //----------------------------------------------------------------------------- |
943 // Generic message subclasses | 943 // Generic message subclasses |
944 | 944 |
945 // Used for asynchronous messages. | 945 // Used for asynchronous messages. |
946 template <class ParamType> | 946 template <class ParamType> |
947 class MessageWithTuple : public Message { | 947 class MessageSchema { |
948 public: | 948 public: |
949 typedef ParamType Param; | 949 typedef ParamType Param; |
950 typedef typename TupleTypes<ParamType>::ParamTuple RefParam; | 950 typedef typename TupleTypes<ParamType>::ParamTuple RefParam; |
951 | 951 |
952 // The constructor and the Read() method's templated implementations are in | 952 static void Write(Message* msg, const RefParam& p) IPC_MSG_NOINLINE; |
953 // ipc_message_utils_impl.h. The subclass constructor and Log() methods call | |
954 // the templated versions of these and make sure there are instantiations in | |
955 // those translation units. | |
956 MessageWithTuple(int32 routing_id, uint32 type, const RefParam& p); | |
957 | |
958 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE; | 953 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE; |
959 | |
960 // Generic dispatcher. Should cover most cases. | |
961 template<class T, class S, class Method> | |
962 static bool Dispatch(const Message* msg, T* obj, S* sender, Method func) { | |
963 Param p; | |
964 if (Read(msg, &p)) { | |
965 DispatchToMethod(obj, func, p); | |
966 return true; | |
967 } | |
968 return false; | |
969 } | |
970 | |
971 // The following dispatchers exist for the case where the callback function | |
972 // needs the message as well. They assume that "Param" is a type of Tuple | |
973 // (except the one arg case, as there is no Tuple1). | |
974 template<class T, class S, typename TA> | |
975 static bool Dispatch(const Message* msg, T* obj, S* sender, | |
976 void (T::*func)(const Message&, TA)) { | |
977 Param p; | |
978 if (Read(msg, &p)) { | |
979 (obj->*func)(*msg, p.a); | |
980 return true; | |
981 } | |
982 return false; | |
983 } | |
984 | |
985 template<class T, class S, typename TA, typename TB> | |
986 static bool Dispatch(const Message* msg, T* obj, S* sender, | |
987 void (T::*func)(const Message&, TA, TB)) { | |
988 Param p; | |
989 if (Read(msg, &p)) { | |
990 (obj->*func)(*msg, p.a, p.b); | |
991 return true; | |
992 } | |
993 return false; | |
994 } | |
995 | |
996 template<class T, class S, typename TA, typename TB, typename TC> | |
997 static bool Dispatch(const Message* msg, T* obj, S* sender, | |
998 void (T::*func)(const Message&, TA, TB, TC)) { | |
999 Param p; | |
1000 if (Read(msg, &p)) { | |
1001 (obj->*func)(*msg, p.a, p.b, p.c); | |
1002 return true; | |
1003 } | |
1004 return false; | |
1005 } | |
1006 | |
1007 template<class T, class S, typename TA, typename TB, typename TC, typename TD> | |
1008 static bool Dispatch(const Message* msg, T* obj, S* sender, | |
1009 void (T::*func)(const Message&, TA, TB, TC, TD)) { | |
1010 Param p; | |
1011 if (Read(msg, &p)) { | |
1012 (obj->*func)(*msg, p.a, p.b, p.c, p.d); | |
1013 return true; | |
1014 } | |
1015 return false; | |
1016 } | |
1017 | |
1018 template<class T, class S, typename TA, typename TB, typename TC, typename TD, | |
1019 typename TE> | |
1020 static bool Dispatch(const Message* msg, T* obj, S* sender, | |
1021 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) { | |
1022 Param p; | |
1023 if (Read(msg, &p)) { | |
1024 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e); | |
1025 return true; | |
1026 } | |
1027 return false; | |
1028 } | |
1029 | |
1030 // Functions used to do manual unpacking. Only used by the automation code, | |
1031 // these should go away once that code uses SyncChannel. | |
1032 template<typename TA, typename TB> | |
1033 static bool Read(const IPC::Message* msg, TA* a, TB* b) { | |
1034 ParamType params; | |
1035 if (!Read(msg, ¶ms)) | |
1036 return false; | |
1037 *a = params.a; | |
1038 *b = params.b; | |
1039 return true; | |
1040 } | |
1041 | |
1042 template<typename TA, typename TB, typename TC> | |
1043 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) { | |
1044 ParamType params; | |
1045 if (!Read(msg, ¶ms)) | |
1046 return false; | |
1047 *a = params.a; | |
1048 *b = params.b; | |
1049 *c = params.c; | |
1050 return true; | |
1051 } | |
1052 | |
1053 template<typename TA, typename TB, typename TC, typename TD> | |
1054 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) { | |
1055 ParamType params; | |
1056 if (!Read(msg, ¶ms)) | |
1057 return false; | |
1058 *a = params.a; | |
1059 *b = params.b; | |
1060 *c = params.c; | |
1061 *d = params.d; | |
1062 return true; | |
1063 } | |
1064 | |
1065 template<typename TA, typename TB, typename TC, typename TD, typename TE> | |
1066 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) { | |
1067 ParamType params; | |
1068 if (!Read(msg, ¶ms)) | |
1069 return false; | |
1070 *a = params.a; | |
1071 *b = params.b; | |
1072 *c = params.c; | |
1073 *d = params.d; | |
1074 *e = params.e; | |
1075 return true; | |
1076 } | |
1077 }; | 954 }; |
1078 | 955 |
1079 // defined in ipc_logging.cc | 956 // defined in ipc_logging.cc |
1080 IPC_EXPORT void GenerateLogData(const std::string& channel, | 957 IPC_EXPORT void GenerateLogData(const std::string& channel, |
1081 const Message& message, | 958 const Message& message, |
1082 LogData* data); | 959 LogData* data); |
1083 | 960 |
1084 | 961 |
1085 #if defined(IPC_MESSAGE_LOG_ENABLED) | 962 #if defined(IPC_MESSAGE_LOG_ENABLED) |
1086 inline void AddOutputParamsToLog(const Message* msg, std::string* l) { | 963 inline void AddOutputParamsToLog(const Message* msg, std::string* l) { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1132 | 1009 |
1133 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) { | 1010 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) { |
1134 return ReadParam(&msg, &iter, &out_); | 1011 return ReadParam(&msg, &iter, &out_); |
1135 } | 1012 } |
1136 | 1013 |
1137 RefTuple out_; | 1014 RefTuple out_; |
1138 }; | 1015 }; |
1139 | 1016 |
1140 // Used for synchronous messages. | 1017 // Used for synchronous messages. |
1141 template <class SendParamType, class ReplyParamType> | 1018 template <class SendParamType, class ReplyParamType> |
1142 class MessageWithReply : public SyncMessage { | 1019 class SyncMessageSchema { |
1143 public: | 1020 public: |
1144 typedef SendParamType SendParam; | 1021 typedef SendParamType SendParam; |
1145 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam; | 1022 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam; |
1146 typedef ReplyParamType ReplyParam; | 1023 typedef ReplyParamType ReplyParam; |
1147 | 1024 |
1148 MessageWithReply(int32 routing_id, uint32 type, | 1025 static void Write(Message* msg, const RefSendParam& send) IPC_MSG_NOINLINE; |
1149 const RefSendParam& send, const ReplyParam& reply); | |
1150 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE; | 1026 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE; |
1151 static bool ReadReplyParam( | 1027 static bool ReadReplyParam( |
1152 const Message* msg, | 1028 const Message* msg, |
1153 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE; | 1029 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE; |
1154 | 1030 |
1155 template<class T, class S, class Method> | 1031 template<class T, class S, class Method> |
1156 static bool Dispatch(const Message* msg, T* obj, S* sender, Method func) { | 1032 static bool DispatchWithSendParams(bool ok, const SendParam& send_params, |
1157 SendParam send_params; | 1033 const Message* msg, T* obj, S* sender, |
1158 Message* reply = GenerateReply(msg); | 1034 Method func) { |
1159 bool error; | 1035 Message* reply = SyncMessage::GenerateReply(msg); |
1160 if (ReadSendParam(msg, &send_params)) { | 1036 if (ok) { |
1161 typename TupleTypes<ReplyParam>::ValueTuple reply_params; | 1037 typename TupleTypes<ReplyParam>::ValueTuple reply_params; |
1162 DispatchToMethod(obj, func, send_params, &reply_params); | 1038 DispatchToMethod(obj, func, send_params, &reply_params); |
1163 WriteParam(reply, reply_params); | 1039 WriteParam(reply, reply_params); |
1164 error = false; | |
1165 LogReplyParamsToMessage(reply_params, msg); | 1040 LogReplyParamsToMessage(reply_params, msg); |
1166 } else { | 1041 } else { |
1167 NOTREACHED() << "Error deserializing message " << msg->type(); | 1042 NOTREACHED() << "Error deserializing message " << msg->type(); |
1168 reply->set_reply_error(); | 1043 reply->set_reply_error(); |
1169 error = true; | |
1170 } | 1044 } |
1171 | |
1172 sender->Send(reply); | 1045 sender->Send(reply); |
1173 return !error; | 1046 return ok; |
1174 } | 1047 } |
1175 | 1048 |
1176 template<class T, class Method> | 1049 template<class T, class Method> |
1177 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) { | 1050 static bool DispatchDelayReplyWithSendParams(bool ok, |
1178 SendParam send_params; | 1051 const SendParam& send_params, |
1179 Message* reply = GenerateReply(msg); | 1052 const Message* msg, T* obj, |
1180 bool error; | 1053 Method func) { |
1181 if (ReadSendParam(msg, &send_params)) { | 1054 Message* reply = SyncMessage::GenerateReply(msg); |
| 1055 if (ok) { |
1182 Tuple1<Message&> t = MakeRefTuple(*reply); | 1056 Tuple1<Message&> t = MakeRefTuple(*reply); |
1183 ConnectMessageAndReply(msg, reply); | 1057 ConnectMessageAndReply(msg, reply); |
1184 DispatchToMethod(obj, func, send_params, &t); | 1058 DispatchToMethod(obj, func, send_params, &t); |
1185 error = false; | |
1186 } else { | 1059 } else { |
1187 NOTREACHED() << "Error deserializing message " << msg->type(); | 1060 NOTREACHED() << "Error deserializing message " << msg->type(); |
1188 reply->set_reply_error(); | 1061 reply->set_reply_error(); |
1189 obj->Send(reply); | 1062 obj->Send(reply); |
1190 error = true; | |
1191 } | 1063 } |
1192 return !error; | 1064 return ok; |
1193 } | 1065 } |
1194 | 1066 |
1195 template<typename TA> | 1067 template<typename TA> |
1196 static void WriteReplyParams(Message* reply, TA a) { | 1068 static void WriteReplyParams(Message* reply, TA a) { |
1197 ReplyParam p(a); | 1069 ReplyParam p(a); |
1198 WriteParam(reply, p); | 1070 WriteParam(reply, p); |
1199 } | 1071 } |
1200 | 1072 |
1201 template<typename TA, typename TB> | 1073 template<typename TA, typename TB> |
1202 static void WriteReplyParams(Message* reply, TA a, TB b) { | 1074 static void WriteReplyParams(Message* reply, TA a, TB b) { |
(...skipping 18 matching lines...) Expand all Loading... |
1221 ReplyParam p(a, b, c, d, e); | 1093 ReplyParam p(a, b, c, d, e); |
1222 WriteParam(reply, p); | 1094 WriteParam(reply, p); |
1223 } | 1095 } |
1224 }; | 1096 }; |
1225 | 1097 |
1226 //----------------------------------------------------------------------------- | 1098 //----------------------------------------------------------------------------- |
1227 | 1099 |
1228 } // namespace IPC | 1100 } // namespace IPC |
1229 | 1101 |
1230 #endif // IPC_IPC_MESSAGE_UTILS_H_ | 1102 #endif // IPC_IPC_MESSAGE_UTILS_H_ |
OLD | NEW |