Remove now-passing tests and rebaseline one after the Big Scary Roll.
[chromium-blink-merge.git] / ipc / ipc_message_utils.h
blob0bffce9a49e1a451fbdc7729c209f8023bc4ed51
1 // Copyright (c) 2006-2009 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.
5 #ifndef IPC_IPC_MESSAGE_UTILS_H_
6 #define IPC_IPC_MESSAGE_UTILS_H_
8 #include <string>
9 #include <vector>
10 #include <map>
12 #include "base/file_path.h"
13 #include "base/format_macros.h"
14 #include "base/nullable_string16.h"
15 #include "base/string16.h"
16 #include "base/string_util.h"
17 #include "base/time.h"
18 #include "base/tuple.h"
19 #include "base/values.h"
20 #if defined(OS_POSIX)
21 #include "ipc/file_descriptor_set_posix.h"
22 #endif
23 #include "ipc/ipc_channel_handle.h"
24 #include "ipc/ipc_sync_message.h"
26 // Used by IPC_BEGIN_MESSAGES so that each message class starts from a unique
27 // base. Messages have unique IDs across channels in order for the IPC logging
28 // code to figure out the message class from its ID.
29 enum IPCMessageStart {
30 // By using a start value of 0 for automation messages, we keep backward
31 // compatibility with old builds.
32 AutomationMsgStart = 0,
33 ViewMsgStart,
34 ViewHostMsgStart,
35 PluginProcessMsgStart,
36 PluginProcessHostMsgStart,
37 PluginMsgStart,
38 PluginHostMsgStart,
39 NPObjectMsgStart,
40 TestMsgStart,
41 DevToolsAgentMsgStart,
42 DevToolsClientMsgStart,
43 WorkerProcessMsgStart,
44 WorkerProcessHostMsgStart,
45 WorkerMsgStart,
46 WorkerHostMsgStart,
47 NaClProcessMsgStart,
48 CommandBufferMsgStart,
49 UtilityMsgStart,
50 UtilityHostMsgStart,
51 GpuMsgStart,
52 GpuHostMsgStart,
53 // NOTE: When you add a new message class, also update
54 // IPCStatusView::IPCStatusView to ensure logging works.
55 LastMsgIndex
58 namespace IPC {
60 //-----------------------------------------------------------------------------
61 // An iterator class for reading the fields contained within a Message.
63 class MessageIterator {
64 public:
65 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
67 int NextInt() const {
68 int val = -1;
69 if (!msg_.ReadInt(&iter_, &val))
70 NOTREACHED();
71 return val;
73 intptr_t NextIntPtr() const {
74 intptr_t val = 0;
75 if (!msg_.ReadIntPtr(&iter_, &val))
76 NOTREACHED();
77 return val;
79 const std::string NextString() const {
80 std::string val;
81 if (!msg_.ReadString(&iter_, &val))
82 NOTREACHED();
83 return val;
85 const std::wstring NextWString() const {
86 std::wstring val;
87 if (!msg_.ReadWString(&iter_, &val))
88 NOTREACHED();
89 return val;
91 const void NextData(const char** data, int* length) const {
92 if (!msg_.ReadData(&iter_, data, length)) {
93 NOTREACHED();
96 private:
97 const Message& msg_;
98 mutable void* iter_;
101 //-----------------------------------------------------------------------------
102 // ParamTraits specializations, etc.
104 template <class P> struct ParamTraits {
107 template <class P>
108 struct SimilarTypeTraits {
109 typedef P Type;
112 template <class P>
113 static inline void WriteParam(Message* m, const P& p) {
114 typedef typename SimilarTypeTraits<P>::Type Type;
115 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
118 template <class P>
119 static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
120 P* p) {
121 typedef typename SimilarTypeTraits<P>::Type Type;
122 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
125 template <class P>
126 static inline void LogParam(const P& p, std::wstring* l) {
127 typedef typename SimilarTypeTraits<P>::Type Type;
128 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
131 template <>
132 struct ParamTraits<bool> {
133 typedef bool param_type;
134 static void Write(Message* m, const param_type& p) {
135 m->WriteBool(p);
137 static bool Read(const Message* m, void** iter, param_type* r) {
138 return m->ReadBool(iter, r);
140 static void Log(const param_type& p, std::wstring* l) {
141 l->append(p ? L"true" : L"false");
145 template <>
146 struct ParamTraits<int> {
147 typedef int param_type;
148 static void Write(Message* m, const param_type& p) {
149 m->WriteInt(p);
151 static bool Read(const Message* m, void** iter, param_type* r) {
152 return m->ReadInt(iter, r);
154 static void Log(const param_type& p, std::wstring* l) {
155 l->append(StringPrintf(L"%d", p));
159 template <>
160 struct ParamTraits<unsigned int> {
161 typedef unsigned int param_type;
162 static void Write(Message* m, const param_type& p) {
163 m->WriteInt(p);
165 static bool Read(const Message* m, void** iter, param_type* r) {
166 return m->ReadInt(iter, reinterpret_cast<int*>(r));
168 static void Log(const param_type& p, std::wstring* l) {
169 l->append(StringPrintf(L"%d", p));
173 template <>
174 struct ParamTraits<long> {
175 typedef long param_type;
176 static void Write(Message* m, const param_type& p) {
177 m->WriteLong(p);
179 static bool Read(const Message* m, void** iter, param_type* r) {
180 return m->ReadLong(iter, r);
182 static void Log(const param_type& p, std::wstring* l) {
183 l->append(StringPrintf(L"%ld", p));
187 template <>
188 struct ParamTraits<unsigned long> {
189 typedef unsigned long param_type;
190 static void Write(Message* m, const param_type& p) {
191 m->WriteLong(p);
193 static bool Read(const Message* m, void** iter, param_type* r) {
194 return m->ReadLong(iter, reinterpret_cast<long*>(r));
196 static void Log(const param_type& p, std::wstring* l) {
197 l->append(StringPrintf(L"%lu", p));
201 template <>
202 struct ParamTraits<long long> {
203 typedef long long param_type;
204 static void Write(Message* m, const param_type& p) {
205 m->WriteInt64(static_cast<int64>(p));
207 static bool Read(const Message* m, void** iter, param_type* r) {
208 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
210 static void Log(const param_type& p, std::wstring* l) {
211 l->append(Int64ToWString(static_cast<int64>(p)));
215 template <>
216 struct ParamTraits<unsigned long long> {
217 typedef unsigned long long param_type;
218 static void Write(Message* m, const param_type& p) {
219 m->WriteInt64(p);
221 static bool Read(const Message* m, void** iter, param_type* r) {
222 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
224 static void Log(const param_type& p, std::wstring* l) {
225 l->append(Uint64ToWString(p));
229 template <>
230 struct ParamTraits<double> {
231 typedef double param_type;
232 static void Write(Message* m, const param_type& p) {
233 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
235 static bool Read(const Message* m, void** iter, param_type* r) {
236 const char *data;
237 int data_size = 0;
238 bool result = m->ReadData(iter, &data, &data_size);
239 if (result && data_size == sizeof(param_type)) {
240 memcpy(r, data, sizeof(param_type));
241 } else {
242 result = false;
243 NOTREACHED();
246 return result;
248 static void Log(const param_type& p, std::wstring* l) {
249 l->append(StringPrintf(L"e", p));
253 template <>
254 struct ParamTraits<wchar_t> {
255 typedef wchar_t param_type;
256 static void Write(Message* m, const param_type& p) {
257 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
259 static bool Read(const Message* m, void** iter, param_type* r) {
260 const char *data;
261 int data_size = 0;
262 bool result = m->ReadData(iter, &data, &data_size);
263 if (result && data_size == sizeof(param_type)) {
264 memcpy(r, data, sizeof(param_type));
265 } else {
266 result = false;
267 NOTREACHED();
270 return result;
272 static void Log(const param_type& p, std::wstring* l) {
273 l->append(StringPrintf(L"%lc", p));
277 template <>
278 struct ParamTraits<base::Time> {
279 typedef base::Time param_type;
280 static void Write(Message* m, const param_type& p) {
281 ParamTraits<int64>::Write(m, p.ToInternalValue());
283 static bool Read(const Message* m, void** iter, param_type* r) {
284 int64 value;
285 if (!ParamTraits<int64>::Read(m, iter, &value))
286 return false;
287 *r = base::Time::FromInternalValue(value);
288 return true;
290 static void Log(const param_type& p, std::wstring* l) {
291 ParamTraits<int64>::Log(p.ToInternalValue(), l);
295 #if defined(OS_WIN)
296 template <>
297 struct ParamTraits<LOGFONT> {
298 typedef LOGFONT param_type;
299 static void Write(Message* m, const param_type& p) {
300 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
302 static bool Read(const Message* m, void** iter, param_type* r) {
303 const char *data;
304 int data_size = 0;
305 bool result = m->ReadData(iter, &data, &data_size);
306 if (result && data_size == sizeof(LOGFONT)) {
307 memcpy(r, data, sizeof(LOGFONT));
308 } else {
309 result = false;
310 NOTREACHED();
313 return result;
315 static void Log(const param_type& p, std::wstring* l) {
316 l->append(StringPrintf(L"<LOGFONT>"));
320 template <>
321 struct ParamTraits<MSG> {
322 typedef MSG param_type;
323 static void Write(Message* m, const param_type& p) {
324 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
326 static bool Read(const Message* m, void** iter, param_type* r) {
327 const char *data;
328 int data_size = 0;
329 bool result = m->ReadData(iter, &data, &data_size);
330 if (result && data_size == sizeof(MSG)) {
331 memcpy(r, data, sizeof(MSG));
332 } else {
333 result = false;
334 NOTREACHED();
337 return result;
340 #endif // defined(OS_WIN)
342 template <>
343 struct ParamTraits<DictionaryValue> {
344 typedef DictionaryValue param_type;
345 static void Write(Message* m, const param_type& p);
346 static bool Read(const Message* m, void** iter, param_type* r);
347 static void Log(const param_type& p, std::wstring* l);
350 template <>
351 struct ParamTraits<ListValue> {
352 typedef ListValue param_type;
353 static void Write(Message* m, const param_type& p);
354 static bool Read(const Message* m, void** iter, param_type* r);
355 static void Log(const param_type& p, std::wstring* l);
358 template <>
359 struct ParamTraits<std::string> {
360 typedef std::string param_type;
361 static void Write(Message* m, const param_type& p) {
362 m->WriteString(p);
364 static bool Read(const Message* m, void** iter, param_type* r) {
365 return m->ReadString(iter, r);
367 static void Log(const param_type& p, std::wstring* l) {
368 l->append(UTF8ToWide(p));
372 template<typename CharType>
373 static void LogBytes(const std::vector<CharType>& data, std::wstring* out) {
374 #if defined(OS_WIN)
375 // Windows has a GUI for logging, which can handle arbitrary binary data.
376 for (size_t i = 0; i < data.size(); ++i)
377 out->push_back(data[i]);
378 #else
379 // On POSIX, we log to stdout, which we assume can display ASCII.
380 static const size_t kMaxBytesToLog = 100;
381 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
382 if (isprint(data[i]))
383 out->push_back(data[i]);
384 else
385 out->append(StringPrintf(L"[%02X]", static_cast<unsigned char>(data[i])));
387 if (data.size() > kMaxBytesToLog) {
388 out->append(
389 StringPrintf(L" and %u more bytes",
390 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
392 #endif
395 template <>
396 struct ParamTraits<std::vector<unsigned char> > {
397 typedef std::vector<unsigned char> param_type;
398 static void Write(Message* m, const param_type& p) {
399 if (p.size() == 0) {
400 m->WriteData(NULL, 0);
401 } else {
402 m->WriteData(reinterpret_cast<const char*>(&p.front()),
403 static_cast<int>(p.size()));
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;
416 static void Log(const param_type& p, std::wstring* l) {
417 LogBytes(p, l);
421 template <>
422 struct ParamTraits<std::vector<char> > {
423 typedef std::vector<char> param_type;
424 static void Write(Message* m, const param_type& p) {
425 if (p.size() == 0) {
426 m->WriteData(NULL, 0);
427 } else {
428 m->WriteData(&p.front(), static_cast<int>(p.size()));
431 static bool Read(const Message* m, void** iter, param_type* r) {
432 const char *data;
433 int data_size = 0;
434 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
435 return false;
436 r->resize(data_size);
437 if (data_size)
438 memcpy(&r->front(), data, data_size);
439 return true;
441 static void Log(const param_type& p, std::wstring* l) {
442 LogBytes(p, l);
446 template <class P>
447 struct ParamTraits<std::vector<P> > {
448 typedef std::vector<P> param_type;
449 static void Write(Message* m, const param_type& p) {
450 WriteParam(m, static_cast<int>(p.size()));
451 for (size_t i = 0; i < p.size(); i++)
452 WriteParam(m, p[i]);
454 static bool Read(const Message* m, void** iter, param_type* r) {
455 int size;
456 // ReadLength() checks for < 0 itself.
457 if (!m->ReadLength(iter, &size))
458 return false;
459 // Resizing beforehand is not safe, see BUG 1006367 for details.
460 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
461 return false;
462 r->resize(size);
463 for (int i = 0; i < size; i++) {
464 if (!ReadParam(m, iter, &(*r)[i]))
465 return false;
467 return true;
469 static void Log(const param_type& p, std::wstring* l) {
470 for (size_t i = 0; i < p.size(); ++i) {
471 if (i != 0)
472 l->append(L" ");
474 LogParam((p[i]), l);
479 template <class K, class V>
480 struct ParamTraits<std::map<K, V> > {
481 typedef std::map<K, V> param_type;
482 static void Write(Message* m, const param_type& p) {
483 WriteParam(m, static_cast<int>(p.size()));
484 typename param_type::const_iterator iter;
485 for (iter = p.begin(); iter != p.end(); ++iter) {
486 WriteParam(m, iter->first);
487 WriteParam(m, iter->second);
490 static bool Read(const Message* m, void** iter, param_type* r) {
491 int size;
492 if (!ReadParam(m, iter, &size) || size < 0)
493 return false;
494 for (int i = 0; i < size; ++i) {
495 K k;
496 if (!ReadParam(m, iter, &k))
497 return false;
498 V& value = (*r)[k];
499 if (!ReadParam(m, iter, &value))
500 return false;
502 return true;
504 static void Log(const param_type& p, std::wstring* l) {
505 l->append(L"<std::map>");
510 template <>
511 struct ParamTraits<std::wstring> {
512 typedef std::wstring param_type;
513 static void Write(Message* m, const param_type& p) {
514 m->WriteWString(p);
516 static bool Read(const Message* m, void** iter, param_type* r) {
517 return m->ReadWString(iter, r);
519 static void Log(const param_type& p, std::wstring* l) {
520 l->append(p);
524 template <class A, class B>
525 struct ParamTraits<std::pair<A, B> > {
526 typedef std::pair<A, B> param_type;
527 static void Write(Message* m, const param_type& p) {
528 WriteParam(m, p.first);
529 WriteParam(m, p.second);
531 static bool Read(const Message* m, void** iter, param_type* r) {
532 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
534 static void Log(const param_type& p, std::wstring* l) {
535 l->append(L"(");
536 LogParam(p.first, l);
537 l->append(L", ");
538 LogParam(p.second, l);
539 l->append(L")");
543 template <>
544 struct ParamTraits<NullableString16> {
545 typedef NullableString16 param_type;
546 static void Write(Message* m, const param_type& p) {
547 WriteParam(m, p.string());
548 WriteParam(m, p.is_null());
550 static bool Read(const Message* m, void** iter, param_type* r) {
551 string16 string;
552 if (!ReadParam(m, iter, &string))
553 return false;
554 bool is_null;
555 if (!ReadParam(m, iter, &is_null))
556 return false;
557 *r = NullableString16(string, is_null);
558 return true;
560 static void Log(const param_type& p, std::wstring* l) {
561 l->append(L"(");
562 LogParam(p.string(), l);
563 l->append(L", ");
564 LogParam(p.is_null(), l);
565 l->append(L")");
569 // If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
570 // need this trait.
571 #if !defined(WCHAR_T_IS_UTF16)
572 template <>
573 struct ParamTraits<string16> {
574 typedef string16 param_type;
575 static void Write(Message* m, const param_type& p) {
576 m->WriteString16(p);
578 static bool Read(const Message* m, void** iter, param_type* r) {
579 return m->ReadString16(iter, r);
581 static void Log(const param_type& p, std::wstring* l) {
582 l->append(UTF16ToWide(p));
585 #endif
587 // and, a few more useful types...
588 #if defined(OS_WIN)
589 template <>
590 struct ParamTraits<HANDLE> {
591 typedef HANDLE param_type;
592 static void Write(Message* m, const param_type& p) {
593 m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
595 static bool Read(const Message* m, void** iter, param_type* r) {
596 DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
597 return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
599 static void Log(const param_type& p, std::wstring* l) {
600 l->append(StringPrintf(L"0x%X", p));
604 template <>
605 struct ParamTraits<HCURSOR> {
606 typedef HCURSOR param_type;
607 static void Write(Message* m, const param_type& p) {
608 m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
610 static bool Read(const Message* m, void** iter, param_type* r) {
611 DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
612 return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
614 static void Log(const param_type& p, std::wstring* l) {
615 l->append(StringPrintf(L"0x%X", p));
619 template <>
620 struct ParamTraits<HACCEL> {
621 typedef HACCEL param_type;
622 static void Write(Message* m, const param_type& p) {
623 m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
625 static bool Read(const Message* m, void** iter, param_type* r) {
626 DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
627 return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
631 template <>
632 struct ParamTraits<POINT> {
633 typedef POINT param_type;
634 static void Write(Message* m, const param_type& p) {
635 m->WriteInt(p.x);
636 m->WriteInt(p.y);
638 static bool Read(const Message* m, void** iter, param_type* r) {
639 int x, y;
640 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
641 return false;
642 r->x = x;
643 r->y = y;
644 return true;
646 static void Log(const param_type& p, std::wstring* l) {
647 l->append(StringPrintf(L"(%d, %d)", p.x, p.y));
650 #endif // defined(OS_WIN)
652 template <>
653 struct ParamTraits<FilePath> {
654 typedef FilePath param_type;
655 static void Write(Message* m, const param_type& p) {
656 ParamTraits<FilePath::StringType>::Write(m, p.value());
658 static bool Read(const Message* m, void** iter, param_type* r) {
659 FilePath::StringType value;
660 if (!ParamTraits<FilePath::StringType>::Read(m, iter, &value))
661 return false;
662 *r = FilePath(value);
663 return true;
665 static void Log(const param_type& p, std::wstring* l) {
666 ParamTraits<FilePath::StringType>::Log(p.value(), l);
670 #if defined(OS_POSIX)
671 // FileDescriptors may be serialised over IPC channels on POSIX. On the
672 // receiving side, the FileDescriptor is a valid duplicate of the file
673 // descriptor which was transmitted: *it is not just a copy of the integer like
674 // HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
675 // this case, the receiving end will see a value of -1. *Zero is a valid file
676 // descriptor*.
678 // The received file descriptor will have the |auto_close| flag set to true. The
679 // code which handles the message is responsible for taking ownership of it.
680 // File descriptors are OS resources and must be closed when no longer needed.
682 // When sending a file descriptor, the file descriptor must be valid at the time
683 // of transmission. Since transmission is not synchronous, one should consider
684 // dup()ing any file descriptors to be transmitted and setting the |auto_close|
685 // flag, which causes the file descriptor to be closed after writing.
686 template<>
687 struct ParamTraits<base::FileDescriptor> {
688 typedef base::FileDescriptor param_type;
689 static void Write(Message* m, const param_type& p) {
690 const bool valid = p.fd >= 0;
691 WriteParam(m, valid);
693 if (valid) {
694 if (!m->WriteFileDescriptor(p))
695 NOTREACHED();
698 static bool Read(const Message* m, void** iter, param_type* r) {
699 bool valid;
700 if (!ReadParam(m, iter, &valid))
701 return false;
703 if (!valid) {
704 r->fd = -1;
705 r->auto_close = false;
706 return true;
709 return m->ReadFileDescriptor(iter, r);
711 static void Log(const param_type& p, std::wstring* l) {
712 if (p.auto_close) {
713 l->append(StringPrintf(L"FD(%d auto-close)", p.fd));
714 } else {
715 l->append(StringPrintf(L"FD(%d)", p.fd));
719 #endif // defined(OS_POSIX)
721 // A ChannelHandle is basically a platform-inspecific wrapper around the
722 // fact that IPC endpoints are handled specially on POSIX. See above comments
723 // on FileDescriptor for more background.
724 template<>
725 struct ParamTraits<IPC::ChannelHandle> {
726 typedef ChannelHandle param_type;
727 static void Write(Message* m, const param_type& p) {
728 WriteParam(m, p.name);
729 #if defined(OS_POSIX)
730 WriteParam(m, p.socket);
731 #endif
733 static bool Read(const Message* m, void** iter, param_type* r) {
734 return ReadParam(m, iter, &r->name)
735 #if defined(OS_POSIX)
736 && ReadParam(m, iter, &r->socket)
737 #endif
740 static void Log(const param_type& p, std::wstring* l) {
741 l->append(ASCIIToWide(StringPrintf("ChannelHandle(%s", p.name.c_str())));
742 #if defined(OS_POSIX)
743 ParamTraits<base::FileDescriptor>::Log(p.socket, l);
744 #endif
745 l->append(L")");
749 #if defined(OS_WIN)
750 template <>
751 struct ParamTraits<XFORM> {
752 typedef XFORM param_type;
753 static void Write(Message* m, const param_type& p) {
754 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
756 static bool Read(const Message* m, void** iter, param_type* r) {
757 const char *data;
758 int data_size = 0;
759 bool result = m->ReadData(iter, &data, &data_size);
760 if (result && data_size == sizeof(XFORM)) {
761 memcpy(r, data, sizeof(XFORM));
762 } else {
763 result = false;
764 NOTREACHED();
767 return result;
769 static void Log(const param_type& p, std::wstring* l) {
770 l->append(L"<XFORM>");
773 #endif // defined(OS_WIN)
775 struct LogData {
776 std::string channel;
777 int32 routing_id;
778 uint32 type; // "User-defined" message type, from ipc_message.h.
779 std::wstring flags;
780 int64 sent; // Time that the message was sent (i.e. at Send()).
781 int64 receive; // Time before it was dispatched (i.e. before calling
782 // OnMessageReceived).
783 int64 dispatch; // Time after it was dispatched (i.e. after calling
784 // OnMessageReceived).
785 std::wstring message_name;
786 std::wstring params;
789 template <>
790 struct ParamTraits<LogData> {
791 typedef LogData param_type;
792 static void Write(Message* m, const param_type& p) {
793 WriteParam(m, p.channel);
794 WriteParam(m, p.routing_id);
795 WriteParam(m, static_cast<int>(p.type));
796 WriteParam(m, p.flags);
797 WriteParam(m, p.sent);
798 WriteParam(m, p.receive);
799 WriteParam(m, p.dispatch);
800 WriteParam(m, p.params);
802 static bool Read(const Message* m, void** iter, param_type* r) {
803 int type;
804 bool result =
805 ReadParam(m, iter, &r->channel) &&
806 ReadParam(m, iter, &r->routing_id);
807 ReadParam(m, iter, &type) &&
808 ReadParam(m, iter, &r->flags) &&
809 ReadParam(m, iter, &r->sent) &&
810 ReadParam(m, iter, &r->receive) &&
811 ReadParam(m, iter, &r->dispatch) &&
812 ReadParam(m, iter, &r->params);
813 r->type = static_cast<uint16>(type);
814 return result;
816 static void Log(const param_type& p, std::wstring* l) {
817 // Doesn't make sense to implement this!
821 template <>
822 struct ParamTraits<Message> {
823 static void Write(Message* m, const Message& p) {
824 m->WriteInt(p.size());
825 m->WriteData(reinterpret_cast<const char*>(p.data()), p.size());
827 static bool Read(const Message* m, void** iter, Message* r) {
828 int size;
829 if (!m->ReadInt(iter, &size))
830 return false;
831 const char* data;
832 if (!m->ReadData(iter, &data, &size))
833 return false;
834 *r = Message(data, size);
835 return true;
837 static void Log(const Message& p, std::wstring* l) {
838 l->append(L"<IPC::Message>");
842 template <>
843 struct ParamTraits<Tuple0> {
844 typedef Tuple0 param_type;
845 static void Write(Message* m, const param_type& p) {
847 static bool Read(const Message* m, void** iter, param_type* r) {
848 return true;
850 static void Log(const param_type& p, std::wstring* l) {
854 template <class A>
855 struct ParamTraits< Tuple1<A> > {
856 typedef Tuple1<A> param_type;
857 static void Write(Message* m, const param_type& p) {
858 WriteParam(m, p.a);
860 static bool Read(const Message* m, void** iter, param_type* r) {
861 return ReadParam(m, iter, &r->a);
863 static void Log(const param_type& p, std::wstring* l) {
864 LogParam(p.a, l);
868 template <class A, class B>
869 struct ParamTraits< Tuple2<A, B> > {
870 typedef Tuple2<A, B> param_type;
871 static void Write(Message* m, const param_type& p) {
872 WriteParam(m, p.a);
873 WriteParam(m, p.b);
875 static bool Read(const Message* m, void** iter, param_type* r) {
876 return (ReadParam(m, iter, &r->a) &&
877 ReadParam(m, iter, &r->b));
879 static void Log(const param_type& p, std::wstring* l) {
880 LogParam(p.a, l);
881 l->append(L", ");
882 LogParam(p.b, l);
886 template <class A, class B, class C>
887 struct ParamTraits< Tuple3<A, B, C> > {
888 typedef Tuple3<A, B, C> param_type;
889 static void Write(Message* m, const param_type& p) {
890 WriteParam(m, p.a);
891 WriteParam(m, p.b);
892 WriteParam(m, p.c);
894 static bool Read(const Message* m, void** iter, param_type* r) {
895 return (ReadParam(m, iter, &r->a) &&
896 ReadParam(m, iter, &r->b) &&
897 ReadParam(m, iter, &r->c));
899 static void Log(const param_type& p, std::wstring* l) {
900 LogParam(p.a, l);
901 l->append(L", ");
902 LogParam(p.b, l);
903 l->append(L", ");
904 LogParam(p.c, l);
908 template <class A, class B, class C, class D>
909 struct ParamTraits< Tuple4<A, B, C, D> > {
910 typedef Tuple4<A, B, C, D> param_type;
911 static void Write(Message* m, const param_type& p) {
912 WriteParam(m, p.a);
913 WriteParam(m, p.b);
914 WriteParam(m, p.c);
915 WriteParam(m, p.d);
917 static bool Read(const Message* m, void** iter, param_type* r) {
918 return (ReadParam(m, iter, &r->a) &&
919 ReadParam(m, iter, &r->b) &&
920 ReadParam(m, iter, &r->c) &&
921 ReadParam(m, iter, &r->d));
923 static void Log(const param_type& p, std::wstring* l) {
924 LogParam(p.a, l);
925 l->append(L", ");
926 LogParam(p.b, l);
927 l->append(L", ");
928 LogParam(p.c, l);
929 l->append(L", ");
930 LogParam(p.d, l);
934 template <class A, class B, class C, class D, class E>
935 struct ParamTraits< Tuple5<A, B, C, D, E> > {
936 typedef Tuple5<A, B, C, D, E> 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);
944 static bool Read(const Message* m, void** iter, param_type* r) {
945 return (ReadParam(m, iter, &r->a) &&
946 ReadParam(m, iter, &r->b) &&
947 ReadParam(m, iter, &r->c) &&
948 ReadParam(m, iter, &r->d) &&
949 ReadParam(m, iter, &r->e));
951 static void Log(const param_type& p, std::wstring* l) {
952 LogParam(p.a, l);
953 l->append(L", ");
954 LogParam(p.b, l);
955 l->append(L", ");
956 LogParam(p.c, l);
957 l->append(L", ");
958 LogParam(p.d, l);
959 l->append(L", ");
960 LogParam(p.e, l);
964 //-----------------------------------------------------------------------------
965 // Generic message subclasses
967 // Used for asynchronous messages.
968 template <class ParamType>
969 class MessageWithTuple : public Message {
970 public:
971 typedef ParamType Param;
972 typedef typename ParamType::ParamTuple RefParam;
974 MessageWithTuple(int32 routing_id, uint32 type, const RefParam& p)
975 : Message(routing_id, type, PRIORITY_NORMAL) {
976 WriteParam(this, p);
979 static bool Read(const Message* msg, Param* p) {
980 void* iter = NULL;
981 if (ReadParam(msg, &iter, p))
982 return true;
983 NOTREACHED() << "Error deserializing message " << msg->type();
984 return false;
987 // Generic dispatcher. Should cover most cases.
988 template<class T, class Method>
989 static bool Dispatch(const Message* msg, T* obj, Method func) {
990 Param p;
991 if (Read(msg, &p)) {
992 DispatchToMethod(obj, func, p);
993 return true;
995 return false;
998 // The following dispatchers exist for the case where the callback function
999 // needs the message as well. They assume that "Param" is a type of Tuple
1000 // (except the one arg case, as there is no Tuple1).
1001 template<class T, typename TA>
1002 static bool Dispatch(const Message* msg, T* obj,
1003 void (T::*func)(const Message&, TA)) {
1004 Param p;
1005 if (Read(msg, &p)) {
1006 (obj->*func)(*msg, p.a);
1007 return true;
1009 return false;
1012 template<class T, typename TA, typename TB>
1013 static bool Dispatch(const Message* msg, T* obj,
1014 void (T::*func)(const Message&, TA, TB)) {
1015 Param p;
1016 if (Read(msg, &p)) {
1017 (obj->*func)(*msg, p.a, p.b);
1018 return true;
1020 return false;
1023 template<class T, typename TA, typename TB, typename TC>
1024 static bool Dispatch(const Message* msg, T* obj,
1025 void (T::*func)(const Message&, TA, TB, TC)) {
1026 Param p;
1027 if (Read(msg, &p)) {
1028 (obj->*func)(*msg, p.a, p.b, p.c);
1029 return true;
1031 return false;
1034 template<class T, typename TA, typename TB, typename TC, typename TD>
1035 static bool Dispatch(const Message* msg, T* obj,
1036 void (T::*func)(const Message&, TA, TB, TC, TD)) {
1037 Param p;
1038 if (Read(msg, &p)) {
1039 (obj->*func)(*msg, p.a, p.b, p.c, p.d);
1040 return true;
1042 return false;
1045 template<class T, typename TA, typename TB, typename TC, typename TD,
1046 typename TE>
1047 static bool Dispatch(const Message* msg, T* obj,
1048 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
1049 Param p;
1050 if (Read(msg, &p)) {
1051 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
1052 return true;
1054 return false;
1057 static void Log(const Message* msg, std::wstring* l) {
1058 Param p;
1059 if (Read(msg, &p))
1060 LogParam(p, l);
1063 // Functions used to do manual unpacking. Only used by the automation code,
1064 // these should go away once that code uses SyncChannel.
1065 template<typename TA, typename TB>
1066 static bool Read(const IPC::Message* msg, TA* a, TB* b) {
1067 ParamType params;
1068 if (!Read(msg, &params))
1069 return false;
1070 *a = params.a;
1071 *b = params.b;
1072 return true;
1075 template<typename TA, typename TB, typename TC>
1076 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
1077 ParamType params;
1078 if (!Read(msg, &params))
1079 return false;
1080 *a = params.a;
1081 *b = params.b;
1082 *c = params.c;
1083 return true;
1086 template<typename TA, typename TB, typename TC, typename TD>
1087 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) {
1088 ParamType params;
1089 if (!Read(msg, &params))
1090 return false;
1091 *a = params.a;
1092 *b = params.b;
1093 *c = params.c;
1094 *d = params.d;
1095 return true;
1098 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1099 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) {
1100 ParamType params;
1101 if (!Read(msg, &params))
1102 return false;
1103 *a = params.a;
1104 *b = params.b;
1105 *c = params.c;
1106 *d = params.d;
1107 *e = params.e;
1108 return true;
1112 // This class assumes that its template argument is a RefTuple (a Tuple with
1113 // reference elements).
1114 template <class RefTuple>
1115 class ParamDeserializer : public MessageReplyDeserializer {
1116 public:
1117 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
1119 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1120 return ReadParam(&msg, &iter, &out_);
1123 RefTuple out_;
1126 // defined in ipc_logging.cc
1127 void GenerateLogData(const std::string& channel, const Message& message,
1128 LogData* data);
1130 // Used for synchronous messages.
1131 template <class SendParamType, class ReplyParamType>
1132 class MessageWithReply : public SyncMessage {
1133 public:
1134 typedef SendParamType SendParam;
1135 typedef typename SendParam::ParamTuple RefSendParam;
1136 typedef ReplyParamType ReplyParam;
1138 MessageWithReply(int32 routing_id, uint32 type,
1139 const RefSendParam& send, const ReplyParam& reply)
1140 : SyncMessage(routing_id, type, PRIORITY_NORMAL,
1141 new ParamDeserializer<ReplyParam>(reply)) {
1142 WriteParam(this, send);
1145 static void Log(const Message* msg, std::wstring* l) {
1146 if (msg->is_sync()) {
1147 SendParam p;
1148 void* iter = SyncMessage::GetDataIterator(msg);
1149 if (ReadParam(msg, &iter, &p))
1150 LogParam(p, l);
1152 #if defined(IPC_MESSAGE_LOG_ENABLED)
1153 const std::wstring& output_params = msg->output_params();
1154 if (!l->empty() && !output_params.empty())
1155 l->append(L", ");
1157 l->append(output_params);
1158 #endif
1159 } else {
1160 // This is an outgoing reply. Now that we have the output parameters, we
1161 // can finally log the message.
1162 typename ReplyParam::ValueTuple p;
1163 void* iter = SyncMessage::GetDataIterator(msg);
1164 if (ReadParam(msg, &iter, &p))
1165 LogParam(p, l);
1169 template<class T, class Method>
1170 static bool Dispatch(const Message* msg, T* obj, Method func) {
1171 SendParam send_params;
1172 void* iter = GetDataIterator(msg);
1173 Message* reply = GenerateReply(msg);
1174 bool error;
1175 if (ReadParam(msg, &iter, &send_params)) {
1176 typename ReplyParam::ValueTuple reply_params;
1177 DispatchToMethod(obj, func, send_params, &reply_params);
1178 WriteParam(reply, reply_params);
1179 error = false;
1180 #ifdef IPC_MESSAGE_LOG_ENABLED
1181 if (msg->received_time() != 0) {
1182 std::wstring output_params;
1183 LogParam(reply_params, &output_params);
1184 msg->set_output_params(output_params);
1186 #endif
1187 } else {
1188 NOTREACHED() << "Error deserializing message " << msg->type();
1189 reply->set_reply_error();
1190 error = true;
1193 obj->Send(reply);
1194 return !error;
1197 template<class T, class Method>
1198 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
1199 SendParam send_params;
1200 void* iter = GetDataIterator(msg);
1201 Message* reply = GenerateReply(msg);
1202 bool error;
1203 if (ReadParam(msg, &iter, &send_params)) {
1204 Tuple1<Message&> t = MakeRefTuple(*reply);
1206 #ifdef IPC_MESSAGE_LOG_ENABLED
1207 if (msg->sent_time()) {
1208 // Don't log the sync message after dispatch, as we don't have the
1209 // output parameters at that point. Instead, save its data and log it
1210 // with the outgoing reply message when it's sent.
1211 LogData* data = new LogData;
1212 GenerateLogData("", *msg, data);
1213 msg->set_dont_log();
1214 reply->set_sync_log_data(data);
1216 #endif
1217 DispatchToMethod(obj, func, send_params, &t);
1218 error = false;
1219 } else {
1220 NOTREACHED() << "Error deserializing message " << msg->type();
1221 reply->set_reply_error();
1222 obj->Send(reply);
1223 error = true;
1225 return !error;
1228 template<typename TA>
1229 static void WriteReplyParams(Message* reply, TA a) {
1230 ReplyParam p(a);
1231 WriteParam(reply, p);
1234 template<typename TA, typename TB>
1235 static void WriteReplyParams(Message* reply, TA a, TB b) {
1236 ReplyParam p(a, b);
1237 WriteParam(reply, p);
1240 template<typename TA, typename TB, typename TC>
1241 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1242 ReplyParam p(a, b, c);
1243 WriteParam(reply, p);
1246 template<typename TA, typename TB, typename TC, typename TD>
1247 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1248 ReplyParam p(a, b, c, d);
1249 WriteParam(reply, p);
1252 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1253 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1254 ReplyParam p(a, b, c, d, e);
1255 WriteParam(reply, p);
1259 //-----------------------------------------------------------------------------
1261 } // namespace IPC
1263 #endif // IPC_IPC_MESSAGE_UTILS_H_