blob: bad5fc279bc5138eed9bb3f3f88f7dfea8889fa2 [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_
initial.commit09911bf2008-07-26 23:55:297
[email protected]379e7a52010-03-09 00:38:418#include <algorithm>
initial.commit09911bf2008-07-26 23:55:299#include <string>
10#include <vector>
11#include <map>
12
[email protected]690a99c2009-01-06 16:48:4513#include "base/file_path.h"
[email protected]dce5df52009-06-29 17:58:2514#include "base/format_macros.h"
[email protected]15bf8712009-08-27 00:55:0215#include "base/nullable_string16.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"
[email protected]379e7a52010-03-09 00:38:4118#include "base/utf_string_conversions.h"
[email protected]946d1b22009-07-22 23:57:2119#include "base/time.h"
initial.commit09911bf2008-07-26 23:55:2920#include "base/tuple.h"
[email protected]946d1b22009-07-22 23:57:2121#include "base/values.h"
[email protected]526776c2009-02-07 00:39:2622#if defined(OS_POSIX)
[email protected]946d1b22009-07-22 23:57:2123#include "ipc/file_descriptor_set_posix.h"
[email protected]526776c2009-02-07 00:39:2624#endif
[email protected]946d1b22009-07-22 23:57:2125#include "ipc/ipc_channel_handle.h"
26#include "ipc/ipc_sync_message.h"
[email protected]82e5ee82009-04-03 02:29:4527
[email protected]f91cb992009-02-04 20:10:1228// Used by IPC_BEGIN_MESSAGES so that each message class starts from a unique
29// base. Messages have unique IDs across channels in order for the IPC logging
30// code to figure out the message class from its ID.
31enum IPCMessageStart {
32 // By using a start value of 0 for automation messages, we keep backward
33 // compatibility with old builds.
34 AutomationMsgStart = 0,
35 ViewMsgStart,
36 ViewHostMsgStart,
37 PluginProcessMsgStart,
38 PluginProcessHostMsgStart,
39 PluginMsgStart,
40 PluginHostMsgStart,
41 NPObjectMsgStart,
42 TestMsgStart,
[email protected]503683f2009-02-26 09:13:0143 DevToolsAgentMsgStart,
44 DevToolsClientMsgStart,
[email protected]eb47a132009-03-04 00:39:5645 WorkerProcessMsgStart,
46 WorkerProcessHostMsgStart,
47 WorkerMsgStart,
48 WorkerHostMsgStart,
[email protected]d032f492009-09-29 00:33:4649 NaClProcessMsgStart,
[email protected]246a70452010-03-05 21:53:5050 GpuCommandBufferMsgStart,
[email protected]60f14392009-12-15 20:46:3251 UtilityMsgStart,
52 UtilityHostMsgStart,
[email protected]c0fc0942010-01-13 00:55:3753 GpuMsgStart,
54 GpuHostMsgStart,
[email protected]246a70452010-03-05 21:53:5055 GpuChannelMsgStart,
[email protected]f91cb992009-02-04 20:10:1256 // NOTE: When you add a new message class, also update
57 // IPCStatusView::IPCStatusView to ensure logging works.
[email protected]f91cb992009-02-04 20:10:1258 LastMsgIndex
59};
60
initial.commit09911bf2008-07-26 23:55:2961namespace IPC {
62
initial.commit09911bf2008-07-26 23:55:2963//-----------------------------------------------------------------------------
64// An iterator class for reading the fields contained within a Message.
65
66class MessageIterator {
67 public:
[email protected]e1981f432008-08-12 15:22:1368 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
initial.commit09911bf2008-07-26 23:55:2969 }
70 int NextInt() const {
[email protected]9422b7dc2009-12-30 20:09:0271 int val = -1;
initial.commit09911bf2008-07-26 23:55:2972 if (!msg_.ReadInt(&iter_, &val))
73 NOTREACHED();
74 return val;
75 }
initial.commit09911bf2008-07-26 23:55:2976 const std::string NextString() const {
77 std::string val;
78 if (!msg_.ReadString(&iter_, &val))
79 NOTREACHED();
80 return val;
81 }
82 const std::wstring NextWString() const {
83 std::wstring val;
84 if (!msg_.ReadWString(&iter_, &val))
85 NOTREACHED();
86 return val;
87 }
[email protected]225c8f52010-02-05 22:23:2088 void NextData(const char** data, int* length) const {
initial.commit09911bf2008-07-26 23:55:2989 if (!msg_.ReadData(&iter_, data, length)) {
90 NOTREACHED();
91 }
92 }
93 private:
94 const Message& msg_;
95 mutable void* iter_;
96};
97
98//-----------------------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:1999// ParamTraits specializations, etc.
100
[email protected]7b291f92009-08-14 05:43:53101template <class P> struct ParamTraits {
102};
103
104template <class P>
105struct SimilarTypeTraits {
106 typedef P Type;
107};
[email protected]7d5c3ac2009-02-04 08:58:19108
109template <class P>
110static inline void WriteParam(Message* m, const P& p) {
[email protected]7b291f92009-08-14 05:43:53111 typedef typename SimilarTypeTraits<P>::Type Type;
112 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
[email protected]7d5c3ac2009-02-04 08:58:19113}
114
115template <class P>
[email protected]1e86aa62009-04-24 21:22:33116static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
117 P* p) {
[email protected]7b291f92009-08-14 05:43:53118 typedef typename SimilarTypeTraits<P>::Type Type;
119 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
[email protected]7d5c3ac2009-02-04 08:58:19120}
121
122template <class P>
123static inline void LogParam(const P& p, std::wstring* l) {
[email protected]7b291f92009-08-14 05:43:53124 typedef typename SimilarTypeTraits<P>::Type Type;
125 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19126}
127
128template <>
129struct ParamTraits<bool> {
130 typedef bool param_type;
131 static void Write(Message* m, const param_type& p) {
132 m->WriteBool(p);
133 }
134 static bool Read(const Message* m, void** iter, param_type* r) {
135 return m->ReadBool(iter, r);
136 }
137 static void Log(const param_type& p, std::wstring* l) {
138 l->append(p ? L"true" : L"false");
139 }
140};
141
142template <>
143struct ParamTraits<int> {
144 typedef int param_type;
145 static void Write(Message* m, const param_type& p) {
146 m->WriteInt(p);
147 }
148 static bool Read(const Message* m, void** iter, param_type* r) {
149 return m->ReadInt(iter, r);
150 }
151 static void Log(const param_type& p, std::wstring* l) {
152 l->append(StringPrintf(L"%d", p));
153 }
154};
155
156template <>
[email protected]63263f92009-07-28 19:35:08157struct ParamTraits<unsigned int> {
158 typedef unsigned int param_type;
159 static void Write(Message* m, const param_type& p) {
160 m->WriteInt(p);
161 }
162 static bool Read(const Message* m, void** iter, param_type* r) {
163 return m->ReadInt(iter, reinterpret_cast<int*>(r));
164 }
165 static void Log(const param_type& p, std::wstring* l) {
166 l->append(StringPrintf(L"%d", p));
167 }
168};
169
170template <>
[email protected]7d5c3ac2009-02-04 08:58:19171struct ParamTraits<long> {
172 typedef long param_type;
173 static void Write(Message* m, const param_type& p) {
174 m->WriteLong(p);
175 }
176 static bool Read(const Message* m, void** iter, param_type* r) {
177 return m->ReadLong(iter, r);
178 }
179 static void Log(const param_type& p, std::wstring* l) {
[email protected]63263f92009-07-28 19:35:08180 l->append(StringPrintf(L"%ld", p));
[email protected]7d5c3ac2009-02-04 08:58:19181 }
182};
183
[email protected]140c3032009-06-26 18:22:54184template <>
185struct ParamTraits<unsigned long> {
186 typedef unsigned long param_type;
187 static void Write(Message* m, const param_type& p) {
188 m->WriteLong(p);
189 }
190 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]63263f92009-07-28 19:35:08191 return m->ReadLong(iter, reinterpret_cast<long*>(r));
[email protected]140c3032009-06-26 18:22:54192 }
193 static void Log(const param_type& p, std::wstring* l) {
[email protected]63263f92009-07-28 19:35:08194 l->append(StringPrintf(L"%lu", p));
[email protected]7d5c3ac2009-02-04 08:58:19195 }
196};
197
198template <>
[email protected]63263f92009-07-28 19:35:08199struct ParamTraits<long long> {
200 typedef long long param_type;
[email protected]7d5c3ac2009-02-04 08:58:19201 static void Write(Message* m, const param_type& p) {
202 m->WriteInt64(static_cast<int64>(p));
203 }
204 static bool Read(const Message* m, void** iter, param_type* r) {
205 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
206 }
207 static void Log(const param_type& p, std::wstring* l) {
[email protected]63263f92009-07-28 19:35:08208 l->append(Int64ToWString(static_cast<int64>(p)));
209 }
210};
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 }
221 static void Log(const param_type& p, std::wstring* l) {
222 l->append(Uint64ToWString(p));
[email protected]7d5c3ac2009-02-04 08:58:19223 }
224};
225
226template <>
227struct ParamTraits<double> {
228 typedef double param_type;
229 static void Write(Message* m, const param_type& p) {
230 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
231 }
232 static bool Read(const Message* m, void** iter, param_type* r) {
233 const char *data;
234 int data_size = 0;
235 bool result = m->ReadData(iter, &data, &data_size);
236 if (result && data_size == sizeof(param_type)) {
237 memcpy(r, data, sizeof(param_type));
238 } else {
239 result = false;
240 NOTREACHED();
241 }
242
243 return result;
244 }
245 static void Log(const param_type& p, std::wstring* l) {
246 l->append(StringPrintf(L"e", p));
247 }
248};
249
250template <>
251struct ParamTraits<wchar_t> {
252 typedef wchar_t param_type;
253 static void Write(Message* m, const param_type& p) {
254 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
255 }
256 static bool Read(const Message* m, void** iter, param_type* r) {
257 const char *data;
258 int data_size = 0;
259 bool result = m->ReadData(iter, &data, &data_size);
260 if (result && data_size == sizeof(param_type)) {
261 memcpy(r, data, sizeof(param_type));
262 } else {
263 result = false;
264 NOTREACHED();
265 }
266
267 return result;
268 }
269 static void Log(const param_type& p, std::wstring* l) {
270 l->append(StringPrintf(L"%lc", p));
271 }
272};
273
274template <>
275struct ParamTraits<base::Time> {
276 typedef base::Time param_type;
277 static void Write(Message* m, const param_type& p) {
278 ParamTraits<int64>::Write(m, p.ToInternalValue());
279 }
280 static bool Read(const Message* m, void** iter, param_type* r) {
281 int64 value;
282 if (!ParamTraits<int64>::Read(m, iter, &value))
283 return false;
284 *r = base::Time::FromInternalValue(value);
285 return true;
286 }
287 static void Log(const param_type& p, std::wstring* l) {
288 ParamTraits<int64>::Log(p.ToInternalValue(), l);
289 }
290};
291
292#if defined(OS_WIN)
293template <>
294struct ParamTraits<LOGFONT> {
295 typedef LOGFONT param_type;
296 static void Write(Message* m, const param_type& p) {
297 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
298 }
299 static bool Read(const Message* m, void** iter, param_type* r) {
300 const char *data;
301 int data_size = 0;
302 bool result = m->ReadData(iter, &data, &data_size);
303 if (result && data_size == sizeof(LOGFONT)) {
304 memcpy(r, data, sizeof(LOGFONT));
305 } else {
306 result = false;
307 NOTREACHED();
308 }
309
310 return result;
311 }
312 static void Log(const param_type& p, std::wstring* l) {
313 l->append(StringPrintf(L"<LOGFONT>"));
314 }
315};
316
317template <>
318struct ParamTraits<MSG> {
319 typedef MSG param_type;
320 static void Write(Message* m, const param_type& p) {
321 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
322 }
323 static bool Read(const Message* m, void** iter, param_type* r) {
324 const char *data;
325 int data_size = 0;
326 bool result = m->ReadData(iter, &data, &data_size);
327 if (result && data_size == sizeof(MSG)) {
328 memcpy(r, data, sizeof(MSG));
329 } else {
330 result = false;
331 NOTREACHED();
332 }
333
334 return result;
335 }
336};
337#endif // defined(OS_WIN)
338
339template <>
[email protected]584f2b22009-05-21 01:01:59340struct ParamTraits<DictionaryValue> {
341 typedef DictionaryValue param_type;
342 static void Write(Message* m, const param_type& p);
343 static bool Read(const Message* m, void** iter, param_type* r);
344 static void Log(const param_type& p, std::wstring* l);
345};
346
347template <>
348struct ParamTraits<ListValue> {
349 typedef ListValue param_type;
350 static void Write(Message* m, const param_type& p);
351 static bool Read(const Message* m, void** iter, param_type* r);
352 static void Log(const param_type& p, std::wstring* l);
353};
354
355template <>
[email protected]7d5c3ac2009-02-04 08:58:19356struct ParamTraits<std::string> {
357 typedef std::string param_type;
358 static void Write(Message* m, const param_type& p) {
359 m->WriteString(p);
360 }
361 static bool Read(const Message* m, void** iter, param_type* r) {
362 return m->ReadString(iter, r);
363 }
364 static void Log(const param_type& p, std::wstring* l) {
365 l->append(UTF8ToWide(p));
366 }
367};
368
[email protected]3dd7a7a2009-07-27 21:09:07369template<typename CharType>
370static void LogBytes(const std::vector<CharType>& data, std::wstring* out) {
371#if defined(OS_WIN)
372 // Windows has a GUI for logging, which can handle arbitrary binary data.
373 for (size_t i = 0; i < data.size(); ++i)
374 out->push_back(data[i]);
375#else
376 // On POSIX, we log to stdout, which we assume can display ASCII.
377 static const size_t kMaxBytesToLog = 100;
378 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
379 if (isprint(data[i]))
380 out->push_back(data[i]);
381 else
382 out->append(StringPrintf(L"[%02X]", static_cast<unsigned char>(data[i])));
383 }
384 if (data.size() > kMaxBytesToLog) {
385 out->append(
386 StringPrintf(L" and %u more bytes",
387 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
388 }
389#endif
390}
391
[email protected]7d5c3ac2009-02-04 08:58:19392template <>
393struct ParamTraits<std::vector<unsigned char> > {
394 typedef std::vector<unsigned char> param_type;
395 static void Write(Message* m, const param_type& p) {
396 if (p.size() == 0) {
397 m->WriteData(NULL, 0);
398 } else {
399 m->WriteData(reinterpret_cast<const char*>(&p.front()),
400 static_cast<int>(p.size()));
401 }
402 }
403 static bool Read(const Message* m, void** iter, param_type* r) {
404 const char *data;
405 int data_size = 0;
406 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
407 return false;
408 r->resize(data_size);
409 if (data_size)
410 memcpy(&r->front(), data, data_size);
411 return true;
412 }
413 static void Log(const param_type& p, std::wstring* l) {
[email protected]3dd7a7a2009-07-27 21:09:07414 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19415 }
416};
417
418template <>
419struct ParamTraits<std::vector<char> > {
420 typedef std::vector<char> param_type;
421 static void Write(Message* m, const param_type& p) {
422 if (p.size() == 0) {
423 m->WriteData(NULL, 0);
424 } else {
425 m->WriteData(&p.front(), static_cast<int>(p.size()));
426 }
427 }
428 static bool Read(const Message* m, void** iter, param_type* r) {
429 const char *data;
430 int data_size = 0;
431 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
432 return false;
433 r->resize(data_size);
434 if (data_size)
435 memcpy(&r->front(), data, data_size);
436 return true;
437 }
438 static void Log(const param_type& p, std::wstring* l) {
[email protected]3dd7a7a2009-07-27 21:09:07439 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19440 }
441};
442
443template <class P>
444struct ParamTraits<std::vector<P> > {
445 typedef std::vector<P> param_type;
446 static void Write(Message* m, const param_type& p) {
447 WriteParam(m, static_cast<int>(p.size()));
448 for (size_t i = 0; i < p.size(); i++)
449 WriteParam(m, p[i]);
450 }
451 static bool Read(const Message* m, void** iter, param_type* r) {
452 int size;
[email protected]86440f52009-12-31 05:17:23453 // ReadLength() checks for < 0 itself.
[email protected]7d5c3ac2009-02-04 08:58:19454 if (!m->ReadLength(iter, &size))
455 return false;
456 // Resizing beforehand is not safe, see BUG 1006367 for details.
[email protected]86440f52009-12-31 05:17:23457 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
458 return false;
459 r->resize(size);
460 for (int i = 0; i < size; i++) {
461 if (!ReadParam(m, iter, &(*r)[i]))
462 return false;
[email protected]7d5c3ac2009-02-04 08:58:19463 }
464 return true;
465 }
466 static void Log(const param_type& p, std::wstring* l) {
467 for (size_t i = 0; i < p.size(); ++i) {
468 if (i != 0)
469 l->append(L" ");
470
471 LogParam((p[i]), l);
472 }
473 }
474};
475
476template <class K, class V>
477struct ParamTraits<std::map<K, V> > {
478 typedef std::map<K, V> param_type;
479 static void Write(Message* m, const param_type& p) {
480 WriteParam(m, static_cast<int>(p.size()));
481 typename param_type::const_iterator iter;
482 for (iter = p.begin(); iter != p.end(); ++iter) {
483 WriteParam(m, iter->first);
484 WriteParam(m, iter->second);
485 }
486 }
487 static bool Read(const Message* m, void** iter, param_type* r) {
488 int size;
489 if (!ReadParam(m, iter, &size) || size < 0)
490 return false;
491 for (int i = 0; i < size; ++i) {
492 K k;
493 if (!ReadParam(m, iter, &k))
494 return false;
495 V& value = (*r)[k];
496 if (!ReadParam(m, iter, &value))
497 return false;
498 }
499 return true;
500 }
501 static void Log(const param_type& p, std::wstring* l) {
502 l->append(L"<std::map>");
503 }
504};
505
[email protected]eb47a132009-03-04 00:39:56506
[email protected]7d5c3ac2009-02-04 08:58:19507template <>
508struct ParamTraits<std::wstring> {
509 typedef std::wstring param_type;
510 static void Write(Message* m, const param_type& p) {
511 m->WriteWString(p);
512 }
513 static bool Read(const Message* m, void** iter, param_type* r) {
514 return m->ReadWString(iter, r);
515 }
516 static void Log(const param_type& p, std::wstring* l) {
517 l->append(p);
518 }
519};
520
[email protected]a5da6d612009-08-04 02:00:56521template <class A, class B>
522struct ParamTraits<std::pair<A, B> > {
523 typedef std::pair<A, B> param_type;
524 static void Write(Message* m, const param_type& p) {
525 WriteParam(m, p.first);
526 WriteParam(m, p.second);
527 }
528 static bool Read(const Message* m, void** iter, param_type* r) {
529 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
530 }
531 static void Log(const param_type& p, std::wstring* l) {
532 l->append(L"(");
533 LogParam(p.first, l);
534 l->append(L", ");
535 LogParam(p.second, l);
536 l->append(L")");
537 }
538};
539
[email protected]15bf8712009-08-27 00:55:02540template <>
541struct ParamTraits<NullableString16> {
542 typedef NullableString16 param_type;
543 static void Write(Message* m, const param_type& p) {
544 WriteParam(m, p.string());
545 WriteParam(m, p.is_null());
546 }
547 static bool Read(const Message* m, void** iter, param_type* r) {
548 string16 string;
549 if (!ReadParam(m, iter, &string))
550 return false;
551 bool is_null;
552 if (!ReadParam(m, iter, &is_null))
553 return false;
554 *r = NullableString16(string, is_null);
555 return true;
556 }
557 static void Log(const param_type& p, std::wstring* l) {
558 l->append(L"(");
559 LogParam(p.string(), l);
560 l->append(L", ");
561 LogParam(p.is_null(), l);
562 l->append(L")");
563 }
564};
565
[email protected]eb47a132009-03-04 00:39:56566// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
567// need this trait.
568#if !defined(WCHAR_T_IS_UTF16)
[email protected]eb47a132009-03-04 00:39:56569template <>
570struct ParamTraits<string16> {
571 typedef string16 param_type;
572 static void Write(Message* m, const param_type& p) {
[email protected]3a2a5d22009-03-04 03:36:36573 m->WriteString16(p);
[email protected]eb47a132009-03-04 00:39:56574 }
575 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]3a2a5d22009-03-04 03:36:36576 return m->ReadString16(iter, r);
[email protected]eb47a132009-03-04 00:39:56577 }
578 static void Log(const param_type& p, std::wstring* l) {
579 l->append(UTF16ToWide(p));
580 }
581};
[email protected]eb47a132009-03-04 00:39:56582#endif
583
[email protected]7d5c3ac2009-02-04 08:58:19584// and, a few more useful types...
585#if defined(OS_WIN)
586template <>
587struct ParamTraits<HANDLE> {
588 typedef HANDLE param_type;
589 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35590 // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
591 // bit systems.
592 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19593 }
594 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35595 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
596 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19597 }
598 static void Log(const param_type& p, std::wstring* l) {
599 l->append(StringPrintf(L"0x%X", p));
600 }
601};
602
603template <>
604struct ParamTraits<HCURSOR> {
605 typedef HCURSOR param_type;
606 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35607 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19608 }
609 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35610 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
611 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19612 }
613 static void Log(const param_type& p, std::wstring* l) {
614 l->append(StringPrintf(L"0x%X", p));
615 }
616};
617
618template <>
[email protected]7d5c3ac2009-02-04 08:58:19619struct ParamTraits<HACCEL> {
620 typedef HACCEL param_type;
621 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35622 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19623 }
624 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35625 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
626 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19627 }
628};
629
630template <>
631struct ParamTraits<POINT> {
632 typedef POINT param_type;
633 static void Write(Message* m, const param_type& p) {
634 m->WriteInt(p.x);
635 m->WriteInt(p.y);
636 }
637 static bool Read(const Message* m, void** iter, param_type* r) {
638 int x, y;
639 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
640 return false;
641 r->x = x;
642 r->y = y;
643 return true;
644 }
645 static void Log(const param_type& p, std::wstring* l) {
646 l->append(StringPrintf(L"(%d, %d)", p.x, p.y));
647 }
648};
649#endif // defined(OS_WIN)
650
651template <>
652struct ParamTraits<FilePath> {
653 typedef FilePath param_type;
654 static void Write(Message* m, const param_type& p) {
655 ParamTraits<FilePath::StringType>::Write(m, p.value());
656 }
657 static bool Read(const Message* m, void** iter, param_type* r) {
658 FilePath::StringType value;
659 if (!ParamTraits<FilePath::StringType>::Read(m, iter, &value))
660 return false;
661 *r = FilePath(value);
662 return true;
663 }
664 static void Log(const param_type& p, std::wstring* l) {
665 ParamTraits<FilePath::StringType>::Log(p.value(), l);
666 }
667};
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]526776c2009-02-07 00:39:26688 static void Write(Message* m, const param_type& p) {
[email protected]2749885f2009-03-05 21:40:11689 const bool valid = p.fd >= 0;
690 WriteParam(m, valid);
691
692 if (valid) {
693 if (!m->WriteFileDescriptor(p))
694 NOTREACHED();
695 }
[email protected]526776c2009-02-07 00:39:26696 }
697 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]2749885f2009-03-05 21:40:11698 bool valid;
699 if (!ReadParam(m, iter, &valid))
700 return false;
701
702 if (!valid) {
703 r->fd = -1;
704 r->auto_close = false;
705 return true;
706 }
707
[email protected]7135bb042009-02-12 04:05:28708 return m->ReadFileDescriptor(iter, r);
[email protected]526776c2009-02-07 00:39:26709 }
710 static void Log(const param_type& p, std::wstring* l) {
711 if (p.auto_close) {
[email protected]7135bb042009-02-12 04:05:28712 l->append(StringPrintf(L"FD(%d auto-close)", p.fd));
[email protected]526776c2009-02-07 00:39:26713 } else {
[email protected]7135bb042009-02-12 04:05:28714 l->append(StringPrintf(L"FD(%d)", p.fd));
[email protected]526776c2009-02-07 00:39:26715 }
716 }
717};
[email protected]379e7a52010-03-09 00:38:41718#endif // defined(OS_POSIX)
[email protected]526776c2009-02-07 00:39:26719
[email protected]d2e884d2009-06-22 20:37:52720// A ChannelHandle is basically a platform-inspecific wrapper around the
721// fact that IPC endpoints are handled specially on POSIX. See above comments
722// on FileDescriptor for more background.
723template<>
724struct ParamTraits<IPC::ChannelHandle> {
725 typedef ChannelHandle param_type;
726 static void Write(Message* m, const param_type& p) {
727 WriteParam(m, p.name);
728#if defined(OS_POSIX)
729 WriteParam(m, p.socket);
730#endif
731 }
732 static bool Read(const Message* m, void** iter, param_type* r) {
733 return ReadParam(m, iter, &r->name)
734#if defined(OS_POSIX)
735 && ReadParam(m, iter, &r->socket)
736#endif
737 ;
738 }
739 static void Log(const param_type& p, std::wstring* l) {
[email protected]e9abf8d2009-07-10 22:41:00740 l->append(ASCIIToWide(StringPrintf("ChannelHandle(%s", p.name.c_str())));
[email protected]d2e884d2009-06-22 20:37:52741#if defined(OS_POSIX)
742 ParamTraits<base::FileDescriptor>::Log(p.socket, l);
743#endif
744 l->append(L")");
745 }
746};
747
[email protected]7d5c3ac2009-02-04 08:58:19748#if defined(OS_WIN)
749template <>
750struct ParamTraits<XFORM> {
751 typedef XFORM param_type;
752 static void Write(Message* m, const param_type& p) {
753 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
754 }
755 static bool Read(const Message* m, void** iter, param_type* r) {
756 const char *data;
757 int data_size = 0;
758 bool result = m->ReadData(iter, &data, &data_size);
759 if (result && data_size == sizeof(XFORM)) {
760 memcpy(r, data, sizeof(XFORM));
761 } else {
762 result = false;
763 NOTREACHED();
764 }
765
766 return result;
767 }
768 static void Log(const param_type& p, std::wstring* l) {
769 l->append(L"<XFORM>");
770 }
771};
772#endif // defined(OS_WIN)
773
[email protected]7d5c3ac2009-02-04 08:58:19774struct LogData {
[email protected]9a3a293b2009-06-04 22:28:16775 std::string channel;
[email protected]8bef70e2009-04-14 19:11:24776 int32 routing_id;
[email protected]168ae922009-12-04 18:08:45777 uint32 type; // "User-defined" message type, from ipc_message.h.
[email protected]7d5c3ac2009-02-04 08:58:19778 std::wstring flags;
779 int64 sent; // Time that the message was sent (i.e. at Send()).
780 int64 receive; // Time before it was dispatched (i.e. before calling
781 // OnMessageReceived).
782 int64 dispatch; // Time after it was dispatched (i.e. after calling
783 // OnMessageReceived).
[email protected]e707d5e62009-02-12 04:00:08784 std::wstring message_name;
[email protected]7d5c3ac2009-02-04 08:58:19785 std::wstring params;
786};
787
788template <>
789struct ParamTraits<LogData> {
790 typedef LogData param_type;
791 static void Write(Message* m, const param_type& p) {
792 WriteParam(m, p.channel);
[email protected]8bef70e2009-04-14 19:11:24793 WriteParam(m, p.routing_id);
[email protected]7d5c3ac2009-02-04 08:58:19794 WriteParam(m, static_cast<int>(p.type));
795 WriteParam(m, p.flags);
796 WriteParam(m, p.sent);
797 WriteParam(m, p.receive);
798 WriteParam(m, p.dispatch);
799 WriteParam(m, p.params);
800 }
801 static bool Read(const Message* m, void** iter, param_type* r) {
802 int type;
803 bool result =
804 ReadParam(m, iter, &r->channel) &&
[email protected]25af92052010-03-26 22:21:17805 ReadParam(m, iter, &r->routing_id) &&
[email protected]7d5c3ac2009-02-04 08:58:19806 ReadParam(m, iter, &type) &&
807 ReadParam(m, iter, &r->flags) &&
808 ReadParam(m, iter, &r->sent) &&
809 ReadParam(m, iter, &r->receive) &&
810 ReadParam(m, iter, &r->dispatch) &&
811 ReadParam(m, iter, &r->params);
812 r->type = static_cast<uint16>(type);
813 return result;
814 }
815 static void Log(const param_type& p, std::wstring* l) {
816 // Doesn't make sense to implement this!
817 }
818};
819
[email protected]eb47a132009-03-04 00:39:56820template <>
[email protected]503683f2009-02-26 09:13:01821struct ParamTraits<Message> {
822 static void Write(Message* m, const Message& p) {
823 m->WriteInt(p.size());
824 m->WriteData(reinterpret_cast<const char*>(p.data()), p.size());
825 }
826 static bool Read(const Message* m, void** iter, Message* r) {
827 int size;
828 if (!m->ReadInt(iter, &size))
829 return false;
830 const char* data;
831 if (!m->ReadData(iter, &data, &size))
832 return false;
833 *r = Message(data, size);
834 return true;
835 }
836 static void Log(const Message& p, std::wstring* l) {
837 l->append(L"<IPC::Message>");
838 }
839};
840
841template <>
[email protected]7d5c3ac2009-02-04 08:58:19842struct ParamTraits<Tuple0> {
843 typedef Tuple0 param_type;
844 static void Write(Message* m, const param_type& p) {
845 }
846 static bool Read(const Message* m, void** iter, param_type* r) {
847 return true;
848 }
849 static void Log(const param_type& p, std::wstring* l) {
850 }
851};
852
853template <class A>
854struct ParamTraits< Tuple1<A> > {
855 typedef Tuple1<A> param_type;
856 static void Write(Message* m, const param_type& p) {
857 WriteParam(m, p.a);
858 }
859 static bool Read(const Message* m, void** iter, param_type* r) {
860 return ReadParam(m, iter, &r->a);
861 }
862 static void Log(const param_type& p, std::wstring* l) {
863 LogParam(p.a, l);
864 }
865};
866
867template <class A, class B>
868struct ParamTraits< Tuple2<A, B> > {
869 typedef Tuple2<A, B> param_type;
870 static void Write(Message* m, const param_type& p) {
871 WriteParam(m, p.a);
872 WriteParam(m, p.b);
873 }
874 static bool Read(const Message* m, void** iter, param_type* r) {
875 return (ReadParam(m, iter, &r->a) &&
876 ReadParam(m, iter, &r->b));
877 }
878 static void Log(const param_type& p, std::wstring* l) {
879 LogParam(p.a, l);
880 l->append(L", ");
881 LogParam(p.b, l);
882 }
883};
884
885template <class A, class B, class C>
886struct ParamTraits< Tuple3<A, B, C> > {
887 typedef Tuple3<A, B, C> param_type;
888 static void Write(Message* m, const param_type& p) {
889 WriteParam(m, p.a);
890 WriteParam(m, p.b);
891 WriteParam(m, p.c);
892 }
893 static bool Read(const Message* m, void** iter, param_type* r) {
894 return (ReadParam(m, iter, &r->a) &&
895 ReadParam(m, iter, &r->b) &&
896 ReadParam(m, iter, &r->c));
897 }
898 static void Log(const param_type& p, std::wstring* l) {
899 LogParam(p.a, l);
900 l->append(L", ");
901 LogParam(p.b, l);
902 l->append(L", ");
903 LogParam(p.c, l);
904 }
905};
906
907template <class A, class B, class C, class D>
908struct ParamTraits< Tuple4<A, B, C, D> > {
909 typedef Tuple4<A, B, C, D> param_type;
910 static void Write(Message* m, const param_type& p) {
911 WriteParam(m, p.a);
912 WriteParam(m, p.b);
913 WriteParam(m, p.c);
914 WriteParam(m, p.d);
915 }
916 static bool Read(const Message* m, void** iter, param_type* r) {
917 return (ReadParam(m, iter, &r->a) &&
918 ReadParam(m, iter, &r->b) &&
919 ReadParam(m, iter, &r->c) &&
920 ReadParam(m, iter, &r->d));
921 }
922 static void Log(const param_type& p, std::wstring* l) {
923 LogParam(p.a, l);
924 l->append(L", ");
925 LogParam(p.b, l);
926 l->append(L", ");
927 LogParam(p.c, l);
928 l->append(L", ");
929 LogParam(p.d, l);
930 }
931};
932
933template <class A, class B, class C, class D, class E>
934struct ParamTraits< Tuple5<A, B, C, D, E> > {
935 typedef Tuple5<A, B, C, D, E> param_type;
936 static void Write(Message* m, const param_type& p) {
937 WriteParam(m, p.a);
938 WriteParam(m, p.b);
939 WriteParam(m, p.c);
940 WriteParam(m, p.d);
941 WriteParam(m, p.e);
942 }
943 static bool Read(const Message* m, void** iter, param_type* r) {
944 return (ReadParam(m, iter, &r->a) &&
945 ReadParam(m, iter, &r->b) &&
946 ReadParam(m, iter, &r->c) &&
947 ReadParam(m, iter, &r->d) &&
948 ReadParam(m, iter, &r->e));
949 }
950 static void Log(const param_type& p, std::wstring* l) {
951 LogParam(p.a, l);
952 l->append(L", ");
953 LogParam(p.b, l);
954 l->append(L", ");
955 LogParam(p.c, l);
956 l->append(L", ");
957 LogParam(p.d, l);
958 l->append(L", ");
959 LogParam(p.e, l);
960 }
961};
962
[email protected]7d5c3ac2009-02-04 08:58:19963//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:29964// Generic message subclasses
965
966// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:24967template <class ParamType>
initial.commit09911bf2008-07-26 23:55:29968class MessageWithTuple : public Message {
969 public:
[email protected]81a34412009-01-05 19:17:24970 typedef ParamType Param;
[email protected]c2fe31542009-05-20 18:24:14971 typedef typename ParamType::ParamTuple RefParam;
[email protected]81a34412009-01-05 19:17:24972
[email protected]168ae922009-12-04 18:08:45973 MessageWithTuple(int32 routing_id, uint32 type, const RefParam& p)
initial.commit09911bf2008-07-26 23:55:29974 : Message(routing_id, type, PRIORITY_NORMAL) {
975 WriteParam(this, p);
976 }
977
[email protected]7d5c3ac2009-02-04 08:58:19978 static bool Read(const Message* msg, Param* p) {
initial.commit09911bf2008-07-26 23:55:29979 void* iter = NULL;
[email protected]3b8463962009-07-16 06:27:38980 if (ReadParam(msg, &iter, p))
981 return true;
982 NOTREACHED() << "Error deserializing message " << msg->type();
983 return false;
initial.commit09911bf2008-07-26 23:55:29984 }
985
986 // Generic dispatcher. Should cover most cases.
987 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:19988 static bool Dispatch(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:29989 Param p;
990 if (Read(msg, &p)) {
991 DispatchToMethod(obj, func, p);
992 return true;
993 }
994 return false;
995 }
996
997 // The following dispatchers exist for the case where the callback function
998 // needs the message as well. They assume that "Param" is a type of Tuple
999 // (except the one arg case, as there is no Tuple1).
1000 template<class T, typename TA>
[email protected]7d5c3ac2009-02-04 08:58:191001 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291002 void (T::*func)(const Message&, TA)) {
1003 Param p;
1004 if (Read(msg, &p)) {
[email protected]c2fe31542009-05-20 18:24:141005 (obj->*func)(*msg, p.a);
initial.commit09911bf2008-07-26 23:55:291006 return true;
1007 }
1008 return false;
1009 }
1010
1011 template<class T, typename TA, typename TB>
[email protected]7d5c3ac2009-02-04 08:58:191012 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291013 void (T::*func)(const Message&, TA, TB)) {
1014 Param p;
1015 if (Read(msg, &p)) {
1016 (obj->*func)(*msg, p.a, p.b);
1017 return true;
1018 }
1019 return false;
1020 }
1021
1022 template<class T, typename TA, typename TB, typename TC>
[email protected]7d5c3ac2009-02-04 08:58:191023 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291024 void (T::*func)(const Message&, TA, TB, TC)) {
1025 Param p;
1026 if (Read(msg, &p)) {
1027 (obj->*func)(*msg, p.a, p.b, p.c);
1028 return true;
1029 }
1030 return false;
1031 }
1032
1033 template<class T, typename TA, typename TB, typename TC, typename TD>
[email protected]7d5c3ac2009-02-04 08:58:191034 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291035 void (T::*func)(const Message&, TA, TB, TC, TD)) {
1036 Param p;
1037 if (Read(msg, &p)) {
1038 (obj->*func)(*msg, p.a, p.b, p.c, p.d);
1039 return true;
1040 }
1041 return false;
1042 }
1043
1044 template<class T, typename TA, typename TB, typename TC, typename TD,
1045 typename TE>
[email protected]7d5c3ac2009-02-04 08:58:191046 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291047 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
1048 Param p;
1049 if (Read(msg, &p)) {
1050 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
1051 return true;
1052 }
1053 return false;
1054 }
1055
[email protected]7d5c3ac2009-02-04 08:58:191056 static void Log(const Message* msg, std::wstring* l) {
initial.commit09911bf2008-07-26 23:55:291057 Param p;
1058 if (Read(msg, &p))
1059 LogParam(p, l);
1060 }
[email protected]deb57402009-02-06 01:35:301061
1062 // Functions used to do manual unpacking. Only used by the automation code,
1063 // these should go away once that code uses SyncChannel.
1064 template<typename TA, typename TB>
1065 static bool Read(const IPC::Message* msg, TA* a, TB* b) {
1066 ParamType params;
1067 if (!Read(msg, &params))
1068 return false;
1069 *a = params.a;
1070 *b = params.b;
1071 return true;
1072 }
1073
1074 template<typename TA, typename TB, typename TC>
1075 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
1076 ParamType params;
1077 if (!Read(msg, &params))
1078 return false;
1079 *a = params.a;
1080 *b = params.b;
1081 *c = params.c;
1082 return true;
1083 }
1084
1085 template<typename TA, typename TB, typename TC, typename TD>
1086 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) {
1087 ParamType params;
1088 if (!Read(msg, &params))
1089 return false;
1090 *a = params.a;
1091 *b = params.b;
1092 *c = params.c;
1093 *d = params.d;
1094 return true;
1095 }
1096
1097 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1098 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) {
1099 ParamType params;
1100 if (!Read(msg, &params))
1101 return false;
1102 *a = params.a;
1103 *b = params.b;
1104 *c = params.c;
1105 *d = params.d;
1106 *e = params.e;
1107 return true;
1108 }
initial.commit09911bf2008-07-26 23:55:291109};
1110
1111// This class assumes that its template argument is a RefTuple (a Tuple with
1112// reference elements).
1113template <class RefTuple>
1114class ParamDeserializer : public MessageReplyDeserializer {
1115 public:
[email protected]e1981f432008-08-12 15:22:131116 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:291117
1118 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1119 return ReadParam(&msg, &iter, &out_);
1120 }
1121
1122 RefTuple out_;
1123};
1124
1125// defined in ipc_logging.cc
[email protected]9a3a293b2009-06-04 22:28:161126void GenerateLogData(const std::string& channel, const Message& message,
initial.commit09911bf2008-07-26 23:55:291127 LogData* data);
1128
1129// Used for synchronous messages.
[email protected]75e5a872009-04-02 23:56:111130template <class SendParamType, class ReplyParamType>
initial.commit09911bf2008-07-26 23:55:291131class MessageWithReply : public SyncMessage {
1132 public:
[email protected]75e5a872009-04-02 23:56:111133 typedef SendParamType SendParam;
[email protected]c2fe31542009-05-20 18:24:141134 typedef typename SendParam::ParamTuple RefSendParam;
[email protected]75e5a872009-04-02 23:56:111135 typedef ReplyParamType ReplyParam;
1136
[email protected]168ae922009-12-04 18:08:451137 MessageWithReply(int32 routing_id, uint32 type,
[email protected]c2fe31542009-05-20 18:24:141138 const RefSendParam& send, const ReplyParam& reply)
initial.commit09911bf2008-07-26 23:55:291139 : SyncMessage(routing_id, type, PRIORITY_NORMAL,
1140 new ParamDeserializer<ReplyParam>(reply)) {
1141 WriteParam(this, send);
1142 }
1143
[email protected]7d5c3ac2009-02-04 08:58:191144 static void Log(const Message* msg, std::wstring* l) {
initial.commit09911bf2008-07-26 23:55:291145 if (msg->is_sync()) {
1146 SendParam p;
1147 void* iter = SyncMessage::GetDataIterator(msg);
[email protected]1e86aa62009-04-24 21:22:331148 if (ReadParam(msg, &iter, &p))
1149 LogParam(p, l);
initial.commit09911bf2008-07-26 23:55:291150
[email protected]1156f7b2008-12-04 19:13:591151#if defined(IPC_MESSAGE_LOG_ENABLED)
initial.commit09911bf2008-07-26 23:55:291152 const std::wstring& output_params = msg->output_params();
1153 if (!l->empty() && !output_params.empty())
1154 l->append(L", ");
1155
1156 l->append(output_params);
[email protected]2a34f9c2008-12-04 19:12:041157#endif
initial.commit09911bf2008-07-26 23:55:291158 } else {
1159 // This is an outgoing reply. Now that we have the output parameters, we
1160 // can finally log the message.
[email protected]d4651ff2008-12-02 16:51:581161 typename ReplyParam::ValueTuple p;
initial.commit09911bf2008-07-26 23:55:291162 void* iter = SyncMessage::GetDataIterator(msg);
[email protected]1e86aa62009-04-24 21:22:331163 if (ReadParam(msg, &iter, &p))
1164 LogParam(p, l);
initial.commit09911bf2008-07-26 23:55:291165 }
1166 }
1167
1168 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191169 static bool Dispatch(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291170 SendParam send_params;
1171 void* iter = GetDataIterator(msg);
1172 Message* reply = GenerateReply(msg);
1173 bool error;
1174 if (ReadParam(msg, &iter, &send_params)) {
[email protected]d4651ff2008-12-02 16:51:581175 typename ReplyParam::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:291176 DispatchToMethod(obj, func, send_params, &reply_params);
1177 WriteParam(reply, reply_params);
1178 error = false;
1179#ifdef IPC_MESSAGE_LOG_ENABLED
1180 if (msg->received_time() != 0) {
1181 std::wstring output_params;
1182 LogParam(reply_params, &output_params);
1183 msg->set_output_params(output_params);
1184 }
1185#endif
1186 } else {
1187 NOTREACHED() << "Error deserializing message " << msg->type();
1188 reply->set_reply_error();
1189 error = true;
1190 }
1191
1192 obj->Send(reply);
1193 return !error;
1194 }
1195
1196 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191197 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291198 SendParam send_params;
1199 void* iter = GetDataIterator(msg);
1200 Message* reply = GenerateReply(msg);
1201 bool error;
1202 if (ReadParam(msg, &iter, &send_params)) {
1203 Tuple1<Message&> t = MakeRefTuple(*reply);
1204
1205#ifdef IPC_MESSAGE_LOG_ENABLED
1206 if (msg->sent_time()) {
1207 // Don't log the sync message after dispatch, as we don't have the
1208 // output parameters at that point. Instead, save its data and log it
1209 // with the outgoing reply message when it's sent.
1210 LogData* data = new LogData;
[email protected]9a3a293b2009-06-04 22:28:161211 GenerateLogData("", *msg, data);
initial.commit09911bf2008-07-26 23:55:291212 msg->set_dont_log();
1213 reply->set_sync_log_data(data);
1214 }
1215#endif
1216 DispatchToMethod(obj, func, send_params, &t);
1217 error = false;
1218 } else {
1219 NOTREACHED() << "Error deserializing message " << msg->type();
1220 reply->set_reply_error();
1221 obj->Send(reply);
1222 error = true;
1223 }
1224 return !error;
1225 }
1226
1227 template<typename TA>
1228 static void WriteReplyParams(Message* reply, TA a) {
1229 ReplyParam p(a);
1230 WriteParam(reply, p);
1231 }
1232
1233 template<typename TA, typename TB>
1234 static void WriteReplyParams(Message* reply, TA a, TB b) {
1235 ReplyParam p(a, b);
1236 WriteParam(reply, p);
1237 }
1238
1239 template<typename TA, typename TB, typename TC>
1240 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1241 ReplyParam p(a, b, c);
1242 WriteParam(reply, p);
1243 }
1244
1245 template<typename TA, typename TB, typename TC, typename TD>
1246 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1247 ReplyParam p(a, b, c, d);
1248 WriteParam(reply, p);
1249 }
1250
1251 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1252 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1253 ReplyParam p(a, b, c, d, e);
1254 WriteParam(reply, p);
1255 }
1256};
1257
[email protected]7d5c3ac2009-02-04 08:58:191258//-----------------------------------------------------------------------------
1259
[email protected]3178f4e22008-08-05 21:20:411260} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291261
[email protected]946d1b22009-07-22 23:57:211262#endif // IPC_IPC_MESSAGE_UTILS_H_