blob: 9629facd02f5cd666f0ce8816ab5f1dc454078fd [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 {
49 // By using a start value of 0 for automation messages, we keep backward
50 // compatibility with old builds.
51 AutomationMsgStart = 0,
52 ViewMsgStart,
53 ViewHostMsgStart,
54 PluginProcessMsgStart,
55 PluginProcessHostMsgStart,
56 PluginMsgStart,
57 PluginHostMsgStart,
[email protected]96da6962010-05-13 19:10:3458 ProfileImportProcessMsgStart,
59 ProfileImportProcessHostMsgStart,
[email protected]f91cb992009-02-04 20:10:1260 NPObjectMsgStart,
61 TestMsgStart,
[email protected]503683f2009-02-26 09:13:0162 DevToolsAgentMsgStart,
63 DevToolsClientMsgStart,
[email protected]eb47a132009-03-04 00:39:5664 WorkerProcessMsgStart,
65 WorkerProcessHostMsgStart,
66 WorkerMsgStart,
67 WorkerHostMsgStart,
[email protected]d032f492009-09-29 00:33:4668 NaClProcessMsgStart,
[email protected]246a70452010-03-05 21:53:5069 GpuCommandBufferMsgStart,
[email protected]60f14392009-12-15 20:46:3270 UtilityMsgStart,
71 UtilityHostMsgStart,
[email protected]c0fc0942010-01-13 00:55:3772 GpuMsgStart,
73 GpuHostMsgStart,
[email protected]246a70452010-03-05 21:53:5074 GpuChannelMsgStart,
[email protected]ee68378a2010-08-10 01:05:4175 GpuVideoDecoderHostMsgStart,
76 GpuVideoDecoderMsgStart,
[email protected]38fe1962010-07-31 07:57:0077 ServiceMsgStart,
78 ServiceHostMsgStart,
[email protected]f91cb992009-02-04 20:10:1279 // NOTE: When you add a new message class, also update
80 // IPCStatusView::IPCStatusView to ensure logging works.
[email protected]f91cb992009-02-04 20:10:1281 LastMsgIndex
82};
83
[email protected]7a4de7a62010-08-17 18:38:2484class DictionaryValue;
85class FilePath;
86class ListValue;
87class NullableString16;
88
89namespace base {
90class Time;
[email protected]d84e48b2010-10-21 22:04:5291class TimeDelta;
[email protected]7a4de7a62010-08-17 18:38:2492struct FileDescriptor;
93}
94
initial.commit09911bf2008-07-26 23:55:2995namespace IPC {
96
[email protected]7a4de7a62010-08-17 18:38:2497struct ChannelHandle;
98
initial.commit09911bf2008-07-26 23:55:2999//-----------------------------------------------------------------------------
100// An iterator class for reading the fields contained within a Message.
101
102class MessageIterator {
103 public:
[email protected]e1981f432008-08-12 15:22:13104 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
initial.commit09911bf2008-07-26 23:55:29105 }
106 int NextInt() const {
[email protected]9422b7dc2009-12-30 20:09:02107 int val = -1;
initial.commit09911bf2008-07-26 23:55:29108 if (!msg_.ReadInt(&iter_, &val))
109 NOTREACHED();
110 return val;
111 }
initial.commit09911bf2008-07-26 23:55:29112 const std::string NextString() const {
113 std::string val;
114 if (!msg_.ReadString(&iter_, &val))
115 NOTREACHED();
116 return val;
117 }
118 const std::wstring NextWString() const {
119 std::wstring val;
120 if (!msg_.ReadWString(&iter_, &val))
121 NOTREACHED();
122 return val;
123 }
[email protected]225c8f52010-02-05 22:23:20124 void NextData(const char** data, int* length) const {
initial.commit09911bf2008-07-26 23:55:29125 if (!msg_.ReadData(&iter_, data, length)) {
126 NOTREACHED();
127 }
128 }
129 private:
130 const Message& msg_;
131 mutable void* iter_;
132};
133
134//-----------------------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19135// ParamTraits specializations, etc.
136
[email protected]7d5c3ac2009-02-04 08:58:19137template <class P>
138static inline void WriteParam(Message* m, const P& p) {
[email protected]7b291f92009-08-14 05:43:53139 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53140 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
[email protected]7d5c3ac2009-02-04 08:58:19141}
142
143template <class P>
[email protected]1e86aa62009-04-24 21:22:33144static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
145 P* p) {
[email protected]7b291f92009-08-14 05:43:53146 typedef typename SimilarTypeTraits<P>::Type Type;
147 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
[email protected]7d5c3ac2009-02-04 08:58:19148}
149
150template <class P>
[email protected]252cad62010-08-18 18:33:57151static inline void LogParam(const P& p, std::string* l) {
[email protected]7b291f92009-08-14 05:43:53152 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53153 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19154}
155
156template <>
157struct ParamTraits<bool> {
158 typedef bool param_type;
159 static void Write(Message* m, const param_type& p) {
160 m->WriteBool(p);
161 }
162 static bool Read(const Message* m, void** iter, param_type* r) {
163 return m->ReadBool(iter, r);
164 }
[email protected]252cad62010-08-18 18:33:57165 static void Log(const param_type& p, std::string* l) {
166 l->append(p ? "true" : "false");
[email protected]7d5c3ac2009-02-04 08:58:19167 }
168};
169
170template <>
171struct ParamTraits<int> {
172 typedef int param_type;
173 static void Write(Message* m, const param_type& p) {
174 m->WriteInt(p);
175 }
176 static bool Read(const Message* m, void** iter, param_type* r) {
177 return m->ReadInt(iter, r);
178 }
[email protected]252cad62010-08-18 18:33:57179 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19180};
181
182template <>
[email protected]63263f92009-07-28 19:35:08183struct ParamTraits<unsigned int> {
184 typedef unsigned int param_type;
185 static void Write(Message* m, const param_type& p) {
186 m->WriteInt(p);
187 }
188 static bool Read(const Message* m, void** iter, param_type* r) {
189 return m->ReadInt(iter, reinterpret_cast<int*>(r));
190 }
[email protected]252cad62010-08-18 18:33:57191 static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08192};
193
194template <>
[email protected]7d5c3ac2009-02-04 08:58:19195struct ParamTraits<long> {
196 typedef long param_type;
197 static void Write(Message* m, const param_type& p) {
198 m->WriteLong(p);
199 }
200 static bool Read(const Message* m, void** iter, param_type* r) {
201 return m->ReadLong(iter, r);
202 }
[email protected]252cad62010-08-18 18:33:57203 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19204};
205
[email protected]140c3032009-06-26 18:22:54206template <>
207struct ParamTraits<unsigned long> {
208 typedef unsigned long param_type;
209 static void Write(Message* m, const param_type& p) {
210 m->WriteLong(p);
211 }
212 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]63263f92009-07-28 19:35:08213 return m->ReadLong(iter, reinterpret_cast<long*>(r));
[email protected]140c3032009-06-26 18:22:54214 }
[email protected]252cad62010-08-18 18:33:57215 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19216};
217
218template <>
[email protected]63263f92009-07-28 19:35:08219struct ParamTraits<long long> {
220 typedef long long param_type;
[email protected]7d5c3ac2009-02-04 08:58:19221 static void Write(Message* m, const param_type& p) {
222 m->WriteInt64(static_cast<int64>(p));
223 }
224 static bool Read(const Message* m, void** iter, param_type* r) {
225 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
226 }
[email protected]252cad62010-08-18 18:33:57227 static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08228};
229
230template <>
231struct ParamTraits<unsigned long long> {
232 typedef unsigned long long param_type;
233 static void Write(Message* m, const param_type& p) {
234 m->WriteInt64(p);
235 }
236 static bool Read(const Message* m, void** iter, param_type* r) {
237 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
238 }
[email protected]252cad62010-08-18 18:33:57239 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19240};
241
[email protected]20199662010-06-17 03:29:26242// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
243// should be sure to check the sanity of these values after receiving them over
244// IPC.
245template <>
246struct ParamTraits<float> {
247 typedef float param_type;
248 static void Write(Message* m, const param_type& p) {
249 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
250 }
251 static bool Read(const Message* m, void** iter, param_type* r) {
252 const char *data;
253 int data_size;
254 if (!m->ReadData(iter, &data, &data_size) ||
255 data_size != sizeof(param_type)) {
256 NOTREACHED();
257 return false;
258 }
259 memcpy(r, data, sizeof(param_type));
260 return true;
261 }
[email protected]252cad62010-08-18 18:33:57262 static void Log(const param_type& p, std::string* l) {
263 l->append(StringPrintf("%e", p));
[email protected]20199662010-06-17 03:29:26264 }
265};
266
[email protected]7d5c3ac2009-02-04 08:58:19267template <>
268struct ParamTraits<double> {
269 typedef double param_type;
270 static void Write(Message* m, const param_type& p) {
271 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
272 }
273 static bool Read(const Message* m, void** iter, param_type* r) {
274 const char *data;
[email protected]20199662010-06-17 03:29:26275 int data_size;
276 if (!m->ReadData(iter, &data, &data_size) ||
277 data_size != sizeof(param_type)) {
[email protected]7d5c3ac2009-02-04 08:58:19278 NOTREACHED();
[email protected]20199662010-06-17 03:29:26279 return false;
[email protected]7d5c3ac2009-02-04 08:58:19280 }
[email protected]20199662010-06-17 03:29:26281 memcpy(r, data, sizeof(param_type));
282 return true;
[email protected]7d5c3ac2009-02-04 08:58:19283 }
[email protected]252cad62010-08-18 18:33:57284 static void Log(const param_type& p, std::string* l) {
285 l->append(StringPrintf("%e", p));
[email protected]7d5c3ac2009-02-04 08:58:19286 }
287};
288
289template <>
[email protected]7d5c3ac2009-02-04 08:58:19290struct ParamTraits<base::Time> {
291 typedef base::Time param_type;
[email protected]7a4de7a62010-08-17 18:38:24292 static void Write(Message* m, const param_type& p);
293 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57294 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19295};
296
[email protected]d84e48b2010-10-21 22:04:52297template <>
298struct ParamTraits<base::TimeDelta> {
299 typedef base::TimeDelta param_type;
300 static void Write(Message* m, const param_type& p);
301 static bool Read(const Message* m, void** iter, param_type* r);
302 static void Log(const param_type& p, std::string* l);
303};
304
[email protected]7d5c3ac2009-02-04 08:58:19305#if defined(OS_WIN)
306template <>
307struct ParamTraits<LOGFONT> {
308 typedef LOGFONT param_type;
309 static void Write(Message* m, const param_type& p) {
310 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
311 }
312 static bool Read(const Message* m, void** iter, param_type* r) {
313 const char *data;
314 int data_size = 0;
315 bool result = m->ReadData(iter, &data, &data_size);
316 if (result && data_size == sizeof(LOGFONT)) {
317 memcpy(r, data, sizeof(LOGFONT));
318 } else {
319 result = false;
320 NOTREACHED();
321 }
322
323 return result;
324 }
[email protected]252cad62010-08-18 18:33:57325 static void Log(const param_type& p, std::string* l) {
326 l->append(StringPrintf("<LOGFONT>"));
[email protected]7d5c3ac2009-02-04 08:58:19327 }
328};
329
330template <>
331struct ParamTraits<MSG> {
332 typedef MSG param_type;
333 static void Write(Message* m, const param_type& p) {
334 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
335 }
336 static bool Read(const Message* m, void** iter, param_type* r) {
337 const char *data;
338 int data_size = 0;
339 bool result = m->ReadData(iter, &data, &data_size);
340 if (result && data_size == sizeof(MSG)) {
341 memcpy(r, data, sizeof(MSG));
342 } else {
343 result = false;
344 NOTREACHED();
345 }
346
347 return result;
348 }
[email protected]252cad62010-08-18 18:33:57349 static void Log(const param_type& p, std::string* l) {
350 l->append("<MSG>");
[email protected]7a4de7a62010-08-17 18:38:24351 }
[email protected]7d5c3ac2009-02-04 08:58:19352};
353#endif // defined(OS_WIN)
354
355template <>
[email protected]584f2b22009-05-21 01:01:59356struct ParamTraits<DictionaryValue> {
357 typedef DictionaryValue param_type;
358 static void Write(Message* m, const param_type& p);
359 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57360 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59361};
362
363template <>
364struct ParamTraits<ListValue> {
365 typedef ListValue param_type;
366 static void Write(Message* m, const param_type& p);
367 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57368 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59369};
370
371template <>
[email protected]7d5c3ac2009-02-04 08:58:19372struct ParamTraits<std::string> {
373 typedef std::string param_type;
374 static void Write(Message* m, const param_type& p) {
375 m->WriteString(p);
376 }
377 static bool Read(const Message* m, void** iter, param_type* r) {
378 return m->ReadString(iter, r);
379 }
[email protected]252cad62010-08-18 18:33:57380 static void Log(const param_type& p, std::string* l) {
381 l->append(p);
[email protected]7d5c3ac2009-02-04 08:58:19382 }
383};
384
[email protected]3dd7a7a2009-07-27 21:09:07385template<typename CharType>
[email protected]252cad62010-08-18 18:33:57386static void LogBytes(const std::vector<CharType>& data, std::string* out) {
[email protected]3dd7a7a2009-07-27 21:09:07387#if defined(OS_WIN)
388 // Windows has a GUI for logging, which can handle arbitrary binary data.
389 for (size_t i = 0; i < data.size(); ++i)
390 out->push_back(data[i]);
391#else
392 // On POSIX, we log to stdout, which we assume can display ASCII.
393 static const size_t kMaxBytesToLog = 100;
394 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
395 if (isprint(data[i]))
396 out->push_back(data[i]);
397 else
[email protected]252cad62010-08-18 18:33:57398 out->append(StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
[email protected]3dd7a7a2009-07-27 21:09:07399 }
400 if (data.size() > kMaxBytesToLog) {
401 out->append(
[email protected]252cad62010-08-18 18:33:57402 StringPrintf(" and %u more bytes",
[email protected]3dd7a7a2009-07-27 21:09:07403 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
404 }
405#endif
406}
407
[email protected]7d5c3ac2009-02-04 08:58:19408template <>
409struct ParamTraits<std::vector<unsigned char> > {
410 typedef std::vector<unsigned char> param_type;
411 static void Write(Message* m, const param_type& p) {
412 if (p.size() == 0) {
413 m->WriteData(NULL, 0);
414 } else {
415 m->WriteData(reinterpret_cast<const char*>(&p.front()),
416 static_cast<int>(p.size()));
417 }
418 }
419 static bool Read(const Message* m, void** iter, param_type* r) {
420 const char *data;
421 int data_size = 0;
422 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
423 return false;
424 r->resize(data_size);
425 if (data_size)
426 memcpy(&r->front(), data, data_size);
427 return true;
428 }
[email protected]252cad62010-08-18 18:33:57429 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07430 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19431 }
432};
433
434template <>
435struct ParamTraits<std::vector<char> > {
436 typedef std::vector<char> param_type;
437 static void Write(Message* m, const param_type& p) {
438 if (p.size() == 0) {
439 m->WriteData(NULL, 0);
440 } else {
441 m->WriteData(&p.front(), static_cast<int>(p.size()));
442 }
443 }
444 static bool Read(const Message* m, void** iter, param_type* r) {
445 const char *data;
446 int data_size = 0;
447 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
448 return false;
449 r->resize(data_size);
450 if (data_size)
451 memcpy(&r->front(), data, data_size);
452 return true;
453 }
[email protected]252cad62010-08-18 18:33:57454 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07455 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19456 }
457};
458
459template <class P>
460struct ParamTraits<std::vector<P> > {
461 typedef std::vector<P> param_type;
462 static void Write(Message* m, const param_type& p) {
463 WriteParam(m, static_cast<int>(p.size()));
464 for (size_t i = 0; i < p.size(); i++)
465 WriteParam(m, p[i]);
466 }
467 static bool Read(const Message* m, void** iter, param_type* r) {
468 int size;
[email protected]86440f52009-12-31 05:17:23469 // ReadLength() checks for < 0 itself.
[email protected]7d5c3ac2009-02-04 08:58:19470 if (!m->ReadLength(iter, &size))
471 return false;
472 // Resizing beforehand is not safe, see BUG 1006367 for details.
[email protected]86440f52009-12-31 05:17:23473 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
474 return false;
475 r->resize(size);
476 for (int i = 0; i < size; i++) {
477 if (!ReadParam(m, iter, &(*r)[i]))
478 return false;
[email protected]7d5c3ac2009-02-04 08:58:19479 }
480 return true;
481 }
[email protected]252cad62010-08-18 18:33:57482 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19483 for (size_t i = 0; i < p.size(); ++i) {
484 if (i != 0)
[email protected]252cad62010-08-18 18:33:57485 l->append(" ");
[email protected]7d5c3ac2009-02-04 08:58:19486 LogParam((p[i]), l);
487 }
488 }
489};
490
[email protected]96da6962010-05-13 19:10:34491template <class P>
492struct ParamTraits<std::set<P> > {
493 typedef std::set<P> param_type;
494 static void Write(Message* m, const param_type& p) {
495 WriteParam(m, static_cast<int>(p.size()));
496 typename param_type::const_iterator iter;
497 for (iter = p.begin(); iter != p.end(); ++iter)
498 WriteParam(m, *iter);
499 }
500 static bool Read(const Message* m, void** iter, param_type* r) {
501 int size;
502 if (!m->ReadLength(iter, &size))
503 return false;
504 for (int i = 0; i < size; ++i) {
505 P item;
506 if (!ReadParam(m, iter, &item))
507 return false;
508 r->insert(item);
509 }
510 return true;
511 }
[email protected]252cad62010-08-18 18:33:57512 static void Log(const param_type& p, std::string* l) {
513 l->append("<std::set>");
[email protected]96da6962010-05-13 19:10:34514 }
515};
516
517
[email protected]7d5c3ac2009-02-04 08:58:19518template <class K, class V>
519struct ParamTraits<std::map<K, V> > {
520 typedef std::map<K, V> param_type;
521 static void Write(Message* m, const param_type& p) {
522 WriteParam(m, static_cast<int>(p.size()));
523 typename param_type::const_iterator iter;
524 for (iter = p.begin(); iter != p.end(); ++iter) {
525 WriteParam(m, iter->first);
526 WriteParam(m, iter->second);
527 }
528 }
529 static bool Read(const Message* m, void** iter, param_type* r) {
530 int size;
531 if (!ReadParam(m, iter, &size) || size < 0)
532 return false;
533 for (int i = 0; i < size; ++i) {
534 K k;
535 if (!ReadParam(m, iter, &k))
536 return false;
537 V& value = (*r)[k];
538 if (!ReadParam(m, iter, &value))
539 return false;
540 }
541 return true;
542 }
[email protected]252cad62010-08-18 18:33:57543 static void Log(const param_type& p, std::string* l) {
544 l->append("<std::map>");
[email protected]7d5c3ac2009-02-04 08:58:19545 }
546};
547
[email protected]eb47a132009-03-04 00:39:56548
[email protected]7d5c3ac2009-02-04 08:58:19549template <>
550struct ParamTraits<std::wstring> {
551 typedef std::wstring param_type;
552 static void Write(Message* m, const param_type& p) {
553 m->WriteWString(p);
554 }
555 static bool Read(const Message* m, void** iter, param_type* r) {
556 return m->ReadWString(iter, r);
557 }
[email protected]252cad62010-08-18 18:33:57558 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19559};
560
[email protected]a5da6d612009-08-04 02:00:56561template <class A, class B>
562struct ParamTraits<std::pair<A, B> > {
563 typedef std::pair<A, B> param_type;
564 static void Write(Message* m, const param_type& p) {
565 WriteParam(m, p.first);
566 WriteParam(m, p.second);
567 }
568 static bool Read(const Message* m, void** iter, param_type* r) {
569 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
570 }
[email protected]252cad62010-08-18 18:33:57571 static void Log(const param_type& p, std::string* l) {
572 l->append("(");
[email protected]a5da6d612009-08-04 02:00:56573 LogParam(p.first, l);
[email protected]252cad62010-08-18 18:33:57574 l->append(", ");
[email protected]a5da6d612009-08-04 02:00:56575 LogParam(p.second, l);
[email protected]252cad62010-08-18 18:33:57576 l->append(")");
[email protected]a5da6d612009-08-04 02:00:56577 }
578};
579
[email protected]15bf8712009-08-27 00:55:02580template <>
581struct ParamTraits<NullableString16> {
582 typedef NullableString16 param_type;
[email protected]7a4de7a62010-08-17 18:38:24583 static void Write(Message* m, const param_type& p);
584 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57585 static void Log(const param_type& p, std::string* l);
[email protected]15bf8712009-08-27 00:55:02586};
587
[email protected]eb47a132009-03-04 00:39:56588// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
589// need this trait.
590#if !defined(WCHAR_T_IS_UTF16)
[email protected]eb47a132009-03-04 00:39:56591template <>
592struct ParamTraits<string16> {
593 typedef string16 param_type;
594 static void Write(Message* m, const param_type& p) {
[email protected]3a2a5d22009-03-04 03:36:36595 m->WriteString16(p);
[email protected]eb47a132009-03-04 00:39:56596 }
597 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]3a2a5d22009-03-04 03:36:36598 return m->ReadString16(iter, r);
[email protected]eb47a132009-03-04 00:39:56599 }
[email protected]252cad62010-08-18 18:33:57600 static void Log(const param_type& p, std::string* l);
[email protected]eb47a132009-03-04 00:39:56601};
[email protected]eb47a132009-03-04 00:39:56602#endif
603
[email protected]7d5c3ac2009-02-04 08:58:19604// and, a few more useful types...
605#if defined(OS_WIN)
606template <>
607struct ParamTraits<HANDLE> {
608 typedef HANDLE param_type;
609 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35610 // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
611 // bit systems.
612 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19613 }
614 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35615 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
616 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19617 }
[email protected]252cad62010-08-18 18:33:57618 static void Log(const param_type& p, std::string* l) {
619 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19620 }
621};
622
623template <>
624struct ParamTraits<HCURSOR> {
625 typedef HCURSOR param_type;
626 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35627 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19628 }
629 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35630 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
631 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19632 }
[email protected]252cad62010-08-18 18:33:57633 static void Log(const param_type& p, std::string* l) {
634 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19635 }
636};
637
638template <>
[email protected]7d5c3ac2009-02-04 08:58:19639struct ParamTraits<HACCEL> {
640 typedef HACCEL param_type;
641 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35642 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19643 }
644 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35645 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
646 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19647 }
648};
649
650template <>
651struct ParamTraits<POINT> {
652 typedef POINT param_type;
653 static void Write(Message* m, const param_type& p) {
654 m->WriteInt(p.x);
655 m->WriteInt(p.y);
656 }
657 static bool Read(const Message* m, void** iter, param_type* r) {
658 int x, y;
659 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
660 return false;
661 r->x = x;
662 r->y = y;
663 return true;
664 }
[email protected]252cad62010-08-18 18:33:57665 static void Log(const param_type& p, std::string* l) {
666 l->append(StringPrintf("(%d, %d)", p.x, p.y));
[email protected]7d5c3ac2009-02-04 08:58:19667 }
668};
669#endif // defined(OS_WIN)
670
671template <>
672struct ParamTraits<FilePath> {
673 typedef FilePath param_type;
[email protected]7a4de7a62010-08-17 18:38:24674 static void Write(Message* m, const param_type& p);
675 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57676 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19677};
678
[email protected]526776c2009-02-07 00:39:26679#if defined(OS_POSIX)
[email protected]2749885f2009-03-05 21:40:11680// FileDescriptors may be serialised over IPC channels on POSIX. On the
681// receiving side, the FileDescriptor is a valid duplicate of the file
682// descriptor which was transmitted: *it is not just a copy of the integer like
683// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
684// this case, the receiving end will see a value of -1. *Zero is a valid file
685// descriptor*.
686//
687// The received file descriptor will have the |auto_close| flag set to true. The
688// code which handles the message is responsible for taking ownership of it.
689// File descriptors are OS resources and must be closed when no longer needed.
690//
691// When sending a file descriptor, the file descriptor must be valid at the time
692// of transmission. Since transmission is not synchronous, one should consider
693// dup()ing any file descriptors to be transmitted and setting the |auto_close|
694// flag, which causes the file descriptor to be closed after writing.
[email protected]526776c2009-02-07 00:39:26695template<>
[email protected]5fe733de2009-02-11 18:59:20696struct ParamTraits<base::FileDescriptor> {
697 typedef base::FileDescriptor param_type;
[email protected]7a4de7a62010-08-17 18:38:24698 static void Write(Message* m, const param_type& p);
699 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57700 static void Log(const param_type& p, std::string* l);
[email protected]526776c2009-02-07 00:39:26701};
[email protected]379e7a52010-03-09 00:38:41702#endif // defined(OS_POSIX)
[email protected]526776c2009-02-07 00:39:26703
[email protected]d2e884d2009-06-22 20:37:52704// A ChannelHandle is basically a platform-inspecific wrapper around the
705// fact that IPC endpoints are handled specially on POSIX. See above comments
706// on FileDescriptor for more background.
707template<>
708struct ParamTraits<IPC::ChannelHandle> {
709 typedef ChannelHandle param_type;
[email protected]7a4de7a62010-08-17 18:38:24710 static void Write(Message* m, const param_type& p);
711 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57712 static void Log(const param_type& p, std::string* l);
[email protected]d2e884d2009-06-22 20:37:52713};
714
[email protected]7d5c3ac2009-02-04 08:58:19715#if defined(OS_WIN)
716template <>
717struct ParamTraits<XFORM> {
718 typedef XFORM param_type;
719 static void Write(Message* m, const param_type& p) {
720 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
721 }
722 static bool Read(const Message* m, void** iter, param_type* r) {
723 const char *data;
724 int data_size = 0;
725 bool result = m->ReadData(iter, &data, &data_size);
726 if (result && data_size == sizeof(XFORM)) {
727 memcpy(r, data, sizeof(XFORM));
728 } else {
729 result = false;
730 NOTREACHED();
731 }
732
733 return result;
734 }
[email protected]252cad62010-08-18 18:33:57735 static void Log(const param_type& p, std::string* l) {
736 l->append("<XFORM>");
[email protected]7d5c3ac2009-02-04 08:58:19737 }
738};
739#endif // defined(OS_WIN)
740
[email protected]7d5c3ac2009-02-04 08:58:19741struct LogData {
[email protected]20f0487a2010-09-30 20:06:30742 LogData();
743 ~LogData();
744
[email protected]9a3a293b2009-06-04 22:28:16745 std::string channel;
[email protected]8bef70e2009-04-14 19:11:24746 int32 routing_id;
[email protected]168ae922009-12-04 18:08:45747 uint32 type; // "User-defined" message type, from ipc_message.h.
[email protected]252cad62010-08-18 18:33:57748 std::string flags;
[email protected]7d5c3ac2009-02-04 08:58:19749 int64 sent; // Time that the message was sent (i.e. at Send()).
750 int64 receive; // Time before it was dispatched (i.e. before calling
751 // OnMessageReceived).
752 int64 dispatch; // Time after it was dispatched (i.e. after calling
753 // OnMessageReceived).
[email protected]252cad62010-08-18 18:33:57754 std::string message_name;
755 std::string params;
[email protected]7d5c3ac2009-02-04 08:58:19756};
757
758template <>
759struct ParamTraits<LogData> {
760 typedef LogData param_type;
[email protected]20f0487a2010-09-30 20:06:30761 static void Write(Message* m, const param_type& p);
762 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57763 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19764 // Doesn't make sense to implement this!
765 }
766};
767
[email protected]eb47a132009-03-04 00:39:56768template <>
[email protected]503683f2009-02-26 09:13:01769struct ParamTraits<Message> {
770 static void Write(Message* m, const Message& p) {
771 m->WriteInt(p.size());
772 m->WriteData(reinterpret_cast<const char*>(p.data()), p.size());
773 }
774 static bool Read(const Message* m, void** iter, Message* r) {
775 int size;
776 if (!m->ReadInt(iter, &size))
777 return false;
778 const char* data;
779 if (!m->ReadData(iter, &data, &size))
780 return false;
781 *r = Message(data, size);
782 return true;
783 }
[email protected]252cad62010-08-18 18:33:57784 static void Log(const Message& p, std::string* l) {
785 l->append("<IPC::Message>");
[email protected]503683f2009-02-26 09:13:01786 }
787};
788
789template <>
[email protected]7d5c3ac2009-02-04 08:58:19790struct ParamTraits<Tuple0> {
791 typedef Tuple0 param_type;
792 static void Write(Message* m, const param_type& p) {
793 }
794 static bool Read(const Message* m, void** iter, param_type* r) {
795 return true;
796 }
[email protected]252cad62010-08-18 18:33:57797 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19798 }
799};
800
801template <class A>
802struct ParamTraits< Tuple1<A> > {
803 typedef Tuple1<A> param_type;
804 static void Write(Message* m, const param_type& p) {
805 WriteParam(m, p.a);
806 }
807 static bool Read(const Message* m, void** iter, param_type* r) {
808 return ReadParam(m, iter, &r->a);
809 }
[email protected]252cad62010-08-18 18:33:57810 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19811 LogParam(p.a, l);
812 }
813};
814
815template <class A, class B>
816struct ParamTraits< Tuple2<A, B> > {
817 typedef Tuple2<A, B> param_type;
818 static void Write(Message* m, const param_type& p) {
819 WriteParam(m, p.a);
820 WriteParam(m, p.b);
821 }
822 static bool Read(const Message* m, void** iter, param_type* r) {
823 return (ReadParam(m, iter, &r->a) &&
824 ReadParam(m, iter, &r->b));
825 }
[email protected]252cad62010-08-18 18:33:57826 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19827 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57828 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19829 LogParam(p.b, l);
830 }
831};
832
833template <class A, class B, class C>
834struct ParamTraits< Tuple3<A, B, C> > {
835 typedef Tuple3<A, B, C> param_type;
836 static void Write(Message* m, const param_type& p) {
837 WriteParam(m, p.a);
838 WriteParam(m, p.b);
839 WriteParam(m, p.c);
840 }
841 static bool Read(const Message* m, void** iter, param_type* r) {
842 return (ReadParam(m, iter, &r->a) &&
843 ReadParam(m, iter, &r->b) &&
844 ReadParam(m, iter, &r->c));
845 }
[email protected]252cad62010-08-18 18:33:57846 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19847 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57848 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19849 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57850 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19851 LogParam(p.c, l);
852 }
853};
854
855template <class A, class B, class C, class D>
856struct ParamTraits< Tuple4<A, B, C, D> > {
857 typedef Tuple4<A, B, C, D> param_type;
858 static void Write(Message* m, const param_type& p) {
859 WriteParam(m, p.a);
860 WriteParam(m, p.b);
861 WriteParam(m, p.c);
862 WriteParam(m, p.d);
863 }
864 static bool Read(const Message* m, void** iter, param_type* r) {
865 return (ReadParam(m, iter, &r->a) &&
866 ReadParam(m, iter, &r->b) &&
867 ReadParam(m, iter, &r->c) &&
868 ReadParam(m, iter, &r->d));
869 }
[email protected]252cad62010-08-18 18:33:57870 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19871 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57872 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19873 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57874 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19875 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57876 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19877 LogParam(p.d, l);
878 }
879};
880
881template <class A, class B, class C, class D, class E>
882struct ParamTraits< Tuple5<A, B, C, D, E> > {
883 typedef Tuple5<A, B, C, D, E> param_type;
884 static void Write(Message* m, const param_type& p) {
885 WriteParam(m, p.a);
886 WriteParam(m, p.b);
887 WriteParam(m, p.c);
888 WriteParam(m, p.d);
889 WriteParam(m, p.e);
890 }
891 static bool Read(const Message* m, void** iter, param_type* r) {
892 return (ReadParam(m, iter, &r->a) &&
893 ReadParam(m, iter, &r->b) &&
894 ReadParam(m, iter, &r->c) &&
895 ReadParam(m, iter, &r->d) &&
896 ReadParam(m, iter, &r->e));
897 }
[email protected]252cad62010-08-18 18:33:57898 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19899 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57900 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19901 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57902 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19903 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57904 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19905 LogParam(p.d, l);
[email protected]252cad62010-08-18 18:33:57906 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19907 LogParam(p.e, l);
908 }
909};
910
[email protected]7d5c3ac2009-02-04 08:58:19911//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:29912// Generic message subclasses
913
914// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:24915template <class ParamType>
initial.commit09911bf2008-07-26 23:55:29916class MessageWithTuple : public Message {
917 public:
[email protected]81a34412009-01-05 19:17:24918 typedef ParamType Param;
[email protected]7a4de7a62010-08-17 18:38:24919 typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
[email protected]81a34412009-01-05 19:17:24920
[email protected]7a4de7a62010-08-17 18:38:24921 // The constructor and the Read() method's templated implementations are in
922 // ipc_message_utils_impl.h. The subclass constructor and Log() methods call
923 // the templated versions of these and make sure there are instantiations in
924 // those translation units.
925 MessageWithTuple(int32 routing_id, uint32 type, const RefParam& p);
[email protected]071b4b92010-08-09 16:06:58926
[email protected]7a4de7a62010-08-17 18:38:24927 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:29928
929 // Generic dispatcher. Should cover most cases.
930 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:19931 static bool Dispatch(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:29932 Param p;
933 if (Read(msg, &p)) {
934 DispatchToMethod(obj, func, p);
935 return true;
936 }
937 return false;
938 }
939
940 // The following dispatchers exist for the case where the callback function
941 // needs the message as well. They assume that "Param" is a type of Tuple
942 // (except the one arg case, as there is no Tuple1).
943 template<class T, typename TA>
[email protected]7d5c3ac2009-02-04 08:58:19944 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:29945 void (T::*func)(const Message&, TA)) {
946 Param p;
947 if (Read(msg, &p)) {
[email protected]c2fe31542009-05-20 18:24:14948 (obj->*func)(*msg, p.a);
initial.commit09911bf2008-07-26 23:55:29949 return true;
950 }
951 return false;
952 }
953
954 template<class T, typename TA, typename TB>
[email protected]7d5c3ac2009-02-04 08:58:19955 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:29956 void (T::*func)(const Message&, TA, TB)) {
957 Param p;
958 if (Read(msg, &p)) {
959 (obj->*func)(*msg, p.a, p.b);
960 return true;
961 }
962 return false;
963 }
964
965 template<class T, typename TA, typename TB, typename TC>
[email protected]7d5c3ac2009-02-04 08:58:19966 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:29967 void (T::*func)(const Message&, TA, TB, TC)) {
968 Param p;
969 if (Read(msg, &p)) {
970 (obj->*func)(*msg, p.a, p.b, p.c);
971 return true;
972 }
973 return false;
974 }
975
976 template<class T, typename TA, typename TB, typename TC, typename TD>
[email protected]7d5c3ac2009-02-04 08:58:19977 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:29978 void (T::*func)(const Message&, TA, TB, TC, TD)) {
979 Param p;
980 if (Read(msg, &p)) {
981 (obj->*func)(*msg, p.a, p.b, p.c, p.d);
982 return true;
983 }
984 return false;
985 }
986
987 template<class T, typename TA, typename TB, typename TC, typename TD,
988 typename TE>
[email protected]7d5c3ac2009-02-04 08:58:19989 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:29990 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
991 Param p;
992 if (Read(msg, &p)) {
993 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
994 return true;
995 }
996 return false;
997 }
998
[email protected]deb57402009-02-06 01:35:30999 // Functions used to do manual unpacking. Only used by the automation code,
1000 // these should go away once that code uses SyncChannel.
1001 template<typename TA, typename TB>
1002 static bool Read(const IPC::Message* msg, TA* a, TB* b) {
1003 ParamType params;
1004 if (!Read(msg, &params))
1005 return false;
1006 *a = params.a;
1007 *b = params.b;
1008 return true;
1009 }
1010
1011 template<typename TA, typename TB, typename TC>
1012 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
1013 ParamType params;
1014 if (!Read(msg, &params))
1015 return false;
1016 *a = params.a;
1017 *b = params.b;
1018 *c = params.c;
1019 return true;
1020 }
1021
1022 template<typename TA, typename TB, typename TC, typename TD>
1023 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) {
1024 ParamType params;
1025 if (!Read(msg, &params))
1026 return false;
1027 *a = params.a;
1028 *b = params.b;
1029 *c = params.c;
1030 *d = params.d;
1031 return true;
1032 }
1033
1034 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1035 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) {
1036 ParamType params;
1037 if (!Read(msg, &params))
1038 return false;
1039 *a = params.a;
1040 *b = params.b;
1041 *c = params.c;
1042 *d = params.d;
1043 *e = params.e;
1044 return true;
1045 }
initial.commit09911bf2008-07-26 23:55:291046};
1047
[email protected]7a4de7a62010-08-17 18:38:241048// defined in ipc_logging.cc
1049void GenerateLogData(const std::string& channel, const Message& message,
1050 LogData* data);
1051
1052
1053#if defined(IPC_MESSAGE_LOG_ENABLED)
[email protected]252cad62010-08-18 18:33:571054inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
1055 const std::string& output_params = msg->output_params();
[email protected]7a4de7a62010-08-17 18:38:241056 if (!l->empty() && !output_params.empty())
[email protected]252cad62010-08-18 18:33:571057 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:241058
1059 l->append(output_params);
1060}
1061
1062template <class ReplyParamType>
1063inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1064 const Message* msg) {
1065 if (msg->received_time() != 0) {
[email protected]252cad62010-08-18 18:33:571066 std::string output_params;
[email protected]7a4de7a62010-08-17 18:38:241067 LogParam(reply_params, &output_params);
1068 msg->set_output_params(output_params);
1069 }
1070}
1071
1072inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
1073 if (msg->sent_time()) {
1074 // Don't log the sync message after dispatch, as we don't have the
1075 // output parameters at that point. Instead, save its data and log it
1076 // with the outgoing reply message when it's sent.
1077 LogData* data = new LogData;
1078 GenerateLogData("", *msg, data);
1079 msg->set_dont_log();
1080 reply->set_sync_log_data(data);
1081 }
1082}
1083#else
[email protected]252cad62010-08-18 18:33:571084inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
[email protected]7a4de7a62010-08-17 18:38:241085
1086template <class ReplyParamType>
1087inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1088 const Message* msg) {}
1089
1090inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1091#endif
1092
initial.commit09911bf2008-07-26 23:55:291093// This class assumes that its template argument is a RefTuple (a Tuple with
[email protected]7a4de7a62010-08-17 18:38:241094// reference elements). This would go into ipc_message_utils_impl.h, but it is
1095// also used by chrome_frame.
initial.commit09911bf2008-07-26 23:55:291096template <class RefTuple>
1097class ParamDeserializer : public MessageReplyDeserializer {
1098 public:
[email protected]e1981f432008-08-12 15:22:131099 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:291100
1101 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1102 return ReadParam(&msg, &iter, &out_);
1103 }
1104
1105 RefTuple out_;
1106};
1107
initial.commit09911bf2008-07-26 23:55:291108// Used for synchronous messages.
[email protected]75e5a872009-04-02 23:56:111109template <class SendParamType, class ReplyParamType>
initial.commit09911bf2008-07-26 23:55:291110class MessageWithReply : public SyncMessage {
1111 public:
[email protected]75e5a872009-04-02 23:56:111112 typedef SendParamType SendParam;
[email protected]7a4de7a62010-08-17 18:38:241113 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
[email protected]75e5a872009-04-02 23:56:111114 typedef ReplyParamType ReplyParam;
1115
[email protected]168ae922009-12-04 18:08:451116 MessageWithReply(int32 routing_id, uint32 type,
[email protected]7a4de7a62010-08-17 18:38:241117 const RefSendParam& send, const ReplyParam& reply);
1118 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
1119 static bool ReadReplyParam(
1120 const Message* msg,
1121 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:291122
1123 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191124 static bool Dispatch(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291125 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291126 Message* reply = GenerateReply(msg);
1127 bool error;
[email protected]7a4de7a62010-08-17 18:38:241128 if (ReadSendParam(msg, &send_params)) {
1129 typename TupleTypes<ReplyParam>::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:291130 DispatchToMethod(obj, func, send_params, &reply_params);
1131 WriteParam(reply, reply_params);
1132 error = false;
[email protected]7a4de7a62010-08-17 18:38:241133 LogReplyParamsToMessage(reply_params, msg);
initial.commit09911bf2008-07-26 23:55:291134 } else {
1135 NOTREACHED() << "Error deserializing message " << msg->type();
1136 reply->set_reply_error();
1137 error = true;
1138 }
1139
1140 obj->Send(reply);
1141 return !error;
1142 }
1143
1144 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191145 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291146 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291147 Message* reply = GenerateReply(msg);
1148 bool error;
[email protected]7a4de7a62010-08-17 18:38:241149 if (ReadSendParam(msg, &send_params)) {
initial.commit09911bf2008-07-26 23:55:291150 Tuple1<Message&> t = MakeRefTuple(*reply);
[email protected]7a4de7a62010-08-17 18:38:241151 ConnectMessageAndReply(msg, reply);
initial.commit09911bf2008-07-26 23:55:291152 DispatchToMethod(obj, func, send_params, &t);
1153 error = false;
1154 } else {
1155 NOTREACHED() << "Error deserializing message " << msg->type();
1156 reply->set_reply_error();
1157 obj->Send(reply);
1158 error = true;
1159 }
1160 return !error;
1161 }
1162
1163 template<typename TA>
1164 static void WriteReplyParams(Message* reply, TA a) {
1165 ReplyParam p(a);
1166 WriteParam(reply, p);
1167 }
1168
1169 template<typename TA, typename TB>
1170 static void WriteReplyParams(Message* reply, TA a, TB b) {
1171 ReplyParam p(a, b);
1172 WriteParam(reply, p);
1173 }
1174
1175 template<typename TA, typename TB, typename TC>
1176 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1177 ReplyParam p(a, b, c);
1178 WriteParam(reply, p);
1179 }
1180
1181 template<typename TA, typename TB, typename TC, typename TD>
1182 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1183 ReplyParam p(a, b, c, d);
1184 WriteParam(reply, p);
1185 }
1186
1187 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1188 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1189 ReplyParam p(a, b, c, d, e);
1190 WriteParam(reply, p);
1191 }
1192};
1193
[email protected]7d5c3ac2009-02-04 08:58:191194//-----------------------------------------------------------------------------
1195
[email protected]3178f4e22008-08-05 21:20:411196} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291197
[email protected]946d1b22009-07-22 23:57:211198#endif // IPC_IPC_MESSAGE_UTILS_H_