blob: ff33e6aa08452d5ce3fef5c47265465cc16f9509 [file] [log] [blame]
license.botbf09a502008-08-24 00:55:551// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2// 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]82e5ee82009-04-03 02:29:455#ifndef CHROME_COMMON_IPC_MESSAGE_UTILS_H_
6#define CHROME_COMMON_IPC_MESSAGE_UTILS_H_
initial.commit09911bf2008-07-26 23:55:297
8#include <string>
9#include <vector>
10#include <map>
11
[email protected]690a99c2009-01-06 16:48:4512#include "base/file_path.h"
initial.commit09911bf2008-07-26 23:55:2913#include "base/string_util.h"
[email protected]eb47a132009-03-04 00:39:5614#include "base/string16.h"
initial.commit09911bf2008-07-26 23:55:2915#include "base/tuple.h"
[email protected]526776c2009-02-07 00:39:2616#if defined(OS_POSIX)
[email protected]82e5ee82009-04-03 02:29:4517#include "chrome/common/file_descriptor_set_posix.h"
[email protected]526776c2009-02-07 00:39:2618#endif
[email protected]82e5ee82009-04-03 02:29:4519#include "chrome/common/ipc_sync_message.h"
20#include "chrome/common/thumbnail_score.h"
21#include "chrome/common/transport_dib.h"
22#include "webkit/glue/webcursor.h"
23#include "webkit/glue/window_open_disposition.h"
[email protected]3178f4e22008-08-05 21:20:4124
25// Forward declarations.
[email protected]82e5ee82009-04-03 02:29:4526class GURL;
27class SkBitmap;
[email protected]584f2b22009-05-21 01:01:5928class DictionaryValue;
29class ListValue;
[email protected]82e5ee82009-04-03 02:29:4530
[email protected]3178f4e22008-08-05 21:20:4131namespace gfx {
32class Point;
33class Rect;
34class Size;
35} // namespace gfx
36
[email protected]82e5ee82009-04-03 02:29:4537namespace webkit_glue {
38struct WebApplicationInfo;
39} // namespace webkit_glue
40
[email protected]f91cb992009-02-04 20:10:1241// Used by IPC_BEGIN_MESSAGES so that each message class starts from a unique
42// base. Messages have unique IDs across channels in order for the IPC logging
43// code to figure out the message class from its ID.
44enum IPCMessageStart {
45 // By using a start value of 0 for automation messages, we keep backward
46 // compatibility with old builds.
47 AutomationMsgStart = 0,
48 ViewMsgStart,
49 ViewHostMsgStart,
50 PluginProcessMsgStart,
51 PluginProcessHostMsgStart,
52 PluginMsgStart,
53 PluginHostMsgStart,
54 NPObjectMsgStart,
55 TestMsgStart,
[email protected]503683f2009-02-26 09:13:0156 DevToolsAgentMsgStart,
57 DevToolsClientMsgStart,
[email protected]eb47a132009-03-04 00:39:5658 WorkerProcessMsgStart,
59 WorkerProcessHostMsgStart,
60 WorkerMsgStart,
61 WorkerHostMsgStart,
[email protected]f91cb992009-02-04 20:10:1262 // NOTE: When you add a new message class, also update
63 // IPCStatusView::IPCStatusView to ensure logging works.
64 // NOTE: this enum is used by IPC_MESSAGE_MACRO to generate a unique message
65 // id. Only 4 bits are used for the message type, so if this enum needs more
66 // than 16 entries, that code needs to be updated.
67 LastMsgIndex
68};
69
70COMPILE_ASSERT(LastMsgIndex <= 16, need_to_update_IPC_MESSAGE_MACRO);
71
initial.commit09911bf2008-07-26 23:55:2972namespace IPC {
73
initial.commit09911bf2008-07-26 23:55:2974//-----------------------------------------------------------------------------
75// An iterator class for reading the fields contained within a Message.
76
77class MessageIterator {
78 public:
[email protected]e1981f432008-08-12 15:22:1379 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
initial.commit09911bf2008-07-26 23:55:2980 }
81 int NextInt() const {
82 int val;
83 if (!msg_.ReadInt(&iter_, &val))
84 NOTREACHED();
85 return val;
86 }
87 intptr_t NextIntPtr() const {
88 intptr_t val;
89 if (!msg_.ReadIntPtr(&iter_, &val))
90 NOTREACHED();
91 return val;
92 }
93 const std::string NextString() const {
94 std::string val;
95 if (!msg_.ReadString(&iter_, &val))
96 NOTREACHED();
97 return val;
98 }
99 const std::wstring NextWString() const {
100 std::wstring val;
101 if (!msg_.ReadWString(&iter_, &val))
102 NOTREACHED();
103 return val;
104 }
105 const void NextData(const char** data, int* length) const {
106 if (!msg_.ReadData(&iter_, data, length)) {
107 NOTREACHED();
108 }
109 }
110 private:
111 const Message& msg_;
112 mutable void* iter_;
113};
114
115//-----------------------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19116// ParamTraits specializations, etc.
117
118template <class P> struct ParamTraits {};
119
120template <class P>
121static inline void WriteParam(Message* m, const P& p) {
122 ParamTraits<P>::Write(m, p);
123}
124
125template <class P>
[email protected]1e86aa62009-04-24 21:22:33126static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
127 P* p) {
[email protected]7d5c3ac2009-02-04 08:58:19128 return ParamTraits<P>::Read(m, iter, p);
129}
130
131template <class P>
132static inline void LogParam(const P& p, std::wstring* l) {
133 ParamTraits<P>::Log(p, l);
134}
135
136template <>
137struct ParamTraits<bool> {
138 typedef bool param_type;
139 static void Write(Message* m, const param_type& p) {
140 m->WriteBool(p);
141 }
142 static bool Read(const Message* m, void** iter, param_type* r) {
143 return m->ReadBool(iter, r);
144 }
145 static void Log(const param_type& p, std::wstring* l) {
146 l->append(p ? L"true" : L"false");
147 }
148};
149
150template <>
151struct ParamTraits<int> {
152 typedef int param_type;
153 static void Write(Message* m, const param_type& p) {
154 m->WriteInt(p);
155 }
156 static bool Read(const Message* m, void** iter, param_type* r) {
157 return m->ReadInt(iter, r);
158 }
159 static void Log(const param_type& p, std::wstring* l) {
160 l->append(StringPrintf(L"%d", p));
161 }
162};
163
164template <>
165struct ParamTraits<long> {
166 typedef long param_type;
167 static void Write(Message* m, const param_type& p) {
168 m->WriteLong(p);
169 }
170 static bool Read(const Message* m, void** iter, param_type* r) {
171 return m->ReadLong(iter, r);
172 }
173 static void Log(const param_type& p, std::wstring* l) {
174 l->append(StringPrintf(L"%l", p));
175 }
176};
177
178template <>
179struct ParamTraits<size_t> {
180 typedef size_t param_type;
181 static void Write(Message* m, const param_type& p) {
182 m->WriteSize(p);
183 }
184 static bool Read(const Message* m, void** iter, param_type* r) {
185 return m->ReadSize(iter, r);
186 }
187 static void Log(const param_type& p, std::wstring* l) {
188 l->append(StringPrintf(L"%u", p));
189 }
190};
191
192#if defined(OS_MACOSX)
193// On Linux size_t & uint32 can be the same type.
194// TODO(playmobil): Fix compilation if this is not the case.
195template <>
196struct ParamTraits<uint32> {
197 typedef uint32 param_type;
198 static void Write(Message* m, const param_type& p) {
199 m->WriteUInt32(p);
200 }
201 static bool Read(const Message* m, void** iter, param_type* r) {
202 return m->ReadUInt32(iter, r);
203 }
204 static void Log(const param_type& p, std::wstring* l) {
205 l->append(StringPrintf(L"%u", p));
206 }
207};
208#endif // defined(OS_MACOSX)
209
210template <>
211struct ParamTraits<int64> {
212 typedef int64 param_type;
213 static void Write(Message* m, const param_type& p) {
214 m->WriteInt64(p);
215 }
216 static bool Read(const Message* m, void** iter, param_type* r) {
217 return m->ReadInt64(iter, r);
218 }
219 static void Log(const param_type& p, std::wstring* l) {
220 l->append(StringPrintf(L"%I64d", p));
221 }
222};
223
224template <>
225struct ParamTraits<uint64> {
226 typedef uint64 param_type;
227 static void Write(Message* m, const param_type& p) {
228 m->WriteInt64(static_cast<int64>(p));
229 }
230 static bool Read(const Message* m, void** iter, param_type* r) {
231 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
232 }
233 static void Log(const param_type& p, std::wstring* l) {
234 l->append(StringPrintf(L"%I64u", p));
235 }
236};
237
238template <>
239struct ParamTraits<double> {
240 typedef double param_type;
241 static void Write(Message* m, const param_type& p) {
242 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
243 }
244 static bool Read(const Message* m, void** iter, param_type* r) {
245 const char *data;
246 int data_size = 0;
247 bool result = m->ReadData(iter, &data, &data_size);
248 if (result && data_size == sizeof(param_type)) {
249 memcpy(r, data, sizeof(param_type));
250 } else {
251 result = false;
252 NOTREACHED();
253 }
254
255 return result;
256 }
257 static void Log(const param_type& p, std::wstring* l) {
258 l->append(StringPrintf(L"e", p));
259 }
260};
261
262template <>
263struct ParamTraits<wchar_t> {
264 typedef wchar_t param_type;
265 static void Write(Message* m, const param_type& p) {
266 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
267 }
268 static bool Read(const Message* m, void** iter, param_type* r) {
269 const char *data;
270 int data_size = 0;
271 bool result = m->ReadData(iter, &data, &data_size);
272 if (result && data_size == sizeof(param_type)) {
273 memcpy(r, data, sizeof(param_type));
274 } else {
275 result = false;
276 NOTREACHED();
277 }
278
279 return result;
280 }
281 static void Log(const param_type& p, std::wstring* l) {
282 l->append(StringPrintf(L"%lc", p));
283 }
284};
285
286template <>
287struct ParamTraits<base::Time> {
288 typedef base::Time param_type;
289 static void Write(Message* m, const param_type& p) {
290 ParamTraits<int64>::Write(m, p.ToInternalValue());
291 }
292 static bool Read(const Message* m, void** iter, param_type* r) {
293 int64 value;
294 if (!ParamTraits<int64>::Read(m, iter, &value))
295 return false;
296 *r = base::Time::FromInternalValue(value);
297 return true;
298 }
299 static void Log(const param_type& p, std::wstring* l) {
300 ParamTraits<int64>::Log(p.ToInternalValue(), l);
301 }
302};
303
304#if defined(OS_WIN)
305template <>
306struct ParamTraits<LOGFONT> {
307 typedef LOGFONT param_type;
308 static void Write(Message* m, const param_type& p) {
309 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
310 }
311 static bool Read(const Message* m, void** iter, param_type* r) {
312 const char *data;
313 int data_size = 0;
314 bool result = m->ReadData(iter, &data, &data_size);
315 if (result && data_size == sizeof(LOGFONT)) {
316 memcpy(r, data, sizeof(LOGFONT));
317 } else {
318 result = false;
319 NOTREACHED();
320 }
321
322 return result;
323 }
324 static void Log(const param_type& p, std::wstring* l) {
325 l->append(StringPrintf(L"<LOGFONT>"));
326 }
327};
328
329template <>
330struct ParamTraits<MSG> {
331 typedef MSG param_type;
332 static void Write(Message* m, const param_type& p) {
333 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
334 }
335 static bool Read(const Message* m, void** iter, param_type* r) {
336 const char *data;
337 int data_size = 0;
338 bool result = m->ReadData(iter, &data, &data_size);
339 if (result && data_size == sizeof(MSG)) {
340 memcpy(r, data, sizeof(MSG));
341 } else {
342 result = false;
343 NOTREACHED();
344 }
345
346 return result;
347 }
348};
349#endif // defined(OS_WIN)
350
351template <>
[email protected]82e5ee82009-04-03 02:29:45352struct ParamTraits<SkBitmap> {
353 typedef SkBitmap param_type;
354 static void Write(Message* m, const param_type& p);
355
356 // Note: This function expects parameter |r| to be of type &SkBitmap since
357 // r->SetConfig() and r->SetPixels() are called.
358 static bool Read(const Message* m, void** iter, param_type* r);
359
360 static void Log(const param_type& p, std::wstring* l);
361};
362
363template <>
[email protected]584f2b22009-05-21 01:01:59364struct ParamTraits<DictionaryValue> {
365 typedef DictionaryValue param_type;
366 static void Write(Message* m, const param_type& p);
367 static bool Read(const Message* m, void** iter, param_type* r);
368 static void Log(const param_type& p, std::wstring* l);
369};
370
371template <>
372struct ParamTraits<ListValue> {
373 typedef ListValue param_type;
374 static void Write(Message* m, const param_type& p);
375 static bool Read(const Message* m, void** iter, param_type* r);
376 static void Log(const param_type& p, std::wstring* l);
377};
378
379template <>
[email protected]7d5c3ac2009-02-04 08:58:19380struct ParamTraits<std::string> {
381 typedef std::string param_type;
382 static void Write(Message* m, const param_type& p) {
383 m->WriteString(p);
384 }
385 static bool Read(const Message* m, void** iter, param_type* r) {
386 return m->ReadString(iter, r);
387 }
388 static void Log(const param_type& p, std::wstring* l) {
389 l->append(UTF8ToWide(p));
390 }
391};
392
393template <>
394struct ParamTraits<std::vector<unsigned char> > {
395 typedef std::vector<unsigned char> param_type;
396 static void Write(Message* m, const param_type& p) {
397 if (p.size() == 0) {
398 m->WriteData(NULL, 0);
399 } else {
400 m->WriteData(reinterpret_cast<const char*>(&p.front()),
401 static_cast<int>(p.size()));
402 }
403 }
404 static bool Read(const Message* m, void** iter, param_type* r) {
405 const char *data;
406 int data_size = 0;
407 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
408 return false;
409 r->resize(data_size);
410 if (data_size)
411 memcpy(&r->front(), data, data_size);
412 return true;
413 }
414 static void Log(const param_type& p, std::wstring* l) {
415 for (size_t i = 0; i < p.size(); ++i)
416 l->push_back(p[i]);
417 }
418};
419
420template <>
421struct ParamTraits<std::vector<char> > {
422 typedef std::vector<char> param_type;
423 static void Write(Message* m, const param_type& p) {
424 if (p.size() == 0) {
425 m->WriteData(NULL, 0);
426 } else {
427 m->WriteData(&p.front(), static_cast<int>(p.size()));
428 }
429 }
430 static bool Read(const Message* m, void** iter, param_type* r) {
431 const char *data;
432 int data_size = 0;
433 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
434 return false;
435 r->resize(data_size);
436 if (data_size)
437 memcpy(&r->front(), data, data_size);
438 return true;
439 }
440 static void Log(const param_type& p, std::wstring* l) {
441 for (size_t i = 0; i < p.size(); ++i)
442 l->push_back(p[i]);
443 }
444};
445
446template <class P>
447struct ParamTraits<std::vector<P> > {
448 typedef std::vector<P> param_type;
449 static void Write(Message* m, const param_type& p) {
450 WriteParam(m, static_cast<int>(p.size()));
451 for (size_t i = 0; i < p.size(); i++)
452 WriteParam(m, p[i]);
453 }
454 static bool Read(const Message* m, void** iter, param_type* r) {
455 int size;
456 if (!m->ReadLength(iter, &size))
457 return false;
458 // Resizing beforehand is not safe, see BUG 1006367 for details.
459 if (m->IteratorHasRoomFor(*iter, size * sizeof(P))) {
460 r->resize(size);
461 for (int i = 0; i < size; i++) {
462 if (!ReadParam(m, iter, &(*r)[i]))
463 return false;
464 }
465 } else {
466 for (int i = 0; i < size; i++) {
467 P element;
468 if (!ReadParam(m, iter, &element))
469 return false;
470 r->push_back(element);
471 }
472 }
473 return true;
474 }
475 static void Log(const param_type& p, std::wstring* l) {
476 for (size_t i = 0; i < p.size(); ++i) {
477 if (i != 0)
478 l->append(L" ");
479
480 LogParam((p[i]), l);
481 }
482 }
483};
484
485template <class K, class V>
486struct ParamTraits<std::map<K, V> > {
487 typedef std::map<K, V> param_type;
488 static void Write(Message* m, const param_type& p) {
489 WriteParam(m, static_cast<int>(p.size()));
490 typename param_type::const_iterator iter;
491 for (iter = p.begin(); iter != p.end(); ++iter) {
492 WriteParam(m, iter->first);
493 WriteParam(m, iter->second);
494 }
495 }
496 static bool Read(const Message* m, void** iter, param_type* r) {
497 int size;
498 if (!ReadParam(m, iter, &size) || size < 0)
499 return false;
500 for (int i = 0; i < size; ++i) {
501 K k;
502 if (!ReadParam(m, iter, &k))
503 return false;
504 V& value = (*r)[k];
505 if (!ReadParam(m, iter, &value))
506 return false;
507 }
508 return true;
509 }
510 static void Log(const param_type& p, std::wstring* l) {
511 l->append(L"<std::map>");
512 }
513};
514
[email protected]eb47a132009-03-04 00:39:56515
[email protected]7d5c3ac2009-02-04 08:58:19516template <>
517struct ParamTraits<std::wstring> {
518 typedef std::wstring param_type;
519 static void Write(Message* m, const param_type& p) {
520 m->WriteWString(p);
521 }
522 static bool Read(const Message* m, void** iter, param_type* r) {
523 return m->ReadWString(iter, r);
524 }
525 static void Log(const param_type& p, std::wstring* l) {
526 l->append(p);
527 }
528};
529
[email protected]eb47a132009-03-04 00:39:56530// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
531// need this trait.
532#if !defined(WCHAR_T_IS_UTF16)
[email protected]eb47a132009-03-04 00:39:56533template <>
534struct ParamTraits<string16> {
535 typedef string16 param_type;
536 static void Write(Message* m, const param_type& p) {
[email protected]3a2a5d22009-03-04 03:36:36537 m->WriteString16(p);
[email protected]eb47a132009-03-04 00:39:56538 }
539 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]3a2a5d22009-03-04 03:36:36540 return m->ReadString16(iter, r);
[email protected]eb47a132009-03-04 00:39:56541 }
542 static void Log(const param_type& p, std::wstring* l) {
543 l->append(UTF16ToWide(p));
544 }
545};
[email protected]eb47a132009-03-04 00:39:56546#endif
547
[email protected]82e5ee82009-04-03 02:29:45548template <>
549struct ParamTraits<GURL> {
550 typedef GURL param_type;
551 static void Write(Message* m, const param_type& p);
552 static bool Read(const Message* m, void** iter, param_type* p);
553 static void Log(const param_type& p, std::wstring* l);
554};
555
[email protected]7d5c3ac2009-02-04 08:58:19556// and, a few more useful types...
557#if defined(OS_WIN)
558template <>
559struct ParamTraits<HANDLE> {
560 typedef HANDLE param_type;
561 static void Write(Message* m, const param_type& p) {
562 m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
563 }
564 static bool Read(const Message* m, void** iter, param_type* r) {
565 DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
566 return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
567 }
568 static void Log(const param_type& p, std::wstring* l) {
569 l->append(StringPrintf(L"0x%X", p));
570 }
571};
572
573template <>
574struct ParamTraits<HCURSOR> {
575 typedef HCURSOR param_type;
576 static void Write(Message* m, const param_type& p) {
577 m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
578 }
579 static bool Read(const Message* m, void** iter, param_type* r) {
580 DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
581 return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
582 }
583 static void Log(const param_type& p, std::wstring* l) {
584 l->append(StringPrintf(L"0x%X", p));
585 }
586};
587
588template <>
589struct ParamTraits<HWND> {
590 typedef HWND param_type;
591 static void Write(Message* m, const param_type& p) {
592 m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
593 }
594 static bool Read(const Message* m, void** iter, param_type* r) {
595 DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
596 return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
597 }
598 static void Log(const param_type& p, std::wstring* l) {
599 l->append(StringPrintf(L"0x%X", p));
600 }
601};
602
603template <>
[email protected]7d5c3ac2009-02-04 08:58:19604struct ParamTraits<HACCEL> {
605 typedef HACCEL param_type;
606 static void Write(Message* m, const param_type& p) {
607 m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
608 }
609 static bool Read(const Message* m, void** iter, param_type* r) {
610 DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
611 return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
612 }
613};
614
615template <>
616struct ParamTraits<POINT> {
617 typedef POINT param_type;
618 static void Write(Message* m, const param_type& p) {
619 m->WriteInt(p.x);
620 m->WriteInt(p.y);
621 }
622 static bool Read(const Message* m, void** iter, param_type* r) {
623 int x, y;
624 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
625 return false;
626 r->x = x;
627 r->y = y;
628 return true;
629 }
630 static void Log(const param_type& p, std::wstring* l) {
631 l->append(StringPrintf(L"(%d, %d)", p.x, p.y));
632 }
633};
634#endif // defined(OS_WIN)
635
636template <>
637struct ParamTraits<FilePath> {
638 typedef FilePath param_type;
639 static void Write(Message* m, const param_type& p) {
640 ParamTraits<FilePath::StringType>::Write(m, p.value());
641 }
642 static bool Read(const Message* m, void** iter, param_type* r) {
643 FilePath::StringType value;
644 if (!ParamTraits<FilePath::StringType>::Read(m, iter, &value))
645 return false;
646 *r = FilePath(value);
647 return true;
648 }
649 static void Log(const param_type& p, std::wstring* l) {
650 ParamTraits<FilePath::StringType>::Log(p.value(), l);
651 }
652};
653
654template <>
655struct ParamTraits<gfx::Point> {
656 typedef gfx::Point param_type;
657 static void Write(Message* m, const param_type& p);
658 static bool Read(const Message* m, void** iter, param_type* r);
659 static void Log(const param_type& p, std::wstring* l);
660};
661
662template <>
663struct ParamTraits<gfx::Rect> {
664 typedef gfx::Rect param_type;
665 static void Write(Message* m, const param_type& p);
666 static bool Read(const Message* m, void** iter, param_type* r);
667 static void Log(const param_type& p, std::wstring* l);
668};
669
670template <>
671struct ParamTraits<gfx::Size> {
672 typedef gfx::Size param_type;
673 static void Write(Message* m, const param_type& p);
674 static bool Read(const Message* m, void** iter, param_type* r);
675 static void Log(const param_type& p, std::wstring* l);
676};
677
[email protected]526776c2009-02-07 00:39:26678#if defined(OS_POSIX)
[email protected]2749885f2009-03-05 21:40:11679// FileDescriptors may be serialised over IPC channels on POSIX. On the
680// receiving side, the FileDescriptor is a valid duplicate of the file
681// descriptor which was transmitted: *it is not just a copy of the integer like
682// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
683// this case, the receiving end will see a value of -1. *Zero is a valid file
684// descriptor*.
685//
686// The received file descriptor will have the |auto_close| flag set to true. The
687// code which handles the message is responsible for taking ownership of it.
688// File descriptors are OS resources and must be closed when no longer needed.
689//
690// When sending a file descriptor, the file descriptor must be valid at the time
691// of transmission. Since transmission is not synchronous, one should consider
692// dup()ing any file descriptors to be transmitted and setting the |auto_close|
693// flag, which causes the file descriptor to be closed after writing.
[email protected]526776c2009-02-07 00:39:26694template<>
[email protected]5fe733de2009-02-11 18:59:20695struct ParamTraits<base::FileDescriptor> {
696 typedef base::FileDescriptor param_type;
[email protected]526776c2009-02-07 00:39:26697 static void Write(Message* m, const param_type& p) {
[email protected]2749885f2009-03-05 21:40:11698 const bool valid = p.fd >= 0;
699 WriteParam(m, valid);
700
701 if (valid) {
702 if (!m->WriteFileDescriptor(p))
703 NOTREACHED();
704 }
[email protected]526776c2009-02-07 00:39:26705 }
706 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]2749885f2009-03-05 21:40:11707 bool valid;
708 if (!ReadParam(m, iter, &valid))
709 return false;
710
711 if (!valid) {
712 r->fd = -1;
713 r->auto_close = false;
714 return true;
715 }
716
[email protected]7135bb042009-02-12 04:05:28717 return m->ReadFileDescriptor(iter, r);
[email protected]526776c2009-02-07 00:39:26718 }
719 static void Log(const param_type& p, std::wstring* l) {
720 if (p.auto_close) {
[email protected]7135bb042009-02-12 04:05:28721 l->append(StringPrintf(L"FD(%d auto-close)", p.fd));
[email protected]526776c2009-02-07 00:39:26722 } else {
[email protected]7135bb042009-02-12 04:05:28723 l->append(StringPrintf(L"FD(%d)", p.fd));
[email protected]526776c2009-02-07 00:39:26724 }
725 }
726};
[email protected]526776c2009-02-07 00:39:26727#endif // defined(OS_POSIX)
728
[email protected]82e5ee82009-04-03 02:29:45729template<>
730struct ParamTraits<ThumbnailScore> {
731 typedef ThumbnailScore param_type;
732 static void Write(Message* m, const param_type& p) {
733 IPC::ParamTraits<double>::Write(m, p.boring_score);
734 IPC::ParamTraits<bool>::Write(m, p.good_clipping);
735 IPC::ParamTraits<bool>::Write(m, p.at_top);
736 IPC::ParamTraits<base::Time>::Write(m, p.time_at_snapshot);
737 }
738 static bool Read(const Message* m, void** iter, param_type* r) {
739 double boring_score;
740 bool good_clipping, at_top;
741 base::Time time_at_snapshot;
742 if (!IPC::ParamTraits<double>::Read(m, iter, &boring_score) ||
743 !IPC::ParamTraits<bool>::Read(m, iter, &good_clipping) ||
744 !IPC::ParamTraits<bool>::Read(m, iter, &at_top) ||
745 !IPC::ParamTraits<base::Time>::Read(m, iter, &time_at_snapshot))
746 return false;
747
748 r->boring_score = boring_score;
749 r->good_clipping = good_clipping;
750 r->at_top = at_top;
751 r->time_at_snapshot = time_at_snapshot;
752 return true;
753 }
754 static void Log(const param_type& p, std::wstring* l) {
755 l->append(StringPrintf(L"(%f, %d, %d)",
756 p.boring_score, p.good_clipping, p.at_top));
757 }
758};
759
760template <>
761struct ParamTraits<WindowOpenDisposition> {
762 typedef WindowOpenDisposition param_type;
763 static void Write(Message* m, const param_type& p) {
764 m->WriteInt(p);
765 }
766 static bool Read(const Message* m, void** iter, param_type* r) {
767 int temp;
768 bool res = m->ReadInt(iter, &temp);
769 *r = static_cast<WindowOpenDisposition>(temp);
770 return res;
771 }
772 static void Log(const param_type& p, std::wstring* l) {
773 l->append(StringPrintf(L"%d", p));
774 }
775};
776
[email protected]7d5c3ac2009-02-04 08:58:19777#if defined(OS_WIN)
778template <>
779struct ParamTraits<XFORM> {
780 typedef XFORM param_type;
781 static void Write(Message* m, const param_type& p) {
782 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
783 }
784 static bool Read(const Message* m, void** iter, param_type* r) {
785 const char *data;
786 int data_size = 0;
787 bool result = m->ReadData(iter, &data, &data_size);
788 if (result && data_size == sizeof(XFORM)) {
789 memcpy(r, data, sizeof(XFORM));
790 } else {
791 result = false;
792 NOTREACHED();
793 }
794
795 return result;
796 }
797 static void Log(const param_type& p, std::wstring* l) {
798 l->append(L"<XFORM>");
799 }
800};
801#endif // defined(OS_WIN)
802
[email protected]82e5ee82009-04-03 02:29:45803template <>
804struct ParamTraits<WebCursor> {
805 typedef WebCursor param_type;
806 static void Write(Message* m, const param_type& p) {
807 p.Serialize(m);
808 }
809 static bool Read(const Message* m, void** iter, param_type* r) {
810 return r->Deserialize(m, iter);
811 }
812 static void Log(const param_type& p, std::wstring* l) {
813 l->append(L"<WebCursor>");
814 }
815};
816
[email protected]7d5c3ac2009-02-04 08:58:19817struct LogData {
818 std::wstring channel;
[email protected]8bef70e2009-04-14 19:11:24819 int32 routing_id;
[email protected]7d5c3ac2009-02-04 08:58:19820 uint16 type;
821 std::wstring flags;
822 int64 sent; // Time that the message was sent (i.e. at Send()).
823 int64 receive; // Time before it was dispatched (i.e. before calling
824 // OnMessageReceived).
825 int64 dispatch; // Time after it was dispatched (i.e. after calling
826 // OnMessageReceived).
[email protected]e707d5e62009-02-12 04:00:08827 std::wstring message_name;
[email protected]7d5c3ac2009-02-04 08:58:19828 std::wstring params;
829};
830
831template <>
832struct ParamTraits<LogData> {
833 typedef LogData param_type;
834 static void Write(Message* m, const param_type& p) {
835 WriteParam(m, p.channel);
[email protected]8bef70e2009-04-14 19:11:24836 WriteParam(m, p.routing_id);
[email protected]7d5c3ac2009-02-04 08:58:19837 WriteParam(m, static_cast<int>(p.type));
838 WriteParam(m, p.flags);
839 WriteParam(m, p.sent);
840 WriteParam(m, p.receive);
841 WriteParam(m, p.dispatch);
842 WriteParam(m, p.params);
843 }
844 static bool Read(const Message* m, void** iter, param_type* r) {
845 int type;
846 bool result =
847 ReadParam(m, iter, &r->channel) &&
[email protected]8bef70e2009-04-14 19:11:24848 ReadParam(m, iter, &r->routing_id);
[email protected]7d5c3ac2009-02-04 08:58:19849 ReadParam(m, iter, &type) &&
850 ReadParam(m, iter, &r->flags) &&
851 ReadParam(m, iter, &r->sent) &&
852 ReadParam(m, iter, &r->receive) &&
853 ReadParam(m, iter, &r->dispatch) &&
854 ReadParam(m, iter, &r->params);
855 r->type = static_cast<uint16>(type);
856 return result;
857 }
858 static void Log(const param_type& p, std::wstring* l) {
859 // Doesn't make sense to implement this!
860 }
861};
862
[email protected]eb47a132009-03-04 00:39:56863
864template <>
[email protected]82e5ee82009-04-03 02:29:45865struct ParamTraits<webkit_glue::WebApplicationInfo> {
866 typedef webkit_glue::WebApplicationInfo param_type;
867 static void Write(Message* m, const param_type& p);
868 static bool Read(const Message* m, void** iter, param_type* r);
869 static void Log(const param_type& p, std::wstring* l);
870};
871
872
873#if defined(OS_WIN)
874template<>
875struct ParamTraits<TransportDIB::Id> {
876 typedef TransportDIB::Id param_type;
877 static void Write(Message* m, const param_type& p) {
878 WriteParam(m, p.handle);
879 WriteParam(m, p.sequence_num);
880 }
881 static bool Read(const Message* m, void** iter, param_type* r) {
882 return (ReadParam(m, iter, &r->handle) &&
883 ReadParam(m, iter, &r->sequence_num));
884 }
885 static void Log(const param_type& p, std::wstring* l) {
886 l->append(L"TransportDIB(");
887 LogParam(p.handle, l);
888 l->append(L", ");
889 LogParam(p.sequence_num, l);
890 l->append(L")");
891 }
892};
893#endif
894
895template <>
[email protected]503683f2009-02-26 09:13:01896struct ParamTraits<Message> {
897 static void Write(Message* m, const Message& p) {
898 m->WriteInt(p.size());
899 m->WriteData(reinterpret_cast<const char*>(p.data()), p.size());
900 }
901 static bool Read(const Message* m, void** iter, Message* r) {
902 int size;
903 if (!m->ReadInt(iter, &size))
904 return false;
905 const char* data;
906 if (!m->ReadData(iter, &data, &size))
907 return false;
908 *r = Message(data, size);
909 return true;
910 }
911 static void Log(const Message& p, std::wstring* l) {
912 l->append(L"<IPC::Message>");
913 }
914};
915
916template <>
[email protected]7d5c3ac2009-02-04 08:58:19917struct ParamTraits<Tuple0> {
918 typedef Tuple0 param_type;
919 static void Write(Message* m, const param_type& p) {
920 }
921 static bool Read(const Message* m, void** iter, param_type* r) {
922 return true;
923 }
924 static void Log(const param_type& p, std::wstring* l) {
925 }
926};
927
928template <class A>
929struct ParamTraits< Tuple1<A> > {
930 typedef Tuple1<A> param_type;
931 static void Write(Message* m, const param_type& p) {
932 WriteParam(m, p.a);
933 }
934 static bool Read(const Message* m, void** iter, param_type* r) {
935 return ReadParam(m, iter, &r->a);
936 }
937 static void Log(const param_type& p, std::wstring* l) {
938 LogParam(p.a, l);
939 }
940};
941
942template <class A, class B>
943struct ParamTraits< Tuple2<A, B> > {
944 typedef Tuple2<A, B> param_type;
945 static void Write(Message* m, const param_type& p) {
946 WriteParam(m, p.a);
947 WriteParam(m, p.b);
948 }
949 static bool Read(const Message* m, void** iter, param_type* r) {
950 return (ReadParam(m, iter, &r->a) &&
951 ReadParam(m, iter, &r->b));
952 }
953 static void Log(const param_type& p, std::wstring* l) {
954 LogParam(p.a, l);
955 l->append(L", ");
956 LogParam(p.b, l);
957 }
958};
959
960template <class A, class B, class C>
961struct ParamTraits< Tuple3<A, B, C> > {
962 typedef Tuple3<A, B, C> param_type;
963 static void Write(Message* m, const param_type& p) {
964 WriteParam(m, p.a);
965 WriteParam(m, p.b);
966 WriteParam(m, p.c);
967 }
968 static bool Read(const Message* m, void** iter, param_type* r) {
969 return (ReadParam(m, iter, &r->a) &&
970 ReadParam(m, iter, &r->b) &&
971 ReadParam(m, iter, &r->c));
972 }
973 static void Log(const param_type& p, std::wstring* l) {
974 LogParam(p.a, l);
975 l->append(L", ");
976 LogParam(p.b, l);
977 l->append(L", ");
978 LogParam(p.c, l);
979 }
980};
981
982template <class A, class B, class C, class D>
983struct ParamTraits< Tuple4<A, B, C, D> > {
984 typedef Tuple4<A, B, C, D> param_type;
985 static void Write(Message* m, const param_type& p) {
986 WriteParam(m, p.a);
987 WriteParam(m, p.b);
988 WriteParam(m, p.c);
989 WriteParam(m, p.d);
990 }
991 static bool Read(const Message* m, void** iter, param_type* r) {
992 return (ReadParam(m, iter, &r->a) &&
993 ReadParam(m, iter, &r->b) &&
994 ReadParam(m, iter, &r->c) &&
995 ReadParam(m, iter, &r->d));
996 }
997 static void Log(const param_type& p, std::wstring* l) {
998 LogParam(p.a, l);
999 l->append(L", ");
1000 LogParam(p.b, l);
1001 l->append(L", ");
1002 LogParam(p.c, l);
1003 l->append(L", ");
1004 LogParam(p.d, l);
1005 }
1006};
1007
1008template <class A, class B, class C, class D, class E>
1009struct ParamTraits< Tuple5<A, B, C, D, E> > {
1010 typedef Tuple5<A, B, C, D, E> param_type;
1011 static void Write(Message* m, const param_type& p) {
1012 WriteParam(m, p.a);
1013 WriteParam(m, p.b);
1014 WriteParam(m, p.c);
1015 WriteParam(m, p.d);
1016 WriteParam(m, p.e);
1017 }
1018 static bool Read(const Message* m, void** iter, param_type* r) {
1019 return (ReadParam(m, iter, &r->a) &&
1020 ReadParam(m, iter, &r->b) &&
1021 ReadParam(m, iter, &r->c) &&
1022 ReadParam(m, iter, &r->d) &&
1023 ReadParam(m, iter, &r->e));
1024 }
1025 static void Log(const param_type& p, std::wstring* l) {
1026 LogParam(p.a, l);
1027 l->append(L", ");
1028 LogParam(p.b, l);
1029 l->append(L", ");
1030 LogParam(p.c, l);
1031 l->append(L", ");
1032 LogParam(p.d, l);
1033 l->append(L", ");
1034 LogParam(p.e, l);
1035 }
1036};
1037
1038template <class A, class B, class C, class D, class E, class F>
1039struct ParamTraits< Tuple6<A, B, C, D, E, F> > {
1040 typedef Tuple6<A, B, C, D, E, F> param_type;
1041 static void Write(Message* m, const param_type& p) {
1042 WriteParam(m, p.a);
1043 WriteParam(m, p.b);
1044 WriteParam(m, p.c);
1045 WriteParam(m, p.d);
1046 WriteParam(m, p.e);
1047 WriteParam(m, p.f);
1048 }
1049 static bool Read(const Message* m, void** iter, param_type* r) {
1050 return (ReadParam(m, iter, &r->a) &&
1051 ReadParam(m, iter, &r->b) &&
1052 ReadParam(m, iter, &r->c) &&
1053 ReadParam(m, iter, &r->d) &&
1054 ReadParam(m, iter, &r->e) &&
1055 ReadParam(m, iter, &r->f));
1056 }
1057 static void Log(const param_type& p, std::wstring* l) {
1058 LogParam(p.a, l);
1059 l->append(L", ");
1060 LogParam(p.b, l);
1061 l->append(L", ");
1062 LogParam(p.c, l);
1063 l->append(L", ");
1064 LogParam(p.d, l);
1065 l->append(L", ");
1066 LogParam(p.e, l);
1067 l->append(L", ");
1068 LogParam(p.f, l);
1069 }
1070};
1071
[email protected]7d5c3ac2009-02-04 08:58:191072
1073
1074//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:291075// Generic message subclasses
1076
1077// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:241078template <class ParamType>
initial.commit09911bf2008-07-26 23:55:291079class MessageWithTuple : public Message {
1080 public:
[email protected]81a34412009-01-05 19:17:241081 typedef ParamType Param;
[email protected]c2fe31542009-05-20 18:24:141082 typedef typename ParamType::ParamTuple RefParam;
[email protected]81a34412009-01-05 19:17:241083
[email protected]c2fe31542009-05-20 18:24:141084 MessageWithTuple(int32 routing_id, uint16 type, const RefParam& p)
initial.commit09911bf2008-07-26 23:55:291085 : Message(routing_id, type, PRIORITY_NORMAL) {
1086 WriteParam(this, p);
1087 }
1088
[email protected]7d5c3ac2009-02-04 08:58:191089 static bool Read(const Message* msg, Param* p) {
initial.commit09911bf2008-07-26 23:55:291090 void* iter = NULL;
1091 bool rv = ReadParam(msg, &iter, p);
1092 DCHECK(rv) << "Error deserializing message " << msg->type();
1093 return rv;
1094 }
1095
1096 // Generic dispatcher. Should cover most cases.
1097 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191098 static bool Dispatch(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291099 Param p;
1100 if (Read(msg, &p)) {
1101 DispatchToMethod(obj, func, p);
1102 return true;
1103 }
1104 return false;
1105 }
1106
1107 // The following dispatchers exist for the case where the callback function
1108 // needs the message as well. They assume that "Param" is a type of Tuple
1109 // (except the one arg case, as there is no Tuple1).
1110 template<class T, typename TA>
[email protected]7d5c3ac2009-02-04 08:58:191111 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291112 void (T::*func)(const Message&, TA)) {
1113 Param p;
1114 if (Read(msg, &p)) {
[email protected]c2fe31542009-05-20 18:24:141115 (obj->*func)(*msg, p.a);
initial.commit09911bf2008-07-26 23:55:291116 return true;
1117 }
1118 return false;
1119 }
1120
1121 template<class T, typename TA, typename TB>
[email protected]7d5c3ac2009-02-04 08:58:191122 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291123 void (T::*func)(const Message&, TA, TB)) {
1124 Param p;
1125 if (Read(msg, &p)) {
1126 (obj->*func)(*msg, p.a, p.b);
1127 return true;
1128 }
1129 return false;
1130 }
1131
1132 template<class T, typename TA, typename TB, typename TC>
[email protected]7d5c3ac2009-02-04 08:58:191133 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291134 void (T::*func)(const Message&, TA, TB, TC)) {
1135 Param p;
1136 if (Read(msg, &p)) {
1137 (obj->*func)(*msg, p.a, p.b, p.c);
1138 return true;
1139 }
1140 return false;
1141 }
1142
1143 template<class T, typename TA, typename TB, typename TC, typename TD>
[email protected]7d5c3ac2009-02-04 08:58:191144 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291145 void (T::*func)(const Message&, TA, TB, TC, TD)) {
1146 Param p;
1147 if (Read(msg, &p)) {
1148 (obj->*func)(*msg, p.a, p.b, p.c, p.d);
1149 return true;
1150 }
1151 return false;
1152 }
1153
1154 template<class T, typename TA, typename TB, typename TC, typename TD,
1155 typename TE>
[email protected]7d5c3ac2009-02-04 08:58:191156 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291157 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
1158 Param p;
1159 if (Read(msg, &p)) {
1160 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
1161 return true;
1162 }
1163 return false;
1164 }
1165
[email protected]7d5c3ac2009-02-04 08:58:191166 static void Log(const Message* msg, std::wstring* l) {
initial.commit09911bf2008-07-26 23:55:291167 Param p;
1168 if (Read(msg, &p))
1169 LogParam(p, l);
1170 }
[email protected]deb57402009-02-06 01:35:301171
1172 // Functions used to do manual unpacking. Only used by the automation code,
1173 // these should go away once that code uses SyncChannel.
1174 template<typename TA, typename TB>
1175 static bool Read(const IPC::Message* msg, TA* a, TB* b) {
1176 ParamType params;
1177 if (!Read(msg, &params))
1178 return false;
1179 *a = params.a;
1180 *b = params.b;
1181 return true;
1182 }
1183
1184 template<typename TA, typename TB, typename TC>
1185 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
1186 ParamType params;
1187 if (!Read(msg, &params))
1188 return false;
1189 *a = params.a;
1190 *b = params.b;
1191 *c = params.c;
1192 return true;
1193 }
1194
1195 template<typename TA, typename TB, typename TC, typename TD>
1196 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) {
1197 ParamType params;
1198 if (!Read(msg, &params))
1199 return false;
1200 *a = params.a;
1201 *b = params.b;
1202 *c = params.c;
1203 *d = params.d;
1204 return true;
1205 }
1206
1207 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1208 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) {
1209 ParamType params;
1210 if (!Read(msg, &params))
1211 return false;
1212 *a = params.a;
1213 *b = params.b;
1214 *c = params.c;
1215 *d = params.d;
1216 *e = params.e;
1217 return true;
1218 }
initial.commit09911bf2008-07-26 23:55:291219};
1220
1221// This class assumes that its template argument is a RefTuple (a Tuple with
1222// reference elements).
1223template <class RefTuple>
1224class ParamDeserializer : public MessageReplyDeserializer {
1225 public:
[email protected]e1981f432008-08-12 15:22:131226 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:291227
1228 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1229 return ReadParam(&msg, &iter, &out_);
1230 }
1231
1232 RefTuple out_;
1233};
1234
1235// defined in ipc_logging.cc
1236void GenerateLogData(const std::wstring& channel, const Message& message,
1237 LogData* data);
1238
1239// Used for synchronous messages.
[email protected]75e5a872009-04-02 23:56:111240template <class SendParamType, class ReplyParamType>
initial.commit09911bf2008-07-26 23:55:291241class MessageWithReply : public SyncMessage {
1242 public:
[email protected]75e5a872009-04-02 23:56:111243 typedef SendParamType SendParam;
[email protected]c2fe31542009-05-20 18:24:141244 typedef typename SendParam::ParamTuple RefSendParam;
[email protected]75e5a872009-04-02 23:56:111245 typedef ReplyParamType ReplyParam;
1246
[email protected]d4651ff2008-12-02 16:51:581247 MessageWithReply(int32 routing_id, uint16 type,
[email protected]c2fe31542009-05-20 18:24:141248 const RefSendParam& send, const ReplyParam& reply)
initial.commit09911bf2008-07-26 23:55:291249 : SyncMessage(routing_id, type, PRIORITY_NORMAL,
1250 new ParamDeserializer<ReplyParam>(reply)) {
1251 WriteParam(this, send);
1252 }
1253
[email protected]7d5c3ac2009-02-04 08:58:191254 static void Log(const Message* msg, std::wstring* l) {
initial.commit09911bf2008-07-26 23:55:291255 if (msg->is_sync()) {
1256 SendParam p;
1257 void* iter = SyncMessage::GetDataIterator(msg);
[email protected]1e86aa62009-04-24 21:22:331258 if (ReadParam(msg, &iter, &p))
1259 LogParam(p, l);
initial.commit09911bf2008-07-26 23:55:291260
[email protected]1156f7b2008-12-04 19:13:591261#if defined(IPC_MESSAGE_LOG_ENABLED)
initial.commit09911bf2008-07-26 23:55:291262 const std::wstring& output_params = msg->output_params();
1263 if (!l->empty() && !output_params.empty())
1264 l->append(L", ");
1265
1266 l->append(output_params);
[email protected]2a34f9c2008-12-04 19:12:041267#endif
initial.commit09911bf2008-07-26 23:55:291268 } else {
1269 // This is an outgoing reply. Now that we have the output parameters, we
1270 // can finally log the message.
[email protected]d4651ff2008-12-02 16:51:581271 typename ReplyParam::ValueTuple p;
initial.commit09911bf2008-07-26 23:55:291272 void* iter = SyncMessage::GetDataIterator(msg);
[email protected]1e86aa62009-04-24 21:22:331273 if (ReadParam(msg, &iter, &p))
1274 LogParam(p, l);
initial.commit09911bf2008-07-26 23:55:291275 }
1276 }
1277
1278 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191279 static bool Dispatch(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291280 SendParam send_params;
1281 void* iter = GetDataIterator(msg);
1282 Message* reply = GenerateReply(msg);
1283 bool error;
1284 if (ReadParam(msg, &iter, &send_params)) {
[email protected]d4651ff2008-12-02 16:51:581285 typename ReplyParam::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:291286 DispatchToMethod(obj, func, send_params, &reply_params);
1287 WriteParam(reply, reply_params);
1288 error = false;
1289#ifdef IPC_MESSAGE_LOG_ENABLED
1290 if (msg->received_time() != 0) {
1291 std::wstring output_params;
1292 LogParam(reply_params, &output_params);
1293 msg->set_output_params(output_params);
1294 }
1295#endif
1296 } else {
1297 NOTREACHED() << "Error deserializing message " << msg->type();
1298 reply->set_reply_error();
1299 error = true;
1300 }
1301
1302 obj->Send(reply);
1303 return !error;
1304 }
1305
1306 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191307 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291308 SendParam send_params;
1309 void* iter = GetDataIterator(msg);
1310 Message* reply = GenerateReply(msg);
1311 bool error;
1312 if (ReadParam(msg, &iter, &send_params)) {
1313 Tuple1<Message&> t = MakeRefTuple(*reply);
1314
1315#ifdef IPC_MESSAGE_LOG_ENABLED
1316 if (msg->sent_time()) {
1317 // Don't log the sync message after dispatch, as we don't have the
1318 // output parameters at that point. Instead, save its data and log it
1319 // with the outgoing reply message when it's sent.
1320 LogData* data = new LogData;
1321 GenerateLogData(L"", *msg, data);
1322 msg->set_dont_log();
1323 reply->set_sync_log_data(data);
1324 }
1325#endif
1326 DispatchToMethod(obj, func, send_params, &t);
1327 error = false;
1328 } else {
1329 NOTREACHED() << "Error deserializing message " << msg->type();
1330 reply->set_reply_error();
1331 obj->Send(reply);
1332 error = true;
1333 }
1334 return !error;
1335 }
1336
1337 template<typename TA>
1338 static void WriteReplyParams(Message* reply, TA a) {
1339 ReplyParam p(a);
1340 WriteParam(reply, p);
1341 }
1342
1343 template<typename TA, typename TB>
1344 static void WriteReplyParams(Message* reply, TA a, TB b) {
1345 ReplyParam p(a, b);
1346 WriteParam(reply, p);
1347 }
1348
1349 template<typename TA, typename TB, typename TC>
1350 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1351 ReplyParam p(a, b, c);
1352 WriteParam(reply, p);
1353 }
1354
1355 template<typename TA, typename TB, typename TC, typename TD>
1356 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1357 ReplyParam p(a, b, c, d);
1358 WriteParam(reply, p);
1359 }
1360
1361 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1362 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1363 ReplyParam p(a, b, c, d, e);
1364 WriteParam(reply, p);
1365 }
1366};
1367
[email protected]7d5c3ac2009-02-04 08:58:191368//-----------------------------------------------------------------------------
1369
[email protected]3178f4e22008-08-05 21:20:411370} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291371
[email protected]82e5ee82009-04-03 02:29:451372#endif // CHROME_COMMON_IPC_MESSAGE_UTILS_H_