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/format_macros.h"
15 #include "base/memory/scoped_vector.h"
16 #include "base/platform_file.h"
17 #include "base/string16.h"
18 #include "base/stringprintf.h"
19 #include "base/string_util.h"
20 #include "base/tuple.h"
21 #include "ipc/ipc_message_start.h"
22 #include "ipc/ipc_param_traits.h"
23 #include "ipc/ipc_sync_message.h"
25 #if defined(COMPILER_GCC)
26 // GCC "helpfully" tries to inline template methods in release mode. Except we
27 // want the majority of the template junk being expanded once in the
28 // implementation file (and only provide the definitions in
29 // ipc_message_utils_impl.h in those files) and exported, instead of expanded
30 // at every call site. Special note: GCC happily accepts the attribute before
31 // the method declaration, but only acts on it if it is after.
32 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 40500
33 // Starting in gcc 4.5, the noinline no longer implies the concept covered by
34 // the introduced noclone attribute, which will create specialized versions of
35 // functions/methods when certain types are constant.
36 // www.gnu.org/software/gcc/gcc-4.5/changes.html
37 #define IPC_MSG_NOINLINE __attribute__((noinline, noclone));
39 #define IPC_MSG_NOINLINE __attribute__((noinline));
41 #elif defined(COMPILER_MSVC)
42 // MSVC++ doesn't do this.
43 #define IPC_MSG_NOINLINE
45 #error "Please add the noinline property for your new compiler here."
48 class NullableString16
;
51 class DictionaryValue
;
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 ParamTraits
<int> {
126 typedef int param_type
;
127 static void Write(Message
* m
, const param_type
& p
) {
130 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
131 return m
->ReadInt(iter
, r
);
133 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
137 struct ParamTraits
<unsigned int> {
138 typedef unsigned int param_type
;
139 static void Write(Message
* m
, const param_type
& p
) {
142 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
143 return m
->ReadInt(iter
, reinterpret_cast<int*>(r
));
145 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
149 struct ParamTraits
<long> {
150 typedef long param_type
;
151 static void Write(Message
* m
, const param_type
& p
) {
152 m
->WriteLongUsingDangerousNonPortableLessPersistableForm(p
);
154 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
155 return m
->ReadLong(iter
, r
);
157 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
161 struct ParamTraits
<unsigned long> {
162 typedef unsigned long param_type
;
163 static void Write(Message
* m
, const param_type
& p
) {
164 m
->WriteLongUsingDangerousNonPortableLessPersistableForm(p
);
166 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
167 return m
->ReadLong(iter
, reinterpret_cast<long*>(r
));
169 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
173 struct ParamTraits
<long long> {
174 typedef long long param_type
;
175 static void Write(Message
* m
, const param_type
& p
) {
176 m
->WriteInt64(static_cast<int64
>(p
));
178 static bool Read(const Message
* m
, PickleIterator
* iter
,
180 return m
->ReadInt64(iter
, reinterpret_cast<int64
*>(r
));
182 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
186 struct ParamTraits
<unsigned long long> {
187 typedef unsigned long long param_type
;
188 static void Write(Message
* m
, const param_type
& p
) {
191 static bool Read(const Message
* m
, PickleIterator
* iter
,
193 return m
->ReadInt64(iter
, reinterpret_cast<int64
*>(r
));
195 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
199 struct IPC_EXPORT ParamTraits
<unsigned short> {
200 typedef unsigned short param_type
;
201 static void Write(Message
* m
, const param_type
& p
);
202 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
203 static void Log(const param_type
& p
, std::string
* l
);
206 // Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
207 // should be sure to check the sanity of these values after receiving them over
210 struct IPC_EXPORT ParamTraits
<float> {
211 typedef float param_type
;
212 static void Write(Message
* m
, const param_type
& p
);
213 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
214 static void Log(const param_type
& p
, std::string
* l
);
218 struct IPC_EXPORT ParamTraits
<double> {
219 typedef double param_type
;
220 static void Write(Message
* m
, const param_type
& p
);
221 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
222 static void Log(const param_type
& p
, std::string
* l
);
225 // STL ParamTraits -------------------------------------------------------------
228 struct ParamTraits
<std::string
> {
229 typedef std::string param_type
;
230 static void Write(Message
* m
, const param_type
& p
) {
233 static bool Read(const Message
* m
, PickleIterator
* iter
,
235 return m
->ReadString(iter
, r
);
237 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
241 struct ParamTraits
<std::wstring
> {
242 typedef std::wstring param_type
;
243 static void Write(Message
* m
, const param_type
& p
) {
246 static bool Read(const Message
* m
, PickleIterator
* iter
,
248 return m
->ReadWString(iter
, r
);
250 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
253 // If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
255 #if !defined(WCHAR_T_IS_UTF16)
257 struct ParamTraits
<string16
> {
258 typedef string16 param_type
;
259 static void Write(Message
* m
, const param_type
& p
) {
262 static bool Read(const Message
* m
, PickleIterator
* iter
,
264 return m
->ReadString16(iter
, r
);
266 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
271 struct IPC_EXPORT ParamTraits
<std::vector
<char> > {
272 typedef std::vector
<char> param_type
;
273 static void Write(Message
* m
, const param_type
& p
);
274 static bool Read(const Message
*, PickleIterator
* iter
, param_type
* r
);
275 static void Log(const param_type
& p
, std::string
* l
);
279 struct IPC_EXPORT ParamTraits
<std::vector
<unsigned char> > {
280 typedef std::vector
<unsigned char> param_type
;
281 static void Write(Message
* m
, const param_type
& p
);
282 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
283 static void Log(const param_type
& p
, std::string
* l
);
287 struct IPC_EXPORT ParamTraits
<std::vector
<bool> > {
288 typedef std::vector
<bool> param_type
;
289 static void Write(Message
* m
, const param_type
& p
);
290 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
291 static void Log(const param_type
& p
, std::string
* l
);
295 struct ParamTraits
<std::vector
<P
> > {
296 typedef std::vector
<P
> param_type
;
297 static void Write(Message
* m
, const param_type
& p
) {
298 WriteParam(m
, static_cast<int>(p
.size()));
299 for (size_t i
= 0; i
< p
.size(); i
++)
302 static bool Read(const Message
* m
, PickleIterator
* iter
,
305 // ReadLength() checks for < 0 itself.
306 if (!m
->ReadLength(iter
, &size
))
308 // Resizing beforehand is not safe, see BUG 1006367 for details.
309 if (INT_MAX
/ sizeof(P
) <= static_cast<size_t>(size
))
312 for (int i
= 0; i
< size
; i
++) {
313 if (!ReadParam(m
, iter
, &(*r
)[i
]))
318 static void Log(const param_type
& p
, std::string
* l
) {
319 for (size_t i
= 0; i
< p
.size(); ++i
) {
328 struct ParamTraits
<std::set
<P
> > {
329 typedef std::set
<P
> param_type
;
330 static void Write(Message
* m
, const param_type
& p
) {
331 WriteParam(m
, static_cast<int>(p
.size()));
332 typename
param_type::const_iterator iter
;
333 for (iter
= p
.begin(); iter
!= p
.end(); ++iter
)
334 WriteParam(m
, *iter
);
336 static bool Read(const Message
* m
, PickleIterator
* iter
,
339 if (!m
->ReadLength(iter
, &size
))
341 for (int i
= 0; i
< size
; ++i
) {
343 if (!ReadParam(m
, iter
, &item
))
349 static void Log(const param_type
& p
, std::string
* l
) {
350 l
->append("<std::set>");
354 template <class K
, class V
>
355 struct ParamTraits
<std::map
<K
, V
> > {
356 typedef std::map
<K
, V
> param_type
;
357 static void Write(Message
* m
, const param_type
& p
) {
358 WriteParam(m
, static_cast<int>(p
.size()));
359 typename
param_type::const_iterator iter
;
360 for (iter
= p
.begin(); iter
!= p
.end(); ++iter
) {
361 WriteParam(m
, iter
->first
);
362 WriteParam(m
, iter
->second
);
365 static bool Read(const Message
* m
, PickleIterator
* iter
,
368 if (!ReadParam(m
, iter
, &size
) || size
< 0)
370 for (int i
= 0; i
< size
; ++i
) {
372 if (!ReadParam(m
, iter
, &k
))
375 if (!ReadParam(m
, iter
, &value
))
380 static void Log(const param_type
& p
, std::string
* l
) {
381 l
->append("<std::map>");
385 template <class A
, class B
>
386 struct ParamTraits
<std::pair
<A
, B
> > {
387 typedef std::pair
<A
, B
> param_type
;
388 static void Write(Message
* m
, const param_type
& p
) {
389 WriteParam(m
, p
.first
);
390 WriteParam(m
, p
.second
);
392 static bool Read(const Message
* m
, PickleIterator
* iter
,
394 return ReadParam(m
, iter
, &r
->first
) && ReadParam(m
, iter
, &r
->second
);
396 static void Log(const param_type
& p
, std::string
* l
) {
398 LogParam(p
.first
, l
);
400 LogParam(p
.second
, l
);
405 // Base ParamTraits ------------------------------------------------------------
408 struct IPC_EXPORT ParamTraits
<base::DictionaryValue
> {
409 typedef base::DictionaryValue param_type
;
410 static void Write(Message
* m
, const param_type
& p
);
411 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
412 static void Log(const param_type
& p
, std::string
* l
);
415 #if defined(OS_POSIX)
416 // FileDescriptors may be serialised over IPC channels on POSIX. On the
417 // receiving side, the FileDescriptor is a valid duplicate of the file
418 // descriptor which was transmitted: *it is not just a copy of the integer like
419 // HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
420 // this case, the receiving end will see a value of -1. *Zero is a valid file
423 // The received file descriptor will have the |auto_close| flag set to true. The
424 // code which handles the message is responsible for taking ownership of it.
425 // File descriptors are OS resources and must be closed when no longer needed.
427 // When sending a file descriptor, the file descriptor must be valid at the time
428 // of transmission. Since transmission is not synchronous, one should consider
429 // dup()ing any file descriptors to be transmitted and setting the |auto_close|
430 // flag, which causes the file descriptor to be closed after writing.
432 struct IPC_EXPORT ParamTraits
<base::FileDescriptor
> {
433 typedef base::FileDescriptor param_type
;
434 static void Write(Message
* m
, const param_type
& p
);
435 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
436 static void Log(const param_type
& p
, std::string
* l
);
438 #endif // defined(OS_POSIX)
441 struct IPC_EXPORT ParamTraits
<base::FilePath
> {
442 typedef base::FilePath param_type
;
443 static void Write(Message
* m
, const param_type
& p
);
444 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
445 static void Log(const param_type
& p
, std::string
* l
);
449 struct IPC_EXPORT ParamTraits
<base::ListValue
> {
450 typedef base::ListValue param_type
;
451 static void Write(Message
* m
, const param_type
& p
);
452 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
453 static void Log(const param_type
& p
, std::string
* l
);
457 struct IPC_EXPORT ParamTraits
<NullableString16
> {
458 typedef NullableString16 param_type
;
459 static void Write(Message
* m
, const param_type
& p
);
460 static bool Read(const Message
* m
, PickleIterator
* iter
,
462 static void Log(const param_type
& p
, std::string
* l
);
466 struct IPC_EXPORT ParamTraits
<base::PlatformFileInfo
> {
467 typedef base::PlatformFileInfo param_type
;
468 static void Write(Message
* m
, const param_type
& p
);
469 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
470 static void Log(const param_type
& p
, std::string
* l
);
474 struct SimilarTypeTraits
<base::PlatformFileError
> {
480 struct SimilarTypeTraits
<HWND
> {
483 #endif // defined(OS_WIN)
486 struct IPC_EXPORT ParamTraits
<base::Time
> {
487 typedef base::Time param_type
;
488 static void Write(Message
* m
, const param_type
& p
);
489 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
490 static void Log(const param_type
& p
, std::string
* l
);
494 struct IPC_EXPORT ParamTraits
<base::TimeDelta
> {
495 typedef base::TimeDelta param_type
;
496 static void Write(Message
* m
, const param_type
& p
);
497 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
498 static void Log(const param_type
& p
, std::string
* l
);
502 struct IPC_EXPORT ParamTraits
<base::TimeTicks
> {
503 typedef base::TimeTicks param_type
;
504 static void Write(Message
* m
, const param_type
& p
);
505 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
506 static void Log(const param_type
& p
, std::string
* l
);
510 struct ParamTraits
<Tuple0
> {
511 typedef Tuple0 param_type
;
512 static void Write(Message
* m
, const param_type
& p
) {
514 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
517 static void Log(const param_type
& p
, std::string
* l
) {
522 struct ParamTraits
< Tuple1
<A
> > {
523 typedef Tuple1
<A
> param_type
;
524 static void Write(Message
* m
, const param_type
& p
) {
527 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
528 return ReadParam(m
, iter
, &r
->a
);
530 static void Log(const param_type
& p
, std::string
* l
) {
535 template <class A
, class B
>
536 struct ParamTraits
< Tuple2
<A
, B
> > {
537 typedef Tuple2
<A
, B
> param_type
;
538 static void Write(Message
* m
, const param_type
& p
) {
542 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
543 return (ReadParam(m
, iter
, &r
->a
) &&
544 ReadParam(m
, iter
, &r
->b
));
546 static void Log(const param_type
& p
, std::string
* l
) {
553 template <class A
, class B
, class C
>
554 struct ParamTraits
< Tuple3
<A
, B
, C
> > {
555 typedef Tuple3
<A
, B
, C
> param_type
;
556 static void Write(Message
* m
, const param_type
& p
) {
561 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
562 return (ReadParam(m
, iter
, &r
->a
) &&
563 ReadParam(m
, iter
, &r
->b
) &&
564 ReadParam(m
, iter
, &r
->c
));
566 static void Log(const param_type
& p
, std::string
* l
) {
575 template <class A
, class B
, class C
, class D
>
576 struct ParamTraits
< Tuple4
<A
, B
, C
, D
> > {
577 typedef Tuple4
<A
, B
, C
, D
> param_type
;
578 static void Write(Message
* m
, const param_type
& p
) {
584 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
585 return (ReadParam(m
, iter
, &r
->a
) &&
586 ReadParam(m
, iter
, &r
->b
) &&
587 ReadParam(m
, iter
, &r
->c
) &&
588 ReadParam(m
, iter
, &r
->d
));
590 static void Log(const param_type
& p
, std::string
* l
) {
601 template <class A
, class B
, class C
, class D
, class E
>
602 struct ParamTraits
< Tuple5
<A
, B
, C
, D
, E
> > {
603 typedef Tuple5
<A
, B
, C
, D
, E
> param_type
;
604 static void Write(Message
* m
, const param_type
& p
) {
611 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
612 return (ReadParam(m
, iter
, &r
->a
) &&
613 ReadParam(m
, iter
, &r
->b
) &&
614 ReadParam(m
, iter
, &r
->c
) &&
615 ReadParam(m
, iter
, &r
->d
) &&
616 ReadParam(m
, iter
, &r
->e
));
618 static void Log(const param_type
& p
, std::string
* l
) {
632 struct ParamTraits
<ScopedVector
<P
> > {
633 typedef ScopedVector
<P
> param_type
;
634 static void Write(Message
* m
, const param_type
& p
) {
635 WriteParam(m
, static_cast<int>(p
.size()));
636 for (size_t i
= 0; i
< p
.size(); i
++)
637 WriteParam(m
, *p
[i
]);
639 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
641 if (!m
->ReadLength(iter
, &size
))
643 if (INT_MAX
/sizeof(P
) <= static_cast<size_t>(size
))
646 for (int i
= 0; i
< size
; i
++) {
648 if (!ReadParam(m
, iter
, (*r
)[i
]))
653 static void Log(const param_type
& p
, std::string
* l
) {
654 for (size_t i
= 0; i
< p
.size(); ++i
) {
662 // IPC types ParamTraits -------------------------------------------------------
664 // A ChannelHandle is basically a platform-inspecific wrapper around the
665 // fact that IPC endpoints are handled specially on POSIX. See above comments
666 // on FileDescriptor for more background.
668 struct IPC_EXPORT ParamTraits
<IPC::ChannelHandle
> {
669 typedef ChannelHandle param_type
;
670 static void Write(Message
* m
, const param_type
& p
);
671 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
672 static void Log(const param_type
& p
, std::string
* l
);
676 struct IPC_EXPORT ParamTraits
<LogData
> {
677 typedef LogData param_type
;
678 static void Write(Message
* m
, const param_type
& p
);
679 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
680 static void Log(const param_type
& p
, std::string
* l
);
684 struct IPC_EXPORT ParamTraits
<Message
> {
685 static void Write(Message
* m
, const Message
& p
);
686 static bool Read(const Message
* m
, PickleIterator
* iter
, Message
* r
);
687 static void Log(const Message
& p
, std::string
* l
);
690 // Windows ParamTraits ---------------------------------------------------------
694 struct IPC_EXPORT ParamTraits
<HANDLE
> {
695 typedef HANDLE param_type
;
696 static void Write(Message
* m
, const param_type
& p
);
697 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
698 static void Log(const param_type
& p
, std::string
* l
);
702 struct IPC_EXPORT ParamTraits
<LOGFONT
> {
703 typedef LOGFONT param_type
;
704 static void Write(Message
* m
, const param_type
& p
);
705 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
706 static void Log(const param_type
& p
, std::string
* l
);
710 struct IPC_EXPORT ParamTraits
<MSG
> {
711 typedef MSG param_type
;
712 static void Write(Message
* m
, const param_type
& p
);
713 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
714 static void Log(const param_type
& p
, std::string
* l
);
716 #endif // defined(OS_WIN)
718 //-----------------------------------------------------------------------------
719 // Generic message subclasses
721 // Used for asynchronous messages.
722 template <class ParamType
>
723 class MessageSchema
{
725 typedef ParamType Param
;
726 typedef typename TupleTypes
<ParamType
>::ParamTuple RefParam
;
728 static void Write(Message
* msg
, const RefParam
& p
) IPC_MSG_NOINLINE
;
729 static bool Read(const Message
* msg
, Param
* p
) IPC_MSG_NOINLINE
;
732 // defined in ipc_logging.cc
733 IPC_EXPORT
void GenerateLogData(const std::string
& channel
,
734 const Message
& message
,
735 LogData
* data
, bool get_params
);
738 #if defined(IPC_MESSAGE_LOG_ENABLED)
739 inline void AddOutputParamsToLog(const Message
* msg
, std::string
* l
) {
740 const std::string
& output_params
= msg
->output_params();
741 if (!l
->empty() && !output_params
.empty())
744 l
->append(output_params
);
747 template <class ReplyParamType
>
748 inline void LogReplyParamsToMessage(const ReplyParamType
& reply_params
,
749 const Message
* msg
) {
750 if (msg
->received_time() != 0) {
751 std::string output_params
;
752 LogParam(reply_params
, &output_params
);
753 msg
->set_output_params(output_params
);
757 inline void ConnectMessageAndReply(const Message
* msg
, Message
* reply
) {
758 if (msg
->sent_time()) {
759 // Don't log the sync message after dispatch, as we don't have the
760 // output parameters at that point. Instead, save its data and log it
761 // with the outgoing reply message when it's sent.
762 LogData
* data
= new LogData
;
763 GenerateLogData("", *msg
, data
, true);
765 reply
->set_sync_log_data(data
);
769 inline void AddOutputParamsToLog(const Message
* msg
, std::string
* l
) {}
771 template <class ReplyParamType
>
772 inline void LogReplyParamsToMessage(const ReplyParamType
& reply_params
,
773 const Message
* msg
) {}
775 inline void ConnectMessageAndReply(const Message
* msg
, Message
* reply
) {}
778 // This class assumes that its template argument is a RefTuple (a Tuple with
779 // reference elements). This would go into ipc_message_utils_impl.h, but it is
780 // also used by chrome_frame.
781 template <class RefTuple
>
782 class ParamDeserializer
: public MessageReplyDeserializer
{
784 explicit ParamDeserializer(const RefTuple
& out
) : out_(out
) { }
786 bool SerializeOutputParameters(const IPC::Message
& msg
, PickleIterator iter
) {
787 return ReadParam(&msg
, &iter
, &out_
);
793 // Used for synchronous messages.
794 template <class SendParamType
, class ReplyParamType
>
795 class SyncMessageSchema
{
797 typedef SendParamType SendParam
;
798 typedef typename TupleTypes
<SendParam
>::ParamTuple RefSendParam
;
799 typedef ReplyParamType ReplyParam
;
801 static void Write(Message
* msg
, const RefSendParam
& send
) IPC_MSG_NOINLINE
;
802 static bool ReadSendParam(const Message
* msg
, SendParam
* p
) IPC_MSG_NOINLINE
;
803 static bool ReadReplyParam(
805 typename TupleTypes
<ReplyParam
>::ValueTuple
* p
) IPC_MSG_NOINLINE
;
807 template<class T
, class S
, class Method
>
808 static bool DispatchWithSendParams(bool ok
, const SendParam
& send_params
,
809 const Message
* msg
, T
* obj
, S
* sender
,
811 Message
* reply
= SyncMessage::GenerateReply(msg
);
813 typename TupleTypes
<ReplyParam
>::ValueTuple reply_params
;
814 DispatchToMethod(obj
, func
, send_params
, &reply_params
);
815 WriteParam(reply
, reply_params
);
816 LogReplyParamsToMessage(reply_params
, msg
);
818 NOTREACHED() << "Error deserializing message " << msg
->type();
819 reply
->set_reply_error();
825 template<class T
, class Method
>
826 static bool DispatchDelayReplyWithSendParams(bool ok
,
827 const SendParam
& send_params
,
828 const Message
* msg
, T
* obj
,
830 Message
* reply
= SyncMessage::GenerateReply(msg
);
832 Tuple1
<Message
&> t
= MakeRefTuple(*reply
);
833 ConnectMessageAndReply(msg
, reply
);
834 DispatchToMethod(obj
, func
, send_params
, &t
);
836 NOTREACHED() << "Error deserializing message " << msg
->type();
837 reply
->set_reply_error();
843 template<typename TA
>
844 static void WriteReplyParams(Message
* reply
, TA a
) {
846 WriteParam(reply
, p
);
849 template<typename TA
, typename TB
>
850 static void WriteReplyParams(Message
* reply
, TA a
, TB b
) {
852 WriteParam(reply
, p
);
855 template<typename TA
, typename TB
, typename TC
>
856 static void WriteReplyParams(Message
* reply
, TA a
, TB b
, TC c
) {
857 ReplyParam
p(a
, b
, c
);
858 WriteParam(reply
, p
);
861 template<typename TA
, typename TB
, typename TC
, typename TD
>
862 static void WriteReplyParams(Message
* reply
, TA a
, TB b
, TC c
, TD d
) {
863 ReplyParam
p(a
, b
, c
, d
);
864 WriteParam(reply
, p
);
867 template<typename TA
, typename TB
, typename TC
, typename TD
, typename TE
>
868 static void WriteReplyParams(Message
* reply
, TA a
, TB b
, TC c
, TD d
, TE e
) {
869 ReplyParam
p(a
, b
, c
, d
, e
);
870 WriteParam(reply
, p
);
876 #endif // IPC_IPC_MESSAGE_UTILS_H_