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