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