blob: 6bfd103c6d88423cc3855eefd821c0a07416d4e1 [file] [log] [blame]
jochen@chromium.org30c8e912012-01-29 19:57:33 +09001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
agl@chromium.org1c6dcf22009-07-23 08:57:21 +09002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef IPC_IPC_MESSAGE_UTILS_H_
6#define IPC_IPC_MESSAGE_UTILS_H_
7
jhawkins@chromium.org63c75eb2010-03-09 09:38:41 +09008#include <algorithm>
agl@chromium.org1c6dcf22009-07-23 08:57:21 +09009#include <map>
mirandac@chromium.orgee262ad2010-05-14 04:10:34 +090010#include <set>
tfarina@chromium.org439aef62011-03-21 10:07:01 +090011#include <string>
12#include <vector>
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090013
jdduke@chromium.org556db8b2014-03-19 05:48:35 +090014#include "base/containers/small_map.h"
rvargas@chromium.org9e469f62014-01-28 06:36:00 +090015#include "base/files/file.h"
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090016#include "base/format_macros.h"
jdduke@chromium.orgc6d80f02014-05-20 11:34:56 +090017#include "base/memory/scoped_ptr.h"
hashimoto@chromium.orgbbf7c502012-11-14 15:35:52 +090018#include "base/memory/scoped_vector.h"
avi@chromium.orge7eaf392013-06-11 15:32:18 +090019#include "base/strings/string16.h"
20#include "base/strings/string_util.h"
21#include "base/strings/stringprintf.h"
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090022#include "base/tuple.h"
tsepez@chromium.org4afe8f72012-10-24 08:03:35 +090023#include "ipc/ipc_message_start.h"
erg@google.comb16c8a62010-08-25 05:29:02 +090024#include "ipc/ipc_param_traits.h"
erg@google.combfae8592010-08-17 09:24:54 +090025#include "ipc/ipc_sync_message.h"
erg@google.comcab37e72010-08-14 05:43:58 +090026
erg@google.come6ffcb52010-08-18 03:38:24 +090027#if defined(COMPILER_GCC)
28// GCC "helpfully" tries to inline template methods in release mode. Except we
29// want the majority of the template junk being expanded once in the
30// implementation file (and only provide the definitions in
31// ipc_message_utils_impl.h in those files) and exported, instead of expanded
32// at every call site. Special note: GCC happily accepts the attribute before
33// the method declaration, but only acts on it if it is after.
erg@google.comcb9c43f2010-08-20 05:23:25 +090034#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 40500
35// Starting in gcc 4.5, the noinline no longer implies the concept covered by
36// the introduced noclone attribute, which will create specialized versions of
37// functions/methods when certain types are constant.
38// www.gnu.org/software/gcc/gcc-4.5/changes.html
39#define IPC_MSG_NOINLINE __attribute__((noinline, noclone));
40#else
erg@google.come6ffcb52010-08-18 03:38:24 +090041#define IPC_MSG_NOINLINE __attribute__((noinline));
erg@google.comcb9c43f2010-08-20 05:23:25 +090042#endif
erg@google.come6ffcb52010-08-18 03:38:24 +090043#elif defined(COMPILER_MSVC)
44// MSVC++ doesn't do this.
45#define IPC_MSG_NOINLINE
46#else
47#error "Please add the noinline property for your new compiler here."
48#endif
49
erg@google.come6ffcb52010-08-18 03:38:24 +090050namespace base {
dmazzoni@chromium.org13e53652011-07-13 04:15:03 +090051class DictionaryValue;
brettw@chromium.orga7086942013-02-02 14:12:33 +090052class FilePath;
dmazzoni@chromium.org13e53652011-07-13 04:15:03 +090053class ListValue;
avi@chromium.orgd8179652013-06-13 22:47:46 +090054class NullableString16;
erg@google.come6ffcb52010-08-18 03:38:24 +090055class Time;
apatrick@chromium.org519c1c62010-10-22 07:04:52 +090056class TimeDelta;
isherman@chromium.org9952aaf2011-09-03 05:42:04 +090057class TimeTicks;
erg@google.come6ffcb52010-08-18 03:38:24 +090058struct FileDescriptor;
59}
60
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090061namespace IPC {
62
erg@google.come6ffcb52010-08-18 03:38:24 +090063struct ChannelHandle;
64
brettw@chromium.orgce352e52012-06-05 06:18:25 +090065// -----------------------------------------------------------------------------
66// How we send IPC message logs across channels.
67struct IPC_EXPORT LogData {
68 LogData();
69 ~LogData();
70
71 std::string channel;
72 int32 routing_id;
73 uint32 type; // "User-defined" message type, from ipc_message.h.
74 std::string flags;
75 int64 sent; // Time that the message was sent (i.e. at Send()).
76 int64 receive; // Time before it was dispatched (i.e. before calling
77 // OnMessageReceived).
78 int64 dispatch; // Time after it was dispatched (i.e. after calling
79 // OnMessageReceived).
80 std::string message_name;
81 std::string params;
82};
83
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090084//-----------------------------------------------------------------------------
viettrungluu@chromium.orgc3ad0512012-12-18 05:23:47 +090085
tsepez@chromium.org1ac46132011-02-12 03:46:19 +090086// A dummy struct to place first just to allow leading commas for all
87// members in the macro-generated constructor initializer lists.
88struct NoParams {
89};
90
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090091template <class P>
92static inline void WriteParam(Message* m, const P& p) {
aa@chromium.org1605b6d2009-08-14 14:43:53 +090093 typedef typename SimilarTypeTraits<P>::Type Type;
thakis@chromium.orgb13bd1d2010-06-17 03:39:53 +090094 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090095}
96
97template <class P>
jbates@chromium.org0fc87362012-03-08 05:42:56 +090098static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m,
99 PickleIterator* iter,
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900100 P* p) {
aa@chromium.org1605b6d2009-08-14 14:43:53 +0900101 typedef typename SimilarTypeTraits<P>::Type Type;
102 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900103}
104
105template <class P>
erg@google.com8aca7272010-08-19 03:33:57 +0900106static inline void LogParam(const P& p, std::string* l) {
aa@chromium.org1605b6d2009-08-14 14:43:53 +0900107 typedef typename SimilarTypeTraits<P>::Type Type;
thakis@chromium.orgb13bd1d2010-06-17 03:39:53 +0900108 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900109}
110
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900111// Primitive ParamTraits -------------------------------------------------------
112
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900113template <>
114struct ParamTraits<bool> {
115 typedef bool param_type;
116 static void Write(Message* m, const param_type& p) {
117 m->WriteBool(p);
118 }
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900119 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900120 return m->ReadBool(iter, r);
121 }
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900122 IPC_EXPORT static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900123};
124
125template <>
tsepez@chromium.org09eb95f2013-07-13 08:12:28 +0900126struct IPC_EXPORT ParamTraits<unsigned char> {
jschuh@chromium.orgccd324a2013-07-13 13:42:10 +0900127 typedef unsigned char param_type;
tsepez@chromium.org09eb95f2013-07-13 08:12:28 +0900128 static void Write(Message* m, const param_type& p);
129 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
130 static void Log(const param_type& p, std::string* l);
131};
132
133template <>
134struct IPC_EXPORT ParamTraits<unsigned short> {
135 typedef unsigned short param_type;
136 static void Write(Message* m, const param_type& p);
137 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
138 static void Log(const param_type& p, std::string* l);
139};
140
141template <>
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900142struct ParamTraits<int> {
143 typedef int param_type;
144 static void Write(Message* m, const param_type& p) {
145 m->WriteInt(p);
146 }
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900147 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900148 return m->ReadInt(iter, r);
149 }
darin@chromium.org80e4c5e2011-08-16 05:41:46 +0900150 IPC_EXPORT static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900151};
152
153template <>
deanm@chromium.org1543aa72009-07-29 04:35:08 +0900154struct ParamTraits<unsigned int> {
155 typedef unsigned int param_type;
156 static void Write(Message* m, const param_type& p) {
157 m->WriteInt(p);
158 }
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900159 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
deanm@chromium.org1543aa72009-07-29 04:35:08 +0900160 return m->ReadInt(iter, reinterpret_cast<int*>(r));
161 }
darin@chromium.org80e4c5e2011-08-16 05:41:46 +0900162 IPC_EXPORT static void Log(const param_type& p, std::string* l);
deanm@chromium.org1543aa72009-07-29 04:35:08 +0900163};
164
165template <>
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900166struct ParamTraits<long> {
167 typedef long param_type;
168 static void Write(Message* m, const param_type& p) {
mdm@chromium.org69bca9d2012-03-23 09:03:10 +0900169 m->WriteLongUsingDangerousNonPortableLessPersistableForm(p);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900170 }
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900171 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900172 return m->ReadLong(iter, r);
173 }
darin@chromium.org80e4c5e2011-08-16 05:41:46 +0900174 IPC_EXPORT static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900175};
176
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900177template <>
178struct ParamTraits<unsigned long> {
179 typedef unsigned long param_type;
180 static void Write(Message* m, const param_type& p) {
mdm@chromium.org69bca9d2012-03-23 09:03:10 +0900181 m->WriteLongUsingDangerousNonPortableLessPersistableForm(p);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900182 }
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900183 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
deanm@chromium.org1543aa72009-07-29 04:35:08 +0900184 return m->ReadLong(iter, reinterpret_cast<long*>(r));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900185 }
darin@chromium.org80e4c5e2011-08-16 05:41:46 +0900186 IPC_EXPORT static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900187};
188
189template <>
deanm@chromium.org1543aa72009-07-29 04:35:08 +0900190struct ParamTraits<long long> {
191 typedef long long param_type;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900192 static void Write(Message* m, const param_type& p) {
193 m->WriteInt64(static_cast<int64>(p));
194 }
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900195 static bool Read(const Message* m, PickleIterator* iter,
196 param_type* r) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900197 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
198 }
darin@chromium.org80e4c5e2011-08-16 05:41:46 +0900199 IPC_EXPORT static void Log(const param_type& p, std::string* l);
deanm@chromium.org1543aa72009-07-29 04:35:08 +0900200};
201
202template <>
203struct ParamTraits<unsigned long long> {
204 typedef unsigned long long param_type;
205 static void Write(Message* m, const param_type& p) {
206 m->WriteInt64(p);
207 }
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900208 static bool Read(const Message* m, PickleIterator* iter,
209 param_type* r) {
deanm@chromium.org1543aa72009-07-29 04:35:08 +0900210 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
211 }
darin@chromium.org80e4c5e2011-08-16 05:41:46 +0900212 IPC_EXPORT static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900213};
214
jeremy@chromium.org4be619f2010-06-17 12:29:26 +0900215// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
216// should be sure to check the sanity of these values after receiving them over
217// IPC.
218template <>
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900219struct IPC_EXPORT ParamTraits<float> {
jeremy@chromium.org4be619f2010-06-17 12:29:26 +0900220 typedef float param_type;
piman@chromium.orgdd413b42013-10-31 18:27:31 +0900221 static void Write(Message* m, const param_type& p) {
222 m->WriteFloat(p);
223 }
224 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
225 return m->ReadFloat(iter, r);
226 }
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900227 static void Log(const param_type& p, std::string* l);
jeremy@chromium.org4be619f2010-06-17 12:29:26 +0900228};
229
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900230template <>
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900231struct IPC_EXPORT ParamTraits<double> {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900232 typedef double param_type;
tsepez@chromium.org3081fac2012-05-31 06:15:57 +0900233 static void Write(Message* m, const param_type& p);
234 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
235 static void Log(const param_type& p, std::string* l);
236};
237
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900238// STL ParamTraits -------------------------------------------------------------
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900239
240template <>
241struct ParamTraits<std::string> {
242 typedef std::string param_type;
243 static void Write(Message* m, const param_type& p) {
244 m->WriteString(p);
245 }
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900246 static bool Read(const Message* m, PickleIterator* iter,
247 param_type* r) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900248 return m->ReadString(iter, r);
249 }
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900250 IPC_EXPORT static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900251};
252
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900253template <>
254struct ParamTraits<std::wstring> {
255 typedef std::wstring param_type;
256 static void Write(Message* m, const param_type& p) {
257 m->WriteWString(p);
evan@chromium.orga6590362009-07-28 06:09:07 +0900258 }
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900259 static bool Read(const Message* m, PickleIterator* iter,
260 param_type* r) {
261 return m->ReadWString(iter, r);
evan@chromium.orga6590362009-07-28 06:09:07 +0900262 }
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900263 IPC_EXPORT static void Log(const param_type& p, std::string* l);
264};
265
266// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
267// need this trait.
268#if !defined(WCHAR_T_IS_UTF16)
269template <>
brettw@chromium.org5b040852013-12-03 09:39:26 +0900270struct ParamTraits<base::string16> {
271 typedef base::string16 param_type;
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900272 static void Write(Message* m, const param_type& p) {
273 m->WriteString16(p);
274 }
275 static bool Read(const Message* m, PickleIterator* iter,
276 param_type* r) {
277 return m->ReadString16(iter, r);
278 }
279 IPC_EXPORT static void Log(const param_type& p, std::string* l);
280};
evan@chromium.orga6590362009-07-28 06:09:07 +0900281#endif
evan@chromium.orga6590362009-07-28 06:09:07 +0900282
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900283template <>
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900284struct IPC_EXPORT ParamTraits<std::vector<char> > {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900285 typedef std::vector<char> param_type;
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900286 static void Write(Message* m, const param_type& p);
287 static bool Read(const Message*, PickleIterator* iter, param_type* r);
288 static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900289};
290
bauerb@chromium.org17246c72011-10-06 03:55:42 +0900291template <>
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900292struct IPC_EXPORT ParamTraits<std::vector<unsigned char> > {
293 typedef std::vector<unsigned char> param_type;
294 static void Write(Message* m, const param_type& p);
295 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
296 static void Log(const param_type& p, std::string* l);
297};
298
299template <>
300struct IPC_EXPORT ParamTraits<std::vector<bool> > {
bauerb@chromium.org17246c72011-10-06 03:55:42 +0900301 typedef std::vector<bool> param_type;
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900302 static void Write(Message* m, const param_type& p);
303 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
304 static void Log(const param_type& p, std::string* l);
bauerb@chromium.org17246c72011-10-06 03:55:42 +0900305};
306
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900307template <class P>
308struct ParamTraits<std::vector<P> > {
309 typedef std::vector<P> param_type;
310 static void Write(Message* m, const param_type& p) {
311 WriteParam(m, static_cast<int>(p.size()));
312 for (size_t i = 0; i < p.size(); i++)
313 WriteParam(m, p[i]);
314 }
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900315 static bool Read(const Message* m, PickleIterator* iter,
316 param_type* r) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900317 int size;
cevans@chromium.org7600d942009-12-31 14:17:23 +0900318 // ReadLength() checks for < 0 itself.
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900319 if (!m->ReadLength(iter, &size))
320 return false;
321 // Resizing beforehand is not safe, see BUG 1006367 for details.
cevans@chromium.org7600d942009-12-31 14:17:23 +0900322 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
323 return false;
324 r->resize(size);
325 for (int i = 0; i < size; i++) {
326 if (!ReadParam(m, iter, &(*r)[i]))
327 return false;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900328 }
329 return true;
330 }
erg@google.com8aca7272010-08-19 03:33:57 +0900331 static void Log(const param_type& p, std::string* l) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900332 for (size_t i = 0; i < p.size(); ++i) {
333 if (i != 0)
erg@google.com8aca7272010-08-19 03:33:57 +0900334 l->append(" ");
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900335 LogParam((p[i]), l);
336 }
337 }
338};
339
mirandac@chromium.orgee262ad2010-05-14 04:10:34 +0900340template <class P>
341struct ParamTraits<std::set<P> > {
342 typedef std::set<P> param_type;
343 static void Write(Message* m, const param_type& p) {
344 WriteParam(m, static_cast<int>(p.size()));
345 typename param_type::const_iterator iter;
346 for (iter = p.begin(); iter != p.end(); ++iter)
347 WriteParam(m, *iter);
348 }
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900349 static bool Read(const Message* m, PickleIterator* iter,
350 param_type* r) {
mirandac@chromium.orgee262ad2010-05-14 04:10:34 +0900351 int size;
352 if (!m->ReadLength(iter, &size))
353 return false;
354 for (int i = 0; i < size; ++i) {
355 P item;
356 if (!ReadParam(m, iter, &item))
357 return false;
358 r->insert(item);
359 }
360 return true;
361 }
erg@google.com8aca7272010-08-19 03:33:57 +0900362 static void Log(const param_type& p, std::string* l) {
363 l->append("<std::set>");
mirandac@chromium.orgee262ad2010-05-14 04:10:34 +0900364 }
365};
366
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900367template <class K, class V>
368struct ParamTraits<std::map<K, V> > {
369 typedef std::map<K, V> param_type;
370 static void Write(Message* m, const param_type& p) {
371 WriteParam(m, static_cast<int>(p.size()));
372 typename param_type::const_iterator iter;
373 for (iter = p.begin(); iter != p.end(); ++iter) {
374 WriteParam(m, iter->first);
375 WriteParam(m, iter->second);
376 }
377 }
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900378 static bool Read(const Message* m, PickleIterator* iter,
379 param_type* r) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900380 int size;
381 if (!ReadParam(m, iter, &size) || size < 0)
382 return false;
383 for (int i = 0; i < size; ++i) {
384 K k;
385 if (!ReadParam(m, iter, &k))
386 return false;
387 V& value = (*r)[k];
388 if (!ReadParam(m, iter, &value))
389 return false;
390 }
391 return true;
392 }
erg@google.com8aca7272010-08-19 03:33:57 +0900393 static void Log(const param_type& p, std::string* l) {
394 l->append("<std::map>");
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900395 }
396};
397
jam@chromium.org0aa05022009-08-04 11:00:56 +0900398template <class A, class B>
399struct ParamTraits<std::pair<A, B> > {
400 typedef std::pair<A, B> param_type;
401 static void Write(Message* m, const param_type& p) {
402 WriteParam(m, p.first);
403 WriteParam(m, p.second);
404 }
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900405 static bool Read(const Message* m, PickleIterator* iter,
406 param_type* r) {
jam@chromium.org0aa05022009-08-04 11:00:56 +0900407 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
408 }
erg@google.com8aca7272010-08-19 03:33:57 +0900409 static void Log(const param_type& p, std::string* l) {
410 l->append("(");
jam@chromium.org0aa05022009-08-04 11:00:56 +0900411 LogParam(p.first, l);
erg@google.com8aca7272010-08-19 03:33:57 +0900412 l->append(", ");
jam@chromium.org0aa05022009-08-04 11:00:56 +0900413 LogParam(p.second, l);
erg@google.com8aca7272010-08-19 03:33:57 +0900414 l->append(")");
jam@chromium.org0aa05022009-08-04 11:00:56 +0900415 }
416};
417
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900418// Base ParamTraits ------------------------------------------------------------
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900419
420template <>
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900421struct IPC_EXPORT ParamTraits<base::DictionaryValue> {
422 typedef base::DictionaryValue param_type;
erg@google.come6ffcb52010-08-18 03:38:24 +0900423 static void Write(Message* m, const param_type& p);
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900424 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
erg@google.com8aca7272010-08-19 03:33:57 +0900425 static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900426};
427
428#if defined(OS_POSIX)
429// FileDescriptors may be serialised over IPC channels on POSIX. On the
430// receiving side, the FileDescriptor is a valid duplicate of the file
431// descriptor which was transmitted: *it is not just a copy of the integer like
432// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
433// this case, the receiving end will see a value of -1. *Zero is a valid file
434// descriptor*.
435//
436// The received file descriptor will have the |auto_close| flag set to true. The
437// code which handles the message is responsible for taking ownership of it.
438// File descriptors are OS resources and must be closed when no longer needed.
439//
440// When sending a file descriptor, the file descriptor must be valid at the time
441// of transmission. Since transmission is not synchronous, one should consider
442// dup()ing any file descriptors to be transmitted and setting the |auto_close|
443// flag, which causes the file descriptor to be closed after writing.
444template<>
darin@chromium.org80e4c5e2011-08-16 05:41:46 +0900445struct IPC_EXPORT ParamTraits<base::FileDescriptor> {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900446 typedef base::FileDescriptor param_type;
erg@google.come6ffcb52010-08-18 03:38:24 +0900447 static void Write(Message* m, const param_type& p);
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900448 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
erg@google.com8aca7272010-08-19 03:33:57 +0900449 static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900450};
jhawkins@chromium.org63c75eb2010-03-09 09:38:41 +0900451#endif // defined(OS_POSIX)
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900452
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900453template <>
brettw@chromium.orga7086942013-02-02 14:12:33 +0900454struct IPC_EXPORT ParamTraits<base::FilePath> {
455 typedef base::FilePath param_type;
erg@google.come6ffcb52010-08-18 03:38:24 +0900456 static void Write(Message* m, const param_type& p);
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900457 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
erg@google.com8aca7272010-08-19 03:33:57 +0900458 static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900459};
460
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900461template <>
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900462struct IPC_EXPORT ParamTraits<base::ListValue> {
463 typedef base::ListValue param_type;
erg@google.com20b66e32010-10-01 05:06:30 +0900464 static void Write(Message* m, const param_type& p);
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900465 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900466 static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900467};
468
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900469template <>
avi@chromium.orgd8179652013-06-13 22:47:46 +0900470struct IPC_EXPORT ParamTraits<base::NullableString16> {
471 typedef base::NullableString16 param_type;
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900472 static void Write(Message* m, const param_type& p);
473 static bool Read(const Message* m, PickleIterator* iter,
474 param_type* r);
475 static void Log(const param_type& p, std::string* l);
476};
477
478template <>
rvargas@chromium.org9e469f62014-01-28 06:36:00 +0900479struct IPC_EXPORT ParamTraits<base::File::Info> {
480 typedef base::File::Info param_type;
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900481 static void Write(Message* m, const param_type& p);
482 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
483 static void Log(const param_type& p, std::string* l);
484};
485
486template <>
rvargas@chromium.org9e469f62014-01-28 06:36:00 +0900487struct SimilarTypeTraits<base::File::Error> {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900488 typedef int Type;
489};
490
grt@chromium.orgb9abb172013-03-01 06:46:11 +0900491#if defined(OS_WIN)
492template <>
493struct SimilarTypeTraits<HWND> {
494 typedef HANDLE Type;
495};
496#endif // defined(OS_WIN)
497
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900498template <>
499struct IPC_EXPORT ParamTraits<base::Time> {
500 typedef base::Time param_type;
501 static void Write(Message* m, const param_type& p);
502 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
503 static void Log(const param_type& p, std::string* l);
504};
505
506template <>
507struct IPC_EXPORT ParamTraits<base::TimeDelta> {
508 typedef base::TimeDelta param_type;
509 static void Write(Message* m, const param_type& p);
510 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
511 static void Log(const param_type& p, std::string* l);
512};
513
514template <>
515struct IPC_EXPORT ParamTraits<base::TimeTicks> {
516 typedef base::TimeTicks param_type;
517 static void Write(Message* m, const param_type& p);
518 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
519 static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900520};
521
522template <>
523struct ParamTraits<Tuple0> {
524 typedef Tuple0 param_type;
525 static void Write(Message* m, const param_type& p) {
526 }
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900527 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900528 return true;
529 }
erg@google.com8aca7272010-08-19 03:33:57 +0900530 static void Log(const param_type& p, std::string* l) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900531 }
532};
533
534template <class A>
535struct ParamTraits< Tuple1<A> > {
536 typedef Tuple1<A> param_type;
537 static void Write(Message* m, const param_type& p) {
538 WriteParam(m, p.a);
539 }
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900540 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900541 return ReadParam(m, iter, &r->a);
542 }
erg@google.com8aca7272010-08-19 03:33:57 +0900543 static void Log(const param_type& p, std::string* l) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900544 LogParam(p.a, l);
545 }
546};
547
548template <class A, class B>
549struct ParamTraits< Tuple2<A, B> > {
550 typedef Tuple2<A, B> param_type;
551 static void Write(Message* m, const param_type& p) {
552 WriteParam(m, p.a);
553 WriteParam(m, p.b);
554 }
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900555 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900556 return (ReadParam(m, iter, &r->a) &&
557 ReadParam(m, iter, &r->b));
558 }
erg@google.com8aca7272010-08-19 03:33:57 +0900559 static void Log(const param_type& p, std::string* l) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900560 LogParam(p.a, l);
erg@google.com8aca7272010-08-19 03:33:57 +0900561 l->append(", ");
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900562 LogParam(p.b, l);
563 }
564};
565
566template <class A, class B, class C>
567struct ParamTraits< Tuple3<A, B, C> > {
568 typedef Tuple3<A, B, C> param_type;
569 static void Write(Message* m, const param_type& p) {
570 WriteParam(m, p.a);
571 WriteParam(m, p.b);
572 WriteParam(m, p.c);
573 }
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900574 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900575 return (ReadParam(m, iter, &r->a) &&
576 ReadParam(m, iter, &r->b) &&
577 ReadParam(m, iter, &r->c));
578 }
erg@google.com8aca7272010-08-19 03:33:57 +0900579 static void Log(const param_type& p, std::string* l) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900580 LogParam(p.a, l);
erg@google.com8aca7272010-08-19 03:33:57 +0900581 l->append(", ");
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900582 LogParam(p.b, l);
erg@google.com8aca7272010-08-19 03:33:57 +0900583 l->append(", ");
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900584 LogParam(p.c, l);
585 }
586};
587
588template <class A, class B, class C, class D>
589struct ParamTraits< Tuple4<A, B, C, D> > {
590 typedef Tuple4<A, B, C, D> param_type;
591 static void Write(Message* m, const param_type& p) {
592 WriteParam(m, p.a);
593 WriteParam(m, p.b);
594 WriteParam(m, p.c);
595 WriteParam(m, p.d);
596 }
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900597 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900598 return (ReadParam(m, iter, &r->a) &&
599 ReadParam(m, iter, &r->b) &&
600 ReadParam(m, iter, &r->c) &&
601 ReadParam(m, iter, &r->d));
602 }
erg@google.com8aca7272010-08-19 03:33:57 +0900603 static void Log(const param_type& p, std::string* l) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900604 LogParam(p.a, l);
erg@google.com8aca7272010-08-19 03:33:57 +0900605 l->append(", ");
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900606 LogParam(p.b, l);
erg@google.com8aca7272010-08-19 03:33:57 +0900607 l->append(", ");
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900608 LogParam(p.c, l);
erg@google.com8aca7272010-08-19 03:33:57 +0900609 l->append(", ");
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900610 LogParam(p.d, l);
611 }
612};
613
614template <class A, class B, class C, class D, class E>
615struct ParamTraits< Tuple5<A, B, C, D, E> > {
616 typedef Tuple5<A, B, C, D, E> param_type;
617 static void Write(Message* m, const param_type& p) {
618 WriteParam(m, p.a);
619 WriteParam(m, p.b);
620 WriteParam(m, p.c);
621 WriteParam(m, p.d);
622 WriteParam(m, p.e);
623 }
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900624 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900625 return (ReadParam(m, iter, &r->a) &&
626 ReadParam(m, iter, &r->b) &&
627 ReadParam(m, iter, &r->c) &&
628 ReadParam(m, iter, &r->d) &&
629 ReadParam(m, iter, &r->e));
630 }
erg@google.com8aca7272010-08-19 03:33:57 +0900631 static void Log(const param_type& p, std::string* l) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900632 LogParam(p.a, l);
erg@google.com8aca7272010-08-19 03:33:57 +0900633 l->append(", ");
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900634 LogParam(p.b, l);
erg@google.com8aca7272010-08-19 03:33:57 +0900635 l->append(", ");
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900636 LogParam(p.c, l);
erg@google.com8aca7272010-08-19 03:33:57 +0900637 l->append(", ");
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900638 LogParam(p.d, l);
erg@google.com8aca7272010-08-19 03:33:57 +0900639 l->append(", ");
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900640 LogParam(p.e, l);
641 }
642};
643
hashimoto@chromium.orgbbf7c502012-11-14 15:35:52 +0900644template<class P>
645struct ParamTraits<ScopedVector<P> > {
646 typedef ScopedVector<P> param_type;
647 static void Write(Message* m, const param_type& p) {
648 WriteParam(m, static_cast<int>(p.size()));
649 for (size_t i = 0; i < p.size(); i++)
650 WriteParam(m, *p[i]);
651 }
652 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
653 int size = 0;
654 if (!m->ReadLength(iter, &size))
655 return false;
656 if (INT_MAX/sizeof(P) <= static_cast<size_t>(size))
657 return false;
658 r->resize(size);
659 for (int i = 0; i < size; i++) {
660 (*r)[i] = new P();
661 if (!ReadParam(m, iter, (*r)[i]))
662 return false;
663 }
664 return true;
665 }
666 static void Log(const param_type& p, std::string* l) {
667 for (size_t i = 0; i < p.size(); ++i) {
668 if (i != 0)
669 l->append(" ");
670 LogParam(*p[i], l);
671 }
672 }
673};
674
jdduke@chromium.org556db8b2014-03-19 05:48:35 +0900675template <typename NormalMap,
676 int kArraySize,
677 typename EqualKey,
678 typename MapInit>
679struct ParamTraits<base::SmallMap<NormalMap, kArraySize, EqualKey, MapInit> > {
680 typedef base::SmallMap<NormalMap, kArraySize, EqualKey, MapInit> param_type;
681 typedef typename param_type::key_type K;
682 typedef typename param_type::data_type V;
683 static void Write(Message* m, const param_type& p) {
684 WriteParam(m, static_cast<int>(p.size()));
685 typename param_type::const_iterator iter;
686 for (iter = p.begin(); iter != p.end(); ++iter) {
687 WriteParam(m, iter->first);
688 WriteParam(m, iter->second);
689 }
690 }
691 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
692 int size;
693 if (!m->ReadLength(iter, &size))
694 return false;
695 for (int i = 0; i < size; ++i) {
696 K key;
697 if (!ReadParam(m, iter, &key))
698 return false;
699 V& value = (*r)[key];
700 if (!ReadParam(m, iter, &value))
701 return false;
702 }
703 return true;
704 }
705 static void Log(const param_type& p, std::string* l) {
706 l->append("<base::SmallMap>");
707 }
708};
709
jdduke@chromium.orgc6d80f02014-05-20 11:34:56 +0900710template <class P>
711struct ParamTraits<scoped_ptr<P> > {
712 typedef scoped_ptr<P> param_type;
713 static void Write(Message* m, const param_type& p) {
714 bool valid = !!p;
715 WriteParam(m, valid);
716 if (valid)
717 WriteParam(m, *p);
718 }
719 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
720 bool valid = false;
721 if (!ReadParam(m, iter, &valid))
722 return false;
723
724 if (!valid) {
725 r->reset();
726 return true;
727 }
728
729 param_type temp(new P());
730 if (!ReadParam(m, iter, temp.get()))
731 return false;
732
733 r->swap(temp);
734 return true;
735 }
736 static void Log(const param_type& p, std::string* l) {
737 if (p)
738 LogParam(*p, l);
739 else
740 l->append("NULL");
741 }
742};
743
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900744// IPC types ParamTraits -------------------------------------------------------
745
746// A ChannelHandle is basically a platform-inspecific wrapper around the
747// fact that IPC endpoints are handled specially on POSIX. See above comments
748// on FileDescriptor for more background.
749template<>
750struct IPC_EXPORT ParamTraits<IPC::ChannelHandle> {
751 typedef ChannelHandle param_type;
752 static void Write(Message* m, const param_type& p);
753 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
754 static void Log(const param_type& p, std::string* l);
755};
756
757template <>
758struct IPC_EXPORT ParamTraits<LogData> {
759 typedef LogData param_type;
760 static void Write(Message* m, const param_type& p);
761 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
762 static void Log(const param_type& p, std::string* l);
763};
764
765template <>
766struct IPC_EXPORT ParamTraits<Message> {
767 static void Write(Message* m, const Message& p);
768 static bool Read(const Message* m, PickleIterator* iter, Message* r);
769 static void Log(const Message& p, std::string* l);
770};
771
772// Windows ParamTraits ---------------------------------------------------------
773
774#if defined(OS_WIN)
775template <>
776struct IPC_EXPORT ParamTraits<HANDLE> {
777 typedef HANDLE param_type;
778 static void Write(Message* m, const param_type& p);
779 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
780 static void Log(const param_type& p, std::string* l);
781};
782
783template <>
784struct IPC_EXPORT ParamTraits<LOGFONT> {
785 typedef LOGFONT param_type;
786 static void Write(Message* m, const param_type& p);
787 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
788 static void Log(const param_type& p, std::string* l);
789};
790
791template <>
792struct IPC_EXPORT ParamTraits<MSG> {
793 typedef MSG param_type;
794 static void Write(Message* m, const param_type& p);
795 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
796 static void Log(const param_type& p, std::string* l);
797};
798#endif // defined(OS_WIN)
799
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900800//-----------------------------------------------------------------------------
801// Generic message subclasses
802
803// Used for asynchronous messages.
804template <class ParamType>
darin@chromium.orgb4587d52011-08-27 06:27:30 +0900805class MessageSchema {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900806 public:
807 typedef ParamType Param;
erg@google.come6ffcb52010-08-18 03:38:24 +0900808 typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900809
darin@chromium.orgb4587d52011-08-27 06:27:30 +0900810 static void Write(Message* msg, const RefParam& p) IPC_MSG_NOINLINE;
erg@google.come6ffcb52010-08-18 03:38:24 +0900811 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900812};
813
erg@google.come6ffcb52010-08-18 03:38:24 +0900814// defined in ipc_logging.cc
darin@chromium.org80e4c5e2011-08-16 05:41:46 +0900815IPC_EXPORT void GenerateLogData(const std::string& channel,
816 const Message& message,
scottbyer@chromium.orgf0cf0b72011-10-21 04:34:43 +0900817 LogData* data, bool get_params);
erg@google.come6ffcb52010-08-18 03:38:24 +0900818
819
820#if defined(IPC_MESSAGE_LOG_ENABLED)
erg@google.com8aca7272010-08-19 03:33:57 +0900821inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
822 const std::string& output_params = msg->output_params();
erg@google.come6ffcb52010-08-18 03:38:24 +0900823 if (!l->empty() && !output_params.empty())
erg@google.com8aca7272010-08-19 03:33:57 +0900824 l->append(", ");
erg@google.come6ffcb52010-08-18 03:38:24 +0900825
826 l->append(output_params);
827}
828
829template <class ReplyParamType>
830inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
831 const Message* msg) {
832 if (msg->received_time() != 0) {
erg@google.com8aca7272010-08-19 03:33:57 +0900833 std::string output_params;
erg@google.come6ffcb52010-08-18 03:38:24 +0900834 LogParam(reply_params, &output_params);
835 msg->set_output_params(output_params);
836 }
837}
838
839inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
840 if (msg->sent_time()) {
841 // Don't log the sync message after dispatch, as we don't have the
842 // output parameters at that point. Instead, save its data and log it
843 // with the outgoing reply message when it's sent.
844 LogData* data = new LogData;
scottbyer@chromium.orgf0cf0b72011-10-21 04:34:43 +0900845 GenerateLogData("", *msg, data, true);
erg@google.come6ffcb52010-08-18 03:38:24 +0900846 msg->set_dont_log();
847 reply->set_sync_log_data(data);
848 }
849}
850#else
erg@google.com8aca7272010-08-19 03:33:57 +0900851inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
erg@google.come6ffcb52010-08-18 03:38:24 +0900852
853template <class ReplyParamType>
854inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
855 const Message* msg) {}
856
857inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
858#endif
859
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900860// This class assumes that its template argument is a RefTuple (a Tuple with
erg@google.come6ffcb52010-08-18 03:38:24 +0900861// reference elements). This would go into ipc_message_utils_impl.h, but it is
862// also used by chrome_frame.
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900863template <class RefTuple>
864class ParamDeserializer : public MessageReplyDeserializer {
865 public:
866 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
867
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900868 bool SerializeOutputParameters(const IPC::Message& msg, PickleIterator iter) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900869 return ReadParam(&msg, &iter, &out_);
870 }
871
872 RefTuple out_;
873};
874
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900875// Used for synchronous messages.
876template <class SendParamType, class ReplyParamType>
darin@chromium.orgb4587d52011-08-27 06:27:30 +0900877class SyncMessageSchema {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900878 public:
879 typedef SendParamType SendParam;
erg@google.come6ffcb52010-08-18 03:38:24 +0900880 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900881 typedef ReplyParamType ReplyParam;
882
darin@chromium.orgb4587d52011-08-27 06:27:30 +0900883 static void Write(Message* msg, const RefSendParam& send) IPC_MSG_NOINLINE;
erg@google.come6ffcb52010-08-18 03:38:24 +0900884 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
885 static bool ReadReplyParam(
886 const Message* msg,
887 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900888
jam@chromium.org82f52f82010-12-22 05:03:24 +0900889 template<class T, class S, class Method>
darin@chromium.orgb4587d52011-08-27 06:27:30 +0900890 static bool DispatchWithSendParams(bool ok, const SendParam& send_params,
891 const Message* msg, T* obj, S* sender,
892 Method func) {
893 Message* reply = SyncMessage::GenerateReply(msg);
894 if (ok) {
erg@google.come6ffcb52010-08-18 03:38:24 +0900895 typename TupleTypes<ReplyParam>::ValueTuple reply_params;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900896 DispatchToMethod(obj, func, send_params, &reply_params);
897 WriteParam(reply, reply_params);
erg@google.come6ffcb52010-08-18 03:38:24 +0900898 LogReplyParamsToMessage(reply_params, msg);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900899 } else {
900 NOTREACHED() << "Error deserializing message " << msg->type();
901 reply->set_reply_error();
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900902 }
jam@chromium.org82f52f82010-12-22 05:03:24 +0900903 sender->Send(reply);
darin@chromium.orgb4587d52011-08-27 06:27:30 +0900904 return ok;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900905 }
906
907 template<class T, class Method>
darin@chromium.orgb4587d52011-08-27 06:27:30 +0900908 static bool DispatchDelayReplyWithSendParams(bool ok,
909 const SendParam& send_params,
910 const Message* msg, T* obj,
911 Method func) {
912 Message* reply = SyncMessage::GenerateReply(msg);
913 if (ok) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900914 Tuple1<Message&> t = MakeRefTuple(*reply);
erg@google.come6ffcb52010-08-18 03:38:24 +0900915 ConnectMessageAndReply(msg, reply);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900916 DispatchToMethod(obj, func, send_params, &t);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900917 } else {
918 NOTREACHED() << "Error deserializing message " << msg->type();
919 reply->set_reply_error();
920 obj->Send(reply);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900921 }
darin@chromium.orgb4587d52011-08-27 06:27:30 +0900922 return ok;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900923 }
924
925 template<typename TA>
926 static void WriteReplyParams(Message* reply, TA a) {
927 ReplyParam p(a);
928 WriteParam(reply, p);
929 }
930
931 template<typename TA, typename TB>
932 static void WriteReplyParams(Message* reply, TA a, TB b) {
933 ReplyParam p(a, b);
934 WriteParam(reply, p);
935 }
936
937 template<typename TA, typename TB, typename TC>
938 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
939 ReplyParam p(a, b, c);
940 WriteParam(reply, p);
941 }
942
943 template<typename TA, typename TB, typename TC, typename TD>
944 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
945 ReplyParam p(a, b, c, d);
946 WriteParam(reply, p);
947 }
948
949 template<typename TA, typename TB, typename TC, typename TD, typename TE>
950 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
951 ReplyParam p(a, b, c, d, e);
952 WriteParam(reply, p);
953 }
954};
955
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900956} // namespace IPC
957
958#endif // IPC_IPC_MESSAGE_UTILS_H_