WebKit Roll 88523:88542.
[chromium-blink-merge.git] / ipc / ipc_message_utils.h
blob75dd5d1fc1e8ce112d59a51cb7f6f6992f8d9ad5
1 // Copyright (c) 2011 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_
7 #pragma once
9 #include <algorithm>
10 #include <map>
11 #include <set>
12 #include <string>
13 #include <vector>
15 #include "base/format_macros.h"
16 #include "base/string16.h"
17 #include "base/stringprintf.h"
18 #include "base/string_util.h"
19 #include "base/tuple.h"
20 #include "ipc/ipc_param_traits.h"
21 #include "ipc/ipc_sync_message.h"
23 #if defined(COMPILER_GCC)
24 // GCC "helpfully" tries to inline template methods in release mode. Except we
25 // want the majority of the template junk being expanded once in the
26 // implementation file (and only provide the definitions in
27 // ipc_message_utils_impl.h in those files) and exported, instead of expanded
28 // at every call site. Special note: GCC happily accepts the attribute before
29 // the method declaration, but only acts on it if it is after.
30 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 40500
31 // Starting in gcc 4.5, the noinline no longer implies the concept covered by
32 // the introduced noclone attribute, which will create specialized versions of
33 // functions/methods when certain types are constant.
34 // www.gnu.org/software/gcc/gcc-4.5/changes.html
35 #define IPC_MSG_NOINLINE __attribute__((noinline, noclone));
36 #else
37 #define IPC_MSG_NOINLINE __attribute__((noinline));
38 #endif
39 #elif defined(COMPILER_MSVC)
40 // MSVC++ doesn't do this.
41 #define IPC_MSG_NOINLINE
42 #else
43 #error "Please add the noinline property for your new compiler here."
44 #endif
46 // Used by IPC_BEGIN_MESSAGES so that each message class starts from a unique
47 // base. Messages have unique IDs across channels in order for the IPC logging
48 // code to figure out the message class from its ID.
49 enum IPCMessageStart {
50 AutomationMsgStart = 0,
51 ViewMsgStart,
52 PluginMsgStart,
53 ProfileImportMsgStart,
54 TestMsgStart,
55 DevToolsMsgStart,
56 WorkerMsgStart,
57 NaClMsgStart,
58 UtilityMsgStart,
59 GpuMsgStart,
60 ServiceMsgStart,
61 PpapiMsgStart,
62 FirefoxImporterUnittestMsgStart,
63 FileUtilitiesMsgStart,
64 MimeRegistryMsgStart,
65 DatabaseMsgStart,
66 DOMStorageMsgStart,
67 IndexedDBMsgStart,
68 PepperFileMsgStart,
69 SpeechInputMsgStart,
70 PepperMsgStart,
71 AutofillMsgStart,
72 SafeBrowsingMsgStart,
73 P2PMsgStart,
74 SocketStreamMsgStart,
75 ResourceMsgStart,
76 FileSystemMsgStart,
77 ChildProcessMsgStart,
78 ClipboardMsgStart,
79 BlobMsgStart,
80 AppCacheMsgStart,
81 DeviceOrientationMsgStart,
82 DesktopNotificationMsgStart,
83 GeolocationMsgStart,
84 AudioMsgStart,
85 ChromeMsgStart,
86 DragMsgStart,
87 PrintMsgStart,
88 SpellCheckMsgStart,
89 ExtensionMsgStart,
90 VideoCaptureMsgStart,
91 QuotaMsgStart,
92 IconMsgStart,
93 TextInputClientMsgStart,
94 ChromeUtilityMsgStart,
95 LastIPCMsgStart // Must come last.
98 class DictionaryValue;
99 class FilePath;
100 class ListValue;
101 class NullableString16;
103 namespace base {
104 class Time;
105 class TimeDelta;
106 struct FileDescriptor;
109 namespace IPC {
111 struct ChannelHandle;
113 //-----------------------------------------------------------------------------
114 // An iterator class for reading the fields contained within a Message.
116 class MessageIterator {
117 public:
118 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
120 int NextInt() const {
121 int val = -1;
122 if (!msg_.ReadInt(&iter_, &val))
123 NOTREACHED();
124 return val;
126 const std::string NextString() const {
127 std::string val;
128 if (!msg_.ReadString(&iter_, &val))
129 NOTREACHED();
130 return val;
132 const std::wstring NextWString() const {
133 std::wstring val;
134 if (!msg_.ReadWString(&iter_, &val))
135 NOTREACHED();
136 return val;
138 void NextData(const char** data, int* length) const {
139 if (!msg_.ReadData(&iter_, data, length)) {
140 NOTREACHED();
143 private:
144 const Message& msg_;
145 mutable void* iter_;
148 //-----------------------------------------------------------------------------
149 // A dummy struct to place first just to allow leading commas for all
150 // members in the macro-generated constructor initializer lists.
151 struct NoParams {
154 //-----------------------------------------------------------------------------
155 // ParamTraits specializations, etc.
157 template <class P>
158 static inline void WriteParam(Message* m, const P& p) {
159 typedef typename SimilarTypeTraits<P>::Type Type;
160 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
163 template <class P>
164 static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
165 P* p) {
166 typedef typename SimilarTypeTraits<P>::Type Type;
167 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
170 template <class P>
171 static inline void LogParam(const P& p, std::string* l) {
172 typedef typename SimilarTypeTraits<P>::Type Type;
173 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
176 template <>
177 struct ParamTraits<bool> {
178 typedef bool param_type;
179 static void Write(Message* m, const param_type& p) {
180 m->WriteBool(p);
182 static bool Read(const Message* m, void** iter, param_type* r) {
183 return m->ReadBool(iter, r);
185 static void Log(const param_type& p, std::string* l) {
186 l->append(p ? "true" : "false");
190 template <>
191 struct ParamTraits<int> {
192 typedef int param_type;
193 static void Write(Message* m, const param_type& p) {
194 m->WriteInt(p);
196 static bool Read(const Message* m, void** iter, param_type* r) {
197 return m->ReadInt(iter, r);
199 static void Log(const param_type& p, std::string* l);
202 template <>
203 struct ParamTraits<unsigned int> {
204 typedef unsigned int param_type;
205 static void Write(Message* m, const param_type& p) {
206 m->WriteInt(p);
208 static bool Read(const Message* m, void** iter, param_type* r) {
209 return m->ReadInt(iter, reinterpret_cast<int*>(r));
211 static void Log(const param_type& p, std::string* l);
214 template <>
215 struct ParamTraits<long> {
216 typedef long param_type;
217 static void Write(Message* m, const param_type& p) {
218 m->WriteLong(p);
220 static bool Read(const Message* m, void** iter, param_type* r) {
221 return m->ReadLong(iter, r);
223 static void Log(const param_type& p, std::string* l);
226 template <>
227 struct ParamTraits<unsigned long> {
228 typedef unsigned long param_type;
229 static void Write(Message* m, const param_type& p) {
230 m->WriteLong(p);
232 static bool Read(const Message* m, void** iter, param_type* r) {
233 return m->ReadLong(iter, reinterpret_cast<long*>(r));
235 static void Log(const param_type& p, std::string* l);
238 template <>
239 struct ParamTraits<long long> {
240 typedef long long param_type;
241 static void Write(Message* m, const param_type& p) {
242 m->WriteInt64(static_cast<int64>(p));
244 static bool Read(const Message* m, void** iter, param_type* r) {
245 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
247 static void Log(const param_type& p, std::string* l);
250 template <>
251 struct ParamTraits<unsigned long long> {
252 typedef unsigned long long param_type;
253 static void Write(Message* m, const param_type& p) {
254 m->WriteInt64(p);
256 static bool Read(const Message* m, void** iter, param_type* r) {
257 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
259 static void Log(const param_type& p, std::string* l);
262 template <>
263 struct ParamTraits<unsigned short> {
264 typedef unsigned short param_type;
265 static void Write(Message* m, const param_type& p);
266 static bool Read(const Message* m, void** iter, param_type* r);
267 static void Log(const param_type& p, std::string* l);
270 // Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
271 // should be sure to check the sanity of these values after receiving them over
272 // IPC.
273 template <>
274 struct ParamTraits<float> {
275 typedef float param_type;
276 static void Write(Message* m, const param_type& p) {
277 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
279 static bool Read(const Message* m, void** iter, param_type* r) {
280 const char *data;
281 int data_size;
282 if (!m->ReadData(iter, &data, &data_size) ||
283 data_size != sizeof(param_type)) {
284 NOTREACHED();
285 return false;
287 memcpy(r, data, sizeof(param_type));
288 return true;
290 static void Log(const param_type& p, std::string* l) {
291 l->append(StringPrintf("%e", p));
295 template <>
296 struct ParamTraits<double> {
297 typedef double param_type;
298 static void Write(Message* m, const param_type& p) {
299 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
301 static bool Read(const Message* m, void** iter, param_type* r) {
302 const char *data;
303 int data_size;
304 if (!m->ReadData(iter, &data, &data_size) ||
305 data_size != sizeof(param_type)) {
306 NOTREACHED();
307 return false;
309 memcpy(r, data, sizeof(param_type));
310 return true;
312 static void Log(const param_type& p, std::string* l) {
313 l->append(StringPrintf("%e", p));
317 template <>
318 struct ParamTraits<base::Time> {
319 typedef base::Time param_type;
320 static void Write(Message* m, const param_type& p);
321 static bool Read(const Message* m, void** iter, param_type* r);
322 static void Log(const param_type& p, std::string* l);
325 template <>
326 struct ParamTraits<base::TimeDelta> {
327 typedef base::TimeDelta param_type;
328 static void Write(Message* m, const param_type& p);
329 static bool Read(const Message* m, void** iter, param_type* r);
330 static void Log(const param_type& p, std::string* l);
333 #if defined(OS_WIN)
334 template <>
335 struct ParamTraits<LOGFONT> {
336 typedef LOGFONT param_type;
337 static void Write(Message* m, const param_type& p) {
338 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
340 static bool Read(const Message* m, void** iter, param_type* r) {
341 const char *data;
342 int data_size = 0;
343 bool result = m->ReadData(iter, &data, &data_size);
344 if (result && data_size == sizeof(LOGFONT)) {
345 memcpy(r, data, sizeof(LOGFONT));
346 } else {
347 result = false;
348 NOTREACHED();
351 return result;
353 static void Log(const param_type& p, std::string* l) {
354 l->append(StringPrintf("<LOGFONT>"));
358 template <>
359 struct ParamTraits<MSG> {
360 typedef MSG param_type;
361 static void Write(Message* m, const param_type& p) {
362 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
364 static bool Read(const Message* m, void** iter, param_type* r) {
365 const char *data;
366 int data_size = 0;
367 bool result = m->ReadData(iter, &data, &data_size);
368 if (result && data_size == sizeof(MSG)) {
369 memcpy(r, data, sizeof(MSG));
370 } else {
371 result = false;
372 NOTREACHED();
375 return result;
377 static void Log(const param_type& p, std::string* l) {
378 l->append("<MSG>");
381 #endif // defined(OS_WIN)
383 template <>
384 struct ParamTraits<DictionaryValue> {
385 typedef DictionaryValue param_type;
386 static void Write(Message* m, const param_type& p);
387 static bool Read(const Message* m, void** iter, param_type* r);
388 static void Log(const param_type& p, std::string* l);
391 template <>
392 struct ParamTraits<ListValue> {
393 typedef ListValue param_type;
394 static void Write(Message* m, const param_type& p);
395 static bool Read(const Message* m, void** iter, param_type* r);
396 static void Log(const param_type& p, std::string* l);
399 template <>
400 struct ParamTraits<std::string> {
401 typedef std::string param_type;
402 static void Write(Message* m, const param_type& p) {
403 m->WriteString(p);
405 static bool Read(const Message* m, void** iter, param_type* r) {
406 return m->ReadString(iter, r);
408 static void Log(const param_type& p, std::string* l) {
409 l->append(p);
413 template<typename CharType>
414 static void LogBytes(const std::vector<CharType>& data, std::string* out) {
415 #if defined(OS_WIN)
416 // Windows has a GUI for logging, which can handle arbitrary binary data.
417 for (size_t i = 0; i < data.size(); ++i)
418 out->push_back(data[i]);
419 #else
420 // On POSIX, we log to stdout, which we assume can display ASCII.
421 static const size_t kMaxBytesToLog = 100;
422 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
423 if (isprint(data[i]))
424 out->push_back(data[i]);
425 else
426 out->append(StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
428 if (data.size() > kMaxBytesToLog) {
429 out->append(
430 StringPrintf(" and %u more bytes",
431 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
433 #endif
436 template <>
437 struct ParamTraits<std::vector<unsigned char> > {
438 typedef std::vector<unsigned char> param_type;
439 static void Write(Message* m, const param_type& p) {
440 if (p.empty()) {
441 m->WriteData(NULL, 0);
442 } else {
443 m->WriteData(reinterpret_cast<const char*>(&p.front()),
444 static_cast<int>(p.size()));
447 static bool Read(const Message* m, void** iter, param_type* r) {
448 const char *data;
449 int data_size = 0;
450 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
451 return false;
452 r->resize(data_size);
453 if (data_size)
454 memcpy(&r->front(), data, data_size);
455 return true;
457 static void Log(const param_type& p, std::string* l) {
458 LogBytes(p, l);
462 template <>
463 struct ParamTraits<std::vector<char> > {
464 typedef std::vector<char> param_type;
465 static void Write(Message* m, const param_type& p) {
466 if (p.empty()) {
467 m->WriteData(NULL, 0);
468 } else {
469 m->WriteData(&p.front(), static_cast<int>(p.size()));
472 static bool Read(const Message* m, void** iter, param_type* r) {
473 const char *data;
474 int data_size = 0;
475 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
476 return false;
477 r->resize(data_size);
478 if (data_size)
479 memcpy(&r->front(), data, data_size);
480 return true;
482 static void Log(const param_type& p, std::string* l) {
483 LogBytes(p, l);
487 template <class P>
488 struct ParamTraits<std::vector<P> > {
489 typedef std::vector<P> param_type;
490 static void Write(Message* m, const param_type& p) {
491 WriteParam(m, static_cast<int>(p.size()));
492 for (size_t i = 0; i < p.size(); i++)
493 WriteParam(m, p[i]);
495 static bool Read(const Message* m, void** iter, param_type* r) {
496 int size;
497 // ReadLength() checks for < 0 itself.
498 if (!m->ReadLength(iter, &size))
499 return false;
500 // Resizing beforehand is not safe, see BUG 1006367 for details.
501 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
502 return false;
503 r->resize(size);
504 for (int i = 0; i < size; i++) {
505 if (!ReadParam(m, iter, &(*r)[i]))
506 return false;
508 return true;
510 static void Log(const param_type& p, std::string* l) {
511 for (size_t i = 0; i < p.size(); ++i) {
512 if (i != 0)
513 l->append(" ");
514 LogParam((p[i]), l);
519 template <class P>
520 struct ParamTraits<std::set<P> > {
521 typedef std::set<P> param_type;
522 static void Write(Message* m, const param_type& p) {
523 WriteParam(m, static_cast<int>(p.size()));
524 typename param_type::const_iterator iter;
525 for (iter = p.begin(); iter != p.end(); ++iter)
526 WriteParam(m, *iter);
528 static bool Read(const Message* m, void** iter, param_type* r) {
529 int size;
530 if (!m->ReadLength(iter, &size))
531 return false;
532 for (int i = 0; i < size; ++i) {
533 P item;
534 if (!ReadParam(m, iter, &item))
535 return false;
536 r->insert(item);
538 return true;
540 static void Log(const param_type& p, std::string* l) {
541 l->append("<std::set>");
546 template <class K, class V>
547 struct ParamTraits<std::map<K, V> > {
548 typedef std::map<K, V> param_type;
549 static void Write(Message* m, const param_type& p) {
550 WriteParam(m, static_cast<int>(p.size()));
551 typename param_type::const_iterator iter;
552 for (iter = p.begin(); iter != p.end(); ++iter) {
553 WriteParam(m, iter->first);
554 WriteParam(m, iter->second);
557 static bool Read(const Message* m, void** iter, param_type* r) {
558 int size;
559 if (!ReadParam(m, iter, &size) || size < 0)
560 return false;
561 for (int i = 0; i < size; ++i) {
562 K k;
563 if (!ReadParam(m, iter, &k))
564 return false;
565 V& value = (*r)[k];
566 if (!ReadParam(m, iter, &value))
567 return false;
569 return true;
571 static void Log(const param_type& p, std::string* l) {
572 l->append("<std::map>");
577 template <>
578 struct ParamTraits<std::wstring> {
579 typedef std::wstring param_type;
580 static void Write(Message* m, const param_type& p) {
581 m->WriteWString(p);
583 static bool Read(const Message* m, void** iter, param_type* r) {
584 return m->ReadWString(iter, r);
586 static void Log(const param_type& p, std::string* l);
589 template <class A, class B>
590 struct ParamTraits<std::pair<A, B> > {
591 typedef std::pair<A, B> param_type;
592 static void Write(Message* m, const param_type& p) {
593 WriteParam(m, p.first);
594 WriteParam(m, p.second);
596 static bool Read(const Message* m, void** iter, param_type* r) {
597 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
599 static void Log(const param_type& p, std::string* l) {
600 l->append("(");
601 LogParam(p.first, l);
602 l->append(", ");
603 LogParam(p.second, l);
604 l->append(")");
608 template <>
609 struct ParamTraits<NullableString16> {
610 typedef NullableString16 param_type;
611 static void Write(Message* m, const param_type& p);
612 static bool Read(const Message* m, void** iter, param_type* r);
613 static void Log(const param_type& p, std::string* l);
616 // If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
617 // need this trait.
618 #if !defined(WCHAR_T_IS_UTF16)
619 template <>
620 struct ParamTraits<string16> {
621 typedef string16 param_type;
622 static void Write(Message* m, const param_type& p) {
623 m->WriteString16(p);
625 static bool Read(const Message* m, void** iter, param_type* r) {
626 return m->ReadString16(iter, r);
628 static void Log(const param_type& p, std::string* l);
630 #endif
632 // and, a few more useful types...
633 #if defined(OS_WIN)
634 template <>
635 struct ParamTraits<HANDLE> {
636 typedef HANDLE param_type;
637 static void Write(Message* m, const param_type& p) {
638 // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
639 // bit systems.
640 m->WriteUInt32(reinterpret_cast<uint32>(p));
642 static bool Read(const Message* m, void** iter, param_type* r) {
643 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
644 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
646 static void Log(const param_type& p, std::string* l) {
647 l->append(StringPrintf("0x%X", p));
651 template <>
652 struct ParamTraits<HCURSOR> {
653 typedef HCURSOR param_type;
654 static void Write(Message* m, const param_type& p) {
655 m->WriteUInt32(reinterpret_cast<uint32>(p));
657 static bool Read(const Message* m, void** iter, param_type* r) {
658 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
659 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
661 static void Log(const param_type& p, std::string* l) {
662 l->append(StringPrintf("0x%X", p));
666 template <>
667 struct ParamTraits<HACCEL> {
668 typedef HACCEL param_type;
669 static void Write(Message* m, const param_type& p) {
670 m->WriteUInt32(reinterpret_cast<uint32>(p));
672 static bool Read(const Message* m, void** iter, param_type* r) {
673 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
674 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
678 template <>
679 struct ParamTraits<POINT> {
680 typedef POINT param_type;
681 static void Write(Message* m, const param_type& p) {
682 m->WriteInt(p.x);
683 m->WriteInt(p.y);
685 static bool Read(const Message* m, void** iter, param_type* r) {
686 int x, y;
687 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
688 return false;
689 r->x = x;
690 r->y = y;
691 return true;
693 static void Log(const param_type& p, std::string* l) {
694 l->append(StringPrintf("(%d, %d)", p.x, p.y));
697 #endif // defined(OS_WIN)
699 template <>
700 struct ParamTraits<FilePath> {
701 typedef FilePath param_type;
702 static void Write(Message* m, const param_type& p);
703 static bool Read(const Message* m, void** iter, param_type* r);
704 static void Log(const param_type& p, std::string* l);
707 #if defined(OS_POSIX)
708 // FileDescriptors may be serialised over IPC channels on POSIX. On the
709 // receiving side, the FileDescriptor is a valid duplicate of the file
710 // descriptor which was transmitted: *it is not just a copy of the integer like
711 // HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
712 // this case, the receiving end will see a value of -1. *Zero is a valid file
713 // descriptor*.
715 // The received file descriptor will have the |auto_close| flag set to true. The
716 // code which handles the message is responsible for taking ownership of it.
717 // File descriptors are OS resources and must be closed when no longer needed.
719 // When sending a file descriptor, the file descriptor must be valid at the time
720 // of transmission. Since transmission is not synchronous, one should consider
721 // dup()ing any file descriptors to be transmitted and setting the |auto_close|
722 // flag, which causes the file descriptor to be closed after writing.
723 template<>
724 struct ParamTraits<base::FileDescriptor> {
725 typedef base::FileDescriptor param_type;
726 static void Write(Message* m, const param_type& p);
727 static bool Read(const Message* m, void** iter, param_type* r);
728 static void Log(const param_type& p, std::string* l);
730 #endif // defined(OS_POSIX)
732 // A ChannelHandle is basically a platform-inspecific wrapper around the
733 // fact that IPC endpoints are handled specially on POSIX. See above comments
734 // on FileDescriptor for more background.
735 template<>
736 struct ParamTraits<IPC::ChannelHandle> {
737 typedef ChannelHandle param_type;
738 static void Write(Message* m, const param_type& p);
739 static bool Read(const Message* m, void** iter, param_type* r);
740 static void Log(const param_type& p, std::string* l);
743 #if defined(OS_WIN)
744 template <>
745 struct ParamTraits<XFORM> {
746 typedef XFORM param_type;
747 static void Write(Message* m, const param_type& p) {
748 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
750 static bool Read(const Message* m, void** iter, param_type* r) {
751 const char *data;
752 int data_size = 0;
753 bool result = m->ReadData(iter, &data, &data_size);
754 if (result && data_size == sizeof(XFORM)) {
755 memcpy(r, data, sizeof(XFORM));
756 } else {
757 result = false;
758 NOTREACHED();
761 return result;
763 static void Log(const param_type& p, std::string* l) {
764 l->append("<XFORM>");
767 #endif // defined(OS_WIN)
769 struct LogData {
770 LogData();
771 ~LogData();
773 std::string channel;
774 int32 routing_id;
775 uint32 type; // "User-defined" message type, from ipc_message.h.
776 std::string flags;
777 int64 sent; // Time that the message was sent (i.e. at Send()).
778 int64 receive; // Time before it was dispatched (i.e. before calling
779 // OnMessageReceived).
780 int64 dispatch; // Time after it was dispatched (i.e. after calling
781 // OnMessageReceived).
782 std::string message_name;
783 std::string params;
786 template <>
787 struct ParamTraits<LogData> {
788 typedef LogData param_type;
789 static void Write(Message* m, const param_type& p);
790 static bool Read(const Message* m, void** iter, param_type* r);
791 static void Log(const param_type& p, std::string* l) {
792 // Doesn't make sense to implement this!
796 template <>
797 struct ParamTraits<Message> {
798 static void Write(Message* m, const Message& p) {
799 DCHECK(p.size() <= INT_MAX);
800 int message_size = static_cast<int>(p.size());
801 m->WriteInt(message_size);
802 m->WriteData(reinterpret_cast<const char*>(p.data()), message_size);
804 static bool Read(const Message* m, void** iter, Message* r) {
805 int size;
806 if (!m->ReadInt(iter, &size))
807 return false;
808 const char* data;
809 if (!m->ReadData(iter, &data, &size))
810 return false;
811 *r = Message(data, size);
812 return true;
814 static void Log(const Message& p, std::string* l) {
815 l->append("<IPC::Message>");
819 template <>
820 struct ParamTraits<Tuple0> {
821 typedef Tuple0 param_type;
822 static void Write(Message* m, const param_type& p) {
824 static bool Read(const Message* m, void** iter, param_type* r) {
825 return true;
827 static void Log(const param_type& p, std::string* l) {
831 template <class A>
832 struct ParamTraits< Tuple1<A> > {
833 typedef Tuple1<A> param_type;
834 static void Write(Message* m, const param_type& p) {
835 WriteParam(m, p.a);
837 static bool Read(const Message* m, void** iter, param_type* r) {
838 return ReadParam(m, iter, &r->a);
840 static void Log(const param_type& p, std::string* l) {
841 LogParam(p.a, l);
845 template <class A, class B>
846 struct ParamTraits< Tuple2<A, B> > {
847 typedef Tuple2<A, B> param_type;
848 static void Write(Message* m, const param_type& p) {
849 WriteParam(m, p.a);
850 WriteParam(m, p.b);
852 static bool Read(const Message* m, void** iter, param_type* r) {
853 return (ReadParam(m, iter, &r->a) &&
854 ReadParam(m, iter, &r->b));
856 static void Log(const param_type& p, std::string* l) {
857 LogParam(p.a, l);
858 l->append(", ");
859 LogParam(p.b, l);
863 template <class A, class B, class C>
864 struct ParamTraits< Tuple3<A, B, C> > {
865 typedef Tuple3<A, B, C> param_type;
866 static void Write(Message* m, const param_type& p) {
867 WriteParam(m, p.a);
868 WriteParam(m, p.b);
869 WriteParam(m, p.c);
871 static bool Read(const Message* m, void** iter, param_type* r) {
872 return (ReadParam(m, iter, &r->a) &&
873 ReadParam(m, iter, &r->b) &&
874 ReadParam(m, iter, &r->c));
876 static void Log(const param_type& p, std::string* l) {
877 LogParam(p.a, l);
878 l->append(", ");
879 LogParam(p.b, l);
880 l->append(", ");
881 LogParam(p.c, l);
885 template <class A, class B, class C, class D>
886 struct ParamTraits< Tuple4<A, B, C, D> > {
887 typedef Tuple4<A, B, C, D> param_type;
888 static void Write(Message* m, const param_type& p) {
889 WriteParam(m, p.a);
890 WriteParam(m, p.b);
891 WriteParam(m, p.c);
892 WriteParam(m, p.d);
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) &&
898 ReadParam(m, iter, &r->d));
900 static void Log(const param_type& p, std::string* l) {
901 LogParam(p.a, l);
902 l->append(", ");
903 LogParam(p.b, l);
904 l->append(", ");
905 LogParam(p.c, l);
906 l->append(", ");
907 LogParam(p.d, l);
911 template <class A, class B, class C, class D, class E>
912 struct ParamTraits< Tuple5<A, B, C, D, E> > {
913 typedef Tuple5<A, B, C, D, E> param_type;
914 static void Write(Message* m, const param_type& p) {
915 WriteParam(m, p.a);
916 WriteParam(m, p.b);
917 WriteParam(m, p.c);
918 WriteParam(m, p.d);
919 WriteParam(m, p.e);
921 static bool Read(const Message* m, void** iter, param_type* r) {
922 return (ReadParam(m, iter, &r->a) &&
923 ReadParam(m, iter, &r->b) &&
924 ReadParam(m, iter, &r->c) &&
925 ReadParam(m, iter, &r->d) &&
926 ReadParam(m, iter, &r->e));
928 static void Log(const param_type& p, std::string* l) {
929 LogParam(p.a, l);
930 l->append(", ");
931 LogParam(p.b, l);
932 l->append(", ");
933 LogParam(p.c, l);
934 l->append(", ");
935 LogParam(p.d, l);
936 l->append(", ");
937 LogParam(p.e, l);
941 //-----------------------------------------------------------------------------
942 // Generic message subclasses
944 // Used for asynchronous messages.
945 template <class ParamType>
946 class MessageWithTuple : public Message {
947 public:
948 typedef ParamType Param;
949 typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
951 // The constructor and the Read() method's templated implementations are in
952 // ipc_message_utils_impl.h. The subclass constructor and Log() methods call
953 // the templated versions of these and make sure there are instantiations in
954 // those translation units.
955 MessageWithTuple(int32 routing_id, uint32 type, const RefParam& p);
957 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
959 // Generic dispatcher. Should cover most cases.
960 template<class T, class S, class Method>
961 static bool Dispatch(const Message* msg, T* obj, S* sender, Method func) {
962 Param p;
963 if (Read(msg, &p)) {
964 DispatchToMethod(obj, func, p);
965 return true;
967 return false;
970 // The following dispatchers exist for the case where the callback function
971 // needs the message as well. They assume that "Param" is a type of Tuple
972 // (except the one arg case, as there is no Tuple1).
973 template<class T, class S, typename TA>
974 static bool Dispatch(const Message* msg, T* obj, S* sender,
975 void (T::*func)(const Message&, TA)) {
976 Param p;
977 if (Read(msg, &p)) {
978 (obj->*func)(*msg, p.a);
979 return true;
981 return false;
984 template<class T, class S, typename TA, typename TB>
985 static bool Dispatch(const Message* msg, T* obj, S* sender,
986 void (T::*func)(const Message&, TA, TB)) {
987 Param p;
988 if (Read(msg, &p)) {
989 (obj->*func)(*msg, p.a, p.b);
990 return true;
992 return false;
995 template<class T, class S, typename TA, typename TB, typename TC>
996 static bool Dispatch(const Message* msg, T* obj, S* sender,
997 void (T::*func)(const Message&, TA, TB, TC)) {
998 Param p;
999 if (Read(msg, &p)) {
1000 (obj->*func)(*msg, p.a, p.b, p.c);
1001 return true;
1003 return false;
1006 template<class T, class S, typename TA, typename TB, typename TC, typename TD>
1007 static bool Dispatch(const Message* msg, T* obj, S* sender,
1008 void (T::*func)(const Message&, TA, TB, TC, TD)) {
1009 Param p;
1010 if (Read(msg, &p)) {
1011 (obj->*func)(*msg, p.a, p.b, p.c, p.d);
1012 return true;
1014 return false;
1017 template<class T, class S, typename TA, typename TB, typename TC, typename TD,
1018 typename TE>
1019 static bool Dispatch(const Message* msg, T* obj, S* sender,
1020 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
1021 Param p;
1022 if (Read(msg, &p)) {
1023 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
1024 return true;
1026 return false;
1029 // Functions used to do manual unpacking. Only used by the automation code,
1030 // these should go away once that code uses SyncChannel.
1031 template<typename TA, typename TB>
1032 static bool Read(const IPC::Message* msg, TA* a, TB* b) {
1033 ParamType params;
1034 if (!Read(msg, &params))
1035 return false;
1036 *a = params.a;
1037 *b = params.b;
1038 return true;
1041 template<typename TA, typename TB, typename TC>
1042 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
1043 ParamType params;
1044 if (!Read(msg, &params))
1045 return false;
1046 *a = params.a;
1047 *b = params.b;
1048 *c = params.c;
1049 return true;
1052 template<typename TA, typename TB, typename TC, typename TD>
1053 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) {
1054 ParamType params;
1055 if (!Read(msg, &params))
1056 return false;
1057 *a = params.a;
1058 *b = params.b;
1059 *c = params.c;
1060 *d = params.d;
1061 return true;
1064 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1065 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) {
1066 ParamType params;
1067 if (!Read(msg, &params))
1068 return false;
1069 *a = params.a;
1070 *b = params.b;
1071 *c = params.c;
1072 *d = params.d;
1073 *e = params.e;
1074 return true;
1078 // defined in ipc_logging.cc
1079 void GenerateLogData(const std::string& channel, const Message& message,
1080 LogData* data);
1083 #if defined(IPC_MESSAGE_LOG_ENABLED)
1084 inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
1085 const std::string& output_params = msg->output_params();
1086 if (!l->empty() && !output_params.empty())
1087 l->append(", ");
1089 l->append(output_params);
1092 template <class ReplyParamType>
1093 inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1094 const Message* msg) {
1095 if (msg->received_time() != 0) {
1096 std::string output_params;
1097 LogParam(reply_params, &output_params);
1098 msg->set_output_params(output_params);
1102 inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
1103 if (msg->sent_time()) {
1104 // Don't log the sync message after dispatch, as we don't have the
1105 // output parameters at that point. Instead, save its data and log it
1106 // with the outgoing reply message when it's sent.
1107 LogData* data = new LogData;
1108 GenerateLogData("", *msg, data);
1109 msg->set_dont_log();
1110 reply->set_sync_log_data(data);
1113 #else
1114 inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
1116 template <class ReplyParamType>
1117 inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1118 const Message* msg) {}
1120 inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1121 #endif
1123 // This class assumes that its template argument is a RefTuple (a Tuple with
1124 // reference elements). This would go into ipc_message_utils_impl.h, but it is
1125 // also used by chrome_frame.
1126 template <class RefTuple>
1127 class ParamDeserializer : public MessageReplyDeserializer {
1128 public:
1129 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
1131 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1132 return ReadParam(&msg, &iter, &out_);
1135 RefTuple out_;
1138 // Used for synchronous messages.
1139 template <class SendParamType, class ReplyParamType>
1140 class MessageWithReply : public SyncMessage {
1141 public:
1142 typedef SendParamType SendParam;
1143 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
1144 typedef ReplyParamType ReplyParam;
1146 MessageWithReply(int32 routing_id, uint32 type,
1147 const RefSendParam& send, const ReplyParam& reply);
1148 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
1149 static bool ReadReplyParam(
1150 const Message* msg,
1151 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
1153 template<class T, class S, class Method>
1154 static bool Dispatch(const Message* msg, T* obj, S* sender, Method func) {
1155 SendParam send_params;
1156 Message* reply = GenerateReply(msg);
1157 bool error;
1158 if (ReadSendParam(msg, &send_params)) {
1159 typename TupleTypes<ReplyParam>::ValueTuple reply_params;
1160 DispatchToMethod(obj, func, send_params, &reply_params);
1161 WriteParam(reply, reply_params);
1162 error = false;
1163 LogReplyParamsToMessage(reply_params, msg);
1164 } else {
1165 NOTREACHED() << "Error deserializing message " << msg->type();
1166 reply->set_reply_error();
1167 error = true;
1170 sender->Send(reply);
1171 return !error;
1174 template<class T, class Method>
1175 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
1176 SendParam send_params;
1177 Message* reply = GenerateReply(msg);
1178 bool error;
1179 if (ReadSendParam(msg, &send_params)) {
1180 Tuple1<Message&> t = MakeRefTuple(*reply);
1181 ConnectMessageAndReply(msg, reply);
1182 DispatchToMethod(obj, func, send_params, &t);
1183 error = false;
1184 } else {
1185 NOTREACHED() << "Error deserializing message " << msg->type();
1186 reply->set_reply_error();
1187 obj->Send(reply);
1188 error = true;
1190 return !error;
1193 template<typename TA>
1194 static void WriteReplyParams(Message* reply, TA a) {
1195 ReplyParam p(a);
1196 WriteParam(reply, p);
1199 template<typename TA, typename TB>
1200 static void WriteReplyParams(Message* reply, TA a, TB b) {
1201 ReplyParam p(a, b);
1202 WriteParam(reply, p);
1205 template<typename TA, typename TB, typename TC>
1206 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1207 ReplyParam p(a, b, c);
1208 WriteParam(reply, p);
1211 template<typename TA, typename TB, typename TC, typename TD>
1212 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1213 ReplyParam p(a, b, c, d);
1214 WriteParam(reply, p);
1217 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1218 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1219 ReplyParam p(a, b, c, d, e);
1220 WriteParam(reply, p);
1224 //-----------------------------------------------------------------------------
1226 } // namespace IPC
1228 #endif // IPC_IPC_MESSAGE_UTILS_H_