blob: add9d19f958bee1237e4355f19a839b4884a42ef [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 <>
[email protected]43beaef42008-08-22 23:24:54161struct ParamTraits<long> {
162 typedef long param_type;
163 static void Write(Message* m, const param_type& p) {
164 m->WriteLong(p);
165 }
166 static bool Read(const Message* m, void** iter, param_type* r) {
167 return m->ReadLong(iter, r);
168 }
169 static void Log(const param_type& p, std::wstring* l) {
170 l->append(StringPrintf(L"%l", p));
171 }
172};
173
174template <>
initial.commit09911bf2008-07-26 23:55:29175struct ParamTraits<size_t> {
176 typedef size_t param_type;
177 static void Write(Message* m, const param_type& p) {
178 m->WriteSize(p);
179 }
180 static bool Read(const Message* m, void** iter, param_type* r) {
181 return m->ReadSize(iter, r);
182 }
183 static void Log(const param_type& p, std::wstring* l) {
184 l->append(StringPrintf(L"%u", p));
185 }
186};
187
188template <>
189struct ParamTraits<int64> {
190 typedef int64 param_type;
191 static void Write(Message* m, const param_type& p) {
192 m->WriteInt64(p);
193 }
194 static bool Read(const Message* m, void** iter, param_type* r) {
195 return m->ReadInt64(iter, r);
196 }
197 static void Log(const param_type& p, std::wstring* l) {
198 l->append(StringPrintf(L"%I64d", p));
199 }
200};
201
202template <>
203struct ParamTraits<uint64> {
204 typedef uint64 param_type;
205 static void Write(Message* m, const param_type& p) {
206 m->WriteInt64(static_cast<int64>(p));
207 }
208 static bool Read(const Message* m, void** iter, param_type* r) {
209 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
210 }
211 static void Log(const param_type& p, std::wstring* l) {
212 l->append(StringPrintf(L"%I64u", p));
213 }
214};
215
216template <>
217struct ParamTraits<double> {
218 typedef double param_type;
219 static void Write(Message* m, const param_type& p) {
[email protected]e1981f432008-08-12 15:22:13220 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
initial.commit09911bf2008-07-26 23:55:29221 }
222 static bool Read(const Message* m, void** iter, param_type* r) {
223 const char *data;
224 int data_size = 0;
225 bool result = m->ReadData(iter, &data, &data_size);
[email protected]e1981f432008-08-12 15:22:13226 if (result && data_size == sizeof(param_type)) {
227 memcpy(r, data, sizeof(param_type));
initial.commit09911bf2008-07-26 23:55:29228 } else {
229 result = false;
230 NOTREACHED();
231 }
232
233 return result;
234 }
235 static void Log(const param_type& p, std::wstring* l) {
236 l->append(StringPrintf(L"e", p));
237 }
238};
239
240template <>
241struct ParamTraits<wchar_t> {
242 typedef wchar_t param_type;
243 static void Write(Message* m, const param_type& p) {
[email protected]e1981f432008-08-12 15:22:13244 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
initial.commit09911bf2008-07-26 23:55:29245 }
246 static bool Read(const Message* m, void** iter, param_type* r) {
247 const char *data;
248 int data_size = 0;
249 bool result = m->ReadData(iter, &data, &data_size);
[email protected]e1981f432008-08-12 15:22:13250 if (result && data_size == sizeof(param_type)) {
251 memcpy(r, data, sizeof(param_type));
initial.commit09911bf2008-07-26 23:55:29252 } else {
253 result = false;
254 NOTREACHED();
255 }
256
257 return result;
258 }
259 static void Log(const param_type& p, std::wstring* l) {
[email protected]51154742008-08-14 00:41:45260 l->append(StringPrintf(L"%lc", p));
initial.commit09911bf2008-07-26 23:55:29261 }
262};
263
264template <>
265struct ParamTraits<Time> {
266 typedef Time param_type;
267 static void Write(Message* m, const param_type& p) {
268 ParamTraits<int64>::Write(m, p.ToInternalValue());
269 }
270 static bool Read(const Message* m, void** iter, param_type* r) {
271 int64 value;
272 if (!ParamTraits<int64>::Read(m, iter, &value))
273 return false;
274 *r = Time::FromInternalValue(value);
275 return true;
276 }
277 static void Log(const param_type& p, std::wstring* l) {
278 ParamTraits<int64>::Log(p.ToInternalValue(), l);
279 }
280};
281
282template <>
283struct ParamTraits<LOGFONT> {
284 typedef LOGFONT param_type;
285 static void Write(Message* m, const param_type& p) {
286 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
287 }
288 static bool Read(const Message* m, void** iter, param_type* r) {
289 const char *data;
290 int data_size = 0;
291 bool result = m->ReadData(iter, &data, &data_size);
292 if (result && data_size == sizeof(LOGFONT)) {
293 memcpy(r, data, sizeof(LOGFONT));
294 } else {
295 result = false;
296 NOTREACHED();
297 }
298
299 return result;
300 }
301 static void Log(const param_type& p, std::wstring* l) {
302 l->append(StringPrintf(L"<LOGFONT>"));
303 }
304};
305
306template <>
307struct ParamTraits<MSG> {
308 typedef MSG param_type;
309 static void Write(Message* m, const param_type& p) {
310 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
311 }
312 static bool Read(const Message* m, void** iter, param_type* r) {
313 const char *data;
314 int data_size = 0;
315 bool result = m->ReadData(iter, &data, &data_size);
316 if (result && data_size == sizeof(MSG)) {
317 memcpy(r, data, sizeof(MSG));
318 } else {
319 result = false;
320 NOTREACHED();
321 }
322
323 return result;
324 }
325};
326
initial.commit09911bf2008-07-26 23:55:29327template <>
328struct ParamTraits<SkBitmap> {
329 typedef SkBitmap param_type;
[email protected]e1981f432008-08-12 15:22:13330 static void Write(Message* m, const param_type& p);
331
initial.commit09911bf2008-07-26 23:55:29332 // Note: This function expects parameter |r| to be of type &SkBitmap since
333 // r->SetConfig() and r->SetPixels() are called.
[email protected]e1981f432008-08-12 15:22:13334 static bool Read(const Message* m, void** iter, param_type* r);
initial.commit09911bf2008-07-26 23:55:29335
[email protected]e1981f432008-08-12 15:22:13336 static void Log(const param_type& p, std::wstring* l);
initial.commit09911bf2008-07-26 23:55:29337};
338
339template <>
340struct ParamTraits<MONITORINFOEX> {
341 typedef MONITORINFOEX param_type;
342 static void Write(Message* m, const param_type& p) {
343 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MONITORINFOEX));
344 }
345 static bool Read(const Message* m, void** iter, param_type* r) {
346 const char *data;
347 int data_size = 0;
348 bool result = m->ReadData(iter, &data, &data_size);
349 if (result && data_size == sizeof(MONITORINFOEX)) {
350 memcpy(r, data, sizeof(MONITORINFOEX));
351 } else {
352 result = false;
353 NOTREACHED();
354 }
355
356 return result;
357 }
358 static void Log(const param_type& p, std::wstring* l) {
359 l->append(StringPrintf(L"<MONITORINFOEX>"));
360 }
361};
362
363template <>
364struct ParamTraits<std::string> {
365 typedef std::string param_type;
366 static void Write(Message* m, const param_type& p) {
367 m->WriteString(p);
368 }
369 static bool Read(const Message* m, void** iter, param_type* r) {
370 return m->ReadString(iter, r);
371 }
372 static void Log(const param_type& p, std::wstring* l) {
373 l->append(UTF8ToWide(p));
374 }
375};
376
377template <>
378struct ParamTraits<std::vector<unsigned char> > {
379 typedef std::vector<unsigned char> param_type;
380 static void Write(Message* m, const param_type& p) {
381 if (p.size() == 0) {
382 m->WriteData(NULL, 0);
383 } else {
384 m->WriteData(reinterpret_cast<const char*>(&p.front()),
385 static_cast<int>(p.size()));
386 }
387 }
388 static bool Read(const Message* m, void** iter, param_type* r) {
389 const char *data;
390 int data_size = 0;
391 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
392 return false;
393 r->resize(data_size);
394 if (data_size)
395 memcpy(&r->front(), data, data_size);
396 return true;
397 }
398 static void Log(const param_type& p, std::wstring* l) {
399 for (size_t i = 0; i < p.size(); ++i)
400 l->push_back(p[i]);
401 }
402};
403
404template <>
405struct ParamTraits<std::vector<char> > {
406 typedef std::vector<char> param_type;
407 static void Write(Message* m, const param_type& p) {
408 if (p.size() == 0) {
409 m->WriteData(NULL, 0);
410 } else {
411 m->WriteData(&p.front(), static_cast<int>(p.size()));
412 }
413 }
414 static bool Read(const Message* m, void** iter, param_type* r) {
415 const char *data;
416 int data_size = 0;
417 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
418 return false;
419 r->resize(data_size);
420 if (data_size)
421 memcpy(&r->front(), data, data_size);
422 return true;
423 }
424 static void Log(const param_type& p, std::wstring* l) {
425 for (size_t i = 0; i < p.size(); ++i)
426 l->push_back(p[i]);
427 }
428};
429
430template <class P>
431struct ParamTraits<std::vector<P> > {
432 typedef std::vector<P> param_type;
433 static void Write(Message* m, const param_type& p) {
434 WriteParam(m, static_cast<int>(p.size()));
435 for (size_t i = 0; i < p.size(); i++)
436 WriteParam(m, p[i]);
437 }
438 static bool Read(const Message* m, void** iter, param_type* r) {
439 int size;
440 if (!m->ReadLength(iter, &size))
441 return false;
442 // Resizing beforehand is not safe, see BUG 1006367 for details.
443 if (m->IteratorHasRoomFor(*iter, size * sizeof(P))) {
444 r->resize(size);
445 for (int i = 0; i < size; i++) {
446 if (!ReadParam(m, iter, &(*r)[i]))
447 return false;
448 }
449 } else {
450 for (int i = 0; i < size; i++) {
451 P element;
452 if (!ReadParam(m, iter, &element))
453 return false;
454 r->push_back(element);
455 }
456 }
457 return true;
458 }
459 static void Log(const param_type& p, std::wstring* l) {
460 for (size_t i = 0; i < p.size(); ++i) {
461 if (i != 0)
462 l->append(L" ");
463
464 LogParam((p[i]), l);
465 }
466 }
467};
468
469template <class K, class V>
470struct ParamTraits<std::map<K, V> > {
471 typedef std::map<K, V> param_type;
472 static void Write(Message* m, const param_type& p) {
473 WriteParam(m, static_cast<int>(p.size()));
474 param_type::const_iterator iter;
475 for (iter = p.begin(); iter != p.end(); ++iter) {
476 WriteParam(m, iter->first);
477 WriteParam(m, iter->second);
478 }
479 }
480 static bool Read(const Message* m, void** iter, param_type* r) {
481 int size;
482 if (!ReadParam(m, iter, &size) || size < 0)
483 return false;
484 for (int i = 0; i < size; ++i) {
485 K k;
486 if (!ReadParam(m, iter, &k))
487 return false;
488 V& value = (*r)[k];
489 if (!ReadParam(m, iter, &value))
490 return false;
491 }
492 return true;
493 }
494 static void Log(const param_type& p, std::wstring* l) {
495 l->append(L"<std::map>");
496 }
497};
498
499template <>
500struct ParamTraits<std::wstring> {
501 typedef std::wstring param_type;
502 static void Write(Message* m, const param_type& p) {
503 m->WriteWString(p);
504 }
505 static bool Read(const Message* m, void** iter, param_type* r) {
506 return m->ReadWString(iter, r);
507 }
508 static void Log(const param_type& p, std::wstring* l) {
509 l->append(p);
510 }
511};
512
513template <>
514struct ParamTraits<GURL> {
515 typedef GURL param_type;
[email protected]3178f4e22008-08-05 21:20:41516 static void Write(Message* m, const param_type& p);
517 static bool Read(const Message* m, void** iter, param_type* p);
518 static void Log(const param_type& p, std::wstring* l);
initial.commit09911bf2008-07-26 23:55:29519};
520
521// and, a few more useful types...
522template <>
523struct ParamTraits<HANDLE> {
524 typedef HANDLE param_type;
525 static void Write(Message* m, const param_type& p) {
526 m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
527 }
528 static bool Read(const Message* m, void** iter, param_type* r) {
529 DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
530 return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
531 }
532 static void Log(const param_type& p, std::wstring* l) {
533 l->append(StringPrintf(L"0x%X", p));
534 }
535};
536
537template <>
538struct ParamTraits<HCURSOR> {
539 typedef HCURSOR param_type;
540 static void Write(Message* m, const param_type& p) {
541 m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
542 }
543 static bool Read(const Message* m, void** iter, param_type* r) {
544 DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
545 return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
546 }
547 static void Log(const param_type& p, std::wstring* l) {
548 l->append(StringPrintf(L"0x%X", p));
549 }
550};
551
552template <>
553struct ParamTraits<HWND> {
554 typedef HWND param_type;
555 static void Write(Message* m, const param_type& p) {
556 m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
557 }
558 static bool Read(const Message* m, void** iter, param_type* r) {
559 DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
560 return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
561 }
562 static void Log(const param_type& p, std::wstring* l) {
563 l->append(StringPrintf(L"0x%X", p));
564 }
565};
566
567template <>
568struct ParamTraits<HRGN> {
569 typedef HRGN param_type;
570 static void Write(Message* m, const param_type& p) {
571 int data_size = GetRegionData(p, 0, NULL);
572 if (data_size) {
573 char* bytes = new char[data_size];
574 GetRegionData(p, data_size, reinterpret_cast<LPRGNDATA>(bytes));
575 m->WriteData(reinterpret_cast<const char*>(bytes), data_size);
576 delete [] bytes;
577 } else {
578 m->WriteData(NULL, 0);
579 }
580 }
581 static bool Read(const Message* m, void** iter, param_type* r) {
582 bool res = FALSE;
583 const char *data;
584 int data_size = 0;
585 res = m->ReadData(iter, &data, &data_size);
586 if (data_size) {
587 *r = ExtCreateRegion(NULL, data_size,
588 reinterpret_cast<CONST RGNDATA*>(data));
589 } else {
590 res = TRUE;
591 *r = CreateRectRgn(0, 0, 0, 0);
592 }
593 return res;
594 }
595 static void Log(const param_type& p, std::wstring* l) {
596 l->append(StringPrintf(L"0x%X", p));
597 }
598};
599
600template <>
601struct ParamTraits<HACCEL> {
602 typedef HACCEL param_type;
603 static void Write(Message* m, const param_type& p) {
604 m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
605 }
606 static bool Read(const Message* m, void** iter, param_type* r) {
607 DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
608 return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
609 }
610};
611
612template <>
613struct ParamTraits<POINT> {
614 typedef POINT param_type;
615 static void Write(Message* m, const param_type& p) {
616 m->WriteInt(p.x);
617 m->WriteInt(p.y);
618 }
619 static bool Read(const Message* m, void** iter, param_type* r) {
620 int x, y;
621 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
622 return false;
623 r->x = x;
624 r->y = y;
625 return true;
626 }
627 static void Log(const param_type& p, std::wstring* l) {
628 l->append(StringPrintf(L"(%d, %d)", p.x, p.y));
629 }
630};
631
632template <>
633struct ParamTraits<gfx::Point> {
634 typedef gfx::Point param_type;
[email protected]3178f4e22008-08-05 21:20:41635 static void Write(Message* m, const param_type& p);
636 static bool Read(const Message* m, void** iter, param_type* r);
637 static void Log(const param_type& p, std::wstring* l);
initial.commit09911bf2008-07-26 23:55:29638};
639
640template <>
641struct ParamTraits<gfx::Rect> {
642 typedef gfx::Rect param_type;
[email protected]3178f4e22008-08-05 21:20:41643 static void Write(Message* m, const param_type& p);
644 static bool Read(const Message* m, void** iter, param_type* r);
645 static void Log(const param_type& p, std::wstring* l);
initial.commit09911bf2008-07-26 23:55:29646};
647
648template <>
649struct ParamTraits<gfx::Size> {
650 typedef gfx::Size param_type;
[email protected]3178f4e22008-08-05 21:20:41651 static void Write(Message* m, const param_type& p);
652 static bool Read(const Message* m, void** iter, param_type* r);
653 static void Log(const param_type& p, std::wstring* l);
initial.commit09911bf2008-07-26 23:55:29654};
655
656template<>
657struct ParamTraits<ThumbnailScore> {
658 typedef ThumbnailScore param_type;
659 static void Write(Message* m, const param_type& p) {
660 IPC::ParamTraits<double>::Write(m, p.boring_score);
661 IPC::ParamTraits<bool>::Write(m, p.good_clipping);
662 IPC::ParamTraits<bool>::Write(m, p.at_top);
663 IPC::ParamTraits<Time>::Write(m, p.time_at_snapshot);
664 }
665 static bool Read(const Message* m, void** iter, param_type* r) {
666 double boring_score;
667 bool good_clipping, at_top;
668 Time time_at_snapshot;
669 if (!IPC::ParamTraits<double>::Read(m, iter, &boring_score) ||
670 !IPC::ParamTraits<bool>::Read(m, iter, &good_clipping) ||
671 !IPC::ParamTraits<bool>::Read(m, iter, &at_top) ||
672 !IPC::ParamTraits<Time>::Read(m, iter, &time_at_snapshot))
673 return false;
674
675 r->boring_score = boring_score;
676 r->good_clipping = good_clipping;
677 r->at_top = at_top;
678 r->time_at_snapshot = time_at_snapshot;
679 return true;
680 }
681 static void Log(const param_type& p, std::wstring* l) {
682 l->append(StringPrintf(L"(%f, %d, %d)",
683 p.boring_score, p.good_clipping, p.at_top));
684 }
685};
686
687template <>
688struct ParamTraits<WindowOpenDisposition> {
689 typedef WindowOpenDisposition param_type;
690 static void Write(Message* m, const param_type& p) {
691 m->WriteInt(p);
692 }
693 static bool Read(const Message* m, void** iter, param_type* r) {
694 int temp;
695 bool res = m->ReadInt(iter, &temp);
696 *r = static_cast<WindowOpenDisposition>(temp);
697 return res;
698 }
699 static void Log(const param_type& p, std::wstring* l) {
700 l->append(StringPrintf(L"%d", p));
701 }
702};
703
704template <>
705struct ParamTraits<ConsoleMessageLevel> {
706 typedef ConsoleMessageLevel param_type;
707 static void Write(Message* m, const param_type& p) {
708 m->WriteInt(p);
709 }
710 static bool Read(const Message* m, void** iter, param_type* r) {
711 int temp;
712 bool res = m->ReadInt(iter, &temp);
713 *r = static_cast<ConsoleMessageLevel>(temp);
714 return res;
715 }
716 static void Log(const param_type& p, std::wstring* l) {
717 l->append(StringPrintf(L"%d", p));
718 }
719};
720
721template <>
722struct ParamTraits<CacheManager::ResourceTypeStat> {
723 typedef CacheManager::ResourceTypeStat param_type;
724 static void Write(Message* m, const param_type& p) {
725 WriteParam(m, p.count);
726 WriteParam(m, p.size);
727 WriteParam(m, p.live_size);
728 WriteParam(m, p.decoded_size);
729 }
730 static bool Read(const Message* m, void** iter, param_type* r) {
731 bool result =
732 ReadParam(m, iter, &r->count) &&
733 ReadParam(m, iter, &r->size) &&
734 ReadParam(m, iter, &r->live_size) &&
735 ReadParam(m, iter, &r->decoded_size);
736 return result;
737 }
738 static void Log(const param_type& p, std::wstring* l) {
739 l->append(StringPrintf(L"%d %d %d %d", p.count, p.size, p.live_size,
740 p.decoded_size));
741 }
742};
743
744template <>
745struct ParamTraits<CacheManager::ResourceTypeStats> {
746 typedef CacheManager::ResourceTypeStats param_type;
747 static void Write(Message* m, const param_type& p) {
748 WriteParam(m, p.images);
749 WriteParam(m, p.css_stylesheets);
750 WriteParam(m, p.scripts);
751 WriteParam(m, p.xsl_stylesheets);
752 WriteParam(m, p.fonts);
753 }
754 static bool Read(const Message* m, void** iter, param_type* r) {
755 bool result =
756 ReadParam(m, iter, &r->images) &&
757 ReadParam(m, iter, &r->css_stylesheets) &&
758 ReadParam(m, iter, &r->scripts) &&
759 ReadParam(m, iter, &r->xsl_stylesheets) &&
760 ReadParam(m, iter, &r->fonts);
761 return result;
762 }
763 static void Log(const param_type& p, std::wstring* l) {
764 l->append(L"<WebCoreStats>");
765 LogParam(p.images, l);
766 LogParam(p.css_stylesheets, l);
767 LogParam(p.scripts, l);
768 LogParam(p.xsl_stylesheets, l);
769 LogParam(p.fonts, l);
770 l->append(L"</WebCoreStats>");
771 }
772};
773
774template <>
775struct ParamTraits<XFORM> {
776 typedef XFORM param_type;
777 static void Write(Message* m, const param_type& p) {
778 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
779 }
780 static bool Read(const Message* m, void** iter, param_type* r) {
781 const char *data;
782 int data_size = 0;
783 bool result = m->ReadData(iter, &data, &data_size);
784 if (result && data_size == sizeof(XFORM)) {
785 memcpy(r, data, sizeof(XFORM));
786 } else {
787 result = false;
788 NOTREACHED();
789 }
790
791 return result;
792 }
793 static void Log(const param_type& p, std::wstring* l) {
794 l->append(L"<XFORM>");
795 }
796};
797
initial.commit09911bf2008-07-26 23:55:29798template <>
799struct ParamTraits<WebCursor> {
800 typedef WebCursor param_type;
[email protected]3178f4e22008-08-05 21:20:41801 static void Write(Message* m, const param_type& p);
802 static bool Read(const Message* m, void** iter, param_type* r);
803 static void Log(const param_type& p, std::wstring* l);
initial.commit09911bf2008-07-26 23:55:29804};
805
806struct LogData {
807 std::wstring channel;
808 uint16 type;
809 std::wstring flags;
810 int64 sent; // Time that the message was sent (i.e. at Send()).
[email protected]e1981f432008-08-12 15:22:13811 int64 receive; // Time before it was dispatched (i.e. before calling
812 // OnMessageReceived).
813 int64 dispatch; // Time after it was dispatched (i.e. after calling
814 // OnMessageReceived).
initial.commit09911bf2008-07-26 23:55:29815 std::wstring params;
816};
817
818template <>
819struct ParamTraits<LogData> {
820 typedef LogData param_type;
821 static void Write(Message* m, const param_type& p) {
822 WriteParam(m, p.channel);
823 WriteParam(m, static_cast<int>(p.type));
824 WriteParam(m, p.flags);
825 WriteParam(m, p.sent);
826 WriteParam(m, p.receive);
827 WriteParam(m, p.dispatch);
828 WriteParam(m, p.params);
829 }
830 static bool Read(const Message* m, void** iter, param_type* r) {
831 int type;
832 bool result =
833 ReadParam(m, iter, &r->channel) &&
834 ReadParam(m, iter, &type) &&
835 ReadParam(m, iter, &r->flags) &&
836 ReadParam(m, iter, &r->sent) &&
837 ReadParam(m, iter, &r->receive) &&
838 ReadParam(m, iter, &r->dispatch) &&
839 ReadParam(m, iter, &r->params);
840 r->type = static_cast<uint16>(type);
841 return result;
842 }
843 static void Log(const param_type& p, std::wstring* l) {
844 // Doesn't make sense to implement this!
845 }
846};
847
848template <>
849struct ParamTraits<Tuple0> {
850 typedef Tuple0 param_type;
851 static void Write(Message* m, const param_type& p) {
852 }
853 static bool Read(const Message* m, void** iter, param_type* r) {
854 return true;
855 }
856 static void Log(const param_type& p, std::wstring* l) {
857 }
858};
859
860template <class A>
861struct ParamTraits< Tuple1<A> > {
862 typedef Tuple1<A> param_type;
863 static void Write(Message* m, const param_type& p) {
864 WriteParam(m, p.a);
865 }
866 static bool Read(const Message* m, void** iter, param_type* r) {
867 return ReadParam(m, iter, &r->a);
868 }
869 static void Log(const param_type& p, std::wstring* l) {
870 LogParam(p.a, l);
871 }
872};
873
874template <class A, class B>
875struct ParamTraits< Tuple2<A, B> > {
876 typedef Tuple2<A, B> param_type;
877 static void Write(Message* m, const param_type& p) {
878 WriteParam(m, p.a);
879 WriteParam(m, p.b);
880 }
881 static bool Read(const Message* m, void** iter, param_type* r) {
882 return (ReadParam(m, iter, &r->a) &&
883 ReadParam(m, iter, &r->b));
884 }
885 static void Log(const param_type& p, std::wstring* l) {
886 LogParam(p.a, l);
887 l->append(L", ");
888 LogParam(p.b, l);
889 }
890};
891
892template <class A, class B, class C>
893struct ParamTraits< Tuple3<A, B, C> > {
894 typedef Tuple3<A, B, C> param_type;
895 static void Write(Message* m, const param_type& p) {
896 WriteParam(m, p.a);
897 WriteParam(m, p.b);
898 WriteParam(m, p.c);
899 }
900 static bool Read(const Message* m, void** iter, param_type* r) {
901 return (ReadParam(m, iter, &r->a) &&
902 ReadParam(m, iter, &r->b) &&
903 ReadParam(m, iter, &r->c));
904 }
905 static void Log(const param_type& p, std::wstring* l) {
906 LogParam(p.a, l);
907 l->append(L", ");
908 LogParam(p.b, l);
909 l->append(L", ");
910 LogParam(p.c, l);
911 }
912};
913
914template <class A, class B, class C, class D>
915struct ParamTraits< Tuple4<A, B, C, D> > {
916 typedef Tuple4<A, B, C, D> param_type;
917 static void Write(Message* m, const param_type& p) {
918 WriteParam(m, p.a);
919 WriteParam(m, p.b);
920 WriteParam(m, p.c);
921 WriteParam(m, p.d);
922 }
923 static bool Read(const Message* m, void** iter, param_type* r) {
924 return (ReadParam(m, iter, &r->a) &&
925 ReadParam(m, iter, &r->b) &&
926 ReadParam(m, iter, &r->c) &&
927 ReadParam(m, iter, &r->d));
928 }
929 static void Log(const param_type& p, std::wstring* l) {
930 LogParam(p.a, l);
931 l->append(L", ");
932 LogParam(p.b, l);
933 l->append(L", ");
934 LogParam(p.c, l);
935 l->append(L", ");
936 LogParam(p.d, l);
937 }
938};
939
940template <class A, class B, class C, class D, class E>
941struct ParamTraits< Tuple5<A, B, C, D, E> > {
942 typedef Tuple5<A, B, C, D, E> param_type;
943 static void Write(Message* m, const param_type& p) {
944 WriteParam(m, p.a);
945 WriteParam(m, p.b);
946 WriteParam(m, p.c);
947 WriteParam(m, p.d);
948 WriteParam(m, p.e);
949 }
950 static bool Read(const Message* m, void** iter, param_type* r) {
951 return (ReadParam(m, iter, &r->a) &&
952 ReadParam(m, iter, &r->b) &&
953 ReadParam(m, iter, &r->c) &&
954 ReadParam(m, iter, &r->d) &&
955 ReadParam(m, iter, &r->e));
956 }
957 static void Log(const param_type& p, std::wstring* l) {
958 LogParam(p.a, l);
959 l->append(L", ");
960 LogParam(p.b, l);
961 l->append(L", ");
962 LogParam(p.c, l);
963 l->append(L", ");
964 LogParam(p.d, l);
965 l->append(L", ");
966 LogParam(p.e, l);
967 }
968};
969
970template <>
971struct ParamTraits<webkit_glue::WebApplicationInfo> {
972 typedef webkit_glue::WebApplicationInfo param_type;
[email protected]3178f4e22008-08-05 21:20:41973 static void Write(Message* m, const param_type& p);
974 static bool Read(const Message* m, void** iter, param_type* r);
975 static void Log(const param_type& p, std::wstring* l);
initial.commit09911bf2008-07-26 23:55:29976};
977
978
979//-----------------------------------------------------------------------------
980// Generic message subclasses
981
982// Used for asynchronous messages.
983template <class Param>
984class MessageWithTuple : public Message {
985 public:
986 MessageWithTuple(int32 routing_id, WORD type, const Param& p)
987 : Message(routing_id, type, PRIORITY_NORMAL) {
988 WriteParam(this, p);
989 }
990
991 static bool Read(const Message* msg, Param* p) {
992 void* iter = NULL;
993 bool rv = ReadParam(msg, &iter, p);
994 DCHECK(rv) << "Error deserializing message " << msg->type();
995 return rv;
996 }
997
998 // Generic dispatcher. Should cover most cases.
999 template<class T, class Method>
1000 static bool Dispatch(const Message* msg, T* obj, Method func) {
1001 Param p;
1002 if (Read(msg, &p)) {
1003 DispatchToMethod(obj, func, p);
1004 return true;
1005 }
1006 return false;
1007 }
1008
1009 // The following dispatchers exist for the case where the callback function
1010 // needs the message as well. They assume that "Param" is a type of Tuple
1011 // (except the one arg case, as there is no Tuple1).
1012 template<class T, typename TA>
1013 static bool Dispatch(const Message* msg, T* obj,
1014 void (T::*func)(const Message&, TA)) {
1015 Param p;
1016 if (Read(msg, &p)) {
1017 (obj->*func)(*msg, p);
1018 return true;
1019 }
1020 return false;
1021 }
1022
1023 template<class T, typename TA, typename TB>
1024 static bool Dispatch(const Message* msg, T* obj,
1025 void (T::*func)(const Message&, TA, TB)) {
1026 Param p;
1027 if (Read(msg, &p)) {
1028 (obj->*func)(*msg, p.a, p.b);
1029 return true;
1030 }
1031 return false;
1032 }
1033
1034 template<class T, typename TA, typename TB, typename TC>
1035 static bool Dispatch(const Message* msg, T* obj,
1036 void (T::*func)(const Message&, TA, TB, TC)) {
1037 Param p;
1038 if (Read(msg, &p)) {
1039 (obj->*func)(*msg, p.a, p.b, p.c);
1040 return true;
1041 }
1042 return false;
1043 }
1044
1045 template<class T, typename TA, typename TB, typename TC, typename TD>
1046 static bool Dispatch(const Message* msg, T* obj,
1047 void (T::*func)(const Message&, TA, TB, TC, TD)) {
1048 Param p;
1049 if (Read(msg, &p)) {
1050 (obj->*func)(*msg, p.a, p.b, p.c, p.d);
1051 return true;
1052 }
1053 return false;
1054 }
1055
1056 template<class T, typename TA, typename TB, typename TC, typename TD,
1057 typename TE>
1058 static bool Dispatch(const Message* msg, T* obj,
1059 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
1060 Param p;
1061 if (Read(msg, &p)) {
1062 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
1063 return true;
1064 }
1065 return false;
1066 }
1067
1068 static void Log(const Message* msg, std::wstring* l) {
1069 Param p;
1070 if (Read(msg, &p))
1071 LogParam(p, l);
1072 }
1073};
1074
1075// This class assumes that its template argument is a RefTuple (a Tuple with
1076// reference elements).
1077template <class RefTuple>
1078class ParamDeserializer : public MessageReplyDeserializer {
1079 public:
[email protected]e1981f432008-08-12 15:22:131080 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:291081
1082 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1083 return ReadParam(&msg, &iter, &out_);
1084 }
1085
1086 RefTuple out_;
1087};
1088
1089// defined in ipc_logging.cc
1090void GenerateLogData(const std::wstring& channel, const Message& message,
1091 LogData* data);
1092
1093// Used for synchronous messages.
1094template <class SendParam, class ReplyParam>
1095class MessageWithReply : public SyncMessage {
1096 public:
1097 MessageWithReply(int32 routing_id, WORD type,
1098 const SendParam& send, const ReplyParam& reply)
1099 : SyncMessage(routing_id, type, PRIORITY_NORMAL,
1100 new ParamDeserializer<ReplyParam>(reply)) {
1101 WriteParam(this, send);
1102 }
1103
1104 static void Log(const Message* msg, std::wstring* l) {
1105 if (msg->is_sync()) {
1106 SendParam p;
1107 void* iter = SyncMessage::GetDataIterator(msg);
1108 ReadParam(msg, &iter, &p);
1109 LogParam(p, l);
1110
1111 const std::wstring& output_params = msg->output_params();
1112 if (!l->empty() && !output_params.empty())
1113 l->append(L", ");
1114
1115 l->append(output_params);
1116 } else {
1117 // This is an outgoing reply. Now that we have the output parameters, we
1118 // can finally log the message.
1119 ReplyParam::ValueTuple p;
1120 void* iter = SyncMessage::GetDataIterator(msg);
1121 ReadParam(msg, &iter, &p);
1122 LogParam(p, l);
1123 }
1124 }
1125
1126 template<class T, class Method>
1127 static bool Dispatch(const Message* msg, T* obj, Method func) {
1128 SendParam send_params;
1129 void* iter = GetDataIterator(msg);
1130 Message* reply = GenerateReply(msg);
1131 bool error;
1132 if (ReadParam(msg, &iter, &send_params)) {
1133 ReplyParam::ValueTuple reply_params;
1134 DispatchToMethod(obj, func, send_params, &reply_params);
1135 WriteParam(reply, reply_params);
1136 error = false;
1137#ifdef IPC_MESSAGE_LOG_ENABLED
1138 if (msg->received_time() != 0) {
1139 std::wstring output_params;
1140 LogParam(reply_params, &output_params);
1141 msg->set_output_params(output_params);
1142 }
1143#endif
1144 } else {
1145 NOTREACHED() << "Error deserializing message " << msg->type();
1146 reply->set_reply_error();
1147 error = true;
1148 }
1149
1150 obj->Send(reply);
1151 return !error;
1152 }
1153
1154 template<class T, class Method>
1155 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
1156 SendParam send_params;
1157 void* iter = GetDataIterator(msg);
1158 Message* reply = GenerateReply(msg);
1159 bool error;
1160 if (ReadParam(msg, &iter, &send_params)) {
1161 Tuple1<Message&> t = MakeRefTuple(*reply);
1162
1163#ifdef IPC_MESSAGE_LOG_ENABLED
1164 if (msg->sent_time()) {
1165 // Don't log the sync message after dispatch, as we don't have the
1166 // output parameters at that point. Instead, save its data and log it
1167 // with the outgoing reply message when it's sent.
1168 LogData* data = new LogData;
1169 GenerateLogData(L"", *msg, data);
1170 msg->set_dont_log();
1171 reply->set_sync_log_data(data);
1172 }
1173#endif
1174 DispatchToMethod(obj, func, send_params, &t);
1175 error = false;
1176 } else {
1177 NOTREACHED() << "Error deserializing message " << msg->type();
1178 reply->set_reply_error();
1179 obj->Send(reply);
1180 error = true;
1181 }
1182 return !error;
1183 }
1184
1185 template<typename TA>
1186 static void WriteReplyParams(Message* reply, TA a) {
1187 ReplyParam p(a);
1188 WriteParam(reply, p);
1189 }
1190
1191 template<typename TA, typename TB>
1192 static void WriteReplyParams(Message* reply, TA a, TB b) {
1193 ReplyParam p(a, b);
1194 WriteParam(reply, p);
1195 }
1196
1197 template<typename TA, typename TB, typename TC>
1198 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1199 ReplyParam p(a, b, c);
1200 WriteParam(reply, p);
1201 }
1202
1203 template<typename TA, typename TB, typename TC, typename TD>
1204 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1205 ReplyParam p(a, b, c, d);
1206 WriteParam(reply, p);
1207 }
1208
1209 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1210 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1211 ReplyParam p(a, b, c, d, e);
1212 WriteParam(reply, p);
1213 }
1214};
1215
1216//-----------------------------------------------------------------------------
[email protected]3178f4e22008-08-05 21:20:411217
1218} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291219
[email protected]e1981f432008-08-12 15:22:131220#endif // CHROME_COMMON_IPC_MESSAGE_UTILS_H_