blob: 7887dcc0f07ae62760e1848546aa7993452fe40b [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)
16#include "chrome/common/file_descriptor_posix.h"
17#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<>
671struct ParamTraits<FileDescriptor> {
672 typedef FileDescriptor param_type;
673 static void Write(Message* m, const param_type& p) {
674 if (p.auto_close) {
675 m->descriptor_set()->AddAndAutoClose(p.fd);
676 } else {
677 m->descriptor_set()->Add(p.fd);
678 }
679 }
680 static bool Read(const Message* m, void** iter, param_type* r) {
681 r->auto_close = false;
682 r->fd = m->descriptor_set()->NextDescriptor();
683
684 return r->fd >= 0;
685 }
686 static void Log(const param_type& p, std::wstring* l) {
687 if (p.auto_close) {
688 l->append(StringPrintf(L"FD(%d auto-close)", p.fd));
689 } else {
690 l->append(StringPrintf(L"FD(%d)", p.fd));
691 }
692 }
693};
694
695#endif // defined(OS_POSIX)
696
[email protected]7d5c3ac2009-02-04 08:58:19697template<>
698struct ParamTraits<ThumbnailScore> {
699 typedef ThumbnailScore param_type;
700 static void Write(Message* m, const param_type& p) {
701 IPC::ParamTraits<double>::Write(m, p.boring_score);
702 IPC::ParamTraits<bool>::Write(m, p.good_clipping);
703 IPC::ParamTraits<bool>::Write(m, p.at_top);
704 IPC::ParamTraits<base::Time>::Write(m, p.time_at_snapshot);
705 }
706 static bool Read(const Message* m, void** iter, param_type* r) {
707 double boring_score;
708 bool good_clipping, at_top;
709 base::Time time_at_snapshot;
710 if (!IPC::ParamTraits<double>::Read(m, iter, &boring_score) ||
711 !IPC::ParamTraits<bool>::Read(m, iter, &good_clipping) ||
712 !IPC::ParamTraits<bool>::Read(m, iter, &at_top) ||
713 !IPC::ParamTraits<base::Time>::Read(m, iter, &time_at_snapshot))
714 return false;
715
716 r->boring_score = boring_score;
717 r->good_clipping = good_clipping;
718 r->at_top = at_top;
719 r->time_at_snapshot = time_at_snapshot;
720 return true;
721 }
722 static void Log(const param_type& p, std::wstring* l) {
723 l->append(StringPrintf(L"(%f, %d, %d)",
724 p.boring_score, p.good_clipping, p.at_top));
725 }
726};
727
728template <>
729struct ParamTraits<WindowOpenDisposition> {
730 typedef WindowOpenDisposition param_type;
731 static void Write(Message* m, const param_type& p) {
732 m->WriteInt(p);
733 }
734 static bool Read(const Message* m, void** iter, param_type* r) {
735 int temp;
736 bool res = m->ReadInt(iter, &temp);
737 *r = static_cast<WindowOpenDisposition>(temp);
738 return res;
739 }
740 static void Log(const param_type& p, std::wstring* l) {
741 l->append(StringPrintf(L"%d", p));
742 }
743};
744
745template <>
746struct ParamTraits<ConsoleMessageLevel> {
747 typedef ConsoleMessageLevel param_type;
748 static void Write(Message* m, const param_type& p) {
749 m->WriteInt(p);
750 }
751 static bool Read(const Message* m, void** iter, param_type* r) {
752 int temp;
753 bool res = m->ReadInt(iter, &temp);
754 *r = static_cast<ConsoleMessageLevel>(temp);
755 return res;
756 }
757 static void Log(const param_type& p, std::wstring* l) {
758 l->append(StringPrintf(L"%d", p));
759 }
760};
761
762template <>
763struct ParamTraits<CacheManager::ResourceTypeStat> {
764 typedef CacheManager::ResourceTypeStat param_type;
765 static void Write(Message* m, const param_type& p) {
766 WriteParam(m, p.count);
767 WriteParam(m, p.size);
768 WriteParam(m, p.live_size);
769 WriteParam(m, p.decoded_size);
770 }
771 static bool Read(const Message* m, void** iter, param_type* r) {
772 bool result =
773 ReadParam(m, iter, &r->count) &&
774 ReadParam(m, iter, &r->size) &&
775 ReadParam(m, iter, &r->live_size) &&
776 ReadParam(m, iter, &r->decoded_size);
777 return result;
778 }
779 static void Log(const param_type& p, std::wstring* l) {
780 l->append(StringPrintf(L"%d %d %d %d", p.count, p.size, p.live_size,
781 p.decoded_size));
782 }
783};
784
785template <>
786struct ParamTraits<CacheManager::ResourceTypeStats> {
787 typedef CacheManager::ResourceTypeStats param_type;
788 static void Write(Message* m, const param_type& p) {
789 WriteParam(m, p.images);
790 WriteParam(m, p.css_stylesheets);
791 WriteParam(m, p.scripts);
792 WriteParam(m, p.xsl_stylesheets);
793 WriteParam(m, p.fonts);
794 }
795 static bool Read(const Message* m, void** iter, param_type* r) {
796 bool result =
797 ReadParam(m, iter, &r->images) &&
798 ReadParam(m, iter, &r->css_stylesheets) &&
799 ReadParam(m, iter, &r->scripts) &&
800 ReadParam(m, iter, &r->xsl_stylesheets) &&
801 ReadParam(m, iter, &r->fonts);
802 return result;
803 }
804 static void Log(const param_type& p, std::wstring* l) {
805 l->append(L"<WebCoreStats>");
806 LogParam(p.images, l);
807 LogParam(p.css_stylesheets, l);
808 LogParam(p.scripts, l);
809 LogParam(p.xsl_stylesheets, l);
810 LogParam(p.fonts, l);
811 l->append(L"</WebCoreStats>");
812 }
813};
814
815#if defined(OS_WIN)
816template <>
817struct ParamTraits<XFORM> {
818 typedef XFORM param_type;
819 static void Write(Message* m, const param_type& p) {
820 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
821 }
822 static bool Read(const Message* m, void** iter, param_type* r) {
823 const char *data;
824 int data_size = 0;
825 bool result = m->ReadData(iter, &data, &data_size);
826 if (result && data_size == sizeof(XFORM)) {
827 memcpy(r, data, sizeof(XFORM));
828 } else {
829 result = false;
830 NOTREACHED();
831 }
832
833 return result;
834 }
835 static void Log(const param_type& p, std::wstring* l) {
836 l->append(L"<XFORM>");
837 }
838};
839#endif // defined(OS_WIN)
840
841template <>
842struct ParamTraits<WebCursor> {
843 typedef WebCursor param_type;
844 static void Write(Message* m, const param_type& p) {
845 p.Serialize(m);
846 }
847 static bool Read(const Message* m, void** iter, param_type* r) {
848 return r->Deserialize(m, iter);
849 }
850 static void Log(const param_type& p, std::wstring* l) {
851 l->append(L"<WebCursor>");
852 }
853};
854
855struct LogData {
856 std::wstring channel;
857 uint16 type;
858 std::wstring flags;
859 int64 sent; // Time that the message was sent (i.e. at Send()).
860 int64 receive; // Time before it was dispatched (i.e. before calling
861 // OnMessageReceived).
862 int64 dispatch; // Time after it was dispatched (i.e. after calling
863 // OnMessageReceived).
864 std::wstring params;
865};
866
867template <>
868struct ParamTraits<LogData> {
869 typedef LogData param_type;
870 static void Write(Message* m, const param_type& p) {
871 WriteParam(m, p.channel);
872 WriteParam(m, static_cast<int>(p.type));
873 WriteParam(m, p.flags);
874 WriteParam(m, p.sent);
875 WriteParam(m, p.receive);
876 WriteParam(m, p.dispatch);
877 WriteParam(m, p.params);
878 }
879 static bool Read(const Message* m, void** iter, param_type* r) {
880 int type;
881 bool result =
882 ReadParam(m, iter, &r->channel) &&
883 ReadParam(m, iter, &type) &&
884 ReadParam(m, iter, &r->flags) &&
885 ReadParam(m, iter, &r->sent) &&
886 ReadParam(m, iter, &r->receive) &&
887 ReadParam(m, iter, &r->dispatch) &&
888 ReadParam(m, iter, &r->params);
889 r->type = static_cast<uint16>(type);
890 return result;
891 }
892 static void Log(const param_type& p, std::wstring* l) {
893 // Doesn't make sense to implement this!
894 }
895};
896
897template <>
898struct ParamTraits<Tuple0> {
899 typedef Tuple0 param_type;
900 static void Write(Message* m, const param_type& p) {
901 }
902 static bool Read(const Message* m, void** iter, param_type* r) {
903 return true;
904 }
905 static void Log(const param_type& p, std::wstring* l) {
906 }
907};
908
909template <class A>
910struct ParamTraits< Tuple1<A> > {
911 typedef Tuple1<A> param_type;
912 static void Write(Message* m, const param_type& p) {
913 WriteParam(m, p.a);
914 }
915 static bool Read(const Message* m, void** iter, param_type* r) {
916 return ReadParam(m, iter, &r->a);
917 }
918 static void Log(const param_type& p, std::wstring* l) {
919 LogParam(p.a, l);
920 }
921};
922
923template <class A, class B>
924struct ParamTraits< Tuple2<A, B> > {
925 typedef Tuple2<A, B> param_type;
926 static void Write(Message* m, const param_type& p) {
927 WriteParam(m, p.a);
928 WriteParam(m, p.b);
929 }
930 static bool Read(const Message* m, void** iter, param_type* r) {
931 return (ReadParam(m, iter, &r->a) &&
932 ReadParam(m, iter, &r->b));
933 }
934 static void Log(const param_type& p, std::wstring* l) {
935 LogParam(p.a, l);
936 l->append(L", ");
937 LogParam(p.b, l);
938 }
939};
940
941template <class A, class B, class C>
942struct ParamTraits< Tuple3<A, B, C> > {
943 typedef Tuple3<A, B, C> param_type;
944 static void Write(Message* m, const param_type& p) {
945 WriteParam(m, p.a);
946 WriteParam(m, p.b);
947 WriteParam(m, p.c);
948 }
949 static bool Read(const Message* m, void** iter, param_type* r) {
950 return (ReadParam(m, iter, &r->a) &&
951 ReadParam(m, iter, &r->b) &&
952 ReadParam(m, iter, &r->c));
953 }
954 static void Log(const param_type& p, std::wstring* l) {
955 LogParam(p.a, l);
956 l->append(L", ");
957 LogParam(p.b, l);
958 l->append(L", ");
959 LogParam(p.c, l);
960 }
961};
962
963template <class A, class B, class C, class D>
964struct ParamTraits< Tuple4<A, B, C, D> > {
965 typedef Tuple4<A, B, C, D> param_type;
966 static void Write(Message* m, const param_type& p) {
967 WriteParam(m, p.a);
968 WriteParam(m, p.b);
969 WriteParam(m, p.c);
970 WriteParam(m, p.d);
971 }
972 static bool Read(const Message* m, void** iter, param_type* r) {
973 return (ReadParam(m, iter, &r->a) &&
974 ReadParam(m, iter, &r->b) &&
975 ReadParam(m, iter, &r->c) &&
976 ReadParam(m, iter, &r->d));
977 }
978 static void Log(const param_type& p, std::wstring* l) {
979 LogParam(p.a, l);
980 l->append(L", ");
981 LogParam(p.b, l);
982 l->append(L", ");
983 LogParam(p.c, l);
984 l->append(L", ");
985 LogParam(p.d, l);
986 }
987};
988
989template <class A, class B, class C, class D, class E>
990struct ParamTraits< Tuple5<A, B, C, D, E> > {
991 typedef Tuple5<A, B, C, D, E> param_type;
992 static void Write(Message* m, const param_type& p) {
993 WriteParam(m, p.a);
994 WriteParam(m, p.b);
995 WriteParam(m, p.c);
996 WriteParam(m, p.d);
997 WriteParam(m, p.e);
998 }
999 static bool Read(const Message* m, void** iter, param_type* r) {
1000 return (ReadParam(m, iter, &r->a) &&
1001 ReadParam(m, iter, &r->b) &&
1002 ReadParam(m, iter, &r->c) &&
1003 ReadParam(m, iter, &r->d) &&
1004 ReadParam(m, iter, &r->e));
1005 }
1006 static void Log(const param_type& p, std::wstring* l) {
1007 LogParam(p.a, l);
1008 l->append(L", ");
1009 LogParam(p.b, l);
1010 l->append(L", ");
1011 LogParam(p.c, l);
1012 l->append(L", ");
1013 LogParam(p.d, l);
1014 l->append(L", ");
1015 LogParam(p.e, l);
1016 }
1017};
1018
1019template <class A, class B, class C, class D, class E, class F>
1020struct ParamTraits< Tuple6<A, B, C, D, E, F> > {
1021 typedef Tuple6<A, B, C, D, E, F> param_type;
1022 static void Write(Message* m, const param_type& p) {
1023 WriteParam(m, p.a);
1024 WriteParam(m, p.b);
1025 WriteParam(m, p.c);
1026 WriteParam(m, p.d);
1027 WriteParam(m, p.e);
1028 WriteParam(m, p.f);
1029 }
1030 static bool Read(const Message* m, void** iter, param_type* r) {
1031 return (ReadParam(m, iter, &r->a) &&
1032 ReadParam(m, iter, &r->b) &&
1033 ReadParam(m, iter, &r->c) &&
1034 ReadParam(m, iter, &r->d) &&
1035 ReadParam(m, iter, &r->e) &&
1036 ReadParam(m, iter, &r->f));
1037 }
1038 static void Log(const param_type& p, std::wstring* l) {
1039 LogParam(p.a, l);
1040 l->append(L", ");
1041 LogParam(p.b, l);
1042 l->append(L", ");
1043 LogParam(p.c, l);
1044 l->append(L", ");
1045 LogParam(p.d, l);
1046 l->append(L", ");
1047 LogParam(p.e, l);
1048 l->append(L", ");
1049 LogParam(p.f, l);
1050 }
1051};
1052
1053template <>
1054struct ParamTraits<webkit_glue::WebApplicationInfo> {
1055 typedef webkit_glue::WebApplicationInfo param_type;
1056 static void Write(Message* m, const param_type& p);
1057 static bool Read(const Message* m, void** iter, param_type* r);
1058 static void Log(const param_type& p, std::wstring* l);
1059};
1060
1061
1062//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:291063// Generic message subclasses
1064
1065// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:241066template <class ParamType>
initial.commit09911bf2008-07-26 23:55:291067class MessageWithTuple : public Message {
1068 public:
[email protected]81a34412009-01-05 19:17:241069 typedef ParamType Param;
1070
[email protected]d4651ff2008-12-02 16:51:581071 MessageWithTuple(int32 routing_id, uint16 type, const Param& p)
initial.commit09911bf2008-07-26 23:55:291072 : Message(routing_id, type, PRIORITY_NORMAL) {
1073 WriteParam(this, p);
1074 }
1075
[email protected]7d5c3ac2009-02-04 08:58:191076 static bool Read(const Message* msg, Param* p) {
initial.commit09911bf2008-07-26 23:55:291077 void* iter = NULL;
1078 bool rv = ReadParam(msg, &iter, p);
1079 DCHECK(rv) << "Error deserializing message " << msg->type();
1080 return rv;
1081 }
1082
1083 // Generic dispatcher. Should cover most cases.
1084 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191085 static bool Dispatch(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291086 Param p;
1087 if (Read(msg, &p)) {
1088 DispatchToMethod(obj, func, p);
1089 return true;
1090 }
1091 return false;
1092 }
1093
1094 // The following dispatchers exist for the case where the callback function
1095 // needs the message as well. They assume that "Param" is a type of Tuple
1096 // (except the one arg case, as there is no Tuple1).
1097 template<class T, typename TA>
[email protected]7d5c3ac2009-02-04 08:58:191098 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291099 void (T::*func)(const Message&, TA)) {
1100 Param p;
1101 if (Read(msg, &p)) {
1102 (obj->*func)(*msg, p);
1103 return true;
1104 }
1105 return false;
1106 }
1107
1108 template<class T, typename TA, typename TB>
[email protected]7d5c3ac2009-02-04 08:58:191109 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291110 void (T::*func)(const Message&, TA, TB)) {
1111 Param p;
1112 if (Read(msg, &p)) {
1113 (obj->*func)(*msg, p.a, p.b);
1114 return true;
1115 }
1116 return false;
1117 }
1118
1119 template<class T, typename TA, typename TB, typename TC>
[email protected]7d5c3ac2009-02-04 08:58:191120 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291121 void (T::*func)(const Message&, TA, TB, TC)) {
1122 Param p;
1123 if (Read(msg, &p)) {
1124 (obj->*func)(*msg, p.a, p.b, p.c);
1125 return true;
1126 }
1127 return false;
1128 }
1129
1130 template<class T, typename TA, typename TB, typename TC, typename TD>
[email protected]7d5c3ac2009-02-04 08:58:191131 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291132 void (T::*func)(const Message&, TA, TB, TC, TD)) {
1133 Param p;
1134 if (Read(msg, &p)) {
1135 (obj->*func)(*msg, p.a, p.b, p.c, p.d);
1136 return true;
1137 }
1138 return false;
1139 }
1140
1141 template<class T, typename TA, typename TB, typename TC, typename TD,
1142 typename TE>
[email protected]7d5c3ac2009-02-04 08:58:191143 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291144 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
1145 Param p;
1146 if (Read(msg, &p)) {
1147 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
1148 return true;
1149 }
1150 return false;
1151 }
1152
[email protected]7d5c3ac2009-02-04 08:58:191153 static void Log(const Message* msg, std::wstring* l) {
initial.commit09911bf2008-07-26 23:55:291154 Param p;
1155 if (Read(msg, &p))
1156 LogParam(p, l);
1157 }
[email protected]deb57402009-02-06 01:35:301158
1159 // Functions used to do manual unpacking. Only used by the automation code,
1160 // these should go away once that code uses SyncChannel.
1161 template<typename TA, typename TB>
1162 static bool Read(const IPC::Message* msg, TA* a, TB* b) {
1163 ParamType params;
1164 if (!Read(msg, &params))
1165 return false;
1166 *a = params.a;
1167 *b = params.b;
1168 return true;
1169 }
1170
1171 template<typename TA, typename TB, typename TC>
1172 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
1173 ParamType params;
1174 if (!Read(msg, &params))
1175 return false;
1176 *a = params.a;
1177 *b = params.b;
1178 *c = params.c;
1179 return true;
1180 }
1181
1182 template<typename TA, typename TB, typename TC, typename TD>
1183 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) {
1184 ParamType params;
1185 if (!Read(msg, &params))
1186 return false;
1187 *a = params.a;
1188 *b = params.b;
1189 *c = params.c;
1190 *d = params.d;
1191 return true;
1192 }
1193
1194 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1195 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) {
1196 ParamType params;
1197 if (!Read(msg, &params))
1198 return false;
1199 *a = params.a;
1200 *b = params.b;
1201 *c = params.c;
1202 *d = params.d;
1203 *e = params.e;
1204 return true;
1205 }
initial.commit09911bf2008-07-26 23:55:291206};
1207
1208// This class assumes that its template argument is a RefTuple (a Tuple with
1209// reference elements).
1210template <class RefTuple>
1211class ParamDeserializer : public MessageReplyDeserializer {
1212 public:
[email protected]e1981f432008-08-12 15:22:131213 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:291214
1215 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1216 return ReadParam(&msg, &iter, &out_);
1217 }
1218
1219 RefTuple out_;
1220};
1221
1222// defined in ipc_logging.cc
1223void GenerateLogData(const std::wstring& channel, const Message& message,
1224 LogData* data);
1225
1226// Used for synchronous messages.
1227template <class SendParam, class ReplyParam>
1228class MessageWithReply : public SyncMessage {
1229 public:
[email protected]d4651ff2008-12-02 16:51:581230 MessageWithReply(int32 routing_id, uint16 type,
initial.commit09911bf2008-07-26 23:55:291231 const SendParam& send, const ReplyParam& reply)
1232 : SyncMessage(routing_id, type, PRIORITY_NORMAL,
1233 new ParamDeserializer<ReplyParam>(reply)) {
1234 WriteParam(this, send);
1235 }
1236
[email protected]7d5c3ac2009-02-04 08:58:191237 static void Log(const Message* msg, std::wstring* l) {
initial.commit09911bf2008-07-26 23:55:291238 if (msg->is_sync()) {
1239 SendParam p;
1240 void* iter = SyncMessage::GetDataIterator(msg);
1241 ReadParam(msg, &iter, &p);
1242 LogParam(p, l);
1243
[email protected]1156f7b2008-12-04 19:13:591244#if defined(IPC_MESSAGE_LOG_ENABLED)
initial.commit09911bf2008-07-26 23:55:291245 const std::wstring& output_params = msg->output_params();
1246 if (!l->empty() && !output_params.empty())
1247 l->append(L", ");
1248
1249 l->append(output_params);
[email protected]2a34f9c2008-12-04 19:12:041250#endif
initial.commit09911bf2008-07-26 23:55:291251 } else {
1252 // This is an outgoing reply. Now that we have the output parameters, we
1253 // can finally log the message.
[email protected]d4651ff2008-12-02 16:51:581254 typename ReplyParam::ValueTuple p;
initial.commit09911bf2008-07-26 23:55:291255 void* iter = SyncMessage::GetDataIterator(msg);
1256 ReadParam(msg, &iter, &p);
1257 LogParam(p, l);
1258 }
1259 }
1260
1261 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191262 static bool Dispatch(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291263 SendParam send_params;
1264 void* iter = GetDataIterator(msg);
1265 Message* reply = GenerateReply(msg);
1266 bool error;
1267 if (ReadParam(msg, &iter, &send_params)) {
[email protected]d4651ff2008-12-02 16:51:581268 typename ReplyParam::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:291269 DispatchToMethod(obj, func, send_params, &reply_params);
1270 WriteParam(reply, reply_params);
1271 error = false;
1272#ifdef IPC_MESSAGE_LOG_ENABLED
1273 if (msg->received_time() != 0) {
1274 std::wstring output_params;
1275 LogParam(reply_params, &output_params);
1276 msg->set_output_params(output_params);
1277 }
1278#endif
1279 } else {
1280 NOTREACHED() << "Error deserializing message " << msg->type();
1281 reply->set_reply_error();
1282 error = true;
1283 }
1284
1285 obj->Send(reply);
1286 return !error;
1287 }
1288
1289 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191290 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291291 SendParam send_params;
1292 void* iter = GetDataIterator(msg);
1293 Message* reply = GenerateReply(msg);
1294 bool error;
1295 if (ReadParam(msg, &iter, &send_params)) {
1296 Tuple1<Message&> t = MakeRefTuple(*reply);
1297
1298#ifdef IPC_MESSAGE_LOG_ENABLED
1299 if (msg->sent_time()) {
1300 // Don't log the sync message after dispatch, as we don't have the
1301 // output parameters at that point. Instead, save its data and log it
1302 // with the outgoing reply message when it's sent.
1303 LogData* data = new LogData;
1304 GenerateLogData(L"", *msg, data);
1305 msg->set_dont_log();
1306 reply->set_sync_log_data(data);
1307 }
1308#endif
1309 DispatchToMethod(obj, func, send_params, &t);
1310 error = false;
1311 } else {
1312 NOTREACHED() << "Error deserializing message " << msg->type();
1313 reply->set_reply_error();
1314 obj->Send(reply);
1315 error = true;
1316 }
1317 return !error;
1318 }
1319
1320 template<typename TA>
1321 static void WriteReplyParams(Message* reply, TA a) {
1322 ReplyParam p(a);
1323 WriteParam(reply, p);
1324 }
1325
1326 template<typename TA, typename TB>
1327 static void WriteReplyParams(Message* reply, TA a, TB b) {
1328 ReplyParam p(a, b);
1329 WriteParam(reply, p);
1330 }
1331
1332 template<typename TA, typename TB, typename TC>
1333 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1334 ReplyParam p(a, b, c);
1335 WriteParam(reply, p);
1336 }
1337
1338 template<typename TA, typename TB, typename TC, typename TD>
1339 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1340 ReplyParam p(a, b, c, d);
1341 WriteParam(reply, p);
1342 }
1343
1344 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1345 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1346 ReplyParam p(a, b, c, d, e);
1347 WriteParam(reply, p);
1348 }
1349};
1350
[email protected]7d5c3ac2009-02-04 08:58:191351// Traits for ViewMsg_FindInPageMsg_Request structure to pack/unpack.
1352template <>
1353struct ParamTraits<FindInPageRequest> {
1354 typedef FindInPageRequest param_type;
1355 static void Write(Message* m, const param_type& p) {
1356 WriteParam(m, p.request_id);
1357 WriteParam(m, p.search_string);
1358 WriteParam(m, p.forward);
1359 WriteParam(m, p.match_case);
1360 WriteParam(m, p.find_next);
1361 }
1362 static bool Read(const Message* m, void** iter, param_type* p) {
1363 return
1364 ReadParam(m, iter, &p->request_id) &&
1365 ReadParam(m, iter, &p->search_string) &&
1366 ReadParam(m, iter, &p->forward) &&
1367 ReadParam(m, iter, &p->match_case) &&
1368 ReadParam(m, iter, &p->find_next);
1369 }
1370 static void Log(const param_type& p, std::wstring* l) {
1371 l->append(L"<FindInPageRequest>");
1372 }
1373};
1374
1375//-----------------------------------------------------------------------------
1376
[email protected]3178f4e22008-08-05 21:20:411377} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291378
[email protected]e1981f432008-08-12 15:22:131379#endif // CHROME_COMMON_IPC_MESSAGE_UTILS_H_
license.botbf09a502008-08-24 00:55:551380