1 // Copyright (c) 2012 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_
14 #include "base/containers/small_map.h"
15 #include "base/files/file.h"
16 #include "base/format_macros.h"
17 #include "base/memory/scoped_vector.h"
18 #include "base/strings/string16.h"
19 #include "base/strings/string_util.h"
20 #include "base/strings/stringprintf.h"
21 #include "base/tuple.h"
22 #include "ipc/ipc_message_start.h"
23 #include "ipc/ipc_param_traits.h"
24 #include "ipc/ipc_sync_message.h"
26 #if defined(COMPILER_GCC)
27 // GCC "helpfully" tries to inline template methods in release mode. Except we
28 // want the majority of the template junk being expanded once in the
29 // implementation file (and only provide the definitions in
30 // ipc_message_utils_impl.h in those files) and exported, instead of expanded
31 // at every call site. Special note: GCC happily accepts the attribute before
32 // the method declaration, but only acts on it if it is after.
33 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 40500
34 // Starting in gcc 4.5, the noinline no longer implies the concept covered by
35 // the introduced noclone attribute, which will create specialized versions of
36 // functions/methods when certain types are constant.
37 // www.gnu.org/software/gcc/gcc-4.5/changes.html
38 #define IPC_MSG_NOINLINE __attribute__((noinline, noclone));
40 #define IPC_MSG_NOINLINE __attribute__((noinline));
42 #elif defined(COMPILER_MSVC)
43 // MSVC++ doesn't do this.
44 #define IPC_MSG_NOINLINE
46 #error "Please add the noinline property for your new compiler here."
50 class DictionaryValue
;
53 class NullableString16
;
57 struct FileDescriptor
;
64 // -----------------------------------------------------------------------------
65 // How we send IPC message logs across channels.
66 struct IPC_EXPORT LogData
{
72 uint32 type
; // "User-defined" message type, from ipc_message.h.
74 int64 sent
; // Time that the message was sent (i.e. at Send()).
75 int64 receive
; // Time before it was dispatched (i.e. before calling
76 // OnMessageReceived).
77 int64 dispatch
; // Time after it was dispatched (i.e. after calling
78 // OnMessageReceived).
79 std::string message_name
;
83 //-----------------------------------------------------------------------------
85 // A dummy struct to place first just to allow leading commas for all
86 // members in the macro-generated constructor initializer lists.
91 static inline void WriteParam(Message
* m
, const P
& p
) {
92 typedef typename SimilarTypeTraits
<P
>::Type Type
;
93 ParamTraits
<Type
>::Write(m
, static_cast<const Type
& >(p
));
97 static inline bool WARN_UNUSED_RESULT
ReadParam(const Message
* m
,
100 typedef typename SimilarTypeTraits
<P
>::Type Type
;
101 return ParamTraits
<Type
>::Read(m
, iter
, reinterpret_cast<Type
* >(p
));
105 static inline void LogParam(const P
& p
, std::string
* l
) {
106 typedef typename SimilarTypeTraits
<P
>::Type Type
;
107 ParamTraits
<Type
>::Log(static_cast<const Type
& >(p
), l
);
110 // Primitive ParamTraits -------------------------------------------------------
113 struct ParamTraits
<bool> {
114 typedef bool param_type
;
115 static void Write(Message
* m
, const param_type
& p
) {
118 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
119 return m
->ReadBool(iter
, r
);
121 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
125 struct IPC_EXPORT ParamTraits
<unsigned char> {
126 typedef unsigned char param_type
;
127 static void Write(Message
* m
, const param_type
& p
);
128 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
129 static void Log(const param_type
& p
, std::string
* l
);
133 struct IPC_EXPORT ParamTraits
<unsigned short> {
134 typedef unsigned short param_type
;
135 static void Write(Message
* m
, const param_type
& p
);
136 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
137 static void Log(const param_type
& p
, std::string
* l
);
141 struct ParamTraits
<int> {
142 typedef int param_type
;
143 static void Write(Message
* m
, const param_type
& p
) {
146 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
147 return m
->ReadInt(iter
, r
);
149 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
153 struct ParamTraits
<unsigned int> {
154 typedef unsigned int param_type
;
155 static void Write(Message
* m
, const param_type
& p
) {
158 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
159 return m
->ReadInt(iter
, reinterpret_cast<int*>(r
));
161 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
165 struct ParamTraits
<long> {
166 typedef long param_type
;
167 static void Write(Message
* m
, const param_type
& p
) {
168 m
->WriteLongUsingDangerousNonPortableLessPersistableForm(p
);
170 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
171 return m
->ReadLong(iter
, r
);
173 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
177 struct ParamTraits
<unsigned long> {
178 typedef unsigned long param_type
;
179 static void Write(Message
* m
, const param_type
& p
) {
180 m
->WriteLongUsingDangerousNonPortableLessPersistableForm(p
);
182 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
183 return m
->ReadLong(iter
, reinterpret_cast<long*>(r
));
185 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
189 struct ParamTraits
<long long> {
190 typedef long long param_type
;
191 static void Write(Message
* m
, const param_type
& p
) {
192 m
->WriteInt64(static_cast<int64
>(p
));
194 static bool Read(const Message
* m
, PickleIterator
* iter
,
196 return m
->ReadInt64(iter
, reinterpret_cast<int64
*>(r
));
198 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
202 struct ParamTraits
<unsigned long long> {
203 typedef unsigned long long param_type
;
204 static void Write(Message
* m
, const param_type
& p
) {
207 static bool Read(const Message
* m
, PickleIterator
* iter
,
209 return m
->ReadInt64(iter
, reinterpret_cast<int64
*>(r
));
211 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
214 // Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
215 // should be sure to check the sanity of these values after receiving them over
218 struct IPC_EXPORT ParamTraits
<float> {
219 typedef float param_type
;
220 static void Write(Message
* m
, const param_type
& p
) {
223 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
224 return m
->ReadFloat(iter
, r
);
226 static void Log(const param_type
& p
, std::string
* l
);
230 struct IPC_EXPORT ParamTraits
<double> {
231 typedef double param_type
;
232 static void Write(Message
* m
, const param_type
& p
);
233 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
234 static void Log(const param_type
& p
, std::string
* l
);
237 // STL ParamTraits -------------------------------------------------------------
240 struct ParamTraits
<std::string
> {
241 typedef std::string param_type
;
242 static void Write(Message
* m
, const param_type
& p
) {
245 static bool Read(const Message
* m
, PickleIterator
* iter
,
247 return m
->ReadString(iter
, r
);
249 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
253 struct ParamTraits
<std::wstring
> {
254 typedef std::wstring param_type
;
255 static void Write(Message
* m
, const param_type
& p
) {
258 static bool Read(const Message
* m
, PickleIterator
* iter
,
260 return m
->ReadWString(iter
, r
);
262 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
265 // If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
267 #if !defined(WCHAR_T_IS_UTF16)
269 struct ParamTraits
<base::string16
> {
270 typedef base::string16 param_type
;
271 static void Write(Message
* m
, const param_type
& p
) {
274 static bool Read(const Message
* m
, PickleIterator
* iter
,
276 return m
->ReadString16(iter
, r
);
278 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
283 struct IPC_EXPORT ParamTraits
<std::vector
<char> > {
284 typedef std::vector
<char> param_type
;
285 static void Write(Message
* m
, const param_type
& p
);
286 static bool Read(const Message
*, PickleIterator
* iter
, param_type
* r
);
287 static void Log(const param_type
& p
, std::string
* l
);
291 struct IPC_EXPORT ParamTraits
<std::vector
<unsigned char> > {
292 typedef std::vector
<unsigned char> param_type
;
293 static void Write(Message
* m
, const param_type
& p
);
294 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
295 static void Log(const param_type
& p
, std::string
* l
);
299 struct IPC_EXPORT ParamTraits
<std::vector
<bool> > {
300 typedef std::vector
<bool> param_type
;
301 static void Write(Message
* m
, const param_type
& p
);
302 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
303 static void Log(const param_type
& p
, std::string
* l
);
307 struct ParamTraits
<std::vector
<P
> > {
308 typedef std::vector
<P
> param_type
;
309 static void Write(Message
* m
, const param_type
& p
) {
310 WriteParam(m
, static_cast<int>(p
.size()));
311 for (size_t i
= 0; i
< p
.size(); i
++)
314 static bool Read(const Message
* m
, PickleIterator
* iter
,
317 // ReadLength() checks for < 0 itself.
318 if (!m
->ReadLength(iter
, &size
))
320 // Resizing beforehand is not safe, see BUG 1006367 for details.
321 if (INT_MAX
/ sizeof(P
) <= static_cast<size_t>(size
))
324 for (int i
= 0; i
< size
; i
++) {
325 if (!ReadParam(m
, iter
, &(*r
)[i
]))
330 static void Log(const param_type
& p
, std::string
* l
) {
331 for (size_t i
= 0; i
< p
.size(); ++i
) {
340 struct ParamTraits
<std::set
<P
> > {
341 typedef std::set
<P
> param_type
;
342 static void Write(Message
* m
, const param_type
& p
) {
343 WriteParam(m
, static_cast<int>(p
.size()));
344 typename
param_type::const_iterator iter
;
345 for (iter
= p
.begin(); iter
!= p
.end(); ++iter
)
346 WriteParam(m
, *iter
);
348 static bool Read(const Message
* m
, PickleIterator
* iter
,
351 if (!m
->ReadLength(iter
, &size
))
353 for (int i
= 0; i
< size
; ++i
) {
355 if (!ReadParam(m
, iter
, &item
))
361 static void Log(const param_type
& p
, std::string
* l
) {
362 l
->append("<std::set>");
366 template <class K
, class V
>
367 struct ParamTraits
<std::map
<K
, V
> > {
368 typedef std::map
<K
, V
> param_type
;
369 static void Write(Message
* m
, const param_type
& p
) {
370 WriteParam(m
, static_cast<int>(p
.size()));
371 typename
param_type::const_iterator iter
;
372 for (iter
= p
.begin(); iter
!= p
.end(); ++iter
) {
373 WriteParam(m
, iter
->first
);
374 WriteParam(m
, iter
->second
);
377 static bool Read(const Message
* m
, PickleIterator
* iter
,
380 if (!ReadParam(m
, iter
, &size
) || size
< 0)
382 for (int i
= 0; i
< size
; ++i
) {
384 if (!ReadParam(m
, iter
, &k
))
387 if (!ReadParam(m
, iter
, &value
))
392 static void Log(const param_type
& p
, std::string
* l
) {
393 l
->append("<std::map>");
397 template <class A
, class B
>
398 struct ParamTraits
<std::pair
<A
, B
> > {
399 typedef std::pair
<A
, B
> param_type
;
400 static void Write(Message
* m
, const param_type
& p
) {
401 WriteParam(m
, p
.first
);
402 WriteParam(m
, p
.second
);
404 static bool Read(const Message
* m
, PickleIterator
* iter
,
406 return ReadParam(m
, iter
, &r
->first
) && ReadParam(m
, iter
, &r
->second
);
408 static void Log(const param_type
& p
, std::string
* l
) {
410 LogParam(p
.first
, l
);
412 LogParam(p
.second
, l
);
417 // Base ParamTraits ------------------------------------------------------------
420 struct IPC_EXPORT ParamTraits
<base::DictionaryValue
> {
421 typedef base::DictionaryValue param_type
;
422 static void Write(Message
* m
, const param_type
& p
);
423 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
424 static void Log(const param_type
& p
, std::string
* l
);
427 #if defined(OS_POSIX)
428 // FileDescriptors may be serialised over IPC channels on POSIX. On the
429 // receiving side, the FileDescriptor is a valid duplicate of the file
430 // descriptor which was transmitted: *it is not just a copy of the integer like
431 // HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
432 // this case, the receiving end will see a value of -1. *Zero is a valid file
435 // The received file descriptor will have the |auto_close| flag set to true. The
436 // code which handles the message is responsible for taking ownership of it.
437 // File descriptors are OS resources and must be closed when no longer needed.
439 // When sending a file descriptor, the file descriptor must be valid at the time
440 // of transmission. Since transmission is not synchronous, one should consider
441 // dup()ing any file descriptors to be transmitted and setting the |auto_close|
442 // flag, which causes the file descriptor to be closed after writing.
444 struct IPC_EXPORT ParamTraits
<base::FileDescriptor
> {
445 typedef base::FileDescriptor param_type
;
446 static void Write(Message
* m
, const param_type
& p
);
447 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
448 static void Log(const param_type
& p
, std::string
* l
);
450 #endif // defined(OS_POSIX)
453 struct IPC_EXPORT ParamTraits
<base::FilePath
> {
454 typedef base::FilePath param_type
;
455 static void Write(Message
* m
, const param_type
& p
);
456 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
457 static void Log(const param_type
& p
, std::string
* l
);
461 struct IPC_EXPORT ParamTraits
<base::ListValue
> {
462 typedef base::ListValue param_type
;
463 static void Write(Message
* m
, const param_type
& p
);
464 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
465 static void Log(const param_type
& p
, std::string
* l
);
469 struct IPC_EXPORT ParamTraits
<base::NullableString16
> {
470 typedef base::NullableString16 param_type
;
471 static void Write(Message
* m
, const param_type
& p
);
472 static bool Read(const Message
* m
, PickleIterator
* iter
,
474 static void Log(const param_type
& p
, std::string
* l
);
478 struct IPC_EXPORT ParamTraits
<base::File::Info
> {
479 typedef base::File::Info param_type
;
480 static void Write(Message
* m
, const param_type
& p
);
481 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
482 static void Log(const param_type
& p
, std::string
* l
);
486 struct SimilarTypeTraits
<base::File::Error
> {
492 struct SimilarTypeTraits
<HWND
> {
495 #endif // defined(OS_WIN)
498 struct IPC_EXPORT ParamTraits
<base::Time
> {
499 typedef base::Time param_type
;
500 static void Write(Message
* m
, const param_type
& p
);
501 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
502 static void Log(const param_type
& p
, std::string
* l
);
506 struct IPC_EXPORT ParamTraits
<base::TimeDelta
> {
507 typedef base::TimeDelta param_type
;
508 static void Write(Message
* m
, const param_type
& p
);
509 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
510 static void Log(const param_type
& p
, std::string
* l
);
514 struct IPC_EXPORT ParamTraits
<base::TimeTicks
> {
515 typedef base::TimeTicks param_type
;
516 static void Write(Message
* m
, const param_type
& p
);
517 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
518 static void Log(const param_type
& p
, std::string
* l
);
522 struct ParamTraits
<Tuple0
> {
523 typedef Tuple0 param_type
;
524 static void Write(Message
* m
, const param_type
& p
) {
526 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
529 static void Log(const param_type
& p
, std::string
* l
) {
534 struct ParamTraits
< Tuple1
<A
> > {
535 typedef Tuple1
<A
> param_type
;
536 static void Write(Message
* m
, const param_type
& p
) {
539 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
540 return ReadParam(m
, iter
, &r
->a
);
542 static void Log(const param_type
& p
, std::string
* l
) {
547 template <class A
, class B
>
548 struct ParamTraits
< Tuple2
<A
, B
> > {
549 typedef Tuple2
<A
, B
> param_type
;
550 static void Write(Message
* m
, const param_type
& p
) {
554 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
555 return (ReadParam(m
, iter
, &r
->a
) &&
556 ReadParam(m
, iter
, &r
->b
));
558 static void Log(const param_type
& p
, std::string
* l
) {
565 template <class A
, class B
, class C
>
566 struct ParamTraits
< Tuple3
<A
, B
, C
> > {
567 typedef Tuple3
<A
, B
, C
> param_type
;
568 static void Write(Message
* m
, const param_type
& p
) {
573 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
574 return (ReadParam(m
, iter
, &r
->a
) &&
575 ReadParam(m
, iter
, &r
->b
) &&
576 ReadParam(m
, iter
, &r
->c
));
578 static void Log(const param_type
& p
, std::string
* l
) {
587 template <class A
, class B
, class C
, class D
>
588 struct ParamTraits
< Tuple4
<A
, B
, C
, D
> > {
589 typedef Tuple4
<A
, B
, C
, D
> param_type
;
590 static void Write(Message
* m
, const param_type
& p
) {
596 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
597 return (ReadParam(m
, iter
, &r
->a
) &&
598 ReadParam(m
, iter
, &r
->b
) &&
599 ReadParam(m
, iter
, &r
->c
) &&
600 ReadParam(m
, iter
, &r
->d
));
602 static void Log(const param_type
& p
, std::string
* l
) {
613 template <class A
, class B
, class C
, class D
, class E
>
614 struct ParamTraits
< Tuple5
<A
, B
, C
, D
, E
> > {
615 typedef Tuple5
<A
, B
, C
, D
, E
> param_type
;
616 static void Write(Message
* m
, const param_type
& p
) {
623 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
624 return (ReadParam(m
, iter
, &r
->a
) &&
625 ReadParam(m
, iter
, &r
->b
) &&
626 ReadParam(m
, iter
, &r
->c
) &&
627 ReadParam(m
, iter
, &r
->d
) &&
628 ReadParam(m
, iter
, &r
->e
));
630 static void Log(const param_type
& p
, std::string
* l
) {
644 struct ParamTraits
<ScopedVector
<P
> > {
645 typedef ScopedVector
<P
> param_type
;
646 static void Write(Message
* m
, const param_type
& p
) {
647 WriteParam(m
, static_cast<int>(p
.size()));
648 for (size_t i
= 0; i
< p
.size(); i
++)
649 WriteParam(m
, *p
[i
]);
651 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
653 if (!m
->ReadLength(iter
, &size
))
655 if (INT_MAX
/sizeof(P
) <= static_cast<size_t>(size
))
658 for (int i
= 0; i
< size
; i
++) {
660 if (!ReadParam(m
, iter
, (*r
)[i
]))
665 static void Log(const param_type
& p
, std::string
* l
) {
666 for (size_t i
= 0; i
< p
.size(); ++i
) {
674 template <typename NormalMap
,
678 struct ParamTraits
<base::SmallMap
<NormalMap
, kArraySize
, EqualKey
, MapInit
> > {
679 typedef base::SmallMap
<NormalMap
, kArraySize
, EqualKey
, MapInit
> param_type
;
680 typedef typename
param_type::key_type K
;
681 typedef typename
param_type::data_type V
;
682 static void Write(Message
* m
, const param_type
& p
) {
683 WriteParam(m
, static_cast<int>(p
.size()));
684 typename
param_type::const_iterator iter
;
685 for (iter
= p
.begin(); iter
!= p
.end(); ++iter
) {
686 WriteParam(m
, iter
->first
);
687 WriteParam(m
, iter
->second
);
690 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
692 if (!m
->ReadLength(iter
, &size
))
694 for (int i
= 0; i
< size
; ++i
) {
696 if (!ReadParam(m
, iter
, &key
))
698 V
& value
= (*r
)[key
];
699 if (!ReadParam(m
, iter
, &value
))
704 static void Log(const param_type
& p
, std::string
* l
) {
705 l
->append("<base::SmallMap>");
709 // IPC types ParamTraits -------------------------------------------------------
711 // A ChannelHandle is basically a platform-inspecific wrapper around the
712 // fact that IPC endpoints are handled specially on POSIX. See above comments
713 // on FileDescriptor for more background.
715 struct IPC_EXPORT ParamTraits
<IPC::ChannelHandle
> {
716 typedef ChannelHandle param_type
;
717 static void Write(Message
* m
, const param_type
& p
);
718 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
719 static void Log(const param_type
& p
, std::string
* l
);
723 struct IPC_EXPORT ParamTraits
<LogData
> {
724 typedef LogData param_type
;
725 static void Write(Message
* m
, const param_type
& p
);
726 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
727 static void Log(const param_type
& p
, std::string
* l
);
731 struct IPC_EXPORT ParamTraits
<Message
> {
732 static void Write(Message
* m
, const Message
& p
);
733 static bool Read(const Message
* m
, PickleIterator
* iter
, Message
* r
);
734 static void Log(const Message
& p
, std::string
* l
);
737 // Windows ParamTraits ---------------------------------------------------------
741 struct IPC_EXPORT ParamTraits
<HANDLE
> {
742 typedef HANDLE param_type
;
743 static void Write(Message
* m
, const param_type
& p
);
744 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
745 static void Log(const param_type
& p
, std::string
* l
);
749 struct IPC_EXPORT ParamTraits
<LOGFONT
> {
750 typedef LOGFONT param_type
;
751 static void Write(Message
* m
, const param_type
& p
);
752 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
753 static void Log(const param_type
& p
, std::string
* l
);
757 struct IPC_EXPORT ParamTraits
<MSG
> {
758 typedef MSG param_type
;
759 static void Write(Message
* m
, const param_type
& p
);
760 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
761 static void Log(const param_type
& p
, std::string
* l
);
763 #endif // defined(OS_WIN)
765 //-----------------------------------------------------------------------------
766 // Generic message subclasses
768 // Used for asynchronous messages.
769 template <class ParamType
>
770 class MessageSchema
{
772 typedef ParamType Param
;
773 typedef typename TupleTypes
<ParamType
>::ParamTuple RefParam
;
775 static void Write(Message
* msg
, const RefParam
& p
) IPC_MSG_NOINLINE
;
776 static bool Read(const Message
* msg
, Param
* p
) IPC_MSG_NOINLINE
;
779 // defined in ipc_logging.cc
780 IPC_EXPORT
void GenerateLogData(const std::string
& channel
,
781 const Message
& message
,
782 LogData
* data
, bool get_params
);
785 #if defined(IPC_MESSAGE_LOG_ENABLED)
786 inline void AddOutputParamsToLog(const Message
* msg
, std::string
* l
) {
787 const std::string
& output_params
= msg
->output_params();
788 if (!l
->empty() && !output_params
.empty())
791 l
->append(output_params
);
794 template <class ReplyParamType
>
795 inline void LogReplyParamsToMessage(const ReplyParamType
& reply_params
,
796 const Message
* msg
) {
797 if (msg
->received_time() != 0) {
798 std::string output_params
;
799 LogParam(reply_params
, &output_params
);
800 msg
->set_output_params(output_params
);
804 inline void ConnectMessageAndReply(const Message
* msg
, Message
* reply
) {
805 if (msg
->sent_time()) {
806 // Don't log the sync message after dispatch, as we don't have the
807 // output parameters at that point. Instead, save its data and log it
808 // with the outgoing reply message when it's sent.
809 LogData
* data
= new LogData
;
810 GenerateLogData("", *msg
, data
, true);
812 reply
->set_sync_log_data(data
);
816 inline void AddOutputParamsToLog(const Message
* msg
, std::string
* l
) {}
818 template <class ReplyParamType
>
819 inline void LogReplyParamsToMessage(const ReplyParamType
& reply_params
,
820 const Message
* msg
) {}
822 inline void ConnectMessageAndReply(const Message
* msg
, Message
* reply
) {}
825 // This class assumes that its template argument is a RefTuple (a Tuple with
826 // reference elements). This would go into ipc_message_utils_impl.h, but it is
827 // also used by chrome_frame.
828 template <class RefTuple
>
829 class ParamDeserializer
: public MessageReplyDeserializer
{
831 explicit ParamDeserializer(const RefTuple
& out
) : out_(out
) { }
833 bool SerializeOutputParameters(const IPC::Message
& msg
, PickleIterator iter
) {
834 return ReadParam(&msg
, &iter
, &out_
);
840 // Used for synchronous messages.
841 template <class SendParamType
, class ReplyParamType
>
842 class SyncMessageSchema
{
844 typedef SendParamType SendParam
;
845 typedef typename TupleTypes
<SendParam
>::ParamTuple RefSendParam
;
846 typedef ReplyParamType ReplyParam
;
848 static void Write(Message
* msg
, const RefSendParam
& send
) IPC_MSG_NOINLINE
;
849 static bool ReadSendParam(const Message
* msg
, SendParam
* p
) IPC_MSG_NOINLINE
;
850 static bool ReadReplyParam(
852 typename TupleTypes
<ReplyParam
>::ValueTuple
* p
) IPC_MSG_NOINLINE
;
854 template<class T
, class S
, class Method
>
855 static bool DispatchWithSendParams(bool ok
, const SendParam
& send_params
,
856 const Message
* msg
, T
* obj
, S
* sender
,
858 Message
* reply
= SyncMessage::GenerateReply(msg
);
860 typename TupleTypes
<ReplyParam
>::ValueTuple reply_params
;
861 DispatchToMethod(obj
, func
, send_params
, &reply_params
);
862 WriteParam(reply
, reply_params
);
863 LogReplyParamsToMessage(reply_params
, msg
);
865 NOTREACHED() << "Error deserializing message " << msg
->type();
866 reply
->set_reply_error();
872 template<class T
, class Method
>
873 static bool DispatchDelayReplyWithSendParams(bool ok
,
874 const SendParam
& send_params
,
875 const Message
* msg
, T
* obj
,
877 Message
* reply
= SyncMessage::GenerateReply(msg
);
879 Tuple1
<Message
&> t
= MakeRefTuple(*reply
);
880 ConnectMessageAndReply(msg
, reply
);
881 DispatchToMethod(obj
, func
, send_params
, &t
);
883 NOTREACHED() << "Error deserializing message " << msg
->type();
884 reply
->set_reply_error();
890 template<typename TA
>
891 static void WriteReplyParams(Message
* reply
, TA a
) {
893 WriteParam(reply
, p
);
896 template<typename TA
, typename TB
>
897 static void WriteReplyParams(Message
* reply
, TA a
, TB b
) {
899 WriteParam(reply
, p
);
902 template<typename TA
, typename TB
, typename TC
>
903 static void WriteReplyParams(Message
* reply
, TA a
, TB b
, TC c
) {
904 ReplyParam
p(a
, b
, c
);
905 WriteParam(reply
, p
);
908 template<typename TA
, typename TB
, typename TC
, typename TD
>
909 static void WriteReplyParams(Message
* reply
, TA a
, TB b
, TC c
, TD d
) {
910 ReplyParam
p(a
, b
, c
, d
);
911 WriteParam(reply
, p
);
914 template<typename TA
, typename TB
, typename TC
, typename TD
, typename TE
>
915 static void WriteReplyParams(Message
* reply
, TA a
, TB b
, TC c
, TD d
, TE e
) {
916 ReplyParam
p(a
, b
, c
, d
, e
);
917 WriteParam(reply
, p
);
923 #endif // IPC_IPC_MESSAGE_UTILS_H_