blob: 858ad1a3883389c74b28bb6caff032a84d790bf2 [file] [log] [blame]
[email protected]225c8f52010-02-05 22:23:201// Copyright (c) 2010 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]946d1b22009-07-22 23:57:215#ifndef IPC_IPC_MESSAGE_UTILS_H_
6#define IPC_IPC_MESSAGE_UTILS_H_
[email protected]32b76ef2010-07-26 23:08:247#pragma once
initial.commit09911bf2008-07-26 23:55:298
[email protected]379e7a52010-03-09 00:38:419#include <algorithm>
initial.commit09911bf2008-07-26 23:55:2910#include <string>
11#include <vector>
12#include <map>
[email protected]96da6962010-05-13 19:10:3413#include <set>
initial.commit09911bf2008-07-26 23:55:2914
[email protected]dce5df52009-06-29 17:58:2515#include "base/format_macros.h"
[email protected]eb47a132009-03-04 00:39:5616#include "base/string16.h"
[email protected]dce5df52009-06-29 17:58:2517#include "base/string_util.h"
initial.commit09911bf2008-07-26 23:55:2918#include "base/tuple.h"
[email protected]939856a2010-08-24 20:29:0219#include "ipc/ipc_param_traits.h"
[email protected]0cfe5dae2010-08-17 00:24:5420#include "ipc/ipc_sync_message.h"
[email protected]55b4e212010-08-13 20:43:5821
[email protected]7a4de7a62010-08-17 18:38:2422#if defined(COMPILER_GCC)
23// GCC "helpfully" tries to inline template methods in release mode. Except we
24// want the majority of the template junk being expanded once in the
25// implementation file (and only provide the definitions in
26// ipc_message_utils_impl.h in those files) and exported, instead of expanded
27// at every call site. Special note: GCC happily accepts the attribute before
28// the method declaration, but only acts on it if it is after.
[email protected]efafbbd2010-08-19 20:23:2529#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 40500
30// Starting in gcc 4.5, the noinline no longer implies the concept covered by
31// the introduced noclone attribute, which will create specialized versions of
32// functions/methods when certain types are constant.
33// www.gnu.org/software/gcc/gcc-4.5/changes.html
34#define IPC_MSG_NOINLINE __attribute__((noinline, noclone));
35#else
[email protected]7a4de7a62010-08-17 18:38:2436#define IPC_MSG_NOINLINE __attribute__((noinline));
[email protected]efafbbd2010-08-19 20:23:2537#endif
[email protected]7a4de7a62010-08-17 18:38:2438#elif defined(COMPILER_MSVC)
39// MSVC++ doesn't do this.
40#define IPC_MSG_NOINLINE
41#else
42#error "Please add the noinline property for your new compiler here."
43#endif
44
[email protected]f91cb992009-02-04 20:10:1245// Used by IPC_BEGIN_MESSAGES so that each message class starts from a unique
46// base. Messages have unique IDs across channels in order for the IPC logging
47// code to figure out the message class from its ID.
48enum IPCMessageStart {
[email protected]f91cb992009-02-04 20:10:1249 AutomationMsgStart = 0,
50 ViewMsgStart,
[email protected]f91cb992009-02-04 20:10:1251 PluginMsgStart,
[email protected]21fa3a12010-12-08 23:34:1652 ProfileImportMsgStart,
[email protected]f91cb992009-02-04 20:10:1253 TestMsgStart,
[email protected]21fa3a12010-12-08 23:34:1654 DevToolsMsgStart,
[email protected]eb47a132009-03-04 00:39:5655 WorkerMsgStart,
[email protected]21fa3a12010-12-08 23:34:1656 NaClMsgStart,
[email protected]60f14392009-12-15 20:46:3257 UtilityMsgStart,
[email protected]c0fc0942010-01-13 00:55:3758 GpuMsgStart,
[email protected]38fe1962010-07-31 07:57:0059 ServiceMsgStart,
[email protected]709a847e2010-11-10 01:16:1160 PpapiMsgStart,
[email protected]21fa3a12010-12-08 23:34:1661 FirefoxImporterUnittestMsgStart,
[email protected]9f547bf2010-12-13 17:00:4262 FileUtilitiesMsgStart,
63 MimeRegistryMsgStart,
[email protected]f91cb992009-02-04 20:10:1264};
65
[email protected]7a4de7a62010-08-17 18:38:2466class DictionaryValue;
67class FilePath;
68class ListValue;
69class NullableString16;
70
71namespace base {
72class Time;
[email protected]d84e48b2010-10-21 22:04:5273class TimeDelta;
[email protected]7a4de7a62010-08-17 18:38:2474struct FileDescriptor;
75}
76
initial.commit09911bf2008-07-26 23:55:2977namespace IPC {
78
[email protected]7a4de7a62010-08-17 18:38:2479struct ChannelHandle;
80
initial.commit09911bf2008-07-26 23:55:2981//-----------------------------------------------------------------------------
82// An iterator class for reading the fields contained within a Message.
83
84class MessageIterator {
85 public:
[email protected]e1981f432008-08-12 15:22:1386 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
initial.commit09911bf2008-07-26 23:55:2987 }
88 int NextInt() const {
[email protected]9422b7dc2009-12-30 20:09:0289 int val = -1;
initial.commit09911bf2008-07-26 23:55:2990 if (!msg_.ReadInt(&iter_, &val))
91 NOTREACHED();
92 return val;
93 }
initial.commit09911bf2008-07-26 23:55:2994 const std::string NextString() const {
95 std::string val;
96 if (!msg_.ReadString(&iter_, &val))
97 NOTREACHED();
98 return val;
99 }
100 const std::wstring NextWString() const {
101 std::wstring val;
102 if (!msg_.ReadWString(&iter_, &val))
103 NOTREACHED();
104 return val;
105 }
[email protected]225c8f52010-02-05 22:23:20106 void NextData(const char** data, int* length) const {
initial.commit09911bf2008-07-26 23:55:29107 if (!msg_.ReadData(&iter_, data, length)) {
108 NOTREACHED();
109 }
110 }
111 private:
112 const Message& msg_;
113 mutable void* iter_;
114};
115
116//-----------------------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19117// ParamTraits specializations, etc.
118
[email protected]7d5c3ac2009-02-04 08:58:19119template <class P>
120static inline void WriteParam(Message* m, const P& p) {
[email protected]7b291f92009-08-14 05:43:53121 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53122 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
[email protected]7d5c3ac2009-02-04 08:58:19123}
124
125template <class P>
[email protected]1e86aa62009-04-24 21:22:33126static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
127 P* p) {
[email protected]7b291f92009-08-14 05:43:53128 typedef typename SimilarTypeTraits<P>::Type Type;
129 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
[email protected]7d5c3ac2009-02-04 08:58:19130}
131
132template <class P>
[email protected]252cad62010-08-18 18:33:57133static inline void LogParam(const P& p, std::string* l) {
[email protected]7b291f92009-08-14 05:43:53134 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53135 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19136}
137
138template <>
139struct ParamTraits<bool> {
140 typedef bool param_type;
141 static void Write(Message* m, const param_type& p) {
142 m->WriteBool(p);
143 }
144 static bool Read(const Message* m, void** iter, param_type* r) {
145 return m->ReadBool(iter, r);
146 }
[email protected]252cad62010-08-18 18:33:57147 static void Log(const param_type& p, std::string* l) {
148 l->append(p ? "true" : "false");
[email protected]7d5c3ac2009-02-04 08:58:19149 }
150};
151
152template <>
153struct ParamTraits<int> {
154 typedef int param_type;
155 static void Write(Message* m, const param_type& p) {
156 m->WriteInt(p);
157 }
158 static bool Read(const Message* m, void** iter, param_type* r) {
159 return m->ReadInt(iter, r);
160 }
[email protected]252cad62010-08-18 18:33:57161 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19162};
163
164template <>
[email protected]63263f92009-07-28 19:35:08165struct ParamTraits<unsigned int> {
166 typedef unsigned int param_type;
167 static void Write(Message* m, const param_type& p) {
168 m->WriteInt(p);
169 }
170 static bool Read(const Message* m, void** iter, param_type* r) {
171 return m->ReadInt(iter, reinterpret_cast<int*>(r));
172 }
[email protected]252cad62010-08-18 18:33:57173 static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08174};
175
176template <>
[email protected]7d5c3ac2009-02-04 08:58:19177struct ParamTraits<long> {
178 typedef long param_type;
179 static void Write(Message* m, const param_type& p) {
180 m->WriteLong(p);
181 }
182 static bool Read(const Message* m, void** iter, param_type* r) {
183 return m->ReadLong(iter, r);
184 }
[email protected]252cad62010-08-18 18:33:57185 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19186};
187
[email protected]140c3032009-06-26 18:22:54188template <>
189struct ParamTraits<unsigned long> {
190 typedef unsigned long param_type;
191 static void Write(Message* m, const param_type& p) {
192 m->WriteLong(p);
193 }
194 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]63263f92009-07-28 19:35:08195 return m->ReadLong(iter, reinterpret_cast<long*>(r));
[email protected]140c3032009-06-26 18:22:54196 }
[email protected]252cad62010-08-18 18:33:57197 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19198};
199
200template <>
[email protected]63263f92009-07-28 19:35:08201struct ParamTraits<long long> {
202 typedef long long param_type;
[email protected]7d5c3ac2009-02-04 08:58:19203 static void Write(Message* m, const param_type& p) {
204 m->WriteInt64(static_cast<int64>(p));
205 }
206 static bool Read(const Message* m, void** iter, param_type* r) {
207 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
208 }
[email protected]252cad62010-08-18 18:33:57209 static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08210};
211
212template <>
213struct ParamTraits<unsigned long long> {
214 typedef unsigned long long param_type;
215 static void Write(Message* m, const param_type& p) {
216 m->WriteInt64(p);
217 }
218 static bool Read(const Message* m, void** iter, param_type* r) {
219 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
220 }
[email protected]252cad62010-08-18 18:33:57221 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19222};
223
[email protected]43a40202010-11-12 16:25:01224template <>
225struct ParamTraits<unsigned short> {
226 typedef unsigned short param_type;
227 static void Write(Message* m, const param_type& p);
228 static bool Read(const Message* m, void** iter, param_type* r);
229 static void Log(const param_type& p, std::string* l);
230};
231
[email protected]20199662010-06-17 03:29:26232// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
233// should be sure to check the sanity of these values after receiving them over
234// IPC.
235template <>
236struct ParamTraits<float> {
237 typedef float param_type;
238 static void Write(Message* m, const param_type& p) {
239 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
240 }
241 static bool Read(const Message* m, void** iter, param_type* r) {
242 const char *data;
243 int data_size;
244 if (!m->ReadData(iter, &data, &data_size) ||
245 data_size != sizeof(param_type)) {
246 NOTREACHED();
247 return false;
248 }
249 memcpy(r, data, sizeof(param_type));
250 return true;
251 }
[email protected]252cad62010-08-18 18:33:57252 static void Log(const param_type& p, std::string* l) {
253 l->append(StringPrintf("%e", p));
[email protected]20199662010-06-17 03:29:26254 }
255};
256
[email protected]7d5c3ac2009-02-04 08:58:19257template <>
258struct ParamTraits<double> {
259 typedef double param_type;
260 static void Write(Message* m, const param_type& p) {
261 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
262 }
263 static bool Read(const Message* m, void** iter, param_type* r) {
264 const char *data;
[email protected]20199662010-06-17 03:29:26265 int data_size;
266 if (!m->ReadData(iter, &data, &data_size) ||
267 data_size != sizeof(param_type)) {
[email protected]7d5c3ac2009-02-04 08:58:19268 NOTREACHED();
[email protected]20199662010-06-17 03:29:26269 return false;
[email protected]7d5c3ac2009-02-04 08:58:19270 }
[email protected]20199662010-06-17 03:29:26271 memcpy(r, data, sizeof(param_type));
272 return true;
[email protected]7d5c3ac2009-02-04 08:58:19273 }
[email protected]252cad62010-08-18 18:33:57274 static void Log(const param_type& p, std::string* l) {
275 l->append(StringPrintf("%e", p));
[email protected]7d5c3ac2009-02-04 08:58:19276 }
277};
278
279template <>
[email protected]7d5c3ac2009-02-04 08:58:19280struct ParamTraits<base::Time> {
281 typedef base::Time param_type;
[email protected]7a4de7a62010-08-17 18:38:24282 static void Write(Message* m, const param_type& p);
283 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57284 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19285};
286
[email protected]d84e48b2010-10-21 22:04:52287template <>
288struct ParamTraits<base::TimeDelta> {
289 typedef base::TimeDelta param_type;
290 static void Write(Message* m, const param_type& p);
291 static bool Read(const Message* m, void** iter, param_type* r);
292 static void Log(const param_type& p, std::string* l);
293};
294
[email protected]7d5c3ac2009-02-04 08:58:19295#if defined(OS_WIN)
296template <>
297struct ParamTraits<LOGFONT> {
298 typedef LOGFONT param_type;
299 static void Write(Message* m, const param_type& p) {
300 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
301 }
302 static bool Read(const Message* m, void** iter, param_type* r) {
303 const char *data;
304 int data_size = 0;
305 bool result = m->ReadData(iter, &data, &data_size);
306 if (result && data_size == sizeof(LOGFONT)) {
307 memcpy(r, data, sizeof(LOGFONT));
308 } else {
309 result = false;
310 NOTREACHED();
311 }
312
313 return result;
314 }
[email protected]252cad62010-08-18 18:33:57315 static void Log(const param_type& p, std::string* l) {
316 l->append(StringPrintf("<LOGFONT>"));
[email protected]7d5c3ac2009-02-04 08:58:19317 }
318};
319
320template <>
321struct ParamTraits<MSG> {
322 typedef MSG param_type;
323 static void Write(Message* m, const param_type& p) {
324 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
325 }
326 static bool Read(const Message* m, void** iter, param_type* r) {
327 const char *data;
328 int data_size = 0;
329 bool result = m->ReadData(iter, &data, &data_size);
330 if (result && data_size == sizeof(MSG)) {
331 memcpy(r, data, sizeof(MSG));
332 } else {
333 result = false;
334 NOTREACHED();
335 }
336
337 return result;
338 }
[email protected]252cad62010-08-18 18:33:57339 static void Log(const param_type& p, std::string* l) {
340 l->append("<MSG>");
[email protected]7a4de7a62010-08-17 18:38:24341 }
[email protected]7d5c3ac2009-02-04 08:58:19342};
343#endif // defined(OS_WIN)
344
345template <>
[email protected]584f2b22009-05-21 01:01:59346struct ParamTraits<DictionaryValue> {
347 typedef DictionaryValue param_type;
348 static void Write(Message* m, const param_type& p);
349 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57350 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59351};
352
353template <>
354struct ParamTraits<ListValue> {
355 typedef ListValue param_type;
356 static void Write(Message* m, const param_type& p);
357 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57358 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59359};
360
361template <>
[email protected]7d5c3ac2009-02-04 08:58:19362struct ParamTraits<std::string> {
363 typedef std::string param_type;
364 static void Write(Message* m, const param_type& p) {
365 m->WriteString(p);
366 }
367 static bool Read(const Message* m, void** iter, param_type* r) {
368 return m->ReadString(iter, r);
369 }
[email protected]252cad62010-08-18 18:33:57370 static void Log(const param_type& p, std::string* l) {
371 l->append(p);
[email protected]7d5c3ac2009-02-04 08:58:19372 }
373};
374
[email protected]3dd7a7a2009-07-27 21:09:07375template<typename CharType>
[email protected]252cad62010-08-18 18:33:57376static void LogBytes(const std::vector<CharType>& data, std::string* out) {
[email protected]3dd7a7a2009-07-27 21:09:07377#if defined(OS_WIN)
378 // Windows has a GUI for logging, which can handle arbitrary binary data.
379 for (size_t i = 0; i < data.size(); ++i)
380 out->push_back(data[i]);
381#else
382 // On POSIX, we log to stdout, which we assume can display ASCII.
383 static const size_t kMaxBytesToLog = 100;
384 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
385 if (isprint(data[i]))
386 out->push_back(data[i]);
387 else
[email protected]252cad62010-08-18 18:33:57388 out->append(StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
[email protected]3dd7a7a2009-07-27 21:09:07389 }
390 if (data.size() > kMaxBytesToLog) {
391 out->append(
[email protected]252cad62010-08-18 18:33:57392 StringPrintf(" and %u more bytes",
[email protected]3dd7a7a2009-07-27 21:09:07393 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
394 }
395#endif
396}
397
[email protected]7d5c3ac2009-02-04 08:58:19398template <>
399struct ParamTraits<std::vector<unsigned char> > {
400 typedef std::vector<unsigned char> param_type;
401 static void Write(Message* m, const param_type& p) {
402 if (p.size() == 0) {
403 m->WriteData(NULL, 0);
404 } else {
405 m->WriteData(reinterpret_cast<const char*>(&p.front()),
406 static_cast<int>(p.size()));
407 }
408 }
409 static bool Read(const Message* m, void** iter, param_type* r) {
410 const char *data;
411 int data_size = 0;
412 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
413 return false;
414 r->resize(data_size);
415 if (data_size)
416 memcpy(&r->front(), data, data_size);
417 return true;
418 }
[email protected]252cad62010-08-18 18:33:57419 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07420 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19421 }
422};
423
424template <>
425struct ParamTraits<std::vector<char> > {
426 typedef std::vector<char> param_type;
427 static void Write(Message* m, const param_type& p) {
428 if (p.size() == 0) {
429 m->WriteData(NULL, 0);
430 } else {
431 m->WriteData(&p.front(), static_cast<int>(p.size()));
432 }
433 }
434 static bool Read(const Message* m, void** iter, param_type* r) {
435 const char *data;
436 int data_size = 0;
437 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
438 return false;
439 r->resize(data_size);
440 if (data_size)
441 memcpy(&r->front(), data, data_size);
442 return true;
443 }
[email protected]252cad62010-08-18 18:33:57444 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07445 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19446 }
447};
448
449template <class P>
450struct ParamTraits<std::vector<P> > {
451 typedef std::vector<P> param_type;
452 static void Write(Message* m, const param_type& p) {
453 WriteParam(m, static_cast<int>(p.size()));
454 for (size_t i = 0; i < p.size(); i++)
455 WriteParam(m, p[i]);
456 }
457 static bool Read(const Message* m, void** iter, param_type* r) {
458 int size;
[email protected]86440f52009-12-31 05:17:23459 // ReadLength() checks for < 0 itself.
[email protected]7d5c3ac2009-02-04 08:58:19460 if (!m->ReadLength(iter, &size))
461 return false;
462 // Resizing beforehand is not safe, see BUG 1006367 for details.
[email protected]86440f52009-12-31 05:17:23463 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
464 return false;
465 r->resize(size);
466 for (int i = 0; i < size; i++) {
467 if (!ReadParam(m, iter, &(*r)[i]))
468 return false;
[email protected]7d5c3ac2009-02-04 08:58:19469 }
470 return true;
471 }
[email protected]252cad62010-08-18 18:33:57472 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19473 for (size_t i = 0; i < p.size(); ++i) {
474 if (i != 0)
[email protected]252cad62010-08-18 18:33:57475 l->append(" ");
[email protected]7d5c3ac2009-02-04 08:58:19476 LogParam((p[i]), l);
477 }
478 }
479};
480
[email protected]96da6962010-05-13 19:10:34481template <class P>
482struct ParamTraits<std::set<P> > {
483 typedef std::set<P> param_type;
484 static void Write(Message* m, const param_type& p) {
485 WriteParam(m, static_cast<int>(p.size()));
486 typename param_type::const_iterator iter;
487 for (iter = p.begin(); iter != p.end(); ++iter)
488 WriteParam(m, *iter);
489 }
490 static bool Read(const Message* m, void** iter, param_type* r) {
491 int size;
492 if (!m->ReadLength(iter, &size))
493 return false;
494 for (int i = 0; i < size; ++i) {
495 P item;
496 if (!ReadParam(m, iter, &item))
497 return false;
498 r->insert(item);
499 }
500 return true;
501 }
[email protected]252cad62010-08-18 18:33:57502 static void Log(const param_type& p, std::string* l) {
503 l->append("<std::set>");
[email protected]96da6962010-05-13 19:10:34504 }
505};
506
507
[email protected]7d5c3ac2009-02-04 08:58:19508template <class K, class V>
509struct ParamTraits<std::map<K, V> > {
510 typedef std::map<K, V> param_type;
511 static void Write(Message* m, const param_type& p) {
512 WriteParam(m, static_cast<int>(p.size()));
513 typename param_type::const_iterator iter;
514 for (iter = p.begin(); iter != p.end(); ++iter) {
515 WriteParam(m, iter->first);
516 WriteParam(m, iter->second);
517 }
518 }
519 static bool Read(const Message* m, void** iter, param_type* r) {
520 int size;
521 if (!ReadParam(m, iter, &size) || size < 0)
522 return false;
523 for (int i = 0; i < size; ++i) {
524 K k;
525 if (!ReadParam(m, iter, &k))
526 return false;
527 V& value = (*r)[k];
528 if (!ReadParam(m, iter, &value))
529 return false;
530 }
531 return true;
532 }
[email protected]252cad62010-08-18 18:33:57533 static void Log(const param_type& p, std::string* l) {
534 l->append("<std::map>");
[email protected]7d5c3ac2009-02-04 08:58:19535 }
536};
537
[email protected]eb47a132009-03-04 00:39:56538
[email protected]7d5c3ac2009-02-04 08:58:19539template <>
540struct ParamTraits<std::wstring> {
541 typedef std::wstring param_type;
542 static void Write(Message* m, const param_type& p) {
543 m->WriteWString(p);
544 }
545 static bool Read(const Message* m, void** iter, param_type* r) {
546 return m->ReadWString(iter, r);
547 }
[email protected]252cad62010-08-18 18:33:57548 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19549};
550
[email protected]a5da6d612009-08-04 02:00:56551template <class A, class B>
552struct ParamTraits<std::pair<A, B> > {
553 typedef std::pair<A, B> param_type;
554 static void Write(Message* m, const param_type& p) {
555 WriteParam(m, p.first);
556 WriteParam(m, p.second);
557 }
558 static bool Read(const Message* m, void** iter, param_type* r) {
559 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
560 }
[email protected]252cad62010-08-18 18:33:57561 static void Log(const param_type& p, std::string* l) {
562 l->append("(");
[email protected]a5da6d612009-08-04 02:00:56563 LogParam(p.first, l);
[email protected]252cad62010-08-18 18:33:57564 l->append(", ");
[email protected]a5da6d612009-08-04 02:00:56565 LogParam(p.second, l);
[email protected]252cad62010-08-18 18:33:57566 l->append(")");
[email protected]a5da6d612009-08-04 02:00:56567 }
568};
569
[email protected]15bf8712009-08-27 00:55:02570template <>
571struct ParamTraits<NullableString16> {
572 typedef NullableString16 param_type;
[email protected]7a4de7a62010-08-17 18:38:24573 static void Write(Message* m, const param_type& p);
574 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57575 static void Log(const param_type& p, std::string* l);
[email protected]15bf8712009-08-27 00:55:02576};
577
[email protected]eb47a132009-03-04 00:39:56578// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
579// need this trait.
580#if !defined(WCHAR_T_IS_UTF16)
[email protected]eb47a132009-03-04 00:39:56581template <>
582struct ParamTraits<string16> {
583 typedef string16 param_type;
584 static void Write(Message* m, const param_type& p) {
[email protected]3a2a5d22009-03-04 03:36:36585 m->WriteString16(p);
[email protected]eb47a132009-03-04 00:39:56586 }
587 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]3a2a5d22009-03-04 03:36:36588 return m->ReadString16(iter, r);
[email protected]eb47a132009-03-04 00:39:56589 }
[email protected]252cad62010-08-18 18:33:57590 static void Log(const param_type& p, std::string* l);
[email protected]eb47a132009-03-04 00:39:56591};
[email protected]eb47a132009-03-04 00:39:56592#endif
593
[email protected]7d5c3ac2009-02-04 08:58:19594// and, a few more useful types...
595#if defined(OS_WIN)
596template <>
597struct ParamTraits<HANDLE> {
598 typedef HANDLE param_type;
599 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35600 // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
601 // bit systems.
602 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19603 }
604 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35605 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
606 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19607 }
[email protected]252cad62010-08-18 18:33:57608 static void Log(const param_type& p, std::string* l) {
609 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19610 }
611};
612
613template <>
614struct ParamTraits<HCURSOR> {
615 typedef HCURSOR param_type;
616 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35617 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19618 }
619 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35620 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
621 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19622 }
[email protected]252cad62010-08-18 18:33:57623 static void Log(const param_type& p, std::string* l) {
624 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19625 }
626};
627
628template <>
[email protected]7d5c3ac2009-02-04 08:58:19629struct ParamTraits<HACCEL> {
630 typedef HACCEL param_type;
631 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35632 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19633 }
634 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35635 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
636 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19637 }
638};
639
640template <>
641struct ParamTraits<POINT> {
642 typedef POINT param_type;
643 static void Write(Message* m, const param_type& p) {
644 m->WriteInt(p.x);
645 m->WriteInt(p.y);
646 }
647 static bool Read(const Message* m, void** iter, param_type* r) {
648 int x, y;
649 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
650 return false;
651 r->x = x;
652 r->y = y;
653 return true;
654 }
[email protected]252cad62010-08-18 18:33:57655 static void Log(const param_type& p, std::string* l) {
656 l->append(StringPrintf("(%d, %d)", p.x, p.y));
[email protected]7d5c3ac2009-02-04 08:58:19657 }
658};
659#endif // defined(OS_WIN)
660
661template <>
662struct ParamTraits<FilePath> {
663 typedef FilePath param_type;
[email protected]7a4de7a62010-08-17 18:38:24664 static void Write(Message* m, const param_type& p);
665 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57666 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19667};
668
[email protected]526776c2009-02-07 00:39:26669#if defined(OS_POSIX)
[email protected]2749885f2009-03-05 21:40:11670// FileDescriptors may be serialised over IPC channels on POSIX. On the
671// receiving side, the FileDescriptor is a valid duplicate of the file
672// descriptor which was transmitted: *it is not just a copy of the integer like
673// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
674// this case, the receiving end will see a value of -1. *Zero is a valid file
675// descriptor*.
676//
677// The received file descriptor will have the |auto_close| flag set to true. The
678// code which handles the message is responsible for taking ownership of it.
679// File descriptors are OS resources and must be closed when no longer needed.
680//
681// When sending a file descriptor, the file descriptor must be valid at the time
682// of transmission. Since transmission is not synchronous, one should consider
683// dup()ing any file descriptors to be transmitted and setting the |auto_close|
684// flag, which causes the file descriptor to be closed after writing.
[email protected]526776c2009-02-07 00:39:26685template<>
[email protected]5fe733de2009-02-11 18:59:20686struct ParamTraits<base::FileDescriptor> {
687 typedef base::FileDescriptor param_type;
[email protected]7a4de7a62010-08-17 18:38:24688 static void Write(Message* m, const param_type& p);
689 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57690 static void Log(const param_type& p, std::string* l);
[email protected]526776c2009-02-07 00:39:26691};
[email protected]379e7a52010-03-09 00:38:41692#endif // defined(OS_POSIX)
[email protected]526776c2009-02-07 00:39:26693
[email protected]d2e884d2009-06-22 20:37:52694// A ChannelHandle is basically a platform-inspecific wrapper around the
695// fact that IPC endpoints are handled specially on POSIX. See above comments
696// on FileDescriptor for more background.
697template<>
698struct ParamTraits<IPC::ChannelHandle> {
699 typedef ChannelHandle param_type;
[email protected]7a4de7a62010-08-17 18:38:24700 static void Write(Message* m, const param_type& p);
701 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57702 static void Log(const param_type& p, std::string* l);
[email protected]d2e884d2009-06-22 20:37:52703};
704
[email protected]7d5c3ac2009-02-04 08:58:19705#if defined(OS_WIN)
706template <>
707struct ParamTraits<XFORM> {
708 typedef XFORM param_type;
709 static void Write(Message* m, const param_type& p) {
710 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
711 }
712 static bool Read(const Message* m, void** iter, param_type* r) {
713 const char *data;
714 int data_size = 0;
715 bool result = m->ReadData(iter, &data, &data_size);
716 if (result && data_size == sizeof(XFORM)) {
717 memcpy(r, data, sizeof(XFORM));
718 } else {
719 result = false;
720 NOTREACHED();
721 }
722
723 return result;
724 }
[email protected]252cad62010-08-18 18:33:57725 static void Log(const param_type& p, std::string* l) {
726 l->append("<XFORM>");
[email protected]7d5c3ac2009-02-04 08:58:19727 }
728};
729#endif // defined(OS_WIN)
730
[email protected]7d5c3ac2009-02-04 08:58:19731struct LogData {
[email protected]20f0487a2010-09-30 20:06:30732 LogData();
733 ~LogData();
734
[email protected]9a3a293b2009-06-04 22:28:16735 std::string channel;
[email protected]8bef70e2009-04-14 19:11:24736 int32 routing_id;
[email protected]168ae922009-12-04 18:08:45737 uint32 type; // "User-defined" message type, from ipc_message.h.
[email protected]252cad62010-08-18 18:33:57738 std::string flags;
[email protected]7d5c3ac2009-02-04 08:58:19739 int64 sent; // Time that the message was sent (i.e. at Send()).
740 int64 receive; // Time before it was dispatched (i.e. before calling
741 // OnMessageReceived).
742 int64 dispatch; // Time after it was dispatched (i.e. after calling
743 // OnMessageReceived).
[email protected]252cad62010-08-18 18:33:57744 std::string message_name;
745 std::string params;
[email protected]7d5c3ac2009-02-04 08:58:19746};
747
748template <>
749struct ParamTraits<LogData> {
750 typedef LogData param_type;
[email protected]20f0487a2010-09-30 20:06:30751 static void Write(Message* m, const param_type& p);
752 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57753 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19754 // Doesn't make sense to implement this!
755 }
756};
757
[email protected]eb47a132009-03-04 00:39:56758template <>
[email protected]503683f2009-02-26 09:13:01759struct ParamTraits<Message> {
760 static void Write(Message* m, const Message& p) {
761 m->WriteInt(p.size());
762 m->WriteData(reinterpret_cast<const char*>(p.data()), p.size());
763 }
764 static bool Read(const Message* m, void** iter, Message* r) {
765 int size;
766 if (!m->ReadInt(iter, &size))
767 return false;
768 const char* data;
769 if (!m->ReadData(iter, &data, &size))
770 return false;
771 *r = Message(data, size);
772 return true;
773 }
[email protected]252cad62010-08-18 18:33:57774 static void Log(const Message& p, std::string* l) {
775 l->append("<IPC::Message>");
[email protected]503683f2009-02-26 09:13:01776 }
777};
778
779template <>
[email protected]7d5c3ac2009-02-04 08:58:19780struct ParamTraits<Tuple0> {
781 typedef Tuple0 param_type;
782 static void Write(Message* m, const param_type& p) {
783 }
784 static bool Read(const Message* m, void** iter, param_type* r) {
785 return true;
786 }
[email protected]252cad62010-08-18 18:33:57787 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19788 }
789};
790
791template <class A>
792struct ParamTraits< Tuple1<A> > {
793 typedef Tuple1<A> param_type;
794 static void Write(Message* m, const param_type& p) {
795 WriteParam(m, p.a);
796 }
797 static bool Read(const Message* m, void** iter, param_type* r) {
798 return ReadParam(m, iter, &r->a);
799 }
[email protected]252cad62010-08-18 18:33:57800 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19801 LogParam(p.a, l);
802 }
803};
804
805template <class A, class B>
806struct ParamTraits< Tuple2<A, B> > {
807 typedef Tuple2<A, B> param_type;
808 static void Write(Message* m, const param_type& p) {
809 WriteParam(m, p.a);
810 WriteParam(m, p.b);
811 }
812 static bool Read(const Message* m, void** iter, param_type* r) {
813 return (ReadParam(m, iter, &r->a) &&
814 ReadParam(m, iter, &r->b));
815 }
[email protected]252cad62010-08-18 18:33:57816 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19817 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57818 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19819 LogParam(p.b, l);
820 }
821};
822
823template <class A, class B, class C>
824struct ParamTraits< Tuple3<A, B, C> > {
825 typedef Tuple3<A, B, C> param_type;
826 static void Write(Message* m, const param_type& p) {
827 WriteParam(m, p.a);
828 WriteParam(m, p.b);
829 WriteParam(m, p.c);
830 }
831 static bool Read(const Message* m, void** iter, param_type* r) {
832 return (ReadParam(m, iter, &r->a) &&
833 ReadParam(m, iter, &r->b) &&
834 ReadParam(m, iter, &r->c));
835 }
[email protected]252cad62010-08-18 18:33:57836 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19837 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57838 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19839 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57840 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19841 LogParam(p.c, l);
842 }
843};
844
845template <class A, class B, class C, class D>
846struct ParamTraits< Tuple4<A, B, C, D> > {
847 typedef Tuple4<A, B, C, D> param_type;
848 static void Write(Message* m, const param_type& p) {
849 WriteParam(m, p.a);
850 WriteParam(m, p.b);
851 WriteParam(m, p.c);
852 WriteParam(m, p.d);
853 }
854 static bool Read(const Message* m, void** iter, param_type* r) {
855 return (ReadParam(m, iter, &r->a) &&
856 ReadParam(m, iter, &r->b) &&
857 ReadParam(m, iter, &r->c) &&
858 ReadParam(m, iter, &r->d));
859 }
[email protected]252cad62010-08-18 18:33:57860 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19861 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57862 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19863 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57864 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19865 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57866 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19867 LogParam(p.d, l);
868 }
869};
870
871template <class A, class B, class C, class D, class E>
872struct ParamTraits< Tuple5<A, B, C, D, E> > {
873 typedef Tuple5<A, B, C, D, E> param_type;
874 static void Write(Message* m, const param_type& p) {
875 WriteParam(m, p.a);
876 WriteParam(m, p.b);
877 WriteParam(m, p.c);
878 WriteParam(m, p.d);
879 WriteParam(m, p.e);
880 }
881 static bool Read(const Message* m, void** iter, param_type* r) {
882 return (ReadParam(m, iter, &r->a) &&
883 ReadParam(m, iter, &r->b) &&
884 ReadParam(m, iter, &r->c) &&
885 ReadParam(m, iter, &r->d) &&
886 ReadParam(m, iter, &r->e));
887 }
[email protected]252cad62010-08-18 18:33:57888 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19889 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57890 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19891 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57892 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19893 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57894 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19895 LogParam(p.d, l);
[email protected]252cad62010-08-18 18:33:57896 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19897 LogParam(p.e, l);
898 }
899};
900
[email protected]7d5c3ac2009-02-04 08:58:19901//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:29902// Generic message subclasses
903
904// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:24905template <class ParamType>
initial.commit09911bf2008-07-26 23:55:29906class MessageWithTuple : public Message {
907 public:
[email protected]81a34412009-01-05 19:17:24908 typedef ParamType Param;
[email protected]7a4de7a62010-08-17 18:38:24909 typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
[email protected]81a34412009-01-05 19:17:24910
[email protected]7a4de7a62010-08-17 18:38:24911 // The constructor and the Read() method's templated implementations are in
912 // ipc_message_utils_impl.h. The subclass constructor and Log() methods call
913 // the templated versions of these and make sure there are instantiations in
914 // those translation units.
915 MessageWithTuple(int32 routing_id, uint32 type, const RefParam& p);
[email protected]071b4b92010-08-09 16:06:58916
[email protected]7a4de7a62010-08-17 18:38:24917 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:29918
919 // Generic dispatcher. Should cover most cases.
920 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:19921 static bool Dispatch(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:29922 Param p;
923 if (Read(msg, &p)) {
924 DispatchToMethod(obj, func, p);
925 return true;
926 }
927 return false;
928 }
929
930 // The following dispatchers exist for the case where the callback function
931 // needs the message as well. They assume that "Param" is a type of Tuple
932 // (except the one arg case, as there is no Tuple1).
933 template<class T, typename TA>
[email protected]7d5c3ac2009-02-04 08:58:19934 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:29935 void (T::*func)(const Message&, TA)) {
936 Param p;
937 if (Read(msg, &p)) {
[email protected]c2fe31542009-05-20 18:24:14938 (obj->*func)(*msg, p.a);
initial.commit09911bf2008-07-26 23:55:29939 return true;
940 }
941 return false;
942 }
943
944 template<class T, typename TA, typename TB>
[email protected]7d5c3ac2009-02-04 08:58:19945 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:29946 void (T::*func)(const Message&, TA, TB)) {
947 Param p;
948 if (Read(msg, &p)) {
949 (obj->*func)(*msg, p.a, p.b);
950 return true;
951 }
952 return false;
953 }
954
955 template<class T, typename TA, typename TB, typename TC>
[email protected]7d5c3ac2009-02-04 08:58:19956 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:29957 void (T::*func)(const Message&, TA, TB, TC)) {
958 Param p;
959 if (Read(msg, &p)) {
960 (obj->*func)(*msg, p.a, p.b, p.c);
961 return true;
962 }
963 return false;
964 }
965
966 template<class T, typename TA, typename TB, typename TC, typename TD>
[email protected]7d5c3ac2009-02-04 08:58:19967 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:29968 void (T::*func)(const Message&, TA, TB, TC, TD)) {
969 Param p;
970 if (Read(msg, &p)) {
971 (obj->*func)(*msg, p.a, p.b, p.c, p.d);
972 return true;
973 }
974 return false;
975 }
976
977 template<class T, typename TA, typename TB, typename TC, typename TD,
978 typename TE>
[email protected]7d5c3ac2009-02-04 08:58:19979 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:29980 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
981 Param p;
982 if (Read(msg, &p)) {
983 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
984 return true;
985 }
986 return false;
987 }
988
[email protected]deb57402009-02-06 01:35:30989 // Functions used to do manual unpacking. Only used by the automation code,
990 // these should go away once that code uses SyncChannel.
991 template<typename TA, typename TB>
992 static bool Read(const IPC::Message* msg, TA* a, TB* b) {
993 ParamType params;
994 if (!Read(msg, &params))
995 return false;
996 *a = params.a;
997 *b = params.b;
998 return true;
999 }
1000
1001 template<typename TA, typename TB, typename TC>
1002 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
1003 ParamType params;
1004 if (!Read(msg, &params))
1005 return false;
1006 *a = params.a;
1007 *b = params.b;
1008 *c = params.c;
1009 return true;
1010 }
1011
1012 template<typename TA, typename TB, typename TC, typename TD>
1013 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) {
1014 ParamType params;
1015 if (!Read(msg, &params))
1016 return false;
1017 *a = params.a;
1018 *b = params.b;
1019 *c = params.c;
1020 *d = params.d;
1021 return true;
1022 }
1023
1024 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1025 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) {
1026 ParamType params;
1027 if (!Read(msg, &params))
1028 return false;
1029 *a = params.a;
1030 *b = params.b;
1031 *c = params.c;
1032 *d = params.d;
1033 *e = params.e;
1034 return true;
1035 }
initial.commit09911bf2008-07-26 23:55:291036};
1037
[email protected]7a4de7a62010-08-17 18:38:241038// defined in ipc_logging.cc
1039void GenerateLogData(const std::string& channel, const Message& message,
1040 LogData* data);
1041
1042
1043#if defined(IPC_MESSAGE_LOG_ENABLED)
[email protected]252cad62010-08-18 18:33:571044inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
1045 const std::string& output_params = msg->output_params();
[email protected]7a4de7a62010-08-17 18:38:241046 if (!l->empty() && !output_params.empty())
[email protected]252cad62010-08-18 18:33:571047 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:241048
1049 l->append(output_params);
1050}
1051
1052template <class ReplyParamType>
1053inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1054 const Message* msg) {
1055 if (msg->received_time() != 0) {
[email protected]252cad62010-08-18 18:33:571056 std::string output_params;
[email protected]7a4de7a62010-08-17 18:38:241057 LogParam(reply_params, &output_params);
1058 msg->set_output_params(output_params);
1059 }
1060}
1061
1062inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
1063 if (msg->sent_time()) {
1064 // Don't log the sync message after dispatch, as we don't have the
1065 // output parameters at that point. Instead, save its data and log it
1066 // with the outgoing reply message when it's sent.
1067 LogData* data = new LogData;
1068 GenerateLogData("", *msg, data);
1069 msg->set_dont_log();
1070 reply->set_sync_log_data(data);
1071 }
1072}
1073#else
[email protected]252cad62010-08-18 18:33:571074inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
[email protected]7a4de7a62010-08-17 18:38:241075
1076template <class ReplyParamType>
1077inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1078 const Message* msg) {}
1079
1080inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1081#endif
1082
initial.commit09911bf2008-07-26 23:55:291083// This class assumes that its template argument is a RefTuple (a Tuple with
[email protected]7a4de7a62010-08-17 18:38:241084// reference elements). This would go into ipc_message_utils_impl.h, but it is
1085// also used by chrome_frame.
initial.commit09911bf2008-07-26 23:55:291086template <class RefTuple>
1087class ParamDeserializer : public MessageReplyDeserializer {
1088 public:
[email protected]e1981f432008-08-12 15:22:131089 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:291090
1091 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1092 return ReadParam(&msg, &iter, &out_);
1093 }
1094
1095 RefTuple out_;
1096};
1097
initial.commit09911bf2008-07-26 23:55:291098// Used for synchronous messages.
[email protected]75e5a872009-04-02 23:56:111099template <class SendParamType, class ReplyParamType>
initial.commit09911bf2008-07-26 23:55:291100class MessageWithReply : public SyncMessage {
1101 public:
[email protected]75e5a872009-04-02 23:56:111102 typedef SendParamType SendParam;
[email protected]7a4de7a62010-08-17 18:38:241103 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
[email protected]75e5a872009-04-02 23:56:111104 typedef ReplyParamType ReplyParam;
1105
[email protected]168ae922009-12-04 18:08:451106 MessageWithReply(int32 routing_id, uint32 type,
[email protected]7a4de7a62010-08-17 18:38:241107 const RefSendParam& send, const ReplyParam& reply);
1108 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
1109 static bool ReadReplyParam(
1110 const Message* msg,
1111 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:291112
1113 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191114 static bool Dispatch(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291115 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291116 Message* reply = GenerateReply(msg);
1117 bool error;
[email protected]7a4de7a62010-08-17 18:38:241118 if (ReadSendParam(msg, &send_params)) {
1119 typename TupleTypes<ReplyParam>::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:291120 DispatchToMethod(obj, func, send_params, &reply_params);
1121 WriteParam(reply, reply_params);
1122 error = false;
[email protected]7a4de7a62010-08-17 18:38:241123 LogReplyParamsToMessage(reply_params, msg);
initial.commit09911bf2008-07-26 23:55:291124 } else {
1125 NOTREACHED() << "Error deserializing message " << msg->type();
1126 reply->set_reply_error();
1127 error = true;
1128 }
1129
1130 obj->Send(reply);
1131 return !error;
1132 }
1133
1134 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191135 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291136 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291137 Message* reply = GenerateReply(msg);
1138 bool error;
[email protected]7a4de7a62010-08-17 18:38:241139 if (ReadSendParam(msg, &send_params)) {
initial.commit09911bf2008-07-26 23:55:291140 Tuple1<Message&> t = MakeRefTuple(*reply);
[email protected]7a4de7a62010-08-17 18:38:241141 ConnectMessageAndReply(msg, reply);
initial.commit09911bf2008-07-26 23:55:291142 DispatchToMethod(obj, func, send_params, &t);
1143 error = false;
1144 } else {
1145 NOTREACHED() << "Error deserializing message " << msg->type();
1146 reply->set_reply_error();
1147 obj->Send(reply);
1148 error = true;
1149 }
1150 return !error;
1151 }
1152
1153 template<typename TA>
1154 static void WriteReplyParams(Message* reply, TA a) {
1155 ReplyParam p(a);
1156 WriteParam(reply, p);
1157 }
1158
1159 template<typename TA, typename TB>
1160 static void WriteReplyParams(Message* reply, TA a, TB b) {
1161 ReplyParam p(a, b);
1162 WriteParam(reply, p);
1163 }
1164
1165 template<typename TA, typename TB, typename TC>
1166 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1167 ReplyParam p(a, b, c);
1168 WriteParam(reply, p);
1169 }
1170
1171 template<typename TA, typename TB, typename TC, typename TD>
1172 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1173 ReplyParam p(a, b, c, d);
1174 WriteParam(reply, p);
1175 }
1176
1177 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1178 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1179 ReplyParam p(a, b, c, d, e);
1180 WriteParam(reply, p);
1181 }
1182};
1183
[email protected]7d5c3ac2009-02-04 08:58:191184//-----------------------------------------------------------------------------
1185
[email protected]3178f4e22008-08-05 21:20:411186} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291187
[email protected]946d1b22009-07-22 23:57:211188#endif // IPC_IPC_MESSAGE_UTILS_H_