blob: dfc36149f2e355e9457249706026f60d8e8c1609 [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
initial.commit09911bf2008-07-26 23:55:2912#include "base/string_util.h"
initial.commit09911bf2008-07-26 23:55:2913#include "base/tuple.h"
initial.commit09911bf2008-07-26 23:55:2914#include "chrome/common/ipc_sync_message.h"
15#include "chrome/common/thumbnail_score.h"
initial.commit09911bf2008-07-26 23:55:2916#include "webkit/glue/cache_manager.h"
17#include "webkit/glue/console_message_level.h"
initial.commit09911bf2008-07-26 23:55:2918#include "webkit/glue/window_open_disposition.h"
[email protected]3178f4e22008-08-05 21:20:4119
20// Forward declarations.
21class GURL;
[email protected]e1981f432008-08-12 15:22:1322class SkBitmap;
[email protected]3178f4e22008-08-05 21:20:4123class WebCursor;
24
25namespace gfx {
26class Point;
27class Rect;
28class Size;
29} // namespace gfx
30
31namespace webkit_glue {
32struct WebApplicationInfo;
33} // namespace webkit_glue
initial.commit09911bf2008-07-26 23:55:2934
35namespace IPC {
36
37// Used by the message macros to register a logging function based on the
38// message class.
39typedef void (LogFunction)(uint16 type,
40 std::wstring* name,
41 const IPC::Message* msg,
42 std::wstring* params);
43void RegisterMessageLogger(int msg_start, LogFunction* func);
44
45
46//-----------------------------------------------------------------------------
47// An iterator class for reading the fields contained within a Message.
48
49class MessageIterator {
50 public:
[email protected]e1981f432008-08-12 15:22:1351 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
initial.commit09911bf2008-07-26 23:55:2952 }
53 int NextInt() const {
54 int val;
55 if (!msg_.ReadInt(&iter_, &val))
56 NOTREACHED();
57 return val;
58 }
59 intptr_t NextIntPtr() const {
60 intptr_t val;
61 if (!msg_.ReadIntPtr(&iter_, &val))
62 NOTREACHED();
63 return val;
64 }
65 const std::string NextString() const {
66 std::string val;
67 if (!msg_.ReadString(&iter_, &val))
68 NOTREACHED();
69 return val;
70 }
71 const std::wstring NextWString() const {
72 std::wstring val;
73 if (!msg_.ReadWString(&iter_, &val))
74 NOTREACHED();
75 return val;
76 }
77 const void NextData(const char** data, int* length) const {
78 if (!msg_.ReadData(&iter_, data, length)) {
79 NOTREACHED();
80 }
81 }
82 private:
83 const Message& msg_;
84 mutable void* iter_;
85};
86
87//-----------------------------------------------------------------------------
88// ParamTraits specializations, etc.
89
90template <class P> struct ParamTraits {};
91
92template <class P>
93static inline void WriteParam(Message* m, const P& p) {
94 ParamTraits<P>::Write(m, p);
95}
96
97template <class P>
98static inline bool ReadParam(const Message* m, void** iter, P* p) {
99 return ParamTraits<P>::Read(m, iter, p);
100}
101
102template <class P>
103static inline void LogParam(const P& p, std::wstring* l) {
104 ParamTraits<P>::Log(p, l);
105}
106
107template <>
108struct ParamTraits<bool> {
109 typedef bool param_type;
110 static void Write(Message* m, const param_type& p) {
111 m->WriteBool(p);
112 }
113 static bool Read(const Message* m, void** iter, param_type* r) {
114 return m->ReadBool(iter, r);
115 }
116 static void Log(const param_type& p, std::wstring* l) {
117 l->append(p ? L"true" : L"false");
118 }
119};
120
121template <>
122struct ParamTraits<int> {
123 typedef int param_type;
124 static void Write(Message* m, const param_type& p) {
125 m->WriteInt(p);
126 }
127 static bool Read(const Message* m, void** iter, param_type* r) {
128 return m->ReadInt(iter, r);
129 }
130 static void Log(const param_type& p, std::wstring* l) {
131 l->append(StringPrintf(L"%d", p));
132 }
133};
134
135template <>
[email protected]43beaef42008-08-22 23:24:54136struct ParamTraits<long> {
137 typedef long param_type;
138 static void Write(Message* m, const param_type& p) {
139 m->WriteLong(p);
140 }
141 static bool Read(const Message* m, void** iter, param_type* r) {
142 return m->ReadLong(iter, r);
143 }
144 static void Log(const param_type& p, std::wstring* l) {
145 l->append(StringPrintf(L"%l", p));
146 }
147};
148
149template <>
initial.commit09911bf2008-07-26 23:55:29150struct ParamTraits<size_t> {
151 typedef size_t param_type;
152 static void Write(Message* m, const param_type& p) {
153 m->WriteSize(p);
154 }
155 static bool Read(const Message* m, void** iter, param_type* r) {
156 return m->ReadSize(iter, r);
157 }
158 static void Log(const param_type& p, std::wstring* l) {
159 l->append(StringPrintf(L"%u", p));
160 }
161};
162
163template <>
164struct ParamTraits<int64> {
165 typedef int64 param_type;
166 static void Write(Message* m, const param_type& p) {
167 m->WriteInt64(p);
168 }
169 static bool Read(const Message* m, void** iter, param_type* r) {
170 return m->ReadInt64(iter, r);
171 }
172 static void Log(const param_type& p, std::wstring* l) {
173 l->append(StringPrintf(L"%I64d", p));
174 }
175};
176
177template <>
178struct ParamTraits<uint64> {
179 typedef uint64 param_type;
180 static void Write(Message* m, const param_type& p) {
181 m->WriteInt64(static_cast<int64>(p));
182 }
183 static bool Read(const Message* m, void** iter, param_type* r) {
184 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
185 }
186 static void Log(const param_type& p, std::wstring* l) {
187 l->append(StringPrintf(L"%I64u", p));
188 }
189};
190
191template <>
192struct ParamTraits<double> {
193 typedef double param_type;
194 static void Write(Message* m, const param_type& p) {
[email protected]e1981f432008-08-12 15:22:13195 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
initial.commit09911bf2008-07-26 23:55:29196 }
197 static bool Read(const Message* m, void** iter, param_type* r) {
198 const char *data;
199 int data_size = 0;
200 bool result = m->ReadData(iter, &data, &data_size);
[email protected]e1981f432008-08-12 15:22:13201 if (result && data_size == sizeof(param_type)) {
202 memcpy(r, data, sizeof(param_type));
initial.commit09911bf2008-07-26 23:55:29203 } else {
204 result = false;
205 NOTREACHED();
206 }
207
208 return result;
209 }
210 static void Log(const param_type& p, std::wstring* l) {
211 l->append(StringPrintf(L"e", p));
212 }
213};
214
215template <>
216struct ParamTraits<wchar_t> {
217 typedef wchar_t param_type;
218 static void Write(Message* m, const param_type& p) {
[email protected]e1981f432008-08-12 15:22:13219 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
initial.commit09911bf2008-07-26 23:55:29220 }
221 static bool Read(const Message* m, void** iter, param_type* r) {
222 const char *data;
223 int data_size = 0;
224 bool result = m->ReadData(iter, &data, &data_size);
[email protected]e1981f432008-08-12 15:22:13225 if (result && data_size == sizeof(param_type)) {
226 memcpy(r, data, sizeof(param_type));
initial.commit09911bf2008-07-26 23:55:29227 } else {
228 result = false;
229 NOTREACHED();
230 }
231
232 return result;
233 }
234 static void Log(const param_type& p, std::wstring* l) {
[email protected]51154742008-08-14 00:41:45235 l->append(StringPrintf(L"%lc", p));
initial.commit09911bf2008-07-26 23:55:29236 }
237};
238
239template <>
240struct ParamTraits<Time> {
241 typedef Time param_type;
242 static void Write(Message* m, const param_type& p) {
243 ParamTraits<int64>::Write(m, p.ToInternalValue());
244 }
245 static bool Read(const Message* m, void** iter, param_type* r) {
246 int64 value;
247 if (!ParamTraits<int64>::Read(m, iter, &value))
248 return false;
249 *r = Time::FromInternalValue(value);
250 return true;
251 }
252 static void Log(const param_type& p, std::wstring* l) {
253 ParamTraits<int64>::Log(p.ToInternalValue(), l);
254 }
255};
256
257template <>
258struct ParamTraits<LOGFONT> {
259 typedef LOGFONT param_type;
260 static void Write(Message* m, const param_type& p) {
261 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
262 }
263 static bool Read(const Message* m, void** iter, param_type* r) {
264 const char *data;
265 int data_size = 0;
266 bool result = m->ReadData(iter, &data, &data_size);
267 if (result && data_size == sizeof(LOGFONT)) {
268 memcpy(r, data, sizeof(LOGFONT));
269 } else {
270 result = false;
271 NOTREACHED();
272 }
273
274 return result;
275 }
276 static void Log(const param_type& p, std::wstring* l) {
277 l->append(StringPrintf(L"<LOGFONT>"));
278 }
279};
280
281template <>
282struct ParamTraits<MSG> {
283 typedef MSG param_type;
284 static void Write(Message* m, const param_type& p) {
285 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
286 }
287 static bool Read(const Message* m, void** iter, param_type* r) {
288 const char *data;
289 int data_size = 0;
290 bool result = m->ReadData(iter, &data, &data_size);
291 if (result && data_size == sizeof(MSG)) {
292 memcpy(r, data, sizeof(MSG));
293 } else {
294 result = false;
295 NOTREACHED();
296 }
297
298 return result;
299 }
300};
301
initial.commit09911bf2008-07-26 23:55:29302template <>
303struct ParamTraits<SkBitmap> {
304 typedef SkBitmap param_type;
[email protected]e1981f432008-08-12 15:22:13305 static void Write(Message* m, const param_type& p);
306
initial.commit09911bf2008-07-26 23:55:29307 // Note: This function expects parameter |r| to be of type &SkBitmap since
308 // r->SetConfig() and r->SetPixels() are called.
[email protected]e1981f432008-08-12 15:22:13309 static bool Read(const Message* m, void** iter, param_type* r);
initial.commit09911bf2008-07-26 23:55:29310
[email protected]e1981f432008-08-12 15:22:13311 static void Log(const param_type& p, std::wstring* l);
initial.commit09911bf2008-07-26 23:55:29312};
313
314template <>
315struct ParamTraits<MONITORINFOEX> {
316 typedef MONITORINFOEX param_type;
317 static void Write(Message* m, const param_type& p) {
318 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MONITORINFOEX));
319 }
320 static bool Read(const Message* m, void** iter, param_type* r) {
321 const char *data;
322 int data_size = 0;
323 bool result = m->ReadData(iter, &data, &data_size);
324 if (result && data_size == sizeof(MONITORINFOEX)) {
325 memcpy(r, data, sizeof(MONITORINFOEX));
326 } else {
327 result = false;
328 NOTREACHED();
329 }
330
331 return result;
332 }
333 static void Log(const param_type& p, std::wstring* l) {
334 l->append(StringPrintf(L"<MONITORINFOEX>"));
335 }
336};
337
338template <>
339struct ParamTraits<std::string> {
340 typedef std::string param_type;
341 static void Write(Message* m, const param_type& p) {
342 m->WriteString(p);
343 }
344 static bool Read(const Message* m, void** iter, param_type* r) {
345 return m->ReadString(iter, r);
346 }
347 static void Log(const param_type& p, std::wstring* l) {
348 l->append(UTF8ToWide(p));
349 }
350};
351
352template <>
353struct ParamTraits<std::vector<unsigned char> > {
354 typedef std::vector<unsigned char> param_type;
355 static void Write(Message* m, const param_type& p) {
356 if (p.size() == 0) {
357 m->WriteData(NULL, 0);
358 } else {
359 m->WriteData(reinterpret_cast<const char*>(&p.front()),
360 static_cast<int>(p.size()));
361 }
362 }
363 static bool Read(const Message* m, void** iter, param_type* r) {
364 const char *data;
365 int data_size = 0;
366 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
367 return false;
368 r->resize(data_size);
369 if (data_size)
370 memcpy(&r->front(), data, data_size);
371 return true;
372 }
373 static void Log(const param_type& p, std::wstring* l) {
374 for (size_t i = 0; i < p.size(); ++i)
375 l->push_back(p[i]);
376 }
377};
378
379template <>
380struct ParamTraits<std::vector<char> > {
381 typedef std::vector<char> param_type;
382 static void Write(Message* m, const param_type& p) {
383 if (p.size() == 0) {
384 m->WriteData(NULL, 0);
385 } else {
386 m->WriteData(&p.front(), static_cast<int>(p.size()));
387 }
388 }
389 static bool Read(const Message* m, void** iter, param_type* r) {
390 const char *data;
391 int data_size = 0;
392 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
393 return false;
394 r->resize(data_size);
395 if (data_size)
396 memcpy(&r->front(), data, data_size);
397 return true;
398 }
399 static void Log(const param_type& p, std::wstring* l) {
400 for (size_t i = 0; i < p.size(); ++i)
401 l->push_back(p[i]);
402 }
403};
404
405template <class P>
406struct ParamTraits<std::vector<P> > {
407 typedef std::vector<P> param_type;
408 static void Write(Message* m, const param_type& p) {
409 WriteParam(m, static_cast<int>(p.size()));
410 for (size_t i = 0; i < p.size(); i++)
411 WriteParam(m, p[i]);
412 }
413 static bool Read(const Message* m, void** iter, param_type* r) {
414 int size;
415 if (!m->ReadLength(iter, &size))
416 return false;
417 // Resizing beforehand is not safe, see BUG 1006367 for details.
418 if (m->IteratorHasRoomFor(*iter, size * sizeof(P))) {
419 r->resize(size);
420 for (int i = 0; i < size; i++) {
421 if (!ReadParam(m, iter, &(*r)[i]))
422 return false;
423 }
424 } else {
425 for (int i = 0; i < size; i++) {
426 P element;
427 if (!ReadParam(m, iter, &element))
428 return false;
429 r->push_back(element);
430 }
431 }
432 return true;
433 }
434 static void Log(const param_type& p, std::wstring* l) {
435 for (size_t i = 0; i < p.size(); ++i) {
436 if (i != 0)
437 l->append(L" ");
438
439 LogParam((p[i]), l);
440 }
441 }
442};
443
444template <class K, class V>
445struct ParamTraits<std::map<K, V> > {
446 typedef std::map<K, V> param_type;
447 static void Write(Message* m, const param_type& p) {
448 WriteParam(m, static_cast<int>(p.size()));
449 param_type::const_iterator iter;
450 for (iter = p.begin(); iter != p.end(); ++iter) {
451 WriteParam(m, iter->first);
452 WriteParam(m, iter->second);
453 }
454 }
455 static bool Read(const Message* m, void** iter, param_type* r) {
456 int size;
457 if (!ReadParam(m, iter, &size) || size < 0)
458 return false;
459 for (int i = 0; i < size; ++i) {
460 K k;
461 if (!ReadParam(m, iter, &k))
462 return false;
463 V& value = (*r)[k];
464 if (!ReadParam(m, iter, &value))
465 return false;
466 }
467 return true;
468 }
469 static void Log(const param_type& p, std::wstring* l) {
470 l->append(L"<std::map>");
471 }
472};
473
474template <>
475struct ParamTraits<std::wstring> {
476 typedef std::wstring param_type;
477 static void Write(Message* m, const param_type& p) {
478 m->WriteWString(p);
479 }
480 static bool Read(const Message* m, void** iter, param_type* r) {
481 return m->ReadWString(iter, r);
482 }
483 static void Log(const param_type& p, std::wstring* l) {
484 l->append(p);
485 }
486};
487
488template <>
489struct ParamTraits<GURL> {
490 typedef GURL param_type;
[email protected]3178f4e22008-08-05 21:20:41491 static void Write(Message* m, const param_type& p);
492 static bool Read(const Message* m, void** iter, param_type* p);
493 static void Log(const param_type& p, std::wstring* l);
initial.commit09911bf2008-07-26 23:55:29494};
495
496// and, a few more useful types...
497template <>
498struct ParamTraits<HANDLE> {
499 typedef HANDLE param_type;
500 static void Write(Message* m, const param_type& p) {
501 m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
502 }
503 static bool Read(const Message* m, void** iter, param_type* r) {
504 DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
505 return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
506 }
507 static void Log(const param_type& p, std::wstring* l) {
508 l->append(StringPrintf(L"0x%X", p));
509 }
510};
511
512template <>
513struct ParamTraits<HCURSOR> {
514 typedef HCURSOR 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<HWND> {
529 typedef HWND 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<HRGN> {
544 typedef HRGN param_type;
545 static void Write(Message* m, const param_type& p) {
546 int data_size = GetRegionData(p, 0, NULL);
547 if (data_size) {
548 char* bytes = new char[data_size];
549 GetRegionData(p, data_size, reinterpret_cast<LPRGNDATA>(bytes));
550 m->WriteData(reinterpret_cast<const char*>(bytes), data_size);
551 delete [] bytes;
552 } else {
553 m->WriteData(NULL, 0);
554 }
555 }
556 static bool Read(const Message* m, void** iter, param_type* r) {
557 bool res = FALSE;
558 const char *data;
559 int data_size = 0;
560 res = m->ReadData(iter, &data, &data_size);
561 if (data_size) {
562 *r = ExtCreateRegion(NULL, data_size,
563 reinterpret_cast<CONST RGNDATA*>(data));
564 } else {
565 res = TRUE;
566 *r = CreateRectRgn(0, 0, 0, 0);
567 }
568 return res;
569 }
570 static void Log(const param_type& p, std::wstring* l) {
571 l->append(StringPrintf(L"0x%X", p));
572 }
573};
574
575template <>
576struct ParamTraits<HACCEL> {
577 typedef HACCEL param_type;
578 static void Write(Message* m, const param_type& p) {
579 m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
580 }
581 static bool Read(const Message* m, void** iter, param_type* r) {
582 DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
583 return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
584 }
585};
586
587template <>
588struct ParamTraits<POINT> {
589 typedef POINT param_type;
590 static void Write(Message* m, const param_type& p) {
591 m->WriteInt(p.x);
592 m->WriteInt(p.y);
593 }
594 static bool Read(const Message* m, void** iter, param_type* r) {
595 int x, y;
596 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
597 return false;
598 r->x = x;
599 r->y = y;
600 return true;
601 }
602 static void Log(const param_type& p, std::wstring* l) {
603 l->append(StringPrintf(L"(%d, %d)", p.x, p.y));
604 }
605};
606
607template <>
608struct ParamTraits<gfx::Point> {
609 typedef gfx::Point param_type;
[email protected]3178f4e22008-08-05 21:20:41610 static void Write(Message* m, const param_type& p);
611 static bool Read(const Message* m, void** iter, param_type* r);
612 static void Log(const param_type& p, std::wstring* l);
initial.commit09911bf2008-07-26 23:55:29613};
614
615template <>
616struct ParamTraits<gfx::Rect> {
617 typedef gfx::Rect param_type;
[email protected]3178f4e22008-08-05 21:20:41618 static void Write(Message* m, const param_type& p);
619 static bool Read(const Message* m, void** iter, param_type* r);
620 static void Log(const param_type& p, std::wstring* l);
initial.commit09911bf2008-07-26 23:55:29621};
622
623template <>
624struct ParamTraits<gfx::Size> {
625 typedef gfx::Size param_type;
[email protected]3178f4e22008-08-05 21:20:41626 static void Write(Message* m, const param_type& p);
627 static bool Read(const Message* m, void** iter, param_type* r);
628 static void Log(const param_type& p, std::wstring* l);
initial.commit09911bf2008-07-26 23:55:29629};
630
631template<>
632struct ParamTraits<ThumbnailScore> {
633 typedef ThumbnailScore param_type;
634 static void Write(Message* m, const param_type& p) {
635 IPC::ParamTraits<double>::Write(m, p.boring_score);
636 IPC::ParamTraits<bool>::Write(m, p.good_clipping);
637 IPC::ParamTraits<bool>::Write(m, p.at_top);
638 IPC::ParamTraits<Time>::Write(m, p.time_at_snapshot);
639 }
640 static bool Read(const Message* m, void** iter, param_type* r) {
641 double boring_score;
642 bool good_clipping, at_top;
643 Time time_at_snapshot;
644 if (!IPC::ParamTraits<double>::Read(m, iter, &boring_score) ||
645 !IPC::ParamTraits<bool>::Read(m, iter, &good_clipping) ||
646 !IPC::ParamTraits<bool>::Read(m, iter, &at_top) ||
647 !IPC::ParamTraits<Time>::Read(m, iter, &time_at_snapshot))
648 return false;
649
650 r->boring_score = boring_score;
651 r->good_clipping = good_clipping;
652 r->at_top = at_top;
653 r->time_at_snapshot = time_at_snapshot;
654 return true;
655 }
656 static void Log(const param_type& p, std::wstring* l) {
657 l->append(StringPrintf(L"(%f, %d, %d)",
658 p.boring_score, p.good_clipping, p.at_top));
659 }
660};
661
662template <>
663struct ParamTraits<WindowOpenDisposition> {
664 typedef WindowOpenDisposition param_type;
665 static void Write(Message* m, const param_type& p) {
666 m->WriteInt(p);
667 }
668 static bool Read(const Message* m, void** iter, param_type* r) {
669 int temp;
670 bool res = m->ReadInt(iter, &temp);
671 *r = static_cast<WindowOpenDisposition>(temp);
672 return res;
673 }
674 static void Log(const param_type& p, std::wstring* l) {
675 l->append(StringPrintf(L"%d", p));
676 }
677};
678
679template <>
680struct ParamTraits<ConsoleMessageLevel> {
681 typedef ConsoleMessageLevel param_type;
682 static void Write(Message* m, const param_type& p) {
683 m->WriteInt(p);
684 }
685 static bool Read(const Message* m, void** iter, param_type* r) {
686 int temp;
687 bool res = m->ReadInt(iter, &temp);
688 *r = static_cast<ConsoleMessageLevel>(temp);
689 return res;
690 }
691 static void Log(const param_type& p, std::wstring* l) {
692 l->append(StringPrintf(L"%d", p));
693 }
694};
695
696template <>
697struct ParamTraits<CacheManager::ResourceTypeStat> {
698 typedef CacheManager::ResourceTypeStat param_type;
699 static void Write(Message* m, const param_type& p) {
700 WriteParam(m, p.count);
701 WriteParam(m, p.size);
702 WriteParam(m, p.live_size);
703 WriteParam(m, p.decoded_size);
704 }
705 static bool Read(const Message* m, void** iter, param_type* r) {
706 bool result =
707 ReadParam(m, iter, &r->count) &&
708 ReadParam(m, iter, &r->size) &&
709 ReadParam(m, iter, &r->live_size) &&
710 ReadParam(m, iter, &r->decoded_size);
711 return result;
712 }
713 static void Log(const param_type& p, std::wstring* l) {
714 l->append(StringPrintf(L"%d %d %d %d", p.count, p.size, p.live_size,
715 p.decoded_size));
716 }
717};
718
719template <>
720struct ParamTraits<CacheManager::ResourceTypeStats> {
721 typedef CacheManager::ResourceTypeStats param_type;
722 static void Write(Message* m, const param_type& p) {
723 WriteParam(m, p.images);
724 WriteParam(m, p.css_stylesheets);
725 WriteParam(m, p.scripts);
726 WriteParam(m, p.xsl_stylesheets);
727 WriteParam(m, p.fonts);
728 }
729 static bool Read(const Message* m, void** iter, param_type* r) {
730 bool result =
731 ReadParam(m, iter, &r->images) &&
732 ReadParam(m, iter, &r->css_stylesheets) &&
733 ReadParam(m, iter, &r->scripts) &&
734 ReadParam(m, iter, &r->xsl_stylesheets) &&
735 ReadParam(m, iter, &r->fonts);
736 return result;
737 }
738 static void Log(const param_type& p, std::wstring* l) {
739 l->append(L"<WebCoreStats>");
740 LogParam(p.images, l);
741 LogParam(p.css_stylesheets, l);
742 LogParam(p.scripts, l);
743 LogParam(p.xsl_stylesheets, l);
744 LogParam(p.fonts, l);
745 l->append(L"</WebCoreStats>");
746 }
747};
748
749template <>
750struct ParamTraits<XFORM> {
751 typedef XFORM param_type;
752 static void Write(Message* m, const param_type& p) {
753 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
754 }
755 static bool Read(const Message* m, void** iter, param_type* r) {
756 const char *data;
757 int data_size = 0;
758 bool result = m->ReadData(iter, &data, &data_size);
759 if (result && data_size == sizeof(XFORM)) {
760 memcpy(r, data, sizeof(XFORM));
761 } else {
762 result = false;
763 NOTREACHED();
764 }
765
766 return result;
767 }
768 static void Log(const param_type& p, std::wstring* l) {
769 l->append(L"<XFORM>");
770 }
771};
772
initial.commit09911bf2008-07-26 23:55:29773template <>
774struct ParamTraits<WebCursor> {
775 typedef WebCursor param_type;
[email protected]3178f4e22008-08-05 21:20:41776 static void Write(Message* m, const param_type& p);
777 static bool Read(const Message* m, void** iter, param_type* r);
778 static void Log(const param_type& p, std::wstring* l);
initial.commit09911bf2008-07-26 23:55:29779};
780
781struct LogData {
782 std::wstring channel;
783 uint16 type;
784 std::wstring flags;
785 int64 sent; // Time that the message was sent (i.e. at Send()).
[email protected]e1981f432008-08-12 15:22:13786 int64 receive; // Time before it was dispatched (i.e. before calling
787 // OnMessageReceived).
788 int64 dispatch; // Time after it was dispatched (i.e. after calling
789 // OnMessageReceived).
initial.commit09911bf2008-07-26 23:55:29790 std::wstring params;
791};
792
793template <>
794struct ParamTraits<LogData> {
795 typedef LogData param_type;
796 static void Write(Message* m, const param_type& p) {
797 WriteParam(m, p.channel);
798 WriteParam(m, static_cast<int>(p.type));
799 WriteParam(m, p.flags);
800 WriteParam(m, p.sent);
801 WriteParam(m, p.receive);
802 WriteParam(m, p.dispatch);
803 WriteParam(m, p.params);
804 }
805 static bool Read(const Message* m, void** iter, param_type* r) {
806 int type;
807 bool result =
808 ReadParam(m, iter, &r->channel) &&
809 ReadParam(m, iter, &type) &&
810 ReadParam(m, iter, &r->flags) &&
811 ReadParam(m, iter, &r->sent) &&
812 ReadParam(m, iter, &r->receive) &&
813 ReadParam(m, iter, &r->dispatch) &&
814 ReadParam(m, iter, &r->params);
815 r->type = static_cast<uint16>(type);
816 return result;
817 }
818 static void Log(const param_type& p, std::wstring* l) {
819 // Doesn't make sense to implement this!
820 }
821};
822
823template <>
824struct ParamTraits<Tuple0> {
825 typedef Tuple0 param_type;
826 static void Write(Message* m, const param_type& p) {
827 }
828 static bool Read(const Message* m, void** iter, param_type* r) {
829 return true;
830 }
831 static void Log(const param_type& p, std::wstring* l) {
832 }
833};
834
835template <class A>
836struct ParamTraits< Tuple1<A> > {
837 typedef Tuple1<A> param_type;
838 static void Write(Message* m, const param_type& p) {
839 WriteParam(m, p.a);
840 }
841 static bool Read(const Message* m, void** iter, param_type* r) {
842 return ReadParam(m, iter, &r->a);
843 }
844 static void Log(const param_type& p, std::wstring* l) {
845 LogParam(p.a, l);
846 }
847};
848
849template <class A, class B>
850struct ParamTraits< Tuple2<A, B> > {
851 typedef Tuple2<A, B> param_type;
852 static void Write(Message* m, const param_type& p) {
853 WriteParam(m, p.a);
854 WriteParam(m, p.b);
855 }
856 static bool Read(const Message* m, void** iter, param_type* r) {
857 return (ReadParam(m, iter, &r->a) &&
858 ReadParam(m, iter, &r->b));
859 }
860 static void Log(const param_type& p, std::wstring* l) {
861 LogParam(p.a, l);
862 l->append(L", ");
863 LogParam(p.b, l);
864 }
865};
866
867template <class A, class B, class C>
868struct ParamTraits< Tuple3<A, B, C> > {
869 typedef Tuple3<A, B, C> param_type;
870 static void Write(Message* m, const param_type& p) {
871 WriteParam(m, p.a);
872 WriteParam(m, p.b);
873 WriteParam(m, p.c);
874 }
875 static bool Read(const Message* m, void** iter, param_type* r) {
876 return (ReadParam(m, iter, &r->a) &&
877 ReadParam(m, iter, &r->b) &&
878 ReadParam(m, iter, &r->c));
879 }
880 static void Log(const param_type& p, std::wstring* l) {
881 LogParam(p.a, l);
882 l->append(L", ");
883 LogParam(p.b, l);
884 l->append(L", ");
885 LogParam(p.c, l);
886 }
887};
888
889template <class A, class B, class C, class D>
890struct ParamTraits< Tuple4<A, B, C, D> > {
891 typedef Tuple4<A, B, C, D> param_type;
892 static void Write(Message* m, const param_type& p) {
893 WriteParam(m, p.a);
894 WriteParam(m, p.b);
895 WriteParam(m, p.c);
896 WriteParam(m, p.d);
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 ReadParam(m, iter, &r->c) &&
902 ReadParam(m, iter, &r->d));
903 }
904 static void Log(const param_type& p, std::wstring* l) {
905 LogParam(p.a, l);
906 l->append(L", ");
907 LogParam(p.b, l);
908 l->append(L", ");
909 LogParam(p.c, l);
910 l->append(L", ");
911 LogParam(p.d, l);
912 }
913};
914
915template <class A, class B, class C, class D, class E>
916struct ParamTraits< Tuple5<A, B, C, D, E> > {
917 typedef Tuple5<A, B, C, D, E> param_type;
918 static void Write(Message* m, const param_type& p) {
919 WriteParam(m, p.a);
920 WriteParam(m, p.b);
921 WriteParam(m, p.c);
922 WriteParam(m, p.d);
923 WriteParam(m, p.e);
924 }
925 static bool Read(const Message* m, void** iter, param_type* r) {
926 return (ReadParam(m, iter, &r->a) &&
927 ReadParam(m, iter, &r->b) &&
928 ReadParam(m, iter, &r->c) &&
929 ReadParam(m, iter, &r->d) &&
930 ReadParam(m, iter, &r->e));
931 }
932 static void Log(const param_type& p, std::wstring* l) {
933 LogParam(p.a, l);
934 l->append(L", ");
935 LogParam(p.b, l);
936 l->append(L", ");
937 LogParam(p.c, l);
938 l->append(L", ");
939 LogParam(p.d, l);
940 l->append(L", ");
941 LogParam(p.e, l);
942 }
943};
944
945template <>
946struct ParamTraits<webkit_glue::WebApplicationInfo> {
947 typedef webkit_glue::WebApplicationInfo param_type;
[email protected]3178f4e22008-08-05 21:20:41948 static void Write(Message* m, const param_type& p);
949 static bool Read(const Message* m, void** iter, param_type* r);
950 static void Log(const param_type& p, std::wstring* l);
initial.commit09911bf2008-07-26 23:55:29951};
952
953
954//-----------------------------------------------------------------------------
955// Generic message subclasses
956
957// Used for asynchronous messages.
958template <class Param>
959class MessageWithTuple : public Message {
960 public:
961 MessageWithTuple(int32 routing_id, WORD type, const Param& p)
962 : Message(routing_id, type, PRIORITY_NORMAL) {
963 WriteParam(this, p);
964 }
965
966 static bool Read(const Message* msg, Param* p) {
967 void* iter = NULL;
968 bool rv = ReadParam(msg, &iter, p);
969 DCHECK(rv) << "Error deserializing message " << msg->type();
970 return rv;
971 }
972
973 // Generic dispatcher. Should cover most cases.
974 template<class T, class Method>
975 static bool Dispatch(const Message* msg, T* obj, Method func) {
976 Param p;
977 if (Read(msg, &p)) {
978 DispatchToMethod(obj, func, p);
979 return true;
980 }
981 return false;
982 }
983
984 // The following dispatchers exist for the case where the callback function
985 // needs the message as well. They assume that "Param" is a type of Tuple
986 // (except the one arg case, as there is no Tuple1).
987 template<class T, typename TA>
988 static bool Dispatch(const Message* msg, T* obj,
989 void (T::*func)(const Message&, TA)) {
990 Param p;
991 if (Read(msg, &p)) {
992 (obj->*func)(*msg, p);
993 return true;
994 }
995 return false;
996 }
997
998 template<class T, typename TA, typename TB>
999 static bool Dispatch(const Message* msg, T* obj,
1000 void (T::*func)(const Message&, TA, TB)) {
1001 Param p;
1002 if (Read(msg, &p)) {
1003 (obj->*func)(*msg, p.a, p.b);
1004 return true;
1005 }
1006 return false;
1007 }
1008
1009 template<class T, typename TA, typename TB, typename TC>
1010 static bool Dispatch(const Message* msg, T* obj,
1011 void (T::*func)(const Message&, TA, TB, TC)) {
1012 Param p;
1013 if (Read(msg, &p)) {
1014 (obj->*func)(*msg, p.a, p.b, p.c);
1015 return true;
1016 }
1017 return false;
1018 }
1019
1020 template<class T, typename TA, typename TB, typename TC, typename TD>
1021 static bool Dispatch(const Message* msg, T* obj,
1022 void (T::*func)(const Message&, TA, TB, TC, TD)) {
1023 Param p;
1024 if (Read(msg, &p)) {
1025 (obj->*func)(*msg, p.a, p.b, p.c, p.d);
1026 return true;
1027 }
1028 return false;
1029 }
1030
1031 template<class T, typename TA, typename TB, typename TC, typename TD,
1032 typename TE>
1033 static bool Dispatch(const Message* msg, T* obj,
1034 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
1035 Param p;
1036 if (Read(msg, &p)) {
1037 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
1038 return true;
1039 }
1040 return false;
1041 }
1042
1043 static void Log(const Message* msg, std::wstring* l) {
1044 Param p;
1045 if (Read(msg, &p))
1046 LogParam(p, l);
1047 }
1048};
1049
1050// This class assumes that its template argument is a RefTuple (a Tuple with
1051// reference elements).
1052template <class RefTuple>
1053class ParamDeserializer : public MessageReplyDeserializer {
1054 public:
[email protected]e1981f432008-08-12 15:22:131055 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:291056
1057 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1058 return ReadParam(&msg, &iter, &out_);
1059 }
1060
1061 RefTuple out_;
1062};
1063
1064// defined in ipc_logging.cc
1065void GenerateLogData(const std::wstring& channel, const Message& message,
1066 LogData* data);
1067
1068// Used for synchronous messages.
1069template <class SendParam, class ReplyParam>
1070class MessageWithReply : public SyncMessage {
1071 public:
1072 MessageWithReply(int32 routing_id, WORD type,
1073 const SendParam& send, const ReplyParam& reply)
1074 : SyncMessage(routing_id, type, PRIORITY_NORMAL,
1075 new ParamDeserializer<ReplyParam>(reply)) {
1076 WriteParam(this, send);
1077 }
1078
1079 static void Log(const Message* msg, std::wstring* l) {
1080 if (msg->is_sync()) {
1081 SendParam p;
1082 void* iter = SyncMessage::GetDataIterator(msg);
1083 ReadParam(msg, &iter, &p);
1084 LogParam(p, l);
1085
1086 const std::wstring& output_params = msg->output_params();
1087 if (!l->empty() && !output_params.empty())
1088 l->append(L", ");
1089
1090 l->append(output_params);
1091 } else {
1092 // This is an outgoing reply. Now that we have the output parameters, we
1093 // can finally log the message.
1094 ReplyParam::ValueTuple p;
1095 void* iter = SyncMessage::GetDataIterator(msg);
1096 ReadParam(msg, &iter, &p);
1097 LogParam(p, l);
1098 }
1099 }
1100
1101 template<class T, class Method>
1102 static bool Dispatch(const Message* msg, T* obj, Method func) {
1103 SendParam send_params;
1104 void* iter = GetDataIterator(msg);
1105 Message* reply = GenerateReply(msg);
1106 bool error;
1107 if (ReadParam(msg, &iter, &send_params)) {
1108 ReplyParam::ValueTuple reply_params;
1109 DispatchToMethod(obj, func, send_params, &reply_params);
1110 WriteParam(reply, reply_params);
1111 error = false;
1112#ifdef IPC_MESSAGE_LOG_ENABLED
1113 if (msg->received_time() != 0) {
1114 std::wstring output_params;
1115 LogParam(reply_params, &output_params);
1116 msg->set_output_params(output_params);
1117 }
1118#endif
1119 } else {
1120 NOTREACHED() << "Error deserializing message " << msg->type();
1121 reply->set_reply_error();
1122 error = true;
1123 }
1124
1125 obj->Send(reply);
1126 return !error;
1127 }
1128
1129 template<class T, class Method>
1130 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
1131 SendParam send_params;
1132 void* iter = GetDataIterator(msg);
1133 Message* reply = GenerateReply(msg);
1134 bool error;
1135 if (ReadParam(msg, &iter, &send_params)) {
1136 Tuple1<Message&> t = MakeRefTuple(*reply);
1137
1138#ifdef IPC_MESSAGE_LOG_ENABLED
1139 if (msg->sent_time()) {
1140 // Don't log the sync message after dispatch, as we don't have the
1141 // output parameters at that point. Instead, save its data and log it
1142 // with the outgoing reply message when it's sent.
1143 LogData* data = new LogData;
1144 GenerateLogData(L"", *msg, data);
1145 msg->set_dont_log();
1146 reply->set_sync_log_data(data);
1147 }
1148#endif
1149 DispatchToMethod(obj, func, send_params, &t);
1150 error = false;
1151 } else {
1152 NOTREACHED() << "Error deserializing message " << msg->type();
1153 reply->set_reply_error();
1154 obj->Send(reply);
1155 error = true;
1156 }
1157 return !error;
1158 }
1159
1160 template<typename TA>
1161 static void WriteReplyParams(Message* reply, TA a) {
1162 ReplyParam p(a);
1163 WriteParam(reply, p);
1164 }
1165
1166 template<typename TA, typename TB>
1167 static void WriteReplyParams(Message* reply, TA a, TB b) {
1168 ReplyParam p(a, b);
1169 WriteParam(reply, p);
1170 }
1171
1172 template<typename TA, typename TB, typename TC>
1173 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1174 ReplyParam p(a, b, c);
1175 WriteParam(reply, p);
1176 }
1177
1178 template<typename TA, typename TB, typename TC, typename TD>
1179 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1180 ReplyParam p(a, b, c, d);
1181 WriteParam(reply, p);
1182 }
1183
1184 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1185 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1186 ReplyParam p(a, b, c, d, e);
1187 WriteParam(reply, p);
1188 }
1189};
1190
1191//-----------------------------------------------------------------------------
[email protected]3178f4e22008-08-05 21:20:411192
1193} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291194
[email protected]e1981f432008-08-12 15:22:131195#endif // CHROME_COMMON_IPC_MESSAGE_UTILS_H_
license.botbf09a502008-08-24 00:55:551196