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_
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"
21 #include "ipc/file_descriptor_set_posix.h"
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,
35 PluginProcessMsgStart
,
36 PluginProcessHostMsgStart
,
41 DevToolsAgentMsgStart
,
42 DevToolsClientMsgStart
,
43 WorkerProcessMsgStart
,
44 WorkerProcessHostMsgStart
,
48 CommandBufferMsgStart
,
53 // NOTE: When you add a new message class, also update
54 // IPCStatusView::IPCStatusView to ensure logging works.
60 //-----------------------------------------------------------------------------
61 // An iterator class for reading the fields contained within a Message.
63 class MessageIterator
{
65 explicit MessageIterator(const Message
& m
) : msg_(m
), iter_(NULL
) {
69 if (!msg_
.ReadInt(&iter_
, &val
))
73 intptr_t NextIntPtr() const {
75 if (!msg_
.ReadIntPtr(&iter_
, &val
))
79 const std::string
NextString() const {
81 if (!msg_
.ReadString(&iter_
, &val
))
85 const std::wstring
NextWString() const {
87 if (!msg_
.ReadWString(&iter_
, &val
))
91 const void NextData(const char** data
, int* length
) const {
92 if (!msg_
.ReadData(&iter_
, data
, length
)) {
101 //-----------------------------------------------------------------------------
102 // ParamTraits specializations, etc.
104 template <class P
> struct ParamTraits
{
108 struct SimilarTypeTraits
{
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
));
119 static inline bool WARN_UNUSED_RESULT
ReadParam(const Message
* m
, void** iter
,
121 typedef typename SimilarTypeTraits
<P
>::Type Type
;
122 return ParamTraits
<Type
>::Read(m
, iter
, reinterpret_cast<Type
* >(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
);
132 struct ParamTraits
<bool> {
133 typedef bool param_type
;
134 static void Write(Message
* m
, const param_type
& 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");
146 struct ParamTraits
<int> {
147 typedef int param_type
;
148 static void Write(Message
* m
, const param_type
& 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
));
160 struct ParamTraits
<unsigned int> {
161 typedef unsigned int param_type
;
162 static void Write(Message
* m
, const param_type
& 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
));
174 struct ParamTraits
<long> {
175 typedef long param_type
;
176 static void Write(Message
* m
, const param_type
& 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
));
188 struct ParamTraits
<unsigned long> {
189 typedef unsigned long param_type
;
190 static void Write(Message
* m
, const param_type
& 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
));
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
)));
216 struct ParamTraits
<unsigned long long> {
217 typedef unsigned long long param_type
;
218 static void Write(Message
* m
, const param_type
& 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
));
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
) {
238 bool result
= m
->ReadData(iter
, &data
, &data_size
);
239 if (result
&& data_size
== sizeof(param_type
)) {
240 memcpy(r
, data
, sizeof(param_type
));
248 static void Log(const param_type
& p
, std::wstring
* l
) {
249 l
->append(StringPrintf(L
"e", p
));
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
) {
262 bool result
= m
->ReadData(iter
, &data
, &data_size
);
263 if (result
&& data_size
== sizeof(param_type
)) {
264 memcpy(r
, data
, sizeof(param_type
));
272 static void Log(const param_type
& p
, std::wstring
* l
) {
273 l
->append(StringPrintf(L
"%lc", p
));
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
) {
285 if (!ParamTraits
<int64
>::Read(m
, iter
, &value
))
287 *r
= base::Time::FromInternalValue(value
);
290 static void Log(const param_type
& p
, std::wstring
* l
) {
291 ParamTraits
<int64
>::Log(p
.ToInternalValue(), l
);
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
) {
305 bool result
= m
->ReadData(iter
, &data
, &data_size
);
306 if (result
&& data_size
== sizeof(LOGFONT
)) {
307 memcpy(r
, data
, sizeof(LOGFONT
));
315 static void Log(const param_type
& p
, std::wstring
* l
) {
316 l
->append(StringPrintf(L
"<LOGFONT>"));
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
) {
329 bool result
= m
->ReadData(iter
, &data
, &data_size
);
330 if (result
&& data_size
== sizeof(MSG
)) {
331 memcpy(r
, data
, sizeof(MSG
));
340 #endif // defined(OS_WIN)
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
);
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
);
359 struct ParamTraits
<std::string
> {
360 typedef std::string param_type
;
361 static void Write(Message
* m
, const param_type
& 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
) {
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
]);
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
]);
385 out
->append(StringPrintf(L
"[%02X]", static_cast<unsigned char>(data
[i
])));
387 if (data
.size() > kMaxBytesToLog
) {
389 StringPrintf(L
" and %u more bytes",
390 static_cast<unsigned>(data
.size() - kMaxBytesToLog
)));
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
) {
400 m
->WriteData(NULL
, 0);
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
) {
409 if (!m
->ReadData(iter
, &data
, &data_size
) || data_size
< 0)
411 r
->resize(data_size
);
413 memcpy(&r
->front(), data
, data_size
);
416 static void Log(const param_type
& p
, std::wstring
* l
) {
422 struct ParamTraits
<std::vector
<char> > {
423 typedef std::vector
<char> param_type
;
424 static void Write(Message
* m
, const param_type
& p
) {
426 m
->WriteData(NULL
, 0);
428 m
->WriteData(&p
.front(), static_cast<int>(p
.size()));
431 static bool Read(const Message
* m
, void** iter
, param_type
* r
) {
434 if (!m
->ReadData(iter
, &data
, &data_size
) || data_size
< 0)
436 r
->resize(data_size
);
438 memcpy(&r
->front(), data
, data_size
);
441 static void Log(const param_type
& p
, std::wstring
* l
) {
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
++)
454 static bool Read(const Message
* m
, void** iter
, param_type
* r
) {
456 // ReadLength() checks for < 0 itself.
457 if (!m
->ReadLength(iter
, &size
))
459 // Resizing beforehand is not safe, see BUG 1006367 for details.
460 if (INT_MAX
/ sizeof(P
) <= static_cast<size_t>(size
))
463 for (int i
= 0; i
< size
; i
++) {
464 if (!ReadParam(m
, iter
, &(*r
)[i
]))
469 static void Log(const param_type
& p
, std::wstring
* l
) {
470 for (size_t i
= 0; i
< p
.size(); ++i
) {
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
) {
492 if (!ReadParam(m
, iter
, &size
) || size
< 0)
494 for (int i
= 0; i
< size
; ++i
) {
496 if (!ReadParam(m
, iter
, &k
))
499 if (!ReadParam(m
, iter
, &value
))
504 static void Log(const param_type
& p
, std::wstring
* l
) {
505 l
->append(L
"<std::map>");
511 struct ParamTraits
<std::wstring
> {
512 typedef std::wstring param_type
;
513 static void Write(Message
* m
, const param_type
& 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
) {
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
) {
536 LogParam(p
.first
, l
);
538 LogParam(p
.second
, l
);
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
) {
552 if (!ReadParam(m
, iter
, &string
))
555 if (!ReadParam(m
, iter
, &is_null
))
557 *r
= NullableString16(string
, is_null
);
560 static void Log(const param_type
& p
, std::wstring
* l
) {
562 LogParam(p
.string(), l
);
564 LogParam(p
.is_null(), l
);
569 // If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
571 #if !defined(WCHAR_T_IS_UTF16)
573 struct ParamTraits
<string16
> {
574 typedef string16 param_type
;
575 static void Write(Message
* m
, const param_type
& 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
));
587 // and, a few more useful types...
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
));
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
));
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
));
632 struct ParamTraits
<POINT
> {
633 typedef POINT param_type
;
634 static void Write(Message
* m
, const param_type
& p
) {
638 static bool Read(const Message
* m
, void** iter
, param_type
* r
) {
640 if (!m
->ReadInt(iter
, &x
) || !m
->ReadInt(iter
, &y
))
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)
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
))
662 *r
= FilePath(value
);
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
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.
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
);
694 if (!m
->WriteFileDescriptor(p
))
698 static bool Read(const Message
* m
, void** iter
, param_type
* r
) {
700 if (!ReadParam(m
, iter
, &valid
))
705 r
->auto_close
= false;
709 return m
->ReadFileDescriptor(iter
, r
);
711 static void Log(const param_type
& p
, std::wstring
* l
) {
713 l
->append(StringPrintf(L
"FD(%d auto-close)", p
.fd
));
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.
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
);
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
)
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
);
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
) {
759 bool result
= m
->ReadData(iter
, &data
, &data_size
);
760 if (result
&& data_size
== sizeof(XFORM
)) {
761 memcpy(r
, data
, sizeof(XFORM
));
769 static void Log(const param_type
& p
, std::wstring
* l
) {
770 l
->append(L
"<XFORM>");
773 #endif // defined(OS_WIN)
778 uint32 type
; // "User-defined" message type, from ipc_message.h.
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
;
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
) {
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
);
816 static void Log(const param_type
& p
, std::wstring
* l
) {
817 // Doesn't make sense to implement this!
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
) {
829 if (!m
->ReadInt(iter
, &size
))
832 if (!m
->ReadData(iter
, &data
, &size
))
834 *r
= Message(data
, size
);
837 static void Log(const Message
& p
, std::wstring
* l
) {
838 l
->append(L
"<IPC::Message>");
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
) {
850 static void Log(const param_type
& p
, std::wstring
* l
) {
855 struct ParamTraits
< Tuple1
<A
> > {
856 typedef Tuple1
<A
> param_type
;
857 static void Write(Message
* m
, const param_type
& p
) {
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
) {
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
) {
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
) {
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
) {
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
) {
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
) {
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
) {
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
) {
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
) {
964 //-----------------------------------------------------------------------------
965 // Generic message subclasses
967 // Used for asynchronous messages.
968 template <class ParamType
>
969 class MessageWithTuple
: public Message
{
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
) {
979 static bool Read(const Message
* msg
, Param
* p
) {
981 if (ReadParam(msg
, &iter
, p
))
983 NOTREACHED() << "Error deserializing message " << msg
->type();
987 // Generic dispatcher. Should cover most cases.
988 template<class T
, class Method
>
989 static bool Dispatch(const Message
* msg
, T
* obj
, Method func
) {
992 DispatchToMethod(obj
, func
, p
);
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
)) {
1005 if (Read(msg
, &p
)) {
1006 (obj
->*func
)(*msg
, p
.a
);
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
)) {
1016 if (Read(msg
, &p
)) {
1017 (obj
->*func
)(*msg
, p
.a
, p
.b
);
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
)) {
1027 if (Read(msg
, &p
)) {
1028 (obj
->*func
)(*msg
, p
.a
, p
.b
, p
.c
);
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
)) {
1038 if (Read(msg
, &p
)) {
1039 (obj
->*func
)(*msg
, p
.a
, p
.b
, p
.c
, p
.d
);
1045 template<class T
, typename TA
, typename TB
, typename TC
, typename TD
,
1047 static bool Dispatch(const Message
* msg
, T
* obj
,
1048 void (T::*func
)(const Message
&, TA
, TB
, TC
, TD
, TE
)) {
1050 if (Read(msg
, &p
)) {
1051 (obj
->*func
)(*msg
, p
.a
, p
.b
, p
.c
, p
.d
, p
.e
);
1057 static void Log(const Message
* msg
, std::wstring
* 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
) {
1068 if (!Read(msg
, ¶ms
))
1075 template<typename TA
, typename TB
, typename TC
>
1076 static bool Read(const IPC::Message
* msg
, TA
* a
, TB
* b
, TC
* c
) {
1078 if (!Read(msg
, ¶ms
))
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
) {
1089 if (!Read(msg
, ¶ms
))
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
) {
1101 if (!Read(msg
, ¶ms
))
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
{
1117 explicit ParamDeserializer(const RefTuple
& out
) : out_(out
) { }
1119 bool SerializeOutputParameters(const IPC::Message
& msg
, void* iter
) {
1120 return ReadParam(&msg
, &iter
, &out_
);
1126 // defined in ipc_logging.cc
1127 void GenerateLogData(const std::string
& channel
, const Message
& message
,
1130 // Used for synchronous messages.
1131 template <class SendParamType
, class ReplyParamType
>
1132 class MessageWithReply
: public SyncMessage
{
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()) {
1148 void* iter
= SyncMessage::GetDataIterator(msg
);
1149 if (ReadParam(msg
, &iter
, &p
))
1152 #if defined(IPC_MESSAGE_LOG_ENABLED)
1153 const std::wstring
& output_params
= msg
->output_params();
1154 if (!l
->empty() && !output_params
.empty())
1157 l
->append(output_params
);
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
))
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
);
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
);
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
);
1188 NOTREACHED() << "Error deserializing message " << msg
->type();
1189 reply
->set_reply_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
);
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
);
1217 DispatchToMethod(obj
, func
, send_params
, &t
);
1220 NOTREACHED() << "Error deserializing message " << msg
->type();
1221 reply
->set_reply_error();
1228 template<typename TA
>
1229 static void WriteReplyParams(Message
* reply
, TA a
) {
1231 WriteParam(reply
, p
);
1234 template<typename TA
, typename TB
>
1235 static void WriteReplyParams(Message
* reply
, TA a
, TB 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 //-----------------------------------------------------------------------------
1263 #endif // IPC_IPC_MESSAGE_UTILS_H_