blob: 2ae2ab5cdbd4b244250f3720befd71cc9585c063 [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]d2e884d2009-06-22 20:37:5219#include "chrome/common/ipc_channel_handle.h"
[email protected]82e5ee82009-04-03 02:29:4520#include "chrome/common/ipc_sync_message.h"
21#include "chrome/common/thumbnail_score.h"
22#include "chrome/common/transport_dib.h"
23#include "webkit/glue/webcursor.h"
24#include "webkit/glue/window_open_disposition.h"
[email protected]3178f4e22008-08-05 21:20:4125
26// Forward declarations.
[email protected]82e5ee82009-04-03 02:29:4527class GURL;
28class SkBitmap;
[email protected]584f2b22009-05-21 01:01:5929class DictionaryValue;
30class ListValue;
[email protected]82e5ee82009-04-03 02:29:4531
[email protected]3178f4e22008-08-05 21:20:4132namespace gfx {
33class Point;
34class Rect;
35class Size;
36} // namespace gfx
37
[email protected]82e5ee82009-04-03 02:29:4538namespace webkit_glue {
39struct WebApplicationInfo;
40} // namespace webkit_glue
41
[email protected]f91cb992009-02-04 20:10:1242// Used by IPC_BEGIN_MESSAGES so that each message class starts from a unique
43// base. Messages have unique IDs across channels in order for the IPC logging
44// code to figure out the message class from its ID.
45enum IPCMessageStart {
46 // By using a start value of 0 for automation messages, we keep backward
47 // compatibility with old builds.
48 AutomationMsgStart = 0,
49 ViewMsgStart,
50 ViewHostMsgStart,
51 PluginProcessMsgStart,
52 PluginProcessHostMsgStart,
53 PluginMsgStart,
54 PluginHostMsgStart,
55 NPObjectMsgStart,
56 TestMsgStart,
[email protected]503683f2009-02-26 09:13:0157 DevToolsAgentMsgStart,
58 DevToolsClientMsgStart,
[email protected]eb47a132009-03-04 00:39:5659 WorkerProcessMsgStart,
60 WorkerProcessHostMsgStart,
61 WorkerMsgStart,
62 WorkerHostMsgStart,
[email protected]f91cb992009-02-04 20:10:1263 // NOTE: When you add a new message class, also update
64 // IPCStatusView::IPCStatusView to ensure logging works.
65 // NOTE: this enum is used by IPC_MESSAGE_MACRO to generate a unique message
66 // id. Only 4 bits are used for the message type, so if this enum needs more
67 // than 16 entries, that code needs to be updated.
68 LastMsgIndex
69};
70
71COMPILE_ASSERT(LastMsgIndex <= 16, need_to_update_IPC_MESSAGE_MACRO);
72
initial.commit09911bf2008-07-26 23:55:2973namespace IPC {
74
initial.commit09911bf2008-07-26 23:55:2975//-----------------------------------------------------------------------------
76// An iterator class for reading the fields contained within a Message.
77
78class MessageIterator {
79 public:
[email protected]e1981f432008-08-12 15:22:1380 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
initial.commit09911bf2008-07-26 23:55:2981 }
82 int NextInt() const {
83 int val;
84 if (!msg_.ReadInt(&iter_, &val))
85 NOTREACHED();
86 return val;
87 }
88 intptr_t NextIntPtr() const {
89 intptr_t val;
90 if (!msg_.ReadIntPtr(&iter_, &val))
91 NOTREACHED();
92 return val;
93 }
94 const std::string NextString() const {
95 std::string val;
96 if (!msg_.ReadString(&iter_, &val))
97 NOTREACHED();
98 return val;
99 }
100 const std::wstring NextWString() const {
101 std::wstring val;
102 if (!msg_.ReadWString(&iter_, &val))
103 NOTREACHED();
104 return val;
105 }
106 const void NextData(const char** data, int* length) const {
107 if (!msg_.ReadData(&iter_, data, length)) {
108 NOTREACHED();
109 }
110 }
111 private:
112 const Message& msg_;
113 mutable void* iter_;
114};
115
116//-----------------------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19117// ParamTraits specializations, etc.
118
119template <class P> struct ParamTraits {};
120
121template <class P>
122static inline void WriteParam(Message* m, const P& p) {
123 ParamTraits<P>::Write(m, p);
124}
125
126template <class P>
[email protected]1e86aa62009-04-24 21:22:33127static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
128 P* p) {
[email protected]7d5c3ac2009-02-04 08:58:19129 return ParamTraits<P>::Read(m, iter, p);
130}
131
132template <class P>
133static inline void LogParam(const P& p, std::wstring* l) {
134 ParamTraits<P>::Log(p, l);
135}
136
137template <>
138struct ParamTraits<bool> {
139 typedef bool param_type;
140 static void Write(Message* m, const param_type& p) {
141 m->WriteBool(p);
142 }
143 static bool Read(const Message* m, void** iter, param_type* r) {
144 return m->ReadBool(iter, r);
145 }
146 static void Log(const param_type& p, std::wstring* l) {
147 l->append(p ? L"true" : L"false");
148 }
149};
150
151template <>
152struct ParamTraits<int> {
153 typedef int param_type;
154 static void Write(Message* m, const param_type& p) {
155 m->WriteInt(p);
156 }
157 static bool Read(const Message* m, void** iter, param_type* r) {
158 return m->ReadInt(iter, r);
159 }
160 static void Log(const param_type& p, std::wstring* l) {
161 l->append(StringPrintf(L"%d", p));
162 }
163};
164
165template <>
166struct ParamTraits<long> {
167 typedef long param_type;
168 static void Write(Message* m, const param_type& p) {
169 m->WriteLong(p);
170 }
171 static bool Read(const Message* m, void** iter, param_type* r) {
172 return m->ReadLong(iter, r);
173 }
174 static void Log(const param_type& p, std::wstring* l) {
175 l->append(StringPrintf(L"%l", p));
176 }
177};
178
179template <>
180struct ParamTraits<size_t> {
181 typedef size_t param_type;
182 static void Write(Message* m, const param_type& p) {
183 m->WriteSize(p);
184 }
185 static bool Read(const Message* m, void** iter, param_type* r) {
186 return m->ReadSize(iter, r);
187 }
188 static void Log(const param_type& p, std::wstring* l) {
189 l->append(StringPrintf(L"%u", p));
190 }
191};
192
193#if defined(OS_MACOSX)
194// On Linux size_t & uint32 can be the same type.
195// TODO(playmobil): Fix compilation if this is not the case.
196template <>
197struct ParamTraits<uint32> {
198 typedef uint32 param_type;
199 static void Write(Message* m, const param_type& p) {
200 m->WriteUInt32(p);
201 }
202 static bool Read(const Message* m, void** iter, param_type* r) {
203 return m->ReadUInt32(iter, r);
204 }
205 static void Log(const param_type& p, std::wstring* l) {
206 l->append(StringPrintf(L"%u", p));
207 }
208};
209#endif // defined(OS_MACOSX)
210
211template <>
212struct ParamTraits<int64> {
213 typedef int64 param_type;
214 static void Write(Message* m, const param_type& p) {
215 m->WriteInt64(p);
216 }
217 static bool Read(const Message* m, void** iter, param_type* r) {
218 return m->ReadInt64(iter, r);
219 }
220 static void Log(const param_type& p, std::wstring* l) {
221 l->append(StringPrintf(L"%I64d", p));
222 }
223};
224
225template <>
226struct ParamTraits<uint64> {
227 typedef uint64 param_type;
228 static void Write(Message* m, const param_type& p) {
229 m->WriteInt64(static_cast<int64>(p));
230 }
231 static bool Read(const Message* m, void** iter, param_type* r) {
232 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
233 }
234 static void Log(const param_type& p, std::wstring* l) {
235 l->append(StringPrintf(L"%I64u", p));
236 }
237};
238
239template <>
240struct ParamTraits<double> {
241 typedef double param_type;
242 static void Write(Message* m, const param_type& p) {
243 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
244 }
245 static bool Read(const Message* m, void** iter, param_type* r) {
246 const char *data;
247 int data_size = 0;
248 bool result = m->ReadData(iter, &data, &data_size);
249 if (result && data_size == sizeof(param_type)) {
250 memcpy(r, data, sizeof(param_type));
251 } else {
252 result = false;
253 NOTREACHED();
254 }
255
256 return result;
257 }
258 static void Log(const param_type& p, std::wstring* l) {
259 l->append(StringPrintf(L"e", p));
260 }
261};
262
263template <>
264struct ParamTraits<wchar_t> {
265 typedef wchar_t param_type;
266 static void Write(Message* m, const param_type& p) {
267 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
268 }
269 static bool Read(const Message* m, void** iter, param_type* r) {
270 const char *data;
271 int data_size = 0;
272 bool result = m->ReadData(iter, &data, &data_size);
273 if (result && data_size == sizeof(param_type)) {
274 memcpy(r, data, sizeof(param_type));
275 } else {
276 result = false;
277 NOTREACHED();
278 }
279
280 return result;
281 }
282 static void Log(const param_type& p, std::wstring* l) {
283 l->append(StringPrintf(L"%lc", p));
284 }
285};
286
287template <>
288struct ParamTraits<base::Time> {
289 typedef base::Time param_type;
290 static void Write(Message* m, const param_type& p) {
291 ParamTraits<int64>::Write(m, p.ToInternalValue());
292 }
293 static bool Read(const Message* m, void** iter, param_type* r) {
294 int64 value;
295 if (!ParamTraits<int64>::Read(m, iter, &value))
296 return false;
297 *r = base::Time::FromInternalValue(value);
298 return true;
299 }
300 static void Log(const param_type& p, std::wstring* l) {
301 ParamTraits<int64>::Log(p.ToInternalValue(), l);
302 }
303};
304
305#if defined(OS_WIN)
306template <>
307struct ParamTraits<LOGFONT> {
308 typedef LOGFONT param_type;
309 static void Write(Message* m, const param_type& p) {
310 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
311 }
312 static bool Read(const Message* m, void** iter, param_type* r) {
313 const char *data;
314 int data_size = 0;
315 bool result = m->ReadData(iter, &data, &data_size);
316 if (result && data_size == sizeof(LOGFONT)) {
317 memcpy(r, data, sizeof(LOGFONT));
318 } else {
319 result = false;
320 NOTREACHED();
321 }
322
323 return result;
324 }
325 static void Log(const param_type& p, std::wstring* l) {
326 l->append(StringPrintf(L"<LOGFONT>"));
327 }
328};
329
330template <>
331struct ParamTraits<MSG> {
332 typedef MSG param_type;
333 static void Write(Message* m, const param_type& p) {
334 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
335 }
336 static bool Read(const Message* m, void** iter, param_type* r) {
337 const char *data;
338 int data_size = 0;
339 bool result = m->ReadData(iter, &data, &data_size);
340 if (result && data_size == sizeof(MSG)) {
341 memcpy(r, data, sizeof(MSG));
342 } else {
343 result = false;
344 NOTREACHED();
345 }
346
347 return result;
348 }
349};
350#endif // defined(OS_WIN)
351
352template <>
[email protected]82e5ee82009-04-03 02:29:45353struct ParamTraits<SkBitmap> {
354 typedef SkBitmap param_type;
355 static void Write(Message* m, const param_type& p);
356
357 // Note: This function expects parameter |r| to be of type &SkBitmap since
358 // r->SetConfig() and r->SetPixels() are called.
359 static bool Read(const Message* m, void** iter, param_type* r);
360
361 static void Log(const param_type& p, std::wstring* l);
362};
363
364template <>
[email protected]584f2b22009-05-21 01:01:59365struct ParamTraits<DictionaryValue> {
366 typedef DictionaryValue param_type;
367 static void Write(Message* m, const param_type& p);
368 static bool Read(const Message* m, void** iter, param_type* r);
369 static void Log(const param_type& p, std::wstring* l);
370};
371
372template <>
373struct ParamTraits<ListValue> {
374 typedef ListValue param_type;
375 static void Write(Message* m, const param_type& p);
376 static bool Read(const Message* m, void** iter, param_type* r);
377 static void Log(const param_type& p, std::wstring* l);
378};
379
380template <>
[email protected]7d5c3ac2009-02-04 08:58:19381struct ParamTraits<std::string> {
382 typedef std::string param_type;
383 static void Write(Message* m, const param_type& p) {
384 m->WriteString(p);
385 }
386 static bool Read(const Message* m, void** iter, param_type* r) {
387 return m->ReadString(iter, r);
388 }
389 static void Log(const param_type& p, std::wstring* l) {
390 l->append(UTF8ToWide(p));
391 }
392};
393
394template <>
395struct ParamTraits<std::vector<unsigned char> > {
396 typedef std::vector<unsigned char> param_type;
397 static void Write(Message* m, const param_type& p) {
398 if (p.size() == 0) {
399 m->WriteData(NULL, 0);
400 } else {
401 m->WriteData(reinterpret_cast<const char*>(&p.front()),
402 static_cast<int>(p.size()));
403 }
404 }
405 static bool Read(const Message* m, void** iter, param_type* r) {
406 const char *data;
407 int data_size = 0;
408 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
409 return false;
410 r->resize(data_size);
411 if (data_size)
412 memcpy(&r->front(), data, data_size);
413 return true;
414 }
415 static void Log(const param_type& p, std::wstring* l) {
416 for (size_t i = 0; i < p.size(); ++i)
417 l->push_back(p[i]);
418 }
419};
420
421template <>
422struct ParamTraits<std::vector<char> > {
423 typedef std::vector<char> param_type;
424 static void Write(Message* m, const param_type& p) {
425 if (p.size() == 0) {
426 m->WriteData(NULL, 0);
427 } else {
428 m->WriteData(&p.front(), static_cast<int>(p.size()));
429 }
430 }
431 static bool Read(const Message* m, void** iter, param_type* r) {
432 const char *data;
433 int data_size = 0;
434 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
435 return false;
436 r->resize(data_size);
437 if (data_size)
438 memcpy(&r->front(), data, data_size);
439 return true;
440 }
441 static void Log(const param_type& p, std::wstring* l) {
442 for (size_t i = 0; i < p.size(); ++i)
443 l->push_back(p[i]);
444 }
445};
446
447template <class P>
448struct ParamTraits<std::vector<P> > {
449 typedef std::vector<P> param_type;
450 static void Write(Message* m, const param_type& p) {
451 WriteParam(m, static_cast<int>(p.size()));
452 for (size_t i = 0; i < p.size(); i++)
453 WriteParam(m, p[i]);
454 }
455 static bool Read(const Message* m, void** iter, param_type* r) {
456 int size;
457 if (!m->ReadLength(iter, &size))
458 return false;
459 // Resizing beforehand is not safe, see BUG 1006367 for details.
460 if (m->IteratorHasRoomFor(*iter, size * sizeof(P))) {
461 r->resize(size);
462 for (int i = 0; i < size; i++) {
463 if (!ReadParam(m, iter, &(*r)[i]))
464 return false;
465 }
466 } else {
467 for (int i = 0; i < size; i++) {
468 P element;
469 if (!ReadParam(m, iter, &element))
470 return false;
471 r->push_back(element);
472 }
473 }
474 return true;
475 }
476 static void Log(const param_type& p, std::wstring* l) {
477 for (size_t i = 0; i < p.size(); ++i) {
478 if (i != 0)
479 l->append(L" ");
480
481 LogParam((p[i]), l);
482 }
483 }
484};
485
486template <class K, class V>
487struct ParamTraits<std::map<K, V> > {
488 typedef std::map<K, V> param_type;
489 static void Write(Message* m, const param_type& p) {
490 WriteParam(m, static_cast<int>(p.size()));
491 typename param_type::const_iterator iter;
492 for (iter = p.begin(); iter != p.end(); ++iter) {
493 WriteParam(m, iter->first);
494 WriteParam(m, iter->second);
495 }
496 }
497 static bool Read(const Message* m, void** iter, param_type* r) {
498 int size;
499 if (!ReadParam(m, iter, &size) || size < 0)
500 return false;
501 for (int i = 0; i < size; ++i) {
502 K k;
503 if (!ReadParam(m, iter, &k))
504 return false;
505 V& value = (*r)[k];
506 if (!ReadParam(m, iter, &value))
507 return false;
508 }
509 return true;
510 }
511 static void Log(const param_type& p, std::wstring* l) {
512 l->append(L"<std::map>");
513 }
514};
515
[email protected]eb47a132009-03-04 00:39:56516
[email protected]7d5c3ac2009-02-04 08:58:19517template <>
518struct ParamTraits<std::wstring> {
519 typedef std::wstring param_type;
520 static void Write(Message* m, const param_type& p) {
521 m->WriteWString(p);
522 }
523 static bool Read(const Message* m, void** iter, param_type* r) {
524 return m->ReadWString(iter, r);
525 }
526 static void Log(const param_type& p, std::wstring* l) {
527 l->append(p);
528 }
529};
530
[email protected]eb47a132009-03-04 00:39:56531// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
532// need this trait.
533#if !defined(WCHAR_T_IS_UTF16)
[email protected]eb47a132009-03-04 00:39:56534template <>
535struct ParamTraits<string16> {
536 typedef string16 param_type;
537 static void Write(Message* m, const param_type& p) {
[email protected]3a2a5d22009-03-04 03:36:36538 m->WriteString16(p);
[email protected]eb47a132009-03-04 00:39:56539 }
540 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]3a2a5d22009-03-04 03:36:36541 return m->ReadString16(iter, r);
[email protected]eb47a132009-03-04 00:39:56542 }
543 static void Log(const param_type& p, std::wstring* l) {
544 l->append(UTF16ToWide(p));
545 }
546};
[email protected]eb47a132009-03-04 00:39:56547#endif
548
[email protected]82e5ee82009-04-03 02:29:45549template <>
550struct ParamTraits<GURL> {
551 typedef GURL param_type;
552 static void Write(Message* m, const param_type& p);
553 static bool Read(const Message* m, void** iter, param_type* p);
554 static void Log(const param_type& p, std::wstring* l);
555};
556
[email protected]7d5c3ac2009-02-04 08:58:19557// and, a few more useful types...
558#if defined(OS_WIN)
559template <>
560struct ParamTraits<HANDLE> {
561 typedef HANDLE param_type;
562 static void Write(Message* m, const param_type& p) {
563 m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
564 }
565 static bool Read(const Message* m, void** iter, param_type* r) {
566 DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
567 return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
568 }
569 static void Log(const param_type& p, std::wstring* l) {
570 l->append(StringPrintf(L"0x%X", p));
571 }
572};
573
574template <>
575struct ParamTraits<HCURSOR> {
576 typedef HCURSOR param_type;
577 static void Write(Message* m, const param_type& p) {
578 m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
579 }
580 static bool Read(const Message* m, void** iter, param_type* r) {
581 DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
582 return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
583 }
584 static void Log(const param_type& p, std::wstring* l) {
585 l->append(StringPrintf(L"0x%X", p));
586 }
587};
588
589template <>
590struct ParamTraits<HWND> {
591 typedef HWND param_type;
592 static void Write(Message* m, const param_type& p) {
593 m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
594 }
595 static bool Read(const Message* m, void** iter, param_type* r) {
596 DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
597 return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
598 }
599 static void Log(const param_type& p, std::wstring* l) {
600 l->append(StringPrintf(L"0x%X", p));
601 }
602};
603
604template <>
[email protected]7d5c3ac2009-02-04 08:58:19605struct ParamTraits<HACCEL> {
606 typedef HACCEL param_type;
607 static void Write(Message* m, const param_type& p) {
608 m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
609 }
610 static bool Read(const Message* m, void** iter, param_type* r) {
611 DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
612 return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
613 }
614};
615
616template <>
617struct ParamTraits<POINT> {
618 typedef POINT param_type;
619 static void Write(Message* m, const param_type& p) {
620 m->WriteInt(p.x);
621 m->WriteInt(p.y);
622 }
623 static bool Read(const Message* m, void** iter, param_type* r) {
624 int x, y;
625 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
626 return false;
627 r->x = x;
628 r->y = y;
629 return true;
630 }
631 static void Log(const param_type& p, std::wstring* l) {
632 l->append(StringPrintf(L"(%d, %d)", p.x, p.y));
633 }
634};
635#endif // defined(OS_WIN)
636
637template <>
638struct ParamTraits<FilePath> {
639 typedef FilePath param_type;
640 static void Write(Message* m, const param_type& p) {
641 ParamTraits<FilePath::StringType>::Write(m, p.value());
642 }
643 static bool Read(const Message* m, void** iter, param_type* r) {
644 FilePath::StringType value;
645 if (!ParamTraits<FilePath::StringType>::Read(m, iter, &value))
646 return false;
647 *r = FilePath(value);
648 return true;
649 }
650 static void Log(const param_type& p, std::wstring* l) {
651 ParamTraits<FilePath::StringType>::Log(p.value(), l);
652 }
653};
654
655template <>
656struct ParamTraits<gfx::Point> {
657 typedef gfx::Point param_type;
658 static void Write(Message* m, const param_type& p);
659 static bool Read(const Message* m, void** iter, param_type* r);
660 static void Log(const param_type& p, std::wstring* l);
661};
662
663template <>
664struct ParamTraits<gfx::Rect> {
665 typedef gfx::Rect param_type;
666 static void Write(Message* m, const param_type& p);
667 static bool Read(const Message* m, void** iter, param_type* r);
668 static void Log(const param_type& p, std::wstring* l);
669};
670
671template <>
672struct ParamTraits<gfx::Size> {
673 typedef gfx::Size param_type;
674 static void Write(Message* m, const param_type& p);
675 static bool Read(const Message* m, void** iter, param_type* r);
676 static void Log(const param_type& p, std::wstring* l);
677};
678
[email protected]526776c2009-02-07 00:39:26679#if defined(OS_POSIX)
[email protected]2749885f2009-03-05 21:40:11680// FileDescriptors may be serialised over IPC channels on POSIX. On the
681// receiving side, the FileDescriptor is a valid duplicate of the file
682// descriptor which was transmitted: *it is not just a copy of the integer like
683// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
684// this case, the receiving end will see a value of -1. *Zero is a valid file
685// descriptor*.
686//
687// The received file descriptor will have the |auto_close| flag set to true. The
688// code which handles the message is responsible for taking ownership of it.
689// File descriptors are OS resources and must be closed when no longer needed.
690//
691// When sending a file descriptor, the file descriptor must be valid at the time
692// of transmission. Since transmission is not synchronous, one should consider
693// dup()ing any file descriptors to be transmitted and setting the |auto_close|
694// flag, which causes the file descriptor to be closed after writing.
[email protected]526776c2009-02-07 00:39:26695template<>
[email protected]5fe733de2009-02-11 18:59:20696struct ParamTraits<base::FileDescriptor> {
697 typedef base::FileDescriptor param_type;
[email protected]526776c2009-02-07 00:39:26698 static void Write(Message* m, const param_type& p) {
[email protected]2749885f2009-03-05 21:40:11699 const bool valid = p.fd >= 0;
700 WriteParam(m, valid);
701
702 if (valid) {
703 if (!m->WriteFileDescriptor(p))
704 NOTREACHED();
705 }
[email protected]526776c2009-02-07 00:39:26706 }
707 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]2749885f2009-03-05 21:40:11708 bool valid;
709 if (!ReadParam(m, iter, &valid))
710 return false;
711
712 if (!valid) {
713 r->fd = -1;
714 r->auto_close = false;
715 return true;
716 }
717
[email protected]7135bb042009-02-12 04:05:28718 return m->ReadFileDescriptor(iter, r);
[email protected]526776c2009-02-07 00:39:26719 }
720 static void Log(const param_type& p, std::wstring* l) {
721 if (p.auto_close) {
[email protected]7135bb042009-02-12 04:05:28722 l->append(StringPrintf(L"FD(%d auto-close)", p.fd));
[email protected]526776c2009-02-07 00:39:26723 } else {
[email protected]7135bb042009-02-12 04:05:28724 l->append(StringPrintf(L"FD(%d)", p.fd));
[email protected]526776c2009-02-07 00:39:26725 }
726 }
727};
[email protected]526776c2009-02-07 00:39:26728#endif // defined(OS_POSIX)
729
[email protected]d2e884d2009-06-22 20:37:52730// A ChannelHandle is basically a platform-inspecific wrapper around the
731// fact that IPC endpoints are handled specially on POSIX. See above comments
732// on FileDescriptor for more background.
733template<>
734struct ParamTraits<IPC::ChannelHandle> {
735 typedef ChannelHandle param_type;
736 static void Write(Message* m, const param_type& p) {
737 WriteParam(m, p.name);
738#if defined(OS_POSIX)
739 WriteParam(m, p.socket);
740#endif
741 }
742 static bool Read(const Message* m, void** iter, param_type* r) {
743 return ReadParam(m, iter, &r->name)
744#if defined(OS_POSIX)
745 && ReadParam(m, iter, &r->socket)
746#endif
747 ;
748 }
749 static void Log(const param_type& p, std::wstring* l) {
750 l->append(StringPrintf(L"ChannelHandle(%s", p.name.c_str()));
751#if defined(OS_POSIX)
752 ParamTraits<base::FileDescriptor>::Log(p.socket, l);
753#endif
754 l->append(L")");
755 }
756};
757
[email protected]82e5ee82009-04-03 02:29:45758template<>
759struct ParamTraits<ThumbnailScore> {
760 typedef ThumbnailScore param_type;
761 static void Write(Message* m, const param_type& p) {
762 IPC::ParamTraits<double>::Write(m, p.boring_score);
763 IPC::ParamTraits<bool>::Write(m, p.good_clipping);
764 IPC::ParamTraits<bool>::Write(m, p.at_top);
765 IPC::ParamTraits<base::Time>::Write(m, p.time_at_snapshot);
766 }
767 static bool Read(const Message* m, void** iter, param_type* r) {
768 double boring_score;
769 bool good_clipping, at_top;
770 base::Time time_at_snapshot;
771 if (!IPC::ParamTraits<double>::Read(m, iter, &boring_score) ||
772 !IPC::ParamTraits<bool>::Read(m, iter, &good_clipping) ||
773 !IPC::ParamTraits<bool>::Read(m, iter, &at_top) ||
774 !IPC::ParamTraits<base::Time>::Read(m, iter, &time_at_snapshot))
775 return false;
776
777 r->boring_score = boring_score;
778 r->good_clipping = good_clipping;
779 r->at_top = at_top;
780 r->time_at_snapshot = time_at_snapshot;
781 return true;
782 }
783 static void Log(const param_type& p, std::wstring* l) {
784 l->append(StringPrintf(L"(%f, %d, %d)",
785 p.boring_score, p.good_clipping, p.at_top));
786 }
787};
788
789template <>
790struct ParamTraits<WindowOpenDisposition> {
791 typedef WindowOpenDisposition param_type;
792 static void Write(Message* m, const param_type& p) {
793 m->WriteInt(p);
794 }
795 static bool Read(const Message* m, void** iter, param_type* r) {
796 int temp;
797 bool res = m->ReadInt(iter, &temp);
798 *r = static_cast<WindowOpenDisposition>(temp);
799 return res;
800 }
801 static void Log(const param_type& p, std::wstring* l) {
802 l->append(StringPrintf(L"%d", p));
803 }
804};
805
[email protected]7d5c3ac2009-02-04 08:58:19806#if defined(OS_WIN)
807template <>
808struct ParamTraits<XFORM> {
809 typedef XFORM param_type;
810 static void Write(Message* m, const param_type& p) {
811 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
812 }
813 static bool Read(const Message* m, void** iter, param_type* r) {
814 const char *data;
815 int data_size = 0;
816 bool result = m->ReadData(iter, &data, &data_size);
817 if (result && data_size == sizeof(XFORM)) {
818 memcpy(r, data, sizeof(XFORM));
819 } else {
820 result = false;
821 NOTREACHED();
822 }
823
824 return result;
825 }
826 static void Log(const param_type& p, std::wstring* l) {
827 l->append(L"<XFORM>");
828 }
829};
830#endif // defined(OS_WIN)
831
[email protected]82e5ee82009-04-03 02:29:45832template <>
833struct ParamTraits<WebCursor> {
834 typedef WebCursor param_type;
835 static void Write(Message* m, const param_type& p) {
836 p.Serialize(m);
837 }
838 static bool Read(const Message* m, void** iter, param_type* r) {
839 return r->Deserialize(m, iter);
840 }
841 static void Log(const param_type& p, std::wstring* l) {
842 l->append(L"<WebCursor>");
843 }
844};
845
[email protected]7d5c3ac2009-02-04 08:58:19846struct LogData {
[email protected]9a3a293b2009-06-04 22:28:16847 std::string channel;
[email protected]8bef70e2009-04-14 19:11:24848 int32 routing_id;
[email protected]7d5c3ac2009-02-04 08:58:19849 uint16 type;
850 std::wstring flags;
851 int64 sent; // Time that the message was sent (i.e. at Send()).
852 int64 receive; // Time before it was dispatched (i.e. before calling
853 // OnMessageReceived).
854 int64 dispatch; // Time after it was dispatched (i.e. after calling
855 // OnMessageReceived).
[email protected]e707d5e62009-02-12 04:00:08856 std::wstring message_name;
[email protected]7d5c3ac2009-02-04 08:58:19857 std::wstring params;
858};
859
860template <>
861struct ParamTraits<LogData> {
862 typedef LogData param_type;
863 static void Write(Message* m, const param_type& p) {
864 WriteParam(m, p.channel);
[email protected]8bef70e2009-04-14 19:11:24865 WriteParam(m, p.routing_id);
[email protected]7d5c3ac2009-02-04 08:58:19866 WriteParam(m, static_cast<int>(p.type));
867 WriteParam(m, p.flags);
868 WriteParam(m, p.sent);
869 WriteParam(m, p.receive);
870 WriteParam(m, p.dispatch);
871 WriteParam(m, p.params);
872 }
873 static bool Read(const Message* m, void** iter, param_type* r) {
874 int type;
875 bool result =
876 ReadParam(m, iter, &r->channel) &&
[email protected]8bef70e2009-04-14 19:11:24877 ReadParam(m, iter, &r->routing_id);
[email protected]7d5c3ac2009-02-04 08:58:19878 ReadParam(m, iter, &type) &&
879 ReadParam(m, iter, &r->flags) &&
880 ReadParam(m, iter, &r->sent) &&
881 ReadParam(m, iter, &r->receive) &&
882 ReadParam(m, iter, &r->dispatch) &&
883 ReadParam(m, iter, &r->params);
884 r->type = static_cast<uint16>(type);
885 return result;
886 }
887 static void Log(const param_type& p, std::wstring* l) {
888 // Doesn't make sense to implement this!
889 }
890};
891
[email protected]eb47a132009-03-04 00:39:56892
893template <>
[email protected]82e5ee82009-04-03 02:29:45894struct ParamTraits<webkit_glue::WebApplicationInfo> {
895 typedef webkit_glue::WebApplicationInfo param_type;
896 static void Write(Message* m, const param_type& p);
897 static bool Read(const Message* m, void** iter, param_type* r);
898 static void Log(const param_type& p, std::wstring* l);
899};
900
901
902#if defined(OS_WIN)
903template<>
904struct ParamTraits<TransportDIB::Id> {
905 typedef TransportDIB::Id param_type;
906 static void Write(Message* m, const param_type& p) {
907 WriteParam(m, p.handle);
908 WriteParam(m, p.sequence_num);
909 }
910 static bool Read(const Message* m, void** iter, param_type* r) {
911 return (ReadParam(m, iter, &r->handle) &&
912 ReadParam(m, iter, &r->sequence_num));
913 }
914 static void Log(const param_type& p, std::wstring* l) {
915 l->append(L"TransportDIB(");
916 LogParam(p.handle, l);
917 l->append(L", ");
918 LogParam(p.sequence_num, l);
919 l->append(L")");
920 }
921};
922#endif
923
924template <>
[email protected]503683f2009-02-26 09:13:01925struct ParamTraits<Message> {
926 static void Write(Message* m, const Message& p) {
927 m->WriteInt(p.size());
928 m->WriteData(reinterpret_cast<const char*>(p.data()), p.size());
929 }
930 static bool Read(const Message* m, void** iter, Message* r) {
931 int size;
932 if (!m->ReadInt(iter, &size))
933 return false;
934 const char* data;
935 if (!m->ReadData(iter, &data, &size))
936 return false;
937 *r = Message(data, size);
938 return true;
939 }
940 static void Log(const Message& p, std::wstring* l) {
941 l->append(L"<IPC::Message>");
942 }
943};
944
945template <>
[email protected]7d5c3ac2009-02-04 08:58:19946struct ParamTraits<Tuple0> {
947 typedef Tuple0 param_type;
948 static void Write(Message* m, const param_type& p) {
949 }
950 static bool Read(const Message* m, void** iter, param_type* r) {
951 return true;
952 }
953 static void Log(const param_type& p, std::wstring* l) {
954 }
955};
956
957template <class A>
958struct ParamTraits< Tuple1<A> > {
959 typedef Tuple1<A> param_type;
960 static void Write(Message* m, const param_type& p) {
961 WriteParam(m, p.a);
962 }
963 static bool Read(const Message* m, void** iter, param_type* r) {
964 return ReadParam(m, iter, &r->a);
965 }
966 static void Log(const param_type& p, std::wstring* l) {
967 LogParam(p.a, l);
968 }
969};
970
971template <class A, class B>
972struct ParamTraits< Tuple2<A, B> > {
973 typedef Tuple2<A, B> param_type;
974 static void Write(Message* m, const param_type& p) {
975 WriteParam(m, p.a);
976 WriteParam(m, p.b);
977 }
978 static bool Read(const Message* m, void** iter, param_type* r) {
979 return (ReadParam(m, iter, &r->a) &&
980 ReadParam(m, iter, &r->b));
981 }
982 static void Log(const param_type& p, std::wstring* l) {
983 LogParam(p.a, l);
984 l->append(L", ");
985 LogParam(p.b, l);
986 }
987};
988
989template <class A, class B, class C>
990struct ParamTraits< Tuple3<A, B, C> > {
991 typedef Tuple3<A, B, C> param_type;
992 static void Write(Message* m, const param_type& p) {
993 WriteParam(m, p.a);
994 WriteParam(m, p.b);
995 WriteParam(m, p.c);
996 }
997 static bool Read(const Message* m, void** iter, param_type* r) {
998 return (ReadParam(m, iter, &r->a) &&
999 ReadParam(m, iter, &r->b) &&
1000 ReadParam(m, iter, &r->c));
1001 }
1002 static void Log(const param_type& p, std::wstring* l) {
1003 LogParam(p.a, l);
1004 l->append(L", ");
1005 LogParam(p.b, l);
1006 l->append(L", ");
1007 LogParam(p.c, l);
1008 }
1009};
1010
1011template <class A, class B, class C, class D>
1012struct ParamTraits< Tuple4<A, B, C, D> > {
1013 typedef Tuple4<A, B, C, D> param_type;
1014 static void Write(Message* m, const param_type& p) {
1015 WriteParam(m, p.a);
1016 WriteParam(m, p.b);
1017 WriteParam(m, p.c);
1018 WriteParam(m, p.d);
1019 }
1020 static bool Read(const Message* m, void** iter, param_type* r) {
1021 return (ReadParam(m, iter, &r->a) &&
1022 ReadParam(m, iter, &r->b) &&
1023 ReadParam(m, iter, &r->c) &&
1024 ReadParam(m, iter, &r->d));
1025 }
1026 static void Log(const param_type& p, std::wstring* l) {
1027 LogParam(p.a, l);
1028 l->append(L", ");
1029 LogParam(p.b, l);
1030 l->append(L", ");
1031 LogParam(p.c, l);
1032 l->append(L", ");
1033 LogParam(p.d, l);
1034 }
1035};
1036
1037template <class A, class B, class C, class D, class E>
1038struct ParamTraits< Tuple5<A, B, C, D, E> > {
1039 typedef Tuple5<A, B, C, D, E> param_type;
1040 static void Write(Message* m, const param_type& p) {
1041 WriteParam(m, p.a);
1042 WriteParam(m, p.b);
1043 WriteParam(m, p.c);
1044 WriteParam(m, p.d);
1045 WriteParam(m, p.e);
1046 }
1047 static bool Read(const Message* m, void** iter, param_type* r) {
1048 return (ReadParam(m, iter, &r->a) &&
1049 ReadParam(m, iter, &r->b) &&
1050 ReadParam(m, iter, &r->c) &&
1051 ReadParam(m, iter, &r->d) &&
1052 ReadParam(m, iter, &r->e));
1053 }
1054 static void Log(const param_type& p, std::wstring* l) {
1055 LogParam(p.a, l);
1056 l->append(L", ");
1057 LogParam(p.b, l);
1058 l->append(L", ");
1059 LogParam(p.c, l);
1060 l->append(L", ");
1061 LogParam(p.d, l);
1062 l->append(L", ");
1063 LogParam(p.e, l);
1064 }
1065};
1066
1067template <class A, class B, class C, class D, class E, class F>
1068struct ParamTraits< Tuple6<A, B, C, D, E, F> > {
1069 typedef Tuple6<A, B, C, D, E, F> param_type;
1070 static void Write(Message* m, const param_type& p) {
1071 WriteParam(m, p.a);
1072 WriteParam(m, p.b);
1073 WriteParam(m, p.c);
1074 WriteParam(m, p.d);
1075 WriteParam(m, p.e);
1076 WriteParam(m, p.f);
1077 }
1078 static bool Read(const Message* m, void** iter, param_type* r) {
1079 return (ReadParam(m, iter, &r->a) &&
1080 ReadParam(m, iter, &r->b) &&
1081 ReadParam(m, iter, &r->c) &&
1082 ReadParam(m, iter, &r->d) &&
1083 ReadParam(m, iter, &r->e) &&
1084 ReadParam(m, iter, &r->f));
1085 }
1086 static void Log(const param_type& p, std::wstring* l) {
1087 LogParam(p.a, l);
1088 l->append(L", ");
1089 LogParam(p.b, l);
1090 l->append(L", ");
1091 LogParam(p.c, l);
1092 l->append(L", ");
1093 LogParam(p.d, l);
1094 l->append(L", ");
1095 LogParam(p.e, l);
1096 l->append(L", ");
1097 LogParam(p.f, l);
1098 }
1099};
1100
[email protected]7d5c3ac2009-02-04 08:58:191101
1102
1103//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:291104// Generic message subclasses
1105
1106// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:241107template <class ParamType>
initial.commit09911bf2008-07-26 23:55:291108class MessageWithTuple : public Message {
1109 public:
[email protected]81a34412009-01-05 19:17:241110 typedef ParamType Param;
[email protected]c2fe31542009-05-20 18:24:141111 typedef typename ParamType::ParamTuple RefParam;
[email protected]81a34412009-01-05 19:17:241112
[email protected]c2fe31542009-05-20 18:24:141113 MessageWithTuple(int32 routing_id, uint16 type, const RefParam& p)
initial.commit09911bf2008-07-26 23:55:291114 : Message(routing_id, type, PRIORITY_NORMAL) {
1115 WriteParam(this, p);
1116 }
1117
[email protected]7d5c3ac2009-02-04 08:58:191118 static bool Read(const Message* msg, Param* p) {
initial.commit09911bf2008-07-26 23:55:291119 void* iter = NULL;
1120 bool rv = ReadParam(msg, &iter, p);
1121 DCHECK(rv) << "Error deserializing message " << msg->type();
1122 return rv;
1123 }
1124
1125 // Generic dispatcher. Should cover most cases.
1126 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191127 static bool Dispatch(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291128 Param p;
1129 if (Read(msg, &p)) {
1130 DispatchToMethod(obj, func, p);
1131 return true;
1132 }
1133 return false;
1134 }
1135
1136 // The following dispatchers exist for the case where the callback function
1137 // needs the message as well. They assume that "Param" is a type of Tuple
1138 // (except the one arg case, as there is no Tuple1).
1139 template<class T, typename TA>
[email protected]7d5c3ac2009-02-04 08:58:191140 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291141 void (T::*func)(const Message&, TA)) {
1142 Param p;
1143 if (Read(msg, &p)) {
[email protected]c2fe31542009-05-20 18:24:141144 (obj->*func)(*msg, p.a);
initial.commit09911bf2008-07-26 23:55:291145 return true;
1146 }
1147 return false;
1148 }
1149
1150 template<class T, typename TA, typename TB>
[email protected]7d5c3ac2009-02-04 08:58:191151 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291152 void (T::*func)(const Message&, TA, TB)) {
1153 Param p;
1154 if (Read(msg, &p)) {
1155 (obj->*func)(*msg, p.a, p.b);
1156 return true;
1157 }
1158 return false;
1159 }
1160
1161 template<class T, typename TA, typename TB, typename TC>
[email protected]7d5c3ac2009-02-04 08:58:191162 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291163 void (T::*func)(const Message&, TA, TB, TC)) {
1164 Param p;
1165 if (Read(msg, &p)) {
1166 (obj->*func)(*msg, p.a, p.b, p.c);
1167 return true;
1168 }
1169 return false;
1170 }
1171
1172 template<class T, typename TA, typename TB, typename TC, typename TD>
[email protected]7d5c3ac2009-02-04 08:58:191173 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291174 void (T::*func)(const Message&, TA, TB, TC, TD)) {
1175 Param p;
1176 if (Read(msg, &p)) {
1177 (obj->*func)(*msg, p.a, p.b, p.c, p.d);
1178 return true;
1179 }
1180 return false;
1181 }
1182
1183 template<class T, typename TA, typename TB, typename TC, typename TD,
1184 typename TE>
[email protected]7d5c3ac2009-02-04 08:58:191185 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291186 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
1187 Param p;
1188 if (Read(msg, &p)) {
1189 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
1190 return true;
1191 }
1192 return false;
1193 }
1194
[email protected]7d5c3ac2009-02-04 08:58:191195 static void Log(const Message* msg, std::wstring* l) {
initial.commit09911bf2008-07-26 23:55:291196 Param p;
1197 if (Read(msg, &p))
1198 LogParam(p, l);
1199 }
[email protected]deb57402009-02-06 01:35:301200
1201 // Functions used to do manual unpacking. Only used by the automation code,
1202 // these should go away once that code uses SyncChannel.
1203 template<typename TA, typename TB>
1204 static bool Read(const IPC::Message* msg, TA* a, TB* b) {
1205 ParamType params;
1206 if (!Read(msg, &params))
1207 return false;
1208 *a = params.a;
1209 *b = params.b;
1210 return true;
1211 }
1212
1213 template<typename TA, typename TB, typename TC>
1214 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
1215 ParamType params;
1216 if (!Read(msg, &params))
1217 return false;
1218 *a = params.a;
1219 *b = params.b;
1220 *c = params.c;
1221 return true;
1222 }
1223
1224 template<typename TA, typename TB, typename TC, typename TD>
1225 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) {
1226 ParamType params;
1227 if (!Read(msg, &params))
1228 return false;
1229 *a = params.a;
1230 *b = params.b;
1231 *c = params.c;
1232 *d = params.d;
1233 return true;
1234 }
1235
1236 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1237 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) {
1238 ParamType params;
1239 if (!Read(msg, &params))
1240 return false;
1241 *a = params.a;
1242 *b = params.b;
1243 *c = params.c;
1244 *d = params.d;
1245 *e = params.e;
1246 return true;
1247 }
initial.commit09911bf2008-07-26 23:55:291248};
1249
1250// This class assumes that its template argument is a RefTuple (a Tuple with
1251// reference elements).
1252template <class RefTuple>
1253class ParamDeserializer : public MessageReplyDeserializer {
1254 public:
[email protected]e1981f432008-08-12 15:22:131255 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:291256
1257 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1258 return ReadParam(&msg, &iter, &out_);
1259 }
1260
1261 RefTuple out_;
1262};
1263
1264// defined in ipc_logging.cc
[email protected]9a3a293b2009-06-04 22:28:161265void GenerateLogData(const std::string& channel, const Message& message,
initial.commit09911bf2008-07-26 23:55:291266 LogData* data);
1267
1268// Used for synchronous messages.
[email protected]75e5a872009-04-02 23:56:111269template <class SendParamType, class ReplyParamType>
initial.commit09911bf2008-07-26 23:55:291270class MessageWithReply : public SyncMessage {
1271 public:
[email protected]75e5a872009-04-02 23:56:111272 typedef SendParamType SendParam;
[email protected]c2fe31542009-05-20 18:24:141273 typedef typename SendParam::ParamTuple RefSendParam;
[email protected]75e5a872009-04-02 23:56:111274 typedef ReplyParamType ReplyParam;
1275
[email protected]d4651ff2008-12-02 16:51:581276 MessageWithReply(int32 routing_id, uint16 type,
[email protected]c2fe31542009-05-20 18:24:141277 const RefSendParam& send, const ReplyParam& reply)
initial.commit09911bf2008-07-26 23:55:291278 : SyncMessage(routing_id, type, PRIORITY_NORMAL,
1279 new ParamDeserializer<ReplyParam>(reply)) {
1280 WriteParam(this, send);
1281 }
1282
[email protected]7d5c3ac2009-02-04 08:58:191283 static void Log(const Message* msg, std::wstring* l) {
initial.commit09911bf2008-07-26 23:55:291284 if (msg->is_sync()) {
1285 SendParam p;
1286 void* iter = SyncMessage::GetDataIterator(msg);
[email protected]1e86aa62009-04-24 21:22:331287 if (ReadParam(msg, &iter, &p))
1288 LogParam(p, l);
initial.commit09911bf2008-07-26 23:55:291289
[email protected]1156f7b2008-12-04 19:13:591290#if defined(IPC_MESSAGE_LOG_ENABLED)
initial.commit09911bf2008-07-26 23:55:291291 const std::wstring& output_params = msg->output_params();
1292 if (!l->empty() && !output_params.empty())
1293 l->append(L", ");
1294
1295 l->append(output_params);
[email protected]2a34f9c2008-12-04 19:12:041296#endif
initial.commit09911bf2008-07-26 23:55:291297 } else {
1298 // This is an outgoing reply. Now that we have the output parameters, we
1299 // can finally log the message.
[email protected]d4651ff2008-12-02 16:51:581300 typename ReplyParam::ValueTuple p;
initial.commit09911bf2008-07-26 23:55:291301 void* iter = SyncMessage::GetDataIterator(msg);
[email protected]1e86aa62009-04-24 21:22:331302 if (ReadParam(msg, &iter, &p))
1303 LogParam(p, l);
initial.commit09911bf2008-07-26 23:55:291304 }
1305 }
1306
1307 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191308 static bool Dispatch(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291309 SendParam send_params;
1310 void* iter = GetDataIterator(msg);
1311 Message* reply = GenerateReply(msg);
1312 bool error;
1313 if (ReadParam(msg, &iter, &send_params)) {
[email protected]d4651ff2008-12-02 16:51:581314 typename ReplyParam::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:291315 DispatchToMethod(obj, func, send_params, &reply_params);
1316 WriteParam(reply, reply_params);
1317 error = false;
1318#ifdef IPC_MESSAGE_LOG_ENABLED
1319 if (msg->received_time() != 0) {
1320 std::wstring output_params;
1321 LogParam(reply_params, &output_params);
1322 msg->set_output_params(output_params);
1323 }
1324#endif
1325 } else {
1326 NOTREACHED() << "Error deserializing message " << msg->type();
1327 reply->set_reply_error();
1328 error = true;
1329 }
1330
1331 obj->Send(reply);
1332 return !error;
1333 }
1334
1335 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191336 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291337 SendParam send_params;
1338 void* iter = GetDataIterator(msg);
1339 Message* reply = GenerateReply(msg);
1340 bool error;
1341 if (ReadParam(msg, &iter, &send_params)) {
1342 Tuple1<Message&> t = MakeRefTuple(*reply);
1343
1344#ifdef IPC_MESSAGE_LOG_ENABLED
1345 if (msg->sent_time()) {
1346 // Don't log the sync message after dispatch, as we don't have the
1347 // output parameters at that point. Instead, save its data and log it
1348 // with the outgoing reply message when it's sent.
1349 LogData* data = new LogData;
[email protected]9a3a293b2009-06-04 22:28:161350 GenerateLogData("", *msg, data);
initial.commit09911bf2008-07-26 23:55:291351 msg->set_dont_log();
1352 reply->set_sync_log_data(data);
1353 }
1354#endif
1355 DispatchToMethod(obj, func, send_params, &t);
1356 error = false;
1357 } else {
1358 NOTREACHED() << "Error deserializing message " << msg->type();
1359 reply->set_reply_error();
1360 obj->Send(reply);
1361 error = true;
1362 }
1363 return !error;
1364 }
1365
1366 template<typename TA>
1367 static void WriteReplyParams(Message* reply, TA a) {
1368 ReplyParam p(a);
1369 WriteParam(reply, p);
1370 }
1371
1372 template<typename TA, typename TB>
1373 static void WriteReplyParams(Message* reply, TA a, TB b) {
1374 ReplyParam p(a, b);
1375 WriteParam(reply, p);
1376 }
1377
1378 template<typename TA, typename TB, typename TC>
1379 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1380 ReplyParam p(a, b, c);
1381 WriteParam(reply, p);
1382 }
1383
1384 template<typename TA, typename TB, typename TC, typename TD>
1385 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1386 ReplyParam p(a, b, c, d);
1387 WriteParam(reply, p);
1388 }
1389
1390 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1391 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1392 ReplyParam p(a, b, c, d, e);
1393 WriteParam(reply, p);
1394 }
1395};
1396
[email protected]7d5c3ac2009-02-04 08:58:191397//-----------------------------------------------------------------------------
1398
[email protected]3178f4e22008-08-05 21:20:411399} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291400
[email protected]82e5ee82009-04-03 02:29:451401#endif // CHROME_COMMON_IPC_MESSAGE_UTILS_H_