blob: d76e69533859b25ab0ee807df6a0206d07b3650d [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"
initial.commit09911bf2008-07-26 23:55:2914#include "base/tuple.h"
initial.commit09911bf2008-07-26 23:55:2915#include "chrome/common/ipc_sync_message.h"
16#include "chrome/common/thumbnail_score.h"
initial.commit09911bf2008-07-26 23:55:2917#include "webkit/glue/cache_manager.h"
18#include "webkit/glue/console_message_level.h"
[email protected]5a52f162008-08-27 04:15:3119#include "webkit/glue/find_in_page_request.h"
[email protected]4c870b42008-11-06 00:36:5220#include "webkit/glue/webcursor.h"
initial.commit09911bf2008-07-26 23:55:2921#include "webkit/glue/window_open_disposition.h"
[email protected]3178f4e22008-08-05 21:20:4122
23// Forward declarations.
24class GURL;
[email protected]e1981f432008-08-12 15:22:1325class SkBitmap;
[email protected]3178f4e22008-08-05 21:20:4126
27namespace gfx {
28class Point;
29class Rect;
30class Size;
31} // namespace gfx
32
33namespace webkit_glue {
34struct WebApplicationInfo;
35} // namespace webkit_glue
initial.commit09911bf2008-07-26 23:55:2936
[email protected]f91cb992009-02-04 20:10:1237// Used by IPC_BEGIN_MESSAGES so that each message class starts from a unique
38// base. Messages have unique IDs across channels in order for the IPC logging
39// code to figure out the message class from its ID.
40enum IPCMessageStart {
41 // By using a start value of 0 for automation messages, we keep backward
42 // compatibility with old builds.
43 AutomationMsgStart = 0,
44 ViewMsgStart,
45 ViewHostMsgStart,
46 PluginProcessMsgStart,
47 PluginProcessHostMsgStart,
48 PluginMsgStart,
49 PluginHostMsgStart,
50 NPObjectMsgStart,
51 TestMsgStart,
52 // NOTE: When you add a new message class, also update
53 // IPCStatusView::IPCStatusView to ensure logging works.
54 // NOTE: this enum is used by IPC_MESSAGE_MACRO to generate a unique message
55 // id. Only 4 bits are used for the message type, so if this enum needs more
56 // than 16 entries, that code needs to be updated.
57 LastMsgIndex
58};
59
60COMPILE_ASSERT(LastMsgIndex <= 16, need_to_update_IPC_MESSAGE_MACRO);
61
initial.commit09911bf2008-07-26 23:55:2962namespace IPC {
63
initial.commit09911bf2008-07-26 23:55:2964//-----------------------------------------------------------------------------
65// An iterator class for reading the fields contained within a Message.
66
67class MessageIterator {
68 public:
[email protected]e1981f432008-08-12 15:22:1369 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
initial.commit09911bf2008-07-26 23:55:2970 }
71 int NextInt() const {
72 int val;
73 if (!msg_.ReadInt(&iter_, &val))
74 NOTREACHED();
75 return val;
76 }
77 intptr_t NextIntPtr() const {
78 intptr_t val;
79 if (!msg_.ReadIntPtr(&iter_, &val))
80 NOTREACHED();
81 return val;
82 }
83 const std::string NextString() const {
84 std::string val;
85 if (!msg_.ReadString(&iter_, &val))
86 NOTREACHED();
87 return val;
88 }
89 const std::wstring NextWString() const {
90 std::wstring val;
91 if (!msg_.ReadWString(&iter_, &val))
92 NOTREACHED();
93 return val;
94 }
95 const void NextData(const char** data, int* length) const {
96 if (!msg_.ReadData(&iter_, data, length)) {
97 NOTREACHED();
98 }
99 }
100 private:
101 const Message& msg_;
102 mutable void* iter_;
103};
104
105//-----------------------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19106// ParamTraits specializations, etc.
107
108template <class P> struct ParamTraits {};
109
110template <class P>
111static inline void WriteParam(Message* m, const P& p) {
112 ParamTraits<P>::Write(m, p);
113}
114
115template <class P>
116static inline bool ReadParam(const Message* m, void** iter, P* p) {
117 return ParamTraits<P>::Read(m, iter, p);
118}
119
120template <class P>
121static inline void LogParam(const P& p, std::wstring* l) {
122 ParamTraits<P>::Log(p, l);
123}
124
125template <>
126struct ParamTraits<bool> {
127 typedef bool param_type;
128 static void Write(Message* m, const param_type& p) {
129 m->WriteBool(p);
130 }
131 static bool Read(const Message* m, void** iter, param_type* r) {
132 return m->ReadBool(iter, r);
133 }
134 static void Log(const param_type& p, std::wstring* l) {
135 l->append(p ? L"true" : L"false");
136 }
137};
138
139template <>
140struct ParamTraits<int> {
141 typedef int param_type;
142 static void Write(Message* m, const param_type& p) {
143 m->WriteInt(p);
144 }
145 static bool Read(const Message* m, void** iter, param_type* r) {
146 return m->ReadInt(iter, r);
147 }
148 static void Log(const param_type& p, std::wstring* l) {
149 l->append(StringPrintf(L"%d", p));
150 }
151};
152
153template <>
154struct ParamTraits<long> {
155 typedef long param_type;
156 static void Write(Message* m, const param_type& p) {
157 m->WriteLong(p);
158 }
159 static bool Read(const Message* m, void** iter, param_type* r) {
160 return m->ReadLong(iter, r);
161 }
162 static void Log(const param_type& p, std::wstring* l) {
163 l->append(StringPrintf(L"%l", p));
164 }
165};
166
167template <>
168struct ParamTraits<size_t> {
169 typedef size_t param_type;
170 static void Write(Message* m, const param_type& p) {
171 m->WriteSize(p);
172 }
173 static bool Read(const Message* m, void** iter, param_type* r) {
174 return m->ReadSize(iter, r);
175 }
176 static void Log(const param_type& p, std::wstring* l) {
177 l->append(StringPrintf(L"%u", p));
178 }
179};
180
181#if defined(OS_MACOSX)
182// On Linux size_t & uint32 can be the same type.
183// TODO(playmobil): Fix compilation if this is not the case.
184template <>
185struct ParamTraits<uint32> {
186 typedef uint32 param_type;
187 static void Write(Message* m, const param_type& p) {
188 m->WriteUInt32(p);
189 }
190 static bool Read(const Message* m, void** iter, param_type* r) {
191 return m->ReadUInt32(iter, r);
192 }
193 static void Log(const param_type& p, std::wstring* l) {
194 l->append(StringPrintf(L"%u", p));
195 }
196};
197#endif // defined(OS_MACOSX)
198
199template <>
200struct ParamTraits<int64> {
201 typedef int64 param_type;
202 static void Write(Message* m, const param_type& p) {
203 m->WriteInt64(p);
204 }
205 static bool Read(const Message* m, void** iter, param_type* r) {
206 return m->ReadInt64(iter, r);
207 }
208 static void Log(const param_type& p, std::wstring* l) {
209 l->append(StringPrintf(L"%I64d", p));
210 }
211};
212
213template <>
214struct ParamTraits<uint64> {
215 typedef uint64 param_type;
216 static void Write(Message* m, const param_type& p) {
217 m->WriteInt64(static_cast<int64>(p));
218 }
219 static bool Read(const Message* m, void** iter, param_type* r) {
220 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
221 }
222 static void Log(const param_type& p, std::wstring* l) {
223 l->append(StringPrintf(L"%I64u", p));
224 }
225};
226
227template <>
228struct ParamTraits<double> {
229 typedef double param_type;
230 static void Write(Message* m, const param_type& p) {
231 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
232 }
233 static bool Read(const Message* m, void** iter, param_type* r) {
234 const char *data;
235 int data_size = 0;
236 bool result = m->ReadData(iter, &data, &data_size);
237 if (result && data_size == sizeof(param_type)) {
238 memcpy(r, data, sizeof(param_type));
239 } else {
240 result = false;
241 NOTREACHED();
242 }
243
244 return result;
245 }
246 static void Log(const param_type& p, std::wstring* l) {
247 l->append(StringPrintf(L"e", p));
248 }
249};
250
251template <>
252struct ParamTraits<wchar_t> {
253 typedef wchar_t param_type;
254 static void Write(Message* m, const param_type& p) {
255 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
256 }
257 static bool Read(const Message* m, void** iter, param_type* r) {
258 const char *data;
259 int data_size = 0;
260 bool result = m->ReadData(iter, &data, &data_size);
261 if (result && data_size == sizeof(param_type)) {
262 memcpy(r, data, sizeof(param_type));
263 } else {
264 result = false;
265 NOTREACHED();
266 }
267
268 return result;
269 }
270 static void Log(const param_type& p, std::wstring* l) {
271 l->append(StringPrintf(L"%lc", p));
272 }
273};
274
275template <>
276struct ParamTraits<base::Time> {
277 typedef base::Time param_type;
278 static void Write(Message* m, const param_type& p) {
279 ParamTraits<int64>::Write(m, p.ToInternalValue());
280 }
281 static bool Read(const Message* m, void** iter, param_type* r) {
282 int64 value;
283 if (!ParamTraits<int64>::Read(m, iter, &value))
284 return false;
285 *r = base::Time::FromInternalValue(value);
286 return true;
287 }
288 static void Log(const param_type& p, std::wstring* l) {
289 ParamTraits<int64>::Log(p.ToInternalValue(), l);
290 }
291};
292
293#if defined(OS_WIN)
294template <>
295struct ParamTraits<LOGFONT> {
296 typedef LOGFONT param_type;
297 static void Write(Message* m, const param_type& p) {
298 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
299 }
300 static bool Read(const Message* m, void** iter, param_type* r) {
301 const char *data;
302 int data_size = 0;
303 bool result = m->ReadData(iter, &data, &data_size);
304 if (result && data_size == sizeof(LOGFONT)) {
305 memcpy(r, data, sizeof(LOGFONT));
306 } else {
307 result = false;
308 NOTREACHED();
309 }
310
311 return result;
312 }
313 static void Log(const param_type& p, std::wstring* l) {
314 l->append(StringPrintf(L"<LOGFONT>"));
315 }
316};
317
318template <>
319struct ParamTraits<MSG> {
320 typedef MSG param_type;
321 static void Write(Message* m, const param_type& p) {
322 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
323 }
324 static bool Read(const Message* m, void** iter, param_type* r) {
325 const char *data;
326 int data_size = 0;
327 bool result = m->ReadData(iter, &data, &data_size);
328 if (result && data_size == sizeof(MSG)) {
329 memcpy(r, data, sizeof(MSG));
330 } else {
331 result = false;
332 NOTREACHED();
333 }
334
335 return result;
336 }
337};
338#endif // defined(OS_WIN)
339
340template <>
341struct ParamTraits<SkBitmap> {
342 typedef SkBitmap param_type;
343 static void Write(Message* m, const param_type& p);
344
345 // Note: This function expects parameter |r| to be of type &SkBitmap since
346 // r->SetConfig() and r->SetPixels() are called.
347 static bool Read(const Message* m, void** iter, param_type* r);
348
349 static void Log(const param_type& p, std::wstring* l);
350};
351
352template <>
353struct ParamTraits<std::string> {
354 typedef std::string param_type;
355 static void Write(Message* m, const param_type& p) {
356 m->WriteString(p);
357 }
358 static bool Read(const Message* m, void** iter, param_type* r) {
359 return m->ReadString(iter, r);
360 }
361 static void Log(const param_type& p, std::wstring* l) {
362 l->append(UTF8ToWide(p));
363 }
364};
365
366template <>
367struct ParamTraits<std::vector<unsigned char> > {
368 typedef std::vector<unsigned char> param_type;
369 static void Write(Message* m, const param_type& p) {
370 if (p.size() == 0) {
371 m->WriteData(NULL, 0);
372 } else {
373 m->WriteData(reinterpret_cast<const char*>(&p.front()),
374 static_cast<int>(p.size()));
375 }
376 }
377 static bool Read(const Message* m, void** iter, param_type* r) {
378 const char *data;
379 int data_size = 0;
380 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
381 return false;
382 r->resize(data_size);
383 if (data_size)
384 memcpy(&r->front(), data, data_size);
385 return true;
386 }
387 static void Log(const param_type& p, std::wstring* l) {
388 for (size_t i = 0; i < p.size(); ++i)
389 l->push_back(p[i]);
390 }
391};
392
393template <>
394struct ParamTraits<std::vector<char> > {
395 typedef std::vector<char> param_type;
396 static void Write(Message* m, const param_type& p) {
397 if (p.size() == 0) {
398 m->WriteData(NULL, 0);
399 } else {
400 m->WriteData(&p.front(), static_cast<int>(p.size()));
401 }
402 }
403 static bool Read(const Message* m, void** iter, param_type* r) {
404 const char *data;
405 int data_size = 0;
406 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
407 return false;
408 r->resize(data_size);
409 if (data_size)
410 memcpy(&r->front(), data, data_size);
411 return true;
412 }
413 static void Log(const param_type& p, std::wstring* l) {
414 for (size_t i = 0; i < p.size(); ++i)
415 l->push_back(p[i]);
416 }
417};
418
419template <class P>
420struct ParamTraits<std::vector<P> > {
421 typedef std::vector<P> param_type;
422 static void Write(Message* m, const param_type& p) {
423 WriteParam(m, static_cast<int>(p.size()));
424 for (size_t i = 0; i < p.size(); i++)
425 WriteParam(m, p[i]);
426 }
427 static bool Read(const Message* m, void** iter, param_type* r) {
428 int size;
429 if (!m->ReadLength(iter, &size))
430 return false;
431 // Resizing beforehand is not safe, see BUG 1006367 for details.
432 if (m->IteratorHasRoomFor(*iter, size * sizeof(P))) {
433 r->resize(size);
434 for (int i = 0; i < size; i++) {
435 if (!ReadParam(m, iter, &(*r)[i]))
436 return false;
437 }
438 } else {
439 for (int i = 0; i < size; i++) {
440 P element;
441 if (!ReadParam(m, iter, &element))
442 return false;
443 r->push_back(element);
444 }
445 }
446 return true;
447 }
448 static void Log(const param_type& p, std::wstring* l) {
449 for (size_t i = 0; i < p.size(); ++i) {
450 if (i != 0)
451 l->append(L" ");
452
453 LogParam((p[i]), l);
454 }
455 }
456};
457
458template <class K, class V>
459struct ParamTraits<std::map<K, V> > {
460 typedef std::map<K, V> param_type;
461 static void Write(Message* m, const param_type& p) {
462 WriteParam(m, static_cast<int>(p.size()));
463 typename param_type::const_iterator iter;
464 for (iter = p.begin(); iter != p.end(); ++iter) {
465 WriteParam(m, iter->first);
466 WriteParam(m, iter->second);
467 }
468 }
469 static bool Read(const Message* m, void** iter, param_type* r) {
470 int size;
471 if (!ReadParam(m, iter, &size) || size < 0)
472 return false;
473 for (int i = 0; i < size; ++i) {
474 K k;
475 if (!ReadParam(m, iter, &k))
476 return false;
477 V& value = (*r)[k];
478 if (!ReadParam(m, iter, &value))
479 return false;
480 }
481 return true;
482 }
483 static void Log(const param_type& p, std::wstring* l) {
484 l->append(L"<std::map>");
485 }
486};
487
488template <>
489struct ParamTraits<std::wstring> {
490 typedef std::wstring param_type;
491 static void Write(Message* m, const param_type& p) {
492 m->WriteWString(p);
493 }
494 static bool Read(const Message* m, void** iter, param_type* r) {
495 return m->ReadWString(iter, r);
496 }
497 static void Log(const param_type& p, std::wstring* l) {
498 l->append(p);
499 }
500};
501
502template <>
503struct ParamTraits<GURL> {
504 typedef GURL param_type;
505 static void Write(Message* m, const param_type& p);
506 static bool Read(const Message* m, void** iter, param_type* p);
507 static void Log(const param_type& p, std::wstring* l);
508};
509
510// and, a few more useful types...
511#if defined(OS_WIN)
512template <>
513struct ParamTraits<HANDLE> {
514 typedef HANDLE param_type;
515 static void Write(Message* m, const param_type& p) {
516 m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
517 }
518 static bool Read(const Message* m, void** iter, param_type* r) {
519 DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
520 return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
521 }
522 static void Log(const param_type& p, std::wstring* l) {
523 l->append(StringPrintf(L"0x%X", p));
524 }
525};
526
527template <>
528struct ParamTraits<HCURSOR> {
529 typedef HCURSOR param_type;
530 static void Write(Message* m, const param_type& p) {
531 m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
532 }
533 static bool Read(const Message* m, void** iter, param_type* r) {
534 DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
535 return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
536 }
537 static void Log(const param_type& p, std::wstring* l) {
538 l->append(StringPrintf(L"0x%X", p));
539 }
540};
541
542template <>
543struct ParamTraits<HWND> {
544 typedef HWND 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<HRGN> {
559 typedef HRGN param_type;
560 static void Write(Message* m, const param_type& p) {
561 int data_size = GetRegionData(p, 0, NULL);
562 if (data_size) {
563 char* bytes = new char[data_size];
564 GetRegionData(p, data_size, reinterpret_cast<LPRGNDATA>(bytes));
565 m->WriteData(reinterpret_cast<const char*>(bytes), data_size);
566 delete [] bytes;
567 } else {
568 m->WriteData(NULL, 0);
569 }
570 }
571 static bool Read(const Message* m, void** iter, param_type* r) {
572 bool res = FALSE;
573 const char *data;
574 int data_size = 0;
575 res = m->ReadData(iter, &data, &data_size);
576 if (data_size) {
577 *r = ExtCreateRegion(NULL, data_size,
578 reinterpret_cast<CONST RGNDATA*>(data));
579 } else {
580 res = TRUE;
581 *r = CreateRectRgn(0, 0, 0, 0);
582 }
583 return res;
584 }
585 static void Log(const param_type& p, std::wstring* l) {
586 l->append(StringPrintf(L"0x%X", p));
587 }
588};
589
590template <>
591struct ParamTraits<HACCEL> {
592 typedef HACCEL param_type;
593 static void Write(Message* m, const param_type& p) {
594 m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
595 }
596 static bool Read(const Message* m, void** iter, param_type* r) {
597 DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
598 return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
599 }
600};
601
602template <>
603struct ParamTraits<POINT> {
604 typedef POINT param_type;
605 static void Write(Message* m, const param_type& p) {
606 m->WriteInt(p.x);
607 m->WriteInt(p.y);
608 }
609 static bool Read(const Message* m, void** iter, param_type* r) {
610 int x, y;
611 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
612 return false;
613 r->x = x;
614 r->y = y;
615 return true;
616 }
617 static void Log(const param_type& p, std::wstring* l) {
618 l->append(StringPrintf(L"(%d, %d)", p.x, p.y));
619 }
620};
621#endif // defined(OS_WIN)
622
623template <>
624struct ParamTraits<FilePath> {
625 typedef FilePath param_type;
626 static void Write(Message* m, const param_type& p) {
627 ParamTraits<FilePath::StringType>::Write(m, p.value());
628 }
629 static bool Read(const Message* m, void** iter, param_type* r) {
630 FilePath::StringType value;
631 if (!ParamTraits<FilePath::StringType>::Read(m, iter, &value))
632 return false;
633 *r = FilePath(value);
634 return true;
635 }
636 static void Log(const param_type& p, std::wstring* l) {
637 ParamTraits<FilePath::StringType>::Log(p.value(), l);
638 }
639};
640
641template <>
642struct ParamTraits<gfx::Point> {
643 typedef gfx::Point param_type;
644 static void Write(Message* m, const param_type& p);
645 static bool Read(const Message* m, void** iter, param_type* r);
646 static void Log(const param_type& p, std::wstring* l);
647};
648
649template <>
650struct ParamTraits<gfx::Rect> {
651 typedef gfx::Rect param_type;
652 static void Write(Message* m, const param_type& p);
653 static bool Read(const Message* m, void** iter, param_type* r);
654 static void Log(const param_type& p, std::wstring* l);
655};
656
657template <>
658struct ParamTraits<gfx::Size> {
659 typedef gfx::Size param_type;
660 static void Write(Message* m, const param_type& p);
661 static bool Read(const Message* m, void** iter, param_type* r);
662 static void Log(const param_type& p, std::wstring* l);
663};
664
665template<>
666struct ParamTraits<ThumbnailScore> {
667 typedef ThumbnailScore param_type;
668 static void Write(Message* m, const param_type& p) {
669 IPC::ParamTraits<double>::Write(m, p.boring_score);
670 IPC::ParamTraits<bool>::Write(m, p.good_clipping);
671 IPC::ParamTraits<bool>::Write(m, p.at_top);
672 IPC::ParamTraits<base::Time>::Write(m, p.time_at_snapshot);
673 }
674 static bool Read(const Message* m, void** iter, param_type* r) {
675 double boring_score;
676 bool good_clipping, at_top;
677 base::Time time_at_snapshot;
678 if (!IPC::ParamTraits<double>::Read(m, iter, &boring_score) ||
679 !IPC::ParamTraits<bool>::Read(m, iter, &good_clipping) ||
680 !IPC::ParamTraits<bool>::Read(m, iter, &at_top) ||
681 !IPC::ParamTraits<base::Time>::Read(m, iter, &time_at_snapshot))
682 return false;
683
684 r->boring_score = boring_score;
685 r->good_clipping = good_clipping;
686 r->at_top = at_top;
687 r->time_at_snapshot = time_at_snapshot;
688 return true;
689 }
690 static void Log(const param_type& p, std::wstring* l) {
691 l->append(StringPrintf(L"(%f, %d, %d)",
692 p.boring_score, p.good_clipping, p.at_top));
693 }
694};
695
696template <>
697struct ParamTraits<WindowOpenDisposition> {
698 typedef WindowOpenDisposition param_type;
699 static void Write(Message* m, const param_type& p) {
700 m->WriteInt(p);
701 }
702 static bool Read(const Message* m, void** iter, param_type* r) {
703 int temp;
704 bool res = m->ReadInt(iter, &temp);
705 *r = static_cast<WindowOpenDisposition>(temp);
706 return res;
707 }
708 static void Log(const param_type& p, std::wstring* l) {
709 l->append(StringPrintf(L"%d", p));
710 }
711};
712
713template <>
714struct ParamTraits<ConsoleMessageLevel> {
715 typedef ConsoleMessageLevel param_type;
716 static void Write(Message* m, const param_type& p) {
717 m->WriteInt(p);
718 }
719 static bool Read(const Message* m, void** iter, param_type* r) {
720 int temp;
721 bool res = m->ReadInt(iter, &temp);
722 *r = static_cast<ConsoleMessageLevel>(temp);
723 return res;
724 }
725 static void Log(const param_type& p, std::wstring* l) {
726 l->append(StringPrintf(L"%d", p));
727 }
728};
729
730template <>
731struct ParamTraits<CacheManager::ResourceTypeStat> {
732 typedef CacheManager::ResourceTypeStat param_type;
733 static void Write(Message* m, const param_type& p) {
734 WriteParam(m, p.count);
735 WriteParam(m, p.size);
736 WriteParam(m, p.live_size);
737 WriteParam(m, p.decoded_size);
738 }
739 static bool Read(const Message* m, void** iter, param_type* r) {
740 bool result =
741 ReadParam(m, iter, &r->count) &&
742 ReadParam(m, iter, &r->size) &&
743 ReadParam(m, iter, &r->live_size) &&
744 ReadParam(m, iter, &r->decoded_size);
745 return result;
746 }
747 static void Log(const param_type& p, std::wstring* l) {
748 l->append(StringPrintf(L"%d %d %d %d", p.count, p.size, p.live_size,
749 p.decoded_size));
750 }
751};
752
753template <>
754struct ParamTraits<CacheManager::ResourceTypeStats> {
755 typedef CacheManager::ResourceTypeStats param_type;
756 static void Write(Message* m, const param_type& p) {
757 WriteParam(m, p.images);
758 WriteParam(m, p.css_stylesheets);
759 WriteParam(m, p.scripts);
760 WriteParam(m, p.xsl_stylesheets);
761 WriteParam(m, p.fonts);
762 }
763 static bool Read(const Message* m, void** iter, param_type* r) {
764 bool result =
765 ReadParam(m, iter, &r->images) &&
766 ReadParam(m, iter, &r->css_stylesheets) &&
767 ReadParam(m, iter, &r->scripts) &&
768 ReadParam(m, iter, &r->xsl_stylesheets) &&
769 ReadParam(m, iter, &r->fonts);
770 return result;
771 }
772 static void Log(const param_type& p, std::wstring* l) {
773 l->append(L"<WebCoreStats>");
774 LogParam(p.images, l);
775 LogParam(p.css_stylesheets, l);
776 LogParam(p.scripts, l);
777 LogParam(p.xsl_stylesheets, l);
778 LogParam(p.fonts, l);
779 l->append(L"</WebCoreStats>");
780 }
781};
782
783#if defined(OS_WIN)
784template <>
785struct ParamTraits<XFORM> {
786 typedef XFORM param_type;
787 static void Write(Message* m, const param_type& p) {
788 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
789 }
790 static bool Read(const Message* m, void** iter, param_type* r) {
791 const char *data;
792 int data_size = 0;
793 bool result = m->ReadData(iter, &data, &data_size);
794 if (result && data_size == sizeof(XFORM)) {
795 memcpy(r, data, sizeof(XFORM));
796 } else {
797 result = false;
798 NOTREACHED();
799 }
800
801 return result;
802 }
803 static void Log(const param_type& p, std::wstring* l) {
804 l->append(L"<XFORM>");
805 }
806};
807#endif // defined(OS_WIN)
808
809template <>
810struct ParamTraits<WebCursor> {
811 typedef WebCursor param_type;
812 static void Write(Message* m, const param_type& p) {
813 p.Serialize(m);
814 }
815 static bool Read(const Message* m, void** iter, param_type* r) {
816 return r->Deserialize(m, iter);
817 }
818 static void Log(const param_type& p, std::wstring* l) {
819 l->append(L"<WebCursor>");
820 }
821};
822
823struct LogData {
824 std::wstring channel;
825 uint16 type;
826 std::wstring flags;
827 int64 sent; // Time that the message was sent (i.e. at Send()).
828 int64 receive; // Time before it was dispatched (i.e. before calling
829 // OnMessageReceived).
830 int64 dispatch; // Time after it was dispatched (i.e. after calling
831 // OnMessageReceived).
832 std::wstring params;
833};
834
835template <>
836struct ParamTraits<LogData> {
837 typedef LogData param_type;
838 static void Write(Message* m, const param_type& p) {
839 WriteParam(m, p.channel);
840 WriteParam(m, static_cast<int>(p.type));
841 WriteParam(m, p.flags);
842 WriteParam(m, p.sent);
843 WriteParam(m, p.receive);
844 WriteParam(m, p.dispatch);
845 WriteParam(m, p.params);
846 }
847 static bool Read(const Message* m, void** iter, param_type* r) {
848 int type;
849 bool result =
850 ReadParam(m, iter, &r->channel) &&
851 ReadParam(m, iter, &type) &&
852 ReadParam(m, iter, &r->flags) &&
853 ReadParam(m, iter, &r->sent) &&
854 ReadParam(m, iter, &r->receive) &&
855 ReadParam(m, iter, &r->dispatch) &&
856 ReadParam(m, iter, &r->params);
857 r->type = static_cast<uint16>(type);
858 return result;
859 }
860 static void Log(const param_type& p, std::wstring* l) {
861 // Doesn't make sense to implement this!
862 }
863};
864
865template <>
866struct ParamTraits<Tuple0> {
867 typedef Tuple0 param_type;
868 static void Write(Message* m, const param_type& p) {
869 }
870 static bool Read(const Message* m, void** iter, param_type* r) {
871 return true;
872 }
873 static void Log(const param_type& p, std::wstring* l) {
874 }
875};
876
877template <class A>
878struct ParamTraits< Tuple1<A> > {
879 typedef Tuple1<A> param_type;
880 static void Write(Message* m, const param_type& p) {
881 WriteParam(m, p.a);
882 }
883 static bool Read(const Message* m, void** iter, param_type* r) {
884 return ReadParam(m, iter, &r->a);
885 }
886 static void Log(const param_type& p, std::wstring* l) {
887 LogParam(p.a, l);
888 }
889};
890
891template <class A, class B>
892struct ParamTraits< Tuple2<A, B> > {
893 typedef Tuple2<A, B> param_type;
894 static void Write(Message* m, const param_type& p) {
895 WriteParam(m, p.a);
896 WriteParam(m, p.b);
897 }
898 static bool Read(const Message* m, void** iter, param_type* r) {
899 return (ReadParam(m, iter, &r->a) &&
900 ReadParam(m, iter, &r->b));
901 }
902 static void Log(const param_type& p, std::wstring* l) {
903 LogParam(p.a, l);
904 l->append(L", ");
905 LogParam(p.b, l);
906 }
907};
908
909template <class A, class B, class C>
910struct ParamTraits< Tuple3<A, B, C> > {
911 typedef Tuple3<A, B, C> param_type;
912 static void Write(Message* m, const param_type& p) {
913 WriteParam(m, p.a);
914 WriteParam(m, p.b);
915 WriteParam(m, p.c);
916 }
917 static bool Read(const Message* m, void** iter, param_type* r) {
918 return (ReadParam(m, iter, &r->a) &&
919 ReadParam(m, iter, &r->b) &&
920 ReadParam(m, iter, &r->c));
921 }
922 static void Log(const param_type& p, std::wstring* l) {
923 LogParam(p.a, l);
924 l->append(L", ");
925 LogParam(p.b, l);
926 l->append(L", ");
927 LogParam(p.c, l);
928 }
929};
930
931template <class A, class B, class C, class D>
932struct ParamTraits< Tuple4<A, B, C, D> > {
933 typedef Tuple4<A, B, C, D> param_type;
934 static void Write(Message* m, const param_type& p) {
935 WriteParam(m, p.a);
936 WriteParam(m, p.b);
937 WriteParam(m, p.c);
938 WriteParam(m, p.d);
939 }
940 static bool Read(const Message* m, void** iter, param_type* r) {
941 return (ReadParam(m, iter, &r->a) &&
942 ReadParam(m, iter, &r->b) &&
943 ReadParam(m, iter, &r->c) &&
944 ReadParam(m, iter, &r->d));
945 }
946 static void Log(const param_type& p, std::wstring* l) {
947 LogParam(p.a, l);
948 l->append(L", ");
949 LogParam(p.b, l);
950 l->append(L", ");
951 LogParam(p.c, l);
952 l->append(L", ");
953 LogParam(p.d, l);
954 }
955};
956
957template <class A, class B, class C, class D, class E>
958struct ParamTraits< Tuple5<A, B, C, D, E> > {
959 typedef Tuple5<A, B, C, D, E> param_type;
960 static void Write(Message* m, const param_type& p) {
961 WriteParam(m, p.a);
962 WriteParam(m, p.b);
963 WriteParam(m, p.c);
964 WriteParam(m, p.d);
965 WriteParam(m, p.e);
966 }
967 static bool Read(const Message* m, void** iter, param_type* r) {
968 return (ReadParam(m, iter, &r->a) &&
969 ReadParam(m, iter, &r->b) &&
970 ReadParam(m, iter, &r->c) &&
971 ReadParam(m, iter, &r->d) &&
972 ReadParam(m, iter, &r->e));
973 }
974 static void Log(const param_type& p, std::wstring* l) {
975 LogParam(p.a, l);
976 l->append(L", ");
977 LogParam(p.b, l);
978 l->append(L", ");
979 LogParam(p.c, l);
980 l->append(L", ");
981 LogParam(p.d, l);
982 l->append(L", ");
983 LogParam(p.e, l);
984 }
985};
986
987template <class A, class B, class C, class D, class E, class F>
988struct ParamTraits< Tuple6<A, B, C, D, E, F> > {
989 typedef Tuple6<A, B, C, D, E, F> param_type;
990 static void Write(Message* m, const param_type& p) {
991 WriteParam(m, p.a);
992 WriteParam(m, p.b);
993 WriteParam(m, p.c);
994 WriteParam(m, p.d);
995 WriteParam(m, p.e);
996 WriteParam(m, p.f);
997 }
998 static bool Read(const Message* m, void** iter, param_type* r) {
999 return (ReadParam(m, iter, &r->a) &&
1000 ReadParam(m, iter, &r->b) &&
1001 ReadParam(m, iter, &r->c) &&
1002 ReadParam(m, iter, &r->d) &&
1003 ReadParam(m, iter, &r->e) &&
1004 ReadParam(m, iter, &r->f));
1005 }
1006 static void Log(const param_type& p, std::wstring* l) {
1007 LogParam(p.a, l);
1008 l->append(L", ");
1009 LogParam(p.b, l);
1010 l->append(L", ");
1011 LogParam(p.c, l);
1012 l->append(L", ");
1013 LogParam(p.d, l);
1014 l->append(L", ");
1015 LogParam(p.e, l);
1016 l->append(L", ");
1017 LogParam(p.f, l);
1018 }
1019};
1020
1021template <>
1022struct ParamTraits<webkit_glue::WebApplicationInfo> {
1023 typedef webkit_glue::WebApplicationInfo param_type;
1024 static void Write(Message* m, const param_type& p);
1025 static bool Read(const Message* m, void** iter, param_type* r);
1026 static void Log(const param_type& p, std::wstring* l);
1027};
1028
1029
1030//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:291031// Generic message subclasses
1032
1033// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:241034template <class ParamType>
initial.commit09911bf2008-07-26 23:55:291035class MessageWithTuple : public Message {
1036 public:
[email protected]81a34412009-01-05 19:17:241037 typedef ParamType Param;
1038
[email protected]d4651ff2008-12-02 16:51:581039 MessageWithTuple(int32 routing_id, uint16 type, const Param& p)
initial.commit09911bf2008-07-26 23:55:291040 : Message(routing_id, type, PRIORITY_NORMAL) {
1041 WriteParam(this, p);
1042 }
1043
[email protected]7d5c3ac2009-02-04 08:58:191044 static bool Read(const Message* msg, Param* p) {
initial.commit09911bf2008-07-26 23:55:291045 void* iter = NULL;
1046 bool rv = ReadParam(msg, &iter, p);
1047 DCHECK(rv) << "Error deserializing message " << msg->type();
1048 return rv;
1049 }
1050
1051 // Generic dispatcher. Should cover most cases.
1052 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191053 static bool Dispatch(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291054 Param p;
1055 if (Read(msg, &p)) {
1056 DispatchToMethod(obj, func, p);
1057 return true;
1058 }
1059 return false;
1060 }
1061
1062 // The following dispatchers exist for the case where the callback function
1063 // needs the message as well. They assume that "Param" is a type of Tuple
1064 // (except the one arg case, as there is no Tuple1).
1065 template<class T, typename TA>
[email protected]7d5c3ac2009-02-04 08:58:191066 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291067 void (T::*func)(const Message&, TA)) {
1068 Param p;
1069 if (Read(msg, &p)) {
1070 (obj->*func)(*msg, p);
1071 return true;
1072 }
1073 return false;
1074 }
1075
1076 template<class T, typename TA, typename TB>
[email protected]7d5c3ac2009-02-04 08:58:191077 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291078 void (T::*func)(const Message&, TA, TB)) {
1079 Param p;
1080 if (Read(msg, &p)) {
1081 (obj->*func)(*msg, p.a, p.b);
1082 return true;
1083 }
1084 return false;
1085 }
1086
1087 template<class T, typename TA, typename TB, typename TC>
[email protected]7d5c3ac2009-02-04 08:58:191088 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291089 void (T::*func)(const Message&, TA, TB, TC)) {
1090 Param p;
1091 if (Read(msg, &p)) {
1092 (obj->*func)(*msg, p.a, p.b, p.c);
1093 return true;
1094 }
1095 return false;
1096 }
1097
1098 template<class T, typename TA, typename TB, typename TC, typename TD>
[email protected]7d5c3ac2009-02-04 08:58:191099 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291100 void (T::*func)(const Message&, TA, TB, TC, TD)) {
1101 Param p;
1102 if (Read(msg, &p)) {
1103 (obj->*func)(*msg, p.a, p.b, p.c, p.d);
1104 return true;
1105 }
1106 return false;
1107 }
1108
1109 template<class T, typename TA, typename TB, typename TC, typename TD,
1110 typename TE>
[email protected]7d5c3ac2009-02-04 08:58:191111 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291112 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
1113 Param p;
1114 if (Read(msg, &p)) {
1115 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
1116 return true;
1117 }
1118 return false;
1119 }
1120
[email protected]7d5c3ac2009-02-04 08:58:191121 static void Log(const Message* msg, std::wstring* l) {
initial.commit09911bf2008-07-26 23:55:291122 Param p;
1123 if (Read(msg, &p))
1124 LogParam(p, l);
1125 }
1126};
1127
1128// This class assumes that its template argument is a RefTuple (a Tuple with
1129// reference elements).
1130template <class RefTuple>
1131class ParamDeserializer : public MessageReplyDeserializer {
1132 public:
[email protected]e1981f432008-08-12 15:22:131133 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:291134
1135 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1136 return ReadParam(&msg, &iter, &out_);
1137 }
1138
1139 RefTuple out_;
1140};
1141
1142// defined in ipc_logging.cc
1143void GenerateLogData(const std::wstring& channel, const Message& message,
1144 LogData* data);
1145
1146// Used for synchronous messages.
1147template <class SendParam, class ReplyParam>
1148class MessageWithReply : public SyncMessage {
1149 public:
[email protected]d4651ff2008-12-02 16:51:581150 MessageWithReply(int32 routing_id, uint16 type,
initial.commit09911bf2008-07-26 23:55:291151 const SendParam& send, const ReplyParam& reply)
1152 : SyncMessage(routing_id, type, PRIORITY_NORMAL,
1153 new ParamDeserializer<ReplyParam>(reply)) {
1154 WriteParam(this, send);
1155 }
1156
[email protected]7d5c3ac2009-02-04 08:58:191157 static void Log(const Message* msg, std::wstring* l) {
initial.commit09911bf2008-07-26 23:55:291158 if (msg->is_sync()) {
1159 SendParam p;
1160 void* iter = SyncMessage::GetDataIterator(msg);
1161 ReadParam(msg, &iter, &p);
1162 LogParam(p, l);
1163
[email protected]1156f7b2008-12-04 19:13:591164#if defined(IPC_MESSAGE_LOG_ENABLED)
initial.commit09911bf2008-07-26 23:55:291165 const std::wstring& output_params = msg->output_params();
1166 if (!l->empty() && !output_params.empty())
1167 l->append(L", ");
1168
1169 l->append(output_params);
[email protected]2a34f9c2008-12-04 19:12:041170#endif
initial.commit09911bf2008-07-26 23:55:291171 } else {
1172 // This is an outgoing reply. Now that we have the output parameters, we
1173 // can finally log the message.
[email protected]d4651ff2008-12-02 16:51:581174 typename ReplyParam::ValueTuple p;
initial.commit09911bf2008-07-26 23:55:291175 void* iter = SyncMessage::GetDataIterator(msg);
1176 ReadParam(msg, &iter, &p);
1177 LogParam(p, l);
1178 }
1179 }
1180
1181 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191182 static bool Dispatch(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291183 SendParam send_params;
1184 void* iter = GetDataIterator(msg);
1185 Message* reply = GenerateReply(msg);
1186 bool error;
1187 if (ReadParam(msg, &iter, &send_params)) {
[email protected]d4651ff2008-12-02 16:51:581188 typename ReplyParam::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:291189 DispatchToMethod(obj, func, send_params, &reply_params);
1190 WriteParam(reply, reply_params);
1191 error = false;
1192#ifdef IPC_MESSAGE_LOG_ENABLED
1193 if (msg->received_time() != 0) {
1194 std::wstring output_params;
1195 LogParam(reply_params, &output_params);
1196 msg->set_output_params(output_params);
1197 }
1198#endif
1199 } else {
1200 NOTREACHED() << "Error deserializing message " << msg->type();
1201 reply->set_reply_error();
1202 error = true;
1203 }
1204
1205 obj->Send(reply);
1206 return !error;
1207 }
1208
1209 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191210 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291211 SendParam send_params;
1212 void* iter = GetDataIterator(msg);
1213 Message* reply = GenerateReply(msg);
1214 bool error;
1215 if (ReadParam(msg, &iter, &send_params)) {
1216 Tuple1<Message&> t = MakeRefTuple(*reply);
1217
1218#ifdef IPC_MESSAGE_LOG_ENABLED
1219 if (msg->sent_time()) {
1220 // Don't log the sync message after dispatch, as we don't have the
1221 // output parameters at that point. Instead, save its data and log it
1222 // with the outgoing reply message when it's sent.
1223 LogData* data = new LogData;
1224 GenerateLogData(L"", *msg, data);
1225 msg->set_dont_log();
1226 reply->set_sync_log_data(data);
1227 }
1228#endif
1229 DispatchToMethod(obj, func, send_params, &t);
1230 error = false;
1231 } else {
1232 NOTREACHED() << "Error deserializing message " << msg->type();
1233 reply->set_reply_error();
1234 obj->Send(reply);
1235 error = true;
1236 }
1237 return !error;
1238 }
1239
1240 template<typename TA>
1241 static void WriteReplyParams(Message* reply, TA a) {
1242 ReplyParam p(a);
1243 WriteParam(reply, p);
1244 }
1245
1246 template<typename TA, typename TB>
1247 static void WriteReplyParams(Message* reply, TA a, TB b) {
1248 ReplyParam p(a, b);
1249 WriteParam(reply, p);
1250 }
1251
1252 template<typename TA, typename TB, typename TC>
1253 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1254 ReplyParam p(a, b, c);
1255 WriteParam(reply, p);
1256 }
1257
1258 template<typename TA, typename TB, typename TC, typename TD>
1259 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1260 ReplyParam p(a, b, c, d);
1261 WriteParam(reply, p);
1262 }
1263
1264 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1265 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1266 ReplyParam p(a, b, c, d, e);
1267 WriteParam(reply, p);
1268 }
1269};
1270
[email protected]7d5c3ac2009-02-04 08:58:191271// Traits for ViewMsg_FindInPageMsg_Request structure to pack/unpack.
1272template <>
1273struct ParamTraits<FindInPageRequest> {
1274 typedef FindInPageRequest param_type;
1275 static void Write(Message* m, const param_type& p) {
1276 WriteParam(m, p.request_id);
1277 WriteParam(m, p.search_string);
1278 WriteParam(m, p.forward);
1279 WriteParam(m, p.match_case);
1280 WriteParam(m, p.find_next);
1281 }
1282 static bool Read(const Message* m, void** iter, param_type* p) {
1283 return
1284 ReadParam(m, iter, &p->request_id) &&
1285 ReadParam(m, iter, &p->search_string) &&
1286 ReadParam(m, iter, &p->forward) &&
1287 ReadParam(m, iter, &p->match_case) &&
1288 ReadParam(m, iter, &p->find_next);
1289 }
1290 static void Log(const param_type& p, std::wstring* l) {
1291 l->append(L"<FindInPageRequest>");
1292 }
1293};
1294
1295//-----------------------------------------------------------------------------
1296
[email protected]3178f4e22008-08-05 21:20:411297} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291298
[email protected]e1981f432008-08-12 15:22:131299#endif // CHROME_COMMON_IPC_MESSAGE_UTILS_H_
license.botbf09a502008-08-24 00:55:551300