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/platform_file.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));
37 #define IPC_MSG_NOINLINE __attribute__((noinline));
39 #elif defined(COMPILER_MSVC)
40 // MSVC++ doesn't do this.
41 #define IPC_MSG_NOINLINE
43 #error "Please add the noinline property for your new compiler here."
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,
53 ProfileImportMsgStart
,
62 FirefoxImporterUnittestMsgStart
,
63 FileUtilitiesMsgStart
,
69 SpeechRecognitionMsgStart
,
82 DeviceOrientationMsgStart
,
83 DesktopNotificationMsgStart
,
94 TextInputClientMsgStart
,
95 ChromeUtilityMsgStart
,
97 ChromeBenchmarkingMsgStart
,
102 AccessibilityMsgStart
,
105 OldBrowserPluginMsgStart
,
106 BrowserPluginMsgStart
,
108 AndroidWebViewMsgStart
,
112 LastIPCMsgStart
// Must come last.
116 class NullableString16
;
119 class DictionaryValue
;
124 struct FileDescriptor
;
129 struct ChannelHandle
;
131 //-----------------------------------------------------------------------------
132 // An iterator class for reading the fields contained within a Message.
133 class IPC_EXPORT MessageIterator
{
135 explicit MessageIterator(const Message
& m
);
138 const std::string
NextString() const;
141 mutable PickleIterator iter_
;
144 // -----------------------------------------------------------------------------
145 // How we send IPC message logs across channels.
146 struct IPC_EXPORT LogData
{
152 uint32 type
; // "User-defined" message type, from ipc_message.h.
154 int64 sent
; // Time that the message was sent (i.e. at Send()).
155 int64 receive
; // Time before it was dispatched (i.e. before calling
156 // OnMessageReceived).
157 int64 dispatch
; // Time after it was dispatched (i.e. after calling
158 // OnMessageReceived).
159 std::string message_name
;
164 //-----------------------------------------------------------------------------
165 // A dummy struct to place first just to allow leading commas for all
166 // members in the macro-generated constructor initializer lists.
171 static inline void WriteParam(Message
* m
, const P
& p
) {
172 typedef typename SimilarTypeTraits
<P
>::Type Type
;
173 ParamTraits
<Type
>::Write(m
, static_cast<const Type
& >(p
));
177 static inline bool WARN_UNUSED_RESULT
ReadParam(const Message
* m
,
178 PickleIterator
* iter
,
180 typedef typename SimilarTypeTraits
<P
>::Type Type
;
181 return ParamTraits
<Type
>::Read(m
, iter
, reinterpret_cast<Type
* >(p
));
185 static inline void LogParam(const P
& p
, std::string
* l
) {
186 typedef typename SimilarTypeTraits
<P
>::Type Type
;
187 ParamTraits
<Type
>::Log(static_cast<const Type
& >(p
), l
);
190 // Primitive ParamTraits -------------------------------------------------------
193 struct ParamTraits
<bool> {
194 typedef bool param_type
;
195 static void Write(Message
* m
, const param_type
& p
) {
198 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
199 return m
->ReadBool(iter
, r
);
201 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
205 struct ParamTraits
<int> {
206 typedef int param_type
;
207 static void Write(Message
* m
, const param_type
& p
) {
210 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
211 return m
->ReadInt(iter
, r
);
213 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
217 struct ParamTraits
<unsigned int> {
218 typedef unsigned int param_type
;
219 static void Write(Message
* m
, const param_type
& p
) {
222 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
223 return m
->ReadInt(iter
, reinterpret_cast<int*>(r
));
225 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
229 struct ParamTraits
<long> {
230 typedef long param_type
;
231 static void Write(Message
* m
, const param_type
& p
) {
232 m
->WriteLongUsingDangerousNonPortableLessPersistableForm(p
);
234 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
235 return m
->ReadLong(iter
, r
);
237 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
241 struct ParamTraits
<unsigned long> {
242 typedef unsigned long param_type
;
243 static void Write(Message
* m
, const param_type
& p
) {
244 m
->WriteLongUsingDangerousNonPortableLessPersistableForm(p
);
246 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
247 return m
->ReadLong(iter
, reinterpret_cast<long*>(r
));
249 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
253 struct ParamTraits
<long long> {
254 typedef long long param_type
;
255 static void Write(Message
* m
, const param_type
& p
) {
256 m
->WriteInt64(static_cast<int64
>(p
));
258 static bool Read(const Message
* m
, PickleIterator
* iter
,
260 return m
->ReadInt64(iter
, reinterpret_cast<int64
*>(r
));
262 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
266 struct ParamTraits
<unsigned long long> {
267 typedef unsigned long long param_type
;
268 static void Write(Message
* m
, const param_type
& p
) {
271 static bool Read(const Message
* m
, PickleIterator
* iter
,
273 return m
->ReadInt64(iter
, reinterpret_cast<int64
*>(r
));
275 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
279 struct IPC_EXPORT ParamTraits
<unsigned short> {
280 typedef unsigned short 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
);
286 // Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
287 // should be sure to check the sanity of these values after receiving them over
290 struct IPC_EXPORT ParamTraits
<float> {
291 typedef float param_type
;
292 static void Write(Message
* m
, const param_type
& p
);
293 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
294 static void Log(const param_type
& p
, std::string
* l
);
298 struct IPC_EXPORT ParamTraits
<double> {
299 typedef double param_type
;
300 static void Write(Message
* m
, const param_type
& p
);
301 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
302 static void Log(const param_type
& p
, std::string
* l
);
305 // STL ParamTraits -------------------------------------------------------------
308 struct ParamTraits
<std::string
> {
309 typedef std::string param_type
;
310 static void Write(Message
* m
, const param_type
& p
) {
313 static bool Read(const Message
* m
, PickleIterator
* iter
,
315 return m
->ReadString(iter
, r
);
317 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
321 struct ParamTraits
<std::wstring
> {
322 typedef std::wstring param_type
;
323 static void Write(Message
* m
, const param_type
& p
) {
326 static bool Read(const Message
* m
, PickleIterator
* iter
,
328 return m
->ReadWString(iter
, r
);
330 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
333 // If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
335 #if !defined(WCHAR_T_IS_UTF16)
337 struct ParamTraits
<string16
> {
338 typedef string16 param_type
;
339 static void Write(Message
* m
, const param_type
& p
) {
342 static bool Read(const Message
* m
, PickleIterator
* iter
,
344 return m
->ReadString16(iter
, r
);
346 IPC_EXPORT
static void Log(const param_type
& p
, std::string
* l
);
351 struct IPC_EXPORT ParamTraits
<std::vector
<char> > {
352 typedef std::vector
<char> param_type
;
353 static void Write(Message
* m
, const param_type
& p
);
354 static bool Read(const Message
*, PickleIterator
* iter
, param_type
* r
);
355 static void Log(const param_type
& p
, std::string
* l
);
359 struct IPC_EXPORT ParamTraits
<std::vector
<unsigned char> > {
360 typedef std::vector
<unsigned char> param_type
;
361 static void Write(Message
* m
, const param_type
& p
);
362 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
363 static void Log(const param_type
& p
, std::string
* l
);
367 struct IPC_EXPORT ParamTraits
<std::vector
<bool> > {
368 typedef std::vector
<bool> param_type
;
369 static void Write(Message
* m
, const param_type
& p
);
370 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
371 static void Log(const param_type
& p
, std::string
* l
);
375 struct ParamTraits
<std::vector
<P
> > {
376 typedef std::vector
<P
> param_type
;
377 static void Write(Message
* m
, const param_type
& p
) {
378 WriteParam(m
, static_cast<int>(p
.size()));
379 for (size_t i
= 0; i
< p
.size(); i
++)
382 static bool Read(const Message
* m
, PickleIterator
* iter
,
385 // ReadLength() checks for < 0 itself.
386 if (!m
->ReadLength(iter
, &size
))
388 // Resizing beforehand is not safe, see BUG 1006367 for details.
389 if (INT_MAX
/ sizeof(P
) <= static_cast<size_t>(size
))
392 for (int i
= 0; i
< size
; i
++) {
393 if (!ReadParam(m
, iter
, &(*r
)[i
]))
398 static void Log(const param_type
& p
, std::string
* l
) {
399 for (size_t i
= 0; i
< p
.size(); ++i
) {
408 struct ParamTraits
<std::set
<P
> > {
409 typedef std::set
<P
> param_type
;
410 static void Write(Message
* m
, const param_type
& p
) {
411 WriteParam(m
, static_cast<int>(p
.size()));
412 typename
param_type::const_iterator iter
;
413 for (iter
= p
.begin(); iter
!= p
.end(); ++iter
)
414 WriteParam(m
, *iter
);
416 static bool Read(const Message
* m
, PickleIterator
* iter
,
419 if (!m
->ReadLength(iter
, &size
))
421 for (int i
= 0; i
< size
; ++i
) {
423 if (!ReadParam(m
, iter
, &item
))
429 static void Log(const param_type
& p
, std::string
* l
) {
430 l
->append("<std::set>");
434 template <class K
, class V
>
435 struct ParamTraits
<std::map
<K
, V
> > {
436 typedef std::map
<K
, V
> param_type
;
437 static void Write(Message
* m
, const param_type
& p
) {
438 WriteParam(m
, static_cast<int>(p
.size()));
439 typename
param_type::const_iterator iter
;
440 for (iter
= p
.begin(); iter
!= p
.end(); ++iter
) {
441 WriteParam(m
, iter
->first
);
442 WriteParam(m
, iter
->second
);
445 static bool Read(const Message
* m
, PickleIterator
* iter
,
448 if (!ReadParam(m
, iter
, &size
) || size
< 0)
450 for (int i
= 0; i
< size
; ++i
) {
452 if (!ReadParam(m
, iter
, &k
))
455 if (!ReadParam(m
, iter
, &value
))
460 static void Log(const param_type
& p
, std::string
* l
) {
461 l
->append("<std::map>");
465 template <class A
, class B
>
466 struct ParamTraits
<std::pair
<A
, B
> > {
467 typedef std::pair
<A
, B
> param_type
;
468 static void Write(Message
* m
, const param_type
& p
) {
469 WriteParam(m
, p
.first
);
470 WriteParam(m
, p
.second
);
472 static bool Read(const Message
* m
, PickleIterator
* iter
,
474 return ReadParam(m
, iter
, &r
->first
) && ReadParam(m
, iter
, &r
->second
);
476 static void Log(const param_type
& p
, std::string
* l
) {
478 LogParam(p
.first
, l
);
480 LogParam(p
.second
, l
);
485 // Base ParamTraits ------------------------------------------------------------
488 struct IPC_EXPORT ParamTraits
<base::DictionaryValue
> {
489 typedef base::DictionaryValue param_type
;
490 static void Write(Message
* m
, const param_type
& p
);
491 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
492 static void Log(const param_type
& p
, std::string
* l
);
495 #if defined(OS_POSIX)
496 // FileDescriptors may be serialised over IPC channels on POSIX. On the
497 // receiving side, the FileDescriptor is a valid duplicate of the file
498 // descriptor which was transmitted: *it is not just a copy of the integer like
499 // HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
500 // this case, the receiving end will see a value of -1. *Zero is a valid file
503 // The received file descriptor will have the |auto_close| flag set to true. The
504 // code which handles the message is responsible for taking ownership of it.
505 // File descriptors are OS resources and must be closed when no longer needed.
507 // When sending a file descriptor, the file descriptor must be valid at the time
508 // of transmission. Since transmission is not synchronous, one should consider
509 // dup()ing any file descriptors to be transmitted and setting the |auto_close|
510 // flag, which causes the file descriptor to be closed after writing.
512 struct IPC_EXPORT ParamTraits
<base::FileDescriptor
> {
513 typedef base::FileDescriptor param_type
;
514 static void Write(Message
* m
, const param_type
& p
);
515 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
516 static void Log(const param_type
& p
, std::string
* l
);
518 #endif // defined(OS_POSIX)
521 struct IPC_EXPORT ParamTraits
<FilePath
> {
522 typedef FilePath param_type
;
523 static void Write(Message
* m
, const param_type
& p
);
524 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
525 static void Log(const param_type
& p
, std::string
* l
);
529 struct IPC_EXPORT ParamTraits
<base::ListValue
> {
530 typedef base::ListValue param_type
;
531 static void Write(Message
* m
, const param_type
& p
);
532 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
533 static void Log(const param_type
& p
, std::string
* l
);
537 struct IPC_EXPORT ParamTraits
<NullableString16
> {
538 typedef NullableString16 param_type
;
539 static void Write(Message
* m
, const param_type
& p
);
540 static bool Read(const Message
* m
, PickleIterator
* iter
,
542 static void Log(const param_type
& p
, std::string
* l
);
546 struct IPC_EXPORT ParamTraits
<base::PlatformFileInfo
> {
547 typedef base::PlatformFileInfo param_type
;
548 static void Write(Message
* m
, const param_type
& p
);
549 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
550 static void Log(const param_type
& p
, std::string
* l
);
554 struct SimilarTypeTraits
<base::PlatformFileError
> {
559 struct IPC_EXPORT ParamTraits
<base::Time
> {
560 typedef base::Time param_type
;
561 static void Write(Message
* m
, const param_type
& p
);
562 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
563 static void Log(const param_type
& p
, std::string
* l
);
567 struct IPC_EXPORT ParamTraits
<base::TimeDelta
> {
568 typedef base::TimeDelta param_type
;
569 static void Write(Message
* m
, const param_type
& p
);
570 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
571 static void Log(const param_type
& p
, std::string
* l
);
575 struct IPC_EXPORT ParamTraits
<base::TimeTicks
> {
576 typedef base::TimeTicks param_type
;
577 static void Write(Message
* m
, const param_type
& p
);
578 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
579 static void Log(const param_type
& p
, std::string
* l
);
583 struct ParamTraits
<Tuple0
> {
584 typedef Tuple0 param_type
;
585 static void Write(Message
* m
, const param_type
& p
) {
587 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
590 static void Log(const param_type
& p
, std::string
* l
) {
595 struct ParamTraits
< Tuple1
<A
> > {
596 typedef Tuple1
<A
> param_type
;
597 static void Write(Message
* m
, const param_type
& p
) {
600 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
601 return ReadParam(m
, iter
, &r
->a
);
603 static void Log(const param_type
& p
, std::string
* l
) {
608 template <class A
, class B
>
609 struct ParamTraits
< Tuple2
<A
, B
> > {
610 typedef Tuple2
<A
, B
> param_type
;
611 static void Write(Message
* m
, const param_type
& p
) {
615 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
616 return (ReadParam(m
, iter
, &r
->a
) &&
617 ReadParam(m
, iter
, &r
->b
));
619 static void Log(const param_type
& p
, std::string
* l
) {
626 template <class A
, class B
, class C
>
627 struct ParamTraits
< Tuple3
<A
, B
, C
> > {
628 typedef Tuple3
<A
, B
, C
> param_type
;
629 static void Write(Message
* m
, const param_type
& p
) {
634 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
635 return (ReadParam(m
, iter
, &r
->a
) &&
636 ReadParam(m
, iter
, &r
->b
) &&
637 ReadParam(m
, iter
, &r
->c
));
639 static void Log(const param_type
& p
, std::string
* l
) {
648 template <class A
, class B
, class C
, class D
>
649 struct ParamTraits
< Tuple4
<A
, B
, C
, D
> > {
650 typedef Tuple4
<A
, B
, C
, D
> param_type
;
651 static void Write(Message
* m
, const param_type
& p
) {
657 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
658 return (ReadParam(m
, iter
, &r
->a
) &&
659 ReadParam(m
, iter
, &r
->b
) &&
660 ReadParam(m
, iter
, &r
->c
) &&
661 ReadParam(m
, iter
, &r
->d
));
663 static void Log(const param_type
& p
, std::string
* l
) {
674 template <class A
, class B
, class C
, class D
, class E
>
675 struct ParamTraits
< Tuple5
<A
, B
, C
, D
, E
> > {
676 typedef Tuple5
<A
, B
, C
, D
, E
> param_type
;
677 static void Write(Message
* m
, const param_type
& p
) {
684 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
685 return (ReadParam(m
, iter
, &r
->a
) &&
686 ReadParam(m
, iter
, &r
->b
) &&
687 ReadParam(m
, iter
, &r
->c
) &&
688 ReadParam(m
, iter
, &r
->d
) &&
689 ReadParam(m
, iter
, &r
->e
));
691 static void Log(const param_type
& p
, std::string
* l
) {
704 // IPC types ParamTraits -------------------------------------------------------
706 // A ChannelHandle is basically a platform-inspecific wrapper around the
707 // fact that IPC endpoints are handled specially on POSIX. See above comments
708 // on FileDescriptor for more background.
710 struct IPC_EXPORT ParamTraits
<IPC::ChannelHandle
> {
711 typedef ChannelHandle 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
);
718 struct IPC_EXPORT ParamTraits
<LogData
> {
719 typedef LogData param_type
;
720 static void Write(Message
* m
, const param_type
& p
);
721 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
722 static void Log(const param_type
& p
, std::string
* l
);
726 struct IPC_EXPORT ParamTraits
<Message
> {
727 static void Write(Message
* m
, const Message
& p
);
728 static bool Read(const Message
* m
, PickleIterator
* iter
, Message
* r
);
729 static void Log(const Message
& p
, std::string
* l
);
732 // Windows ParamTraits ---------------------------------------------------------
736 struct IPC_EXPORT ParamTraits
<HANDLE
> {
737 typedef HANDLE param_type
;
738 static void Write(Message
* m
, const param_type
& p
);
739 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
740 static void Log(const param_type
& p
, std::string
* l
);
744 struct IPC_EXPORT ParamTraits
<LOGFONT
> {
745 typedef LOGFONT param_type
;
746 static void Write(Message
* m
, const param_type
& p
);
747 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
748 static void Log(const param_type
& p
, std::string
* l
);
752 struct IPC_EXPORT ParamTraits
<MSG
> {
753 typedef MSG param_type
;
754 static void Write(Message
* m
, const param_type
& p
);
755 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
);
756 static void Log(const param_type
& p
, std::string
* l
);
758 #endif // defined(OS_WIN)
760 //-----------------------------------------------------------------------------
761 // Generic message subclasses
763 // Used for asynchronous messages.
764 template <class ParamType
>
765 class MessageSchema
{
767 typedef ParamType Param
;
768 typedef typename TupleTypes
<ParamType
>::ParamTuple RefParam
;
770 static void Write(Message
* msg
, const RefParam
& p
) IPC_MSG_NOINLINE
;
771 static bool Read(const Message
* msg
, Param
* p
) IPC_MSG_NOINLINE
;
774 // defined in ipc_logging.cc
775 IPC_EXPORT
void GenerateLogData(const std::string
& channel
,
776 const Message
& message
,
777 LogData
* data
, bool get_params
);
780 #if defined(IPC_MESSAGE_LOG_ENABLED)
781 inline void AddOutputParamsToLog(const Message
* msg
, std::string
* l
) {
782 const std::string
& output_params
= msg
->output_params();
783 if (!l
->empty() && !output_params
.empty())
786 l
->append(output_params
);
789 template <class ReplyParamType
>
790 inline void LogReplyParamsToMessage(const ReplyParamType
& reply_params
,
791 const Message
* msg
) {
792 if (msg
->received_time() != 0) {
793 std::string output_params
;
794 LogParam(reply_params
, &output_params
);
795 msg
->set_output_params(output_params
);
799 inline void ConnectMessageAndReply(const Message
* msg
, Message
* reply
) {
800 if (msg
->sent_time()) {
801 // Don't log the sync message after dispatch, as we don't have the
802 // output parameters at that point. Instead, save its data and log it
803 // with the outgoing reply message when it's sent.
804 LogData
* data
= new LogData
;
805 GenerateLogData("", *msg
, data
, true);
807 reply
->set_sync_log_data(data
);
811 inline void AddOutputParamsToLog(const Message
* msg
, std::string
* l
) {}
813 template <class ReplyParamType
>
814 inline void LogReplyParamsToMessage(const ReplyParamType
& reply_params
,
815 const Message
* msg
) {}
817 inline void ConnectMessageAndReply(const Message
* msg
, Message
* reply
) {}
820 // This class assumes that its template argument is a RefTuple (a Tuple with
821 // reference elements). This would go into ipc_message_utils_impl.h, but it is
822 // also used by chrome_frame.
823 template <class RefTuple
>
824 class ParamDeserializer
: public MessageReplyDeserializer
{
826 explicit ParamDeserializer(const RefTuple
& out
) : out_(out
) { }
828 bool SerializeOutputParameters(const IPC::Message
& msg
, PickleIterator iter
) {
829 return ReadParam(&msg
, &iter
, &out_
);
835 // Used for synchronous messages.
836 template <class SendParamType
, class ReplyParamType
>
837 class SyncMessageSchema
{
839 typedef SendParamType SendParam
;
840 typedef typename TupleTypes
<SendParam
>::ParamTuple RefSendParam
;
841 typedef ReplyParamType ReplyParam
;
843 static void Write(Message
* msg
, const RefSendParam
& send
) IPC_MSG_NOINLINE
;
844 static bool ReadSendParam(const Message
* msg
, SendParam
* p
) IPC_MSG_NOINLINE
;
845 static bool ReadReplyParam(
847 typename TupleTypes
<ReplyParam
>::ValueTuple
* p
) IPC_MSG_NOINLINE
;
849 template<class T
, class S
, class Method
>
850 static bool DispatchWithSendParams(bool ok
, const SendParam
& send_params
,
851 const Message
* msg
, T
* obj
, S
* sender
,
853 Message
* reply
= SyncMessage::GenerateReply(msg
);
855 typename TupleTypes
<ReplyParam
>::ValueTuple reply_params
;
856 DispatchToMethod(obj
, func
, send_params
, &reply_params
);
857 WriteParam(reply
, reply_params
);
858 LogReplyParamsToMessage(reply_params
, msg
);
860 NOTREACHED() << "Error deserializing message " << msg
->type();
861 reply
->set_reply_error();
867 template<class T
, class Method
>
868 static bool DispatchDelayReplyWithSendParams(bool ok
,
869 const SendParam
& send_params
,
870 const Message
* msg
, T
* obj
,
872 Message
* reply
= SyncMessage::GenerateReply(msg
);
874 Tuple1
<Message
&> t
= MakeRefTuple(*reply
);
875 ConnectMessageAndReply(msg
, reply
);
876 DispatchToMethod(obj
, func
, send_params
, &t
);
878 NOTREACHED() << "Error deserializing message " << msg
->type();
879 reply
->set_reply_error();
885 template<typename TA
>
886 static void WriteReplyParams(Message
* reply
, TA a
) {
888 WriteParam(reply
, p
);
891 template<typename TA
, typename TB
>
892 static void WriteReplyParams(Message
* reply
, TA a
, TB b
) {
894 WriteParam(reply
, p
);
897 template<typename TA
, typename TB
, typename TC
>
898 static void WriteReplyParams(Message
* reply
, TA a
, TB b
, TC c
) {
899 ReplyParam
p(a
, b
, c
);
900 WriteParam(reply
, p
);
903 template<typename TA
, typename TB
, typename TC
, typename TD
>
904 static void WriteReplyParams(Message
* reply
, TA a
, TB b
, TC c
, TD d
) {
905 ReplyParam
p(a
, b
, c
, d
);
906 WriteParam(reply
, p
);
909 template<typename TA
, typename TB
, typename TC
, typename TD
, typename TE
>
910 static void WriteReplyParams(Message
* reply
, TA a
, TB b
, TC c
, TD d
, TE e
) {
911 ReplyParam
p(a
, b
, c
, d
, e
);
912 WriteParam(reply
, p
);
918 #endif // IPC_IPC_MESSAGE_UTILS_H_