blob: 1f54645d25ebda233bc85de7caf9294ca690e068 [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]e1981f432008-08-12 15:22:135#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]d0c0b1d2009-02-12 18:32:4517#include "chrome/common/file_descriptor_set_posix.h"
[email protected]526776c2009-02-07 00:39:2618#endif
initial.commit09911bf2008-07-26 23:55:2919#include "chrome/common/ipc_sync_message.h"
20#include "chrome/common/thumbnail_score.h"
[email protected]e68e62fa2009-02-20 02:00:0421#include "chrome/common/transport_dib.h"
initial.commit09911bf2008-07-26 23:55:2922#include "webkit/glue/cache_manager.h"
23#include "webkit/glue/console_message_level.h"
[email protected]5a52f162008-08-27 04:15:3124#include "webkit/glue/find_in_page_request.h"
[email protected]4c870b42008-11-06 00:36:5225#include "webkit/glue/webcursor.h"
initial.commit09911bf2008-07-26 23:55:2926#include "webkit/glue/window_open_disposition.h"
[email protected]3178f4e22008-08-05 21:20:4127
28// Forward declarations.
29class GURL;
[email protected]e1981f432008-08-12 15:22:1330class SkBitmap;
[email protected]3178f4e22008-08-05 21:20:4131
32namespace gfx {
33class Point;
34class Rect;
35class Size;
36} // namespace gfx
37
38namespace webkit_glue {
39struct WebApplicationInfo;
40} // namespace webkit_glue
initial.commit09911bf2008-07-26 23:55:2941
[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>
127static inline bool ReadParam(const Message* m, void** iter, P* p) {
128 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 <>
352struct 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 <>
364struct ParamTraits<std::string> {
365 typedef std::string param_type;
366 static void Write(Message* m, const param_type& p) {
367 m->WriteString(p);
368 }
369 static bool Read(const Message* m, void** iter, param_type* r) {
370 return m->ReadString(iter, r);
371 }
372 static void Log(const param_type& p, std::wstring* l) {
373 l->append(UTF8ToWide(p));
374 }
375};
376
377template <>
378struct ParamTraits<std::vector<unsigned char> > {
379 typedef std::vector<unsigned char> param_type;
380 static void Write(Message* m, const param_type& p) {
381 if (p.size() == 0) {
382 m->WriteData(NULL, 0);
383 } else {
384 m->WriteData(reinterpret_cast<const char*>(&p.front()),
385 static_cast<int>(p.size()));
386 }
387 }
388 static bool Read(const Message* m, void** iter, param_type* r) {
389 const char *data;
390 int data_size = 0;
391 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
392 return false;
393 r->resize(data_size);
394 if (data_size)
395 memcpy(&r->front(), data, data_size);
396 return true;
397 }
398 static void Log(const param_type& p, std::wstring* l) {
399 for (size_t i = 0; i < p.size(); ++i)
400 l->push_back(p[i]);
401 }
402};
403
404template <>
405struct ParamTraits<std::vector<char> > {
406 typedef std::vector<char> param_type;
407 static void Write(Message* m, const param_type& p) {
408 if (p.size() == 0) {
409 m->WriteData(NULL, 0);
410 } else {
411 m->WriteData(&p.front(), static_cast<int>(p.size()));
412 }
413 }
414 static bool Read(const Message* m, void** iter, param_type* r) {
415 const char *data;
416 int data_size = 0;
417 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
418 return false;
419 r->resize(data_size);
420 if (data_size)
421 memcpy(&r->front(), data, data_size);
422 return true;
423 }
424 static void Log(const param_type& p, std::wstring* l) {
425 for (size_t i = 0; i < p.size(); ++i)
426 l->push_back(p[i]);
427 }
428};
429
430template <class P>
431struct ParamTraits<std::vector<P> > {
432 typedef std::vector<P> param_type;
433 static void Write(Message* m, const param_type& p) {
434 WriteParam(m, static_cast<int>(p.size()));
435 for (size_t i = 0; i < p.size(); i++)
436 WriteParam(m, p[i]);
437 }
438 static bool Read(const Message* m, void** iter, param_type* r) {
439 int size;
440 if (!m->ReadLength(iter, &size))
441 return false;
442 // Resizing beforehand is not safe, see BUG 1006367 for details.
443 if (m->IteratorHasRoomFor(*iter, size * sizeof(P))) {
444 r->resize(size);
445 for (int i = 0; i < size; i++) {
446 if (!ReadParam(m, iter, &(*r)[i]))
447 return false;
448 }
449 } else {
450 for (int i = 0; i < size; i++) {
451 P element;
452 if (!ReadParam(m, iter, &element))
453 return false;
454 r->push_back(element);
455 }
456 }
457 return true;
458 }
459 static void Log(const param_type& p, std::wstring* l) {
460 for (size_t i = 0; i < p.size(); ++i) {
461 if (i != 0)
462 l->append(L" ");
463
464 LogParam((p[i]), l);
465 }
466 }
467};
468
469template <class K, class V>
470struct ParamTraits<std::map<K, V> > {
471 typedef std::map<K, V> param_type;
472 static void Write(Message* m, const param_type& p) {
473 WriteParam(m, static_cast<int>(p.size()));
474 typename param_type::const_iterator iter;
475 for (iter = p.begin(); iter != p.end(); ++iter) {
476 WriteParam(m, iter->first);
477 WriteParam(m, iter->second);
478 }
479 }
480 static bool Read(const Message* m, void** iter, param_type* r) {
481 int size;
482 if (!ReadParam(m, iter, &size) || size < 0)
483 return false;
484 for (int i = 0; i < size; ++i) {
485 K k;
486 if (!ReadParam(m, iter, &k))
487 return false;
488 V& value = (*r)[k];
489 if (!ReadParam(m, iter, &value))
490 return false;
491 }
492 return true;
493 }
494 static void Log(const param_type& p, std::wstring* l) {
495 l->append(L"<std::map>");
496 }
497};
498
[email protected]eb47a132009-03-04 00:39:56499
[email protected]7d5c3ac2009-02-04 08:58:19500template <>
501struct ParamTraits<std::wstring> {
502 typedef std::wstring param_type;
503 static void Write(Message* m, const param_type& p) {
504 m->WriteWString(p);
505 }
506 static bool Read(const Message* m, void** iter, param_type* r) {
507 return m->ReadWString(iter, r);
508 }
509 static void Log(const param_type& p, std::wstring* l) {
510 l->append(p);
511 }
512};
513
[email protected]eb47a132009-03-04 00:39:56514// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
515// need this trait.
516#if !defined(WCHAR_T_IS_UTF16)
[email protected]eb47a132009-03-04 00:39:56517template <>
518struct ParamTraits<string16> {
519 typedef string16 param_type;
520 static void Write(Message* m, const param_type& p) {
[email protected]3a2a5d22009-03-04 03:36:36521 m->WriteString16(p);
[email protected]eb47a132009-03-04 00:39:56522 }
523 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]3a2a5d22009-03-04 03:36:36524 return m->ReadString16(iter, r);
[email protected]eb47a132009-03-04 00:39:56525 }
526 static void Log(const param_type& p, std::wstring* l) {
527 l->append(UTF16ToWide(p));
528 }
529};
[email protected]eb47a132009-03-04 00:39:56530#endif
531
[email protected]7d5c3ac2009-02-04 08:58:19532template <>
533struct ParamTraits<GURL> {
534 typedef GURL param_type;
535 static void Write(Message* m, const param_type& p);
536 static bool Read(const Message* m, void** iter, param_type* p);
537 static void Log(const param_type& p, std::wstring* l);
538};
539
540// and, a few more useful types...
541#if defined(OS_WIN)
542template <>
543struct ParamTraits<HANDLE> {
544 typedef HANDLE param_type;
545 static void Write(Message* m, const param_type& p) {
546 m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
547 }
548 static bool Read(const Message* m, void** iter, param_type* r) {
549 DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
550 return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
551 }
552 static void Log(const param_type& p, std::wstring* l) {
553 l->append(StringPrintf(L"0x%X", p));
554 }
555};
556
557template <>
558struct ParamTraits<HCURSOR> {
559 typedef HCURSOR param_type;
560 static void Write(Message* m, const param_type& p) {
561 m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
562 }
563 static bool Read(const Message* m, void** iter, param_type* r) {
564 DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
565 return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
566 }
567 static void Log(const param_type& p, std::wstring* l) {
568 l->append(StringPrintf(L"0x%X", p));
569 }
570};
571
572template <>
573struct ParamTraits<HWND> {
574 typedef HWND param_type;
575 static void Write(Message* m, const param_type& p) {
576 m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
577 }
578 static bool Read(const Message* m, void** iter, param_type* r) {
579 DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
580 return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
581 }
582 static void Log(const param_type& p, std::wstring* l) {
583 l->append(StringPrintf(L"0x%X", p));
584 }
585};
586
587template <>
588struct ParamTraits<HRGN> {
589 typedef HRGN param_type;
590 static void Write(Message* m, const param_type& p) {
591 int data_size = GetRegionData(p, 0, NULL);
592 if (data_size) {
593 char* bytes = new char[data_size];
594 GetRegionData(p, data_size, reinterpret_cast<LPRGNDATA>(bytes));
595 m->WriteData(reinterpret_cast<const char*>(bytes), data_size);
596 delete [] bytes;
597 } else {
598 m->WriteData(NULL, 0);
599 }
600 }
601 static bool Read(const Message* m, void** iter, param_type* r) {
602 bool res = FALSE;
603 const char *data;
604 int data_size = 0;
605 res = m->ReadData(iter, &data, &data_size);
606 if (data_size) {
607 *r = ExtCreateRegion(NULL, data_size,
608 reinterpret_cast<CONST RGNDATA*>(data));
609 } else {
610 res = TRUE;
611 *r = CreateRectRgn(0, 0, 0, 0);
612 }
613 return res;
614 }
615 static void Log(const param_type& p, std::wstring* l) {
616 l->append(StringPrintf(L"0x%X", p));
617 }
618};
619
620template <>
621struct ParamTraits<HACCEL> {
622 typedef HACCEL param_type;
623 static void Write(Message* m, const param_type& p) {
624 m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
625 }
626 static bool Read(const Message* m, void** iter, param_type* r) {
627 DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
628 return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
629 }
630};
631
632template <>
633struct ParamTraits<POINT> {
634 typedef POINT param_type;
635 static void Write(Message* m, const param_type& p) {
636 m->WriteInt(p.x);
637 m->WriteInt(p.y);
638 }
639 static bool Read(const Message* m, void** iter, param_type* r) {
640 int x, y;
641 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
642 return false;
643 r->x = x;
644 r->y = y;
645 return true;
646 }
647 static void Log(const param_type& p, std::wstring* l) {
648 l->append(StringPrintf(L"(%d, %d)", p.x, p.y));
649 }
650};
651#endif // defined(OS_WIN)
652
653template <>
654struct ParamTraits<FilePath> {
655 typedef FilePath param_type;
656 static void Write(Message* m, const param_type& p) {
657 ParamTraits<FilePath::StringType>::Write(m, p.value());
658 }
659 static bool Read(const Message* m, void** iter, param_type* r) {
660 FilePath::StringType value;
661 if (!ParamTraits<FilePath::StringType>::Read(m, iter, &value))
662 return false;
663 *r = FilePath(value);
664 return true;
665 }
666 static void Log(const param_type& p, std::wstring* l) {
667 ParamTraits<FilePath::StringType>::Log(p.value(), l);
668 }
669};
670
671template <>
672struct ParamTraits<gfx::Point> {
673 typedef gfx::Point 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
679template <>
680struct ParamTraits<gfx::Rect> {
681 typedef gfx::Rect param_type;
682 static void Write(Message* m, const param_type& p);
683 static bool Read(const Message* m, void** iter, param_type* r);
684 static void Log(const param_type& p, std::wstring* l);
685};
686
687template <>
688struct ParamTraits<gfx::Size> {
689 typedef gfx::Size param_type;
690 static void Write(Message* m, const param_type& p);
691 static bool Read(const Message* m, void** iter, param_type* r);
692 static void Log(const param_type& p, std::wstring* l);
693};
694
[email protected]526776c2009-02-07 00:39:26695#if defined(OS_POSIX)
[email protected]2749885f2009-03-05 21:40:11696// FileDescriptors may be serialised over IPC channels on POSIX. On the
697// receiving side, the FileDescriptor is a valid duplicate of the file
698// descriptor which was transmitted: *it is not just a copy of the integer like
699// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
700// this case, the receiving end will see a value of -1. *Zero is a valid file
701// descriptor*.
702//
703// The received file descriptor will have the |auto_close| flag set to true. The
704// code which handles the message is responsible for taking ownership of it.
705// File descriptors are OS resources and must be closed when no longer needed.
706//
707// When sending a file descriptor, the file descriptor must be valid at the time
708// of transmission. Since transmission is not synchronous, one should consider
709// dup()ing any file descriptors to be transmitted and setting the |auto_close|
710// flag, which causes the file descriptor to be closed after writing.
[email protected]526776c2009-02-07 00:39:26711template<>
[email protected]5fe733de2009-02-11 18:59:20712struct ParamTraits<base::FileDescriptor> {
713 typedef base::FileDescriptor param_type;
[email protected]526776c2009-02-07 00:39:26714 static void Write(Message* m, const param_type& p) {
[email protected]2749885f2009-03-05 21:40:11715 const bool valid = p.fd >= 0;
716 WriteParam(m, valid);
717
718 if (valid) {
719 if (!m->WriteFileDescriptor(p))
720 NOTREACHED();
721 }
[email protected]526776c2009-02-07 00:39:26722 }
723 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]2749885f2009-03-05 21:40:11724 bool valid;
725 if (!ReadParam(m, iter, &valid))
726 return false;
727
728 if (!valid) {
729 r->fd = -1;
730 r->auto_close = false;
731 return true;
732 }
733
[email protected]7135bb042009-02-12 04:05:28734 return m->ReadFileDescriptor(iter, r);
[email protected]526776c2009-02-07 00:39:26735 }
736 static void Log(const param_type& p, std::wstring* l) {
737 if (p.auto_close) {
[email protected]7135bb042009-02-12 04:05:28738 l->append(StringPrintf(L"FD(%d auto-close)", p.fd));
[email protected]526776c2009-02-07 00:39:26739 } else {
[email protected]7135bb042009-02-12 04:05:28740 l->append(StringPrintf(L"FD(%d)", p.fd));
[email protected]526776c2009-02-07 00:39:26741 }
742 }
743};
[email protected]526776c2009-02-07 00:39:26744#endif // defined(OS_POSIX)
745
[email protected]7d5c3ac2009-02-04 08:58:19746template<>
747struct ParamTraits<ThumbnailScore> {
748 typedef ThumbnailScore param_type;
749 static void Write(Message* m, const param_type& p) {
750 IPC::ParamTraits<double>::Write(m, p.boring_score);
751 IPC::ParamTraits<bool>::Write(m, p.good_clipping);
752 IPC::ParamTraits<bool>::Write(m, p.at_top);
753 IPC::ParamTraits<base::Time>::Write(m, p.time_at_snapshot);
754 }
755 static bool Read(const Message* m, void** iter, param_type* r) {
756 double boring_score;
757 bool good_clipping, at_top;
758 base::Time time_at_snapshot;
759 if (!IPC::ParamTraits<double>::Read(m, iter, &boring_score) ||
760 !IPC::ParamTraits<bool>::Read(m, iter, &good_clipping) ||
761 !IPC::ParamTraits<bool>::Read(m, iter, &at_top) ||
762 !IPC::ParamTraits<base::Time>::Read(m, iter, &time_at_snapshot))
763 return false;
764
765 r->boring_score = boring_score;
766 r->good_clipping = good_clipping;
767 r->at_top = at_top;
768 r->time_at_snapshot = time_at_snapshot;
769 return true;
770 }
771 static void Log(const param_type& p, std::wstring* l) {
772 l->append(StringPrintf(L"(%f, %d, %d)",
773 p.boring_score, p.good_clipping, p.at_top));
774 }
775};
776
777template <>
778struct ParamTraits<WindowOpenDisposition> {
779 typedef WindowOpenDisposition param_type;
780 static void Write(Message* m, const param_type& p) {
781 m->WriteInt(p);
782 }
783 static bool Read(const Message* m, void** iter, param_type* r) {
784 int temp;
785 bool res = m->ReadInt(iter, &temp);
786 *r = static_cast<WindowOpenDisposition>(temp);
787 return res;
788 }
789 static void Log(const param_type& p, std::wstring* l) {
790 l->append(StringPrintf(L"%d", p));
791 }
792};
793
794template <>
795struct ParamTraits<ConsoleMessageLevel> {
796 typedef ConsoleMessageLevel param_type;
797 static void Write(Message* m, const param_type& p) {
798 m->WriteInt(p);
799 }
800 static bool Read(const Message* m, void** iter, param_type* r) {
801 int temp;
802 bool res = m->ReadInt(iter, &temp);
803 *r = static_cast<ConsoleMessageLevel>(temp);
804 return res;
805 }
806 static void Log(const param_type& p, std::wstring* l) {
807 l->append(StringPrintf(L"%d", p));
808 }
809};
810
811template <>
812struct ParamTraits<CacheManager::ResourceTypeStat> {
813 typedef CacheManager::ResourceTypeStat param_type;
814 static void Write(Message* m, const param_type& p) {
815 WriteParam(m, p.count);
816 WriteParam(m, p.size);
817 WriteParam(m, p.live_size);
818 WriteParam(m, p.decoded_size);
819 }
820 static bool Read(const Message* m, void** iter, param_type* r) {
821 bool result =
822 ReadParam(m, iter, &r->count) &&
823 ReadParam(m, iter, &r->size) &&
824 ReadParam(m, iter, &r->live_size) &&
825 ReadParam(m, iter, &r->decoded_size);
826 return result;
827 }
828 static void Log(const param_type& p, std::wstring* l) {
829 l->append(StringPrintf(L"%d %d %d %d", p.count, p.size, p.live_size,
830 p.decoded_size));
831 }
832};
833
834template <>
835struct ParamTraits<CacheManager::ResourceTypeStats> {
836 typedef CacheManager::ResourceTypeStats param_type;
837 static void Write(Message* m, const param_type& p) {
838 WriteParam(m, p.images);
839 WriteParam(m, p.css_stylesheets);
840 WriteParam(m, p.scripts);
841 WriteParam(m, p.xsl_stylesheets);
842 WriteParam(m, p.fonts);
843 }
844 static bool Read(const Message* m, void** iter, param_type* r) {
845 bool result =
846 ReadParam(m, iter, &r->images) &&
847 ReadParam(m, iter, &r->css_stylesheets) &&
848 ReadParam(m, iter, &r->scripts) &&
849 ReadParam(m, iter, &r->xsl_stylesheets) &&
850 ReadParam(m, iter, &r->fonts);
851 return result;
852 }
853 static void Log(const param_type& p, std::wstring* l) {
854 l->append(L"<WebCoreStats>");
855 LogParam(p.images, l);
856 LogParam(p.css_stylesheets, l);
857 LogParam(p.scripts, l);
858 LogParam(p.xsl_stylesheets, l);
859 LogParam(p.fonts, l);
860 l->append(L"</WebCoreStats>");
861 }
862};
863
864#if defined(OS_WIN)
865template <>
866struct ParamTraits<XFORM> {
867 typedef XFORM param_type;
868 static void Write(Message* m, const param_type& p) {
869 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
870 }
871 static bool Read(const Message* m, void** iter, param_type* r) {
872 const char *data;
873 int data_size = 0;
874 bool result = m->ReadData(iter, &data, &data_size);
875 if (result && data_size == sizeof(XFORM)) {
876 memcpy(r, data, sizeof(XFORM));
877 } else {
878 result = false;
879 NOTREACHED();
880 }
881
882 return result;
883 }
884 static void Log(const param_type& p, std::wstring* l) {
885 l->append(L"<XFORM>");
886 }
887};
888#endif // defined(OS_WIN)
889
890template <>
891struct ParamTraits<WebCursor> {
892 typedef WebCursor param_type;
893 static void Write(Message* m, const param_type& p) {
894 p.Serialize(m);
895 }
896 static bool Read(const Message* m, void** iter, param_type* r) {
897 return r->Deserialize(m, iter);
898 }
899 static void Log(const param_type& p, std::wstring* l) {
900 l->append(L"<WebCursor>");
901 }
902};
903
904struct LogData {
905 std::wstring channel;
906 uint16 type;
907 std::wstring flags;
908 int64 sent; // Time that the message was sent (i.e. at Send()).
909 int64 receive; // Time before it was dispatched (i.e. before calling
910 // OnMessageReceived).
911 int64 dispatch; // Time after it was dispatched (i.e. after calling
912 // OnMessageReceived).
[email protected]e707d5e62009-02-12 04:00:08913 std::wstring message_name;
[email protected]7d5c3ac2009-02-04 08:58:19914 std::wstring params;
915};
916
917template <>
918struct ParamTraits<LogData> {
919 typedef LogData param_type;
920 static void Write(Message* m, const param_type& p) {
921 WriteParam(m, p.channel);
922 WriteParam(m, static_cast<int>(p.type));
923 WriteParam(m, p.flags);
924 WriteParam(m, p.sent);
925 WriteParam(m, p.receive);
926 WriteParam(m, p.dispatch);
927 WriteParam(m, p.params);
928 }
929 static bool Read(const Message* m, void** iter, param_type* r) {
930 int type;
931 bool result =
932 ReadParam(m, iter, &r->channel) &&
933 ReadParam(m, iter, &type) &&
934 ReadParam(m, iter, &r->flags) &&
935 ReadParam(m, iter, &r->sent) &&
936 ReadParam(m, iter, &r->receive) &&
937 ReadParam(m, iter, &r->dispatch) &&
938 ReadParam(m, iter, &r->params);
939 r->type = static_cast<uint16>(type);
940 return result;
941 }
942 static void Log(const param_type& p, std::wstring* l) {
943 // Doesn't make sense to implement this!
944 }
945};
946
[email protected]eb47a132009-03-04 00:39:56947
948template <>
949struct ParamTraits<webkit_glue::WebApplicationInfo> {
950 typedef webkit_glue::WebApplicationInfo param_type;
951 static void Write(Message* m, const param_type& p);
952 static bool Read(const Message* m, void** iter, param_type* r);
953 static void Log(const param_type& p, std::wstring* l);
954};
955
956
957#if defined(OS_WIN)
958template<>
959struct ParamTraits<TransportDIB::Id> {
960 typedef TransportDIB::Id param_type;
961 static void Write(Message* m, const param_type& p) {
962 WriteParam(m, p.handle);
963 WriteParam(m, p.sequence_num);
964 }
965 static bool Read(const Message* m, void** iter, param_type* r) {
966 return (ReadParam(m, iter, &r->handle) &&
967 ReadParam(m, iter, &r->sequence_num));
968 }
969 static void Log(const param_type& p, std::wstring* l) {
970 l->append(L"TransportDIB(");
971 LogParam(p.handle, l);
972 l->append(L", ");
973 LogParam(p.sequence_num, l);
974 l->append(L")");
975 }
976};
977#endif
978
[email protected]7d5c3ac2009-02-04 08:58:19979template <>
[email protected]503683f2009-02-26 09:13:01980struct ParamTraits<Message> {
981 static void Write(Message* m, const Message& p) {
982 m->WriteInt(p.size());
983 m->WriteData(reinterpret_cast<const char*>(p.data()), p.size());
984 }
985 static bool Read(const Message* m, void** iter, Message* r) {
986 int size;
987 if (!m->ReadInt(iter, &size))
988 return false;
989 const char* data;
990 if (!m->ReadData(iter, &data, &size))
991 return false;
992 *r = Message(data, size);
993 return true;
994 }
995 static void Log(const Message& p, std::wstring* l) {
996 l->append(L"<IPC::Message>");
997 }
998};
999
1000template <>
[email protected]7d5c3ac2009-02-04 08:58:191001struct ParamTraits<Tuple0> {
1002 typedef Tuple0 param_type;
1003 static void Write(Message* m, const param_type& p) {
1004 }
1005 static bool Read(const Message* m, void** iter, param_type* r) {
1006 return true;
1007 }
1008 static void Log(const param_type& p, std::wstring* l) {
1009 }
1010};
1011
1012template <class A>
1013struct ParamTraits< Tuple1<A> > {
1014 typedef Tuple1<A> param_type;
1015 static void Write(Message* m, const param_type& p) {
1016 WriteParam(m, p.a);
1017 }
1018 static bool Read(const Message* m, void** iter, param_type* r) {
1019 return ReadParam(m, iter, &r->a);
1020 }
1021 static void Log(const param_type& p, std::wstring* l) {
1022 LogParam(p.a, l);
1023 }
1024};
1025
1026template <class A, class B>
1027struct ParamTraits< Tuple2<A, B> > {
1028 typedef Tuple2<A, B> param_type;
1029 static void Write(Message* m, const param_type& p) {
1030 WriteParam(m, p.a);
1031 WriteParam(m, p.b);
1032 }
1033 static bool Read(const Message* m, void** iter, param_type* r) {
1034 return (ReadParam(m, iter, &r->a) &&
1035 ReadParam(m, iter, &r->b));
1036 }
1037 static void Log(const param_type& p, std::wstring* l) {
1038 LogParam(p.a, l);
1039 l->append(L", ");
1040 LogParam(p.b, l);
1041 }
1042};
1043
1044template <class A, class B, class C>
1045struct ParamTraits< Tuple3<A, B, C> > {
1046 typedef Tuple3<A, B, C> param_type;
1047 static void Write(Message* m, const param_type& p) {
1048 WriteParam(m, p.a);
1049 WriteParam(m, p.b);
1050 WriteParam(m, p.c);
1051 }
1052 static bool Read(const Message* m, void** iter, param_type* r) {
1053 return (ReadParam(m, iter, &r->a) &&
1054 ReadParam(m, iter, &r->b) &&
1055 ReadParam(m, iter, &r->c));
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 }
1064};
1065
1066template <class A, class B, class C, class D>
1067struct ParamTraits< Tuple4<A, B, C, D> > {
1068 typedef Tuple4<A, B, C, D> param_type;
1069 static void Write(Message* m, const param_type& p) {
1070 WriteParam(m, p.a);
1071 WriteParam(m, p.b);
1072 WriteParam(m, p.c);
1073 WriteParam(m, p.d);
1074 }
1075 static bool Read(const Message* m, void** iter, param_type* r) {
1076 return (ReadParam(m, iter, &r->a) &&
1077 ReadParam(m, iter, &r->b) &&
1078 ReadParam(m, iter, &r->c) &&
1079 ReadParam(m, iter, &r->d));
1080 }
1081 static void Log(const param_type& p, std::wstring* l) {
1082 LogParam(p.a, l);
1083 l->append(L", ");
1084 LogParam(p.b, l);
1085 l->append(L", ");
1086 LogParam(p.c, l);
1087 l->append(L", ");
1088 LogParam(p.d, l);
1089 }
1090};
1091
1092template <class A, class B, class C, class D, class E>
1093struct ParamTraits< Tuple5<A, B, C, D, E> > {
1094 typedef Tuple5<A, B, C, D, E> param_type;
1095 static void Write(Message* m, const param_type& p) {
1096 WriteParam(m, p.a);
1097 WriteParam(m, p.b);
1098 WriteParam(m, p.c);
1099 WriteParam(m, p.d);
1100 WriteParam(m, p.e);
1101 }
1102 static bool Read(const Message* m, void** iter, param_type* r) {
1103 return (ReadParam(m, iter, &r->a) &&
1104 ReadParam(m, iter, &r->b) &&
1105 ReadParam(m, iter, &r->c) &&
1106 ReadParam(m, iter, &r->d) &&
1107 ReadParam(m, iter, &r->e));
1108 }
1109 static void Log(const param_type& p, std::wstring* l) {
1110 LogParam(p.a, l);
1111 l->append(L", ");
1112 LogParam(p.b, l);
1113 l->append(L", ");
1114 LogParam(p.c, l);
1115 l->append(L", ");
1116 LogParam(p.d, l);
1117 l->append(L", ");
1118 LogParam(p.e, l);
1119 }
1120};
1121
1122template <class A, class B, class C, class D, class E, class F>
1123struct ParamTraits< Tuple6<A, B, C, D, E, F> > {
1124 typedef Tuple6<A, B, C, D, E, F> param_type;
1125 static void Write(Message* m, const param_type& p) {
1126 WriteParam(m, p.a);
1127 WriteParam(m, p.b);
1128 WriteParam(m, p.c);
1129 WriteParam(m, p.d);
1130 WriteParam(m, p.e);
1131 WriteParam(m, p.f);
1132 }
1133 static bool Read(const Message* m, void** iter, param_type* r) {
1134 return (ReadParam(m, iter, &r->a) &&
1135 ReadParam(m, iter, &r->b) &&
1136 ReadParam(m, iter, &r->c) &&
1137 ReadParam(m, iter, &r->d) &&
1138 ReadParam(m, iter, &r->e) &&
1139 ReadParam(m, iter, &r->f));
1140 }
1141 static void Log(const param_type& p, std::wstring* l) {
1142 LogParam(p.a, l);
1143 l->append(L", ");
1144 LogParam(p.b, l);
1145 l->append(L", ");
1146 LogParam(p.c, l);
1147 l->append(L", ");
1148 LogParam(p.d, l);
1149 l->append(L", ");
1150 LogParam(p.e, l);
1151 l->append(L", ");
1152 LogParam(p.f, l);
1153 }
1154};
1155
[email protected]7d5c3ac2009-02-04 08:58:191156
1157
1158//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:291159// Generic message subclasses
1160
1161// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:241162template <class ParamType>
initial.commit09911bf2008-07-26 23:55:291163class MessageWithTuple : public Message {
1164 public:
[email protected]81a34412009-01-05 19:17:241165 typedef ParamType Param;
1166
[email protected]d4651ff2008-12-02 16:51:581167 MessageWithTuple(int32 routing_id, uint16 type, const Param& p)
initial.commit09911bf2008-07-26 23:55:291168 : Message(routing_id, type, PRIORITY_NORMAL) {
1169 WriteParam(this, p);
1170 }
1171
[email protected]7d5c3ac2009-02-04 08:58:191172 static bool Read(const Message* msg, Param* p) {
initial.commit09911bf2008-07-26 23:55:291173 void* iter = NULL;
1174 bool rv = ReadParam(msg, &iter, p);
1175 DCHECK(rv) << "Error deserializing message " << msg->type();
1176 return rv;
1177 }
1178
1179 // Generic dispatcher. Should cover most cases.
1180 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191181 static bool Dispatch(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291182 Param p;
1183 if (Read(msg, &p)) {
1184 DispatchToMethod(obj, func, p);
1185 return true;
1186 }
1187 return false;
1188 }
1189
1190 // The following dispatchers exist for the case where the callback function
1191 // needs the message as well. They assume that "Param" is a type of Tuple
1192 // (except the one arg case, as there is no Tuple1).
1193 template<class T, typename TA>
[email protected]7d5c3ac2009-02-04 08:58:191194 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291195 void (T::*func)(const Message&, TA)) {
1196 Param p;
1197 if (Read(msg, &p)) {
1198 (obj->*func)(*msg, p);
1199 return true;
1200 }
1201 return false;
1202 }
1203
1204 template<class T, typename TA, typename TB>
[email protected]7d5c3ac2009-02-04 08:58:191205 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291206 void (T::*func)(const Message&, TA, TB)) {
1207 Param p;
1208 if (Read(msg, &p)) {
1209 (obj->*func)(*msg, p.a, p.b);
1210 return true;
1211 }
1212 return false;
1213 }
1214
1215 template<class T, typename TA, typename TB, typename TC>
[email protected]7d5c3ac2009-02-04 08:58:191216 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291217 void (T::*func)(const Message&, TA, TB, TC)) {
1218 Param p;
1219 if (Read(msg, &p)) {
1220 (obj->*func)(*msg, p.a, p.b, p.c);
1221 return true;
1222 }
1223 return false;
1224 }
1225
1226 template<class T, typename TA, typename TB, typename TC, typename TD>
[email protected]7d5c3ac2009-02-04 08:58:191227 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291228 void (T::*func)(const Message&, TA, TB, TC, TD)) {
1229 Param p;
1230 if (Read(msg, &p)) {
1231 (obj->*func)(*msg, p.a, p.b, p.c, p.d);
1232 return true;
1233 }
1234 return false;
1235 }
1236
1237 template<class T, typename TA, typename TB, typename TC, typename TD,
1238 typename TE>
[email protected]7d5c3ac2009-02-04 08:58:191239 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291240 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
1241 Param p;
1242 if (Read(msg, &p)) {
1243 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
1244 return true;
1245 }
1246 return false;
1247 }
1248
[email protected]7d5c3ac2009-02-04 08:58:191249 static void Log(const Message* msg, std::wstring* l) {
initial.commit09911bf2008-07-26 23:55:291250 Param p;
1251 if (Read(msg, &p))
1252 LogParam(p, l);
1253 }
[email protected]deb57402009-02-06 01:35:301254
1255 // Functions used to do manual unpacking. Only used by the automation code,
1256 // these should go away once that code uses SyncChannel.
1257 template<typename TA, typename TB>
1258 static bool Read(const IPC::Message* msg, TA* a, TB* b) {
1259 ParamType params;
1260 if (!Read(msg, &params))
1261 return false;
1262 *a = params.a;
1263 *b = params.b;
1264 return true;
1265 }
1266
1267 template<typename TA, typename TB, typename TC>
1268 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
1269 ParamType params;
1270 if (!Read(msg, &params))
1271 return false;
1272 *a = params.a;
1273 *b = params.b;
1274 *c = params.c;
1275 return true;
1276 }
1277
1278 template<typename TA, typename TB, typename TC, typename TD>
1279 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) {
1280 ParamType params;
1281 if (!Read(msg, &params))
1282 return false;
1283 *a = params.a;
1284 *b = params.b;
1285 *c = params.c;
1286 *d = params.d;
1287 return true;
1288 }
1289
1290 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1291 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) {
1292 ParamType params;
1293 if (!Read(msg, &params))
1294 return false;
1295 *a = params.a;
1296 *b = params.b;
1297 *c = params.c;
1298 *d = params.d;
1299 *e = params.e;
1300 return true;
1301 }
initial.commit09911bf2008-07-26 23:55:291302};
1303
1304// This class assumes that its template argument is a RefTuple (a Tuple with
1305// reference elements).
1306template <class RefTuple>
1307class ParamDeserializer : public MessageReplyDeserializer {
1308 public:
[email protected]e1981f432008-08-12 15:22:131309 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:291310
1311 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1312 return ReadParam(&msg, &iter, &out_);
1313 }
1314
1315 RefTuple out_;
1316};
1317
1318// defined in ipc_logging.cc
1319void GenerateLogData(const std::wstring& channel, const Message& message,
1320 LogData* data);
1321
1322// Used for synchronous messages.
1323template <class SendParam, class ReplyParam>
1324class MessageWithReply : public SyncMessage {
1325 public:
[email protected]d4651ff2008-12-02 16:51:581326 MessageWithReply(int32 routing_id, uint16 type,
initial.commit09911bf2008-07-26 23:55:291327 const SendParam& send, const ReplyParam& reply)
1328 : SyncMessage(routing_id, type, PRIORITY_NORMAL,
1329 new ParamDeserializer<ReplyParam>(reply)) {
1330 WriteParam(this, send);
1331 }
1332
[email protected]7d5c3ac2009-02-04 08:58:191333 static void Log(const Message* msg, std::wstring* l) {
initial.commit09911bf2008-07-26 23:55:291334 if (msg->is_sync()) {
1335 SendParam p;
1336 void* iter = SyncMessage::GetDataIterator(msg);
1337 ReadParam(msg, &iter, &p);
1338 LogParam(p, l);
1339
[email protected]1156f7b2008-12-04 19:13:591340#if defined(IPC_MESSAGE_LOG_ENABLED)
initial.commit09911bf2008-07-26 23:55:291341 const std::wstring& output_params = msg->output_params();
1342 if (!l->empty() && !output_params.empty())
1343 l->append(L", ");
1344
1345 l->append(output_params);
[email protected]2a34f9c2008-12-04 19:12:041346#endif
initial.commit09911bf2008-07-26 23:55:291347 } else {
1348 // This is an outgoing reply. Now that we have the output parameters, we
1349 // can finally log the message.
[email protected]d4651ff2008-12-02 16:51:581350 typename ReplyParam::ValueTuple p;
initial.commit09911bf2008-07-26 23:55:291351 void* iter = SyncMessage::GetDataIterator(msg);
1352 ReadParam(msg, &iter, &p);
1353 LogParam(p, l);
1354 }
1355 }
1356
1357 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191358 static bool Dispatch(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291359 SendParam send_params;
1360 void* iter = GetDataIterator(msg);
1361 Message* reply = GenerateReply(msg);
1362 bool error;
1363 if (ReadParam(msg, &iter, &send_params)) {
[email protected]d4651ff2008-12-02 16:51:581364 typename ReplyParam::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:291365 DispatchToMethod(obj, func, send_params, &reply_params);
1366 WriteParam(reply, reply_params);
1367 error = false;
1368#ifdef IPC_MESSAGE_LOG_ENABLED
1369 if (msg->received_time() != 0) {
1370 std::wstring output_params;
1371 LogParam(reply_params, &output_params);
1372 msg->set_output_params(output_params);
1373 }
1374#endif
1375 } else {
1376 NOTREACHED() << "Error deserializing message " << msg->type();
1377 reply->set_reply_error();
1378 error = true;
1379 }
1380
1381 obj->Send(reply);
1382 return !error;
1383 }
1384
1385 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191386 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291387 SendParam send_params;
1388 void* iter = GetDataIterator(msg);
1389 Message* reply = GenerateReply(msg);
1390 bool error;
1391 if (ReadParam(msg, &iter, &send_params)) {
1392 Tuple1<Message&> t = MakeRefTuple(*reply);
1393
1394#ifdef IPC_MESSAGE_LOG_ENABLED
1395 if (msg->sent_time()) {
1396 // Don't log the sync message after dispatch, as we don't have the
1397 // output parameters at that point. Instead, save its data and log it
1398 // with the outgoing reply message when it's sent.
1399 LogData* data = new LogData;
1400 GenerateLogData(L"", *msg, data);
1401 msg->set_dont_log();
1402 reply->set_sync_log_data(data);
1403 }
1404#endif
1405 DispatchToMethod(obj, func, send_params, &t);
1406 error = false;
1407 } else {
1408 NOTREACHED() << "Error deserializing message " << msg->type();
1409 reply->set_reply_error();
1410 obj->Send(reply);
1411 error = true;
1412 }
1413 return !error;
1414 }
1415
1416 template<typename TA>
1417 static void WriteReplyParams(Message* reply, TA a) {
1418 ReplyParam p(a);
1419 WriteParam(reply, p);
1420 }
1421
1422 template<typename TA, typename TB>
1423 static void WriteReplyParams(Message* reply, TA a, TB b) {
1424 ReplyParam p(a, b);
1425 WriteParam(reply, p);
1426 }
1427
1428 template<typename TA, typename TB, typename TC>
1429 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1430 ReplyParam p(a, b, c);
1431 WriteParam(reply, p);
1432 }
1433
1434 template<typename TA, typename TB, typename TC, typename TD>
1435 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1436 ReplyParam p(a, b, c, d);
1437 WriteParam(reply, p);
1438 }
1439
1440 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1441 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1442 ReplyParam p(a, b, c, d, e);
1443 WriteParam(reply, p);
1444 }
1445};
1446
[email protected]7d5c3ac2009-02-04 08:58:191447// Traits for ViewMsg_FindInPageMsg_Request structure to pack/unpack.
1448template <>
1449struct ParamTraits<FindInPageRequest> {
1450 typedef FindInPageRequest param_type;
1451 static void Write(Message* m, const param_type& p) {
1452 WriteParam(m, p.request_id);
1453 WriteParam(m, p.search_string);
1454 WriteParam(m, p.forward);
1455 WriteParam(m, p.match_case);
1456 WriteParam(m, p.find_next);
1457 }
1458 static bool Read(const Message* m, void** iter, param_type* p) {
1459 return
1460 ReadParam(m, iter, &p->request_id) &&
1461 ReadParam(m, iter, &p->search_string) &&
1462 ReadParam(m, iter, &p->forward) &&
1463 ReadParam(m, iter, &p->match_case) &&
1464 ReadParam(m, iter, &p->find_next);
1465 }
1466 static void Log(const param_type& p, std::wstring* l) {
1467 l->append(L"<FindInPageRequest>");
1468 }
1469};
1470
1471//-----------------------------------------------------------------------------
1472
[email protected]3178f4e22008-08-05 21:20:411473} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291474
[email protected]e1981f432008-08-12 15:22:131475#endif // CHROME_COMMON_IPC_MESSAGE_UTILS_H_
license.botbf09a502008-08-24 00:55:551476