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