Revert 161499 - Add systemInfo.cpu.onUpdated event implementation.
[chromium-blink-merge.git] / ipc / ipc_message_utils.h
blob757bae44262b7334f5899d50899c5adb9f98f2ff
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_
8 #include <algorithm>
9 #include <map>
10 #include <set>
11 #include <string>
12 #include <vector>
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));
36 #else
37 #define IPC_MSG_NOINLINE __attribute__((noinline));
38 #endif
39 #elif defined(COMPILER_MSVC)
40 // MSVC++ doesn't do this.
41 #define IPC_MSG_NOINLINE
42 #else
43 #error "Please add the noinline property for your new compiler here."
44 #endif
46 // Used by IPC_BEGIN_MESSAGES so that each message class starts from a unique
47 // base. Messages have unique IDs across channels in order for the IPC logging
48 // code to figure out the message class from its ID.
49 enum IPCMessageStart {
50 AutomationMsgStart = 0,
51 ViewMsgStart,
52 PluginMsgStart,
53 ProfileImportMsgStart,
54 TestMsgStart,
55 DevToolsMsgStart,
56 WorkerMsgStart,
57 NaClMsgStart,
58 UtilityMsgStart,
59 GpuMsgStart,
60 ServiceMsgStart,
61 PpapiMsgStart,
62 FirefoxImporterUnittestMsgStart,
63 FileUtilitiesMsgStart,
64 MimeRegistryMsgStart,
65 DatabaseMsgStart,
66 DOMStorageMsgStart,
67 IndexedDBMsgStart,
68 PepperFileMsgStart,
69 SpeechRecognitionMsgStart,
70 PepperMsgStart,
71 AutofillMsgStart,
72 SafeBrowsingMsgStart,
73 P2PMsgStart,
74 SocketStreamMsgStart,
75 ResourceMsgStart,
76 FileSystemMsgStart,
77 ChildProcessMsgStart,
78 ClipboardMsgStart,
79 BlobMsgStart,
80 AppCacheMsgStart,
81 DeviceMotionMsgStart,
82 DeviceOrientationMsgStart,
83 DesktopNotificationMsgStart,
84 GeolocationMsgStart,
85 AudioMsgStart,
86 ChromeMsgStart,
87 DragMsgStart,
88 PrintMsgStart,
89 SpellCheckMsgStart,
90 ExtensionMsgStart,
91 VideoCaptureMsgStart,
92 QuotaMsgStart,
93 IconMsgStart,
94 TextInputClientMsgStart,
95 ChromeUtilityMsgStart,
96 MediaStreamMsgStart,
97 ChromeBenchmarkingMsgStart,
98 IntentsMsgStart,
99 JavaBridgeMsgStart,
100 GamepadMsgStart,
101 ShellMsgStart,
102 AccessibilityMsgStart,
103 PrerenderMsgStart,
104 ChromotingMsgStart,
105 OldBrowserPluginMsgStart,
106 BrowserPluginMsgStart,
107 HyphenatorMsgStart,
108 AndroidWebViewMsgStart,
109 MetroViewerMsgStart,
110 CCMsgStart,
111 MediaPlayerMsgStart,
112 LastIPCMsgStart // Must come last.
115 class FilePath;
116 class NullableString16;
118 namespace base {
119 class DictionaryValue;
120 class ListValue;
121 class Time;
122 class TimeDelta;
123 class TimeTicks;
124 struct FileDescriptor;
127 namespace IPC {
129 struct ChannelHandle;
131 //-----------------------------------------------------------------------------
132 // An iterator class for reading the fields contained within a Message.
133 class IPC_EXPORT MessageIterator {
134 public:
135 explicit MessageIterator(const Message& m);
137 int NextInt() const;
138 const std::string NextString() const;
140 private:
141 mutable PickleIterator iter_;
144 // -----------------------------------------------------------------------------
145 // How we send IPC message logs across channels.
146 struct IPC_EXPORT LogData {
147 LogData();
148 ~LogData();
150 std::string channel;
151 int32 routing_id;
152 uint32 type; // "User-defined" message type, from ipc_message.h.
153 std::string flags;
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;
160 std::string params;
164 //-----------------------------------------------------------------------------
165 // A dummy struct to place first just to allow leading commas for all
166 // members in the macro-generated constructor initializer lists.
167 struct NoParams {
170 template <class P>
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));
176 template <class P>
177 static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m,
178 PickleIterator* iter,
179 P* p) {
180 typedef typename SimilarTypeTraits<P>::Type Type;
181 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
184 template <class 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 -------------------------------------------------------
192 template <>
193 struct ParamTraits<bool> {
194 typedef bool param_type;
195 static void Write(Message* m, const param_type& p) {
196 m->WriteBool(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);
204 template <>
205 struct ParamTraits<int> {
206 typedef int param_type;
207 static void Write(Message* m, const param_type& p) {
208 m->WriteInt(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);
216 template <>
217 struct ParamTraits<unsigned int> {
218 typedef unsigned int param_type;
219 static void Write(Message* m, const param_type& p) {
220 m->WriteInt(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);
228 template <>
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);
240 template <>
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);
252 template <>
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,
259 param_type* r) {
260 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
262 IPC_EXPORT static void Log(const param_type& p, std::string* l);
265 template <>
266 struct ParamTraits<unsigned long long> {
267 typedef unsigned long long param_type;
268 static void Write(Message* m, const param_type& p) {
269 m->WriteInt64(p);
271 static bool Read(const Message* m, PickleIterator* iter,
272 param_type* r) {
273 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
275 IPC_EXPORT static void Log(const param_type& p, std::string* l);
278 template <>
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
288 // IPC.
289 template <>
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);
297 template <>
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 -------------------------------------------------------------
307 template <>
308 struct ParamTraits<std::string> {
309 typedef std::string param_type;
310 static void Write(Message* m, const param_type& p) {
311 m->WriteString(p);
313 static bool Read(const Message* m, PickleIterator* iter,
314 param_type* r) {
315 return m->ReadString(iter, r);
317 IPC_EXPORT static void Log(const param_type& p, std::string* l);
320 template <>
321 struct ParamTraits<std::wstring> {
322 typedef std::wstring param_type;
323 static void Write(Message* m, const param_type& p) {
324 m->WriteWString(p);
326 static bool Read(const Message* m, PickleIterator* iter,
327 param_type* r) {
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
334 // need this trait.
335 #if !defined(WCHAR_T_IS_UTF16)
336 template <>
337 struct ParamTraits<string16> {
338 typedef string16 param_type;
339 static void Write(Message* m, const param_type& p) {
340 m->WriteString16(p);
342 static bool Read(const Message* m, PickleIterator* iter,
343 param_type* r) {
344 return m->ReadString16(iter, r);
346 IPC_EXPORT static void Log(const param_type& p, std::string* l);
348 #endif
350 template <>
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);
358 template <>
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);
366 template <>
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);
374 template <class P>
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++)
380 WriteParam(m, p[i]);
382 static bool Read(const Message* m, PickleIterator* iter,
383 param_type* r) {
384 int size;
385 // ReadLength() checks for < 0 itself.
386 if (!m->ReadLength(iter, &size))
387 return false;
388 // Resizing beforehand is not safe, see BUG 1006367 for details.
389 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
390 return false;
391 r->resize(size);
392 for (int i = 0; i < size; i++) {
393 if (!ReadParam(m, iter, &(*r)[i]))
394 return false;
396 return true;
398 static void Log(const param_type& p, std::string* l) {
399 for (size_t i = 0; i < p.size(); ++i) {
400 if (i != 0)
401 l->append(" ");
402 LogParam((p[i]), l);
407 template <class P>
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,
417 param_type* r) {
418 int size;
419 if (!m->ReadLength(iter, &size))
420 return false;
421 for (int i = 0; i < size; ++i) {
422 P item;
423 if (!ReadParam(m, iter, &item))
424 return false;
425 r->insert(item);
427 return true;
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,
446 param_type* r) {
447 int size;
448 if (!ReadParam(m, iter, &size) || size < 0)
449 return false;
450 for (int i = 0; i < size; ++i) {
451 K k;
452 if (!ReadParam(m, iter, &k))
453 return false;
454 V& value = (*r)[k];
455 if (!ReadParam(m, iter, &value))
456 return false;
458 return true;
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,
473 param_type* r) {
474 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
476 static void Log(const param_type& p, std::string* l) {
477 l->append("(");
478 LogParam(p.first, l);
479 l->append(", ");
480 LogParam(p.second, l);
481 l->append(")");
485 // Base ParamTraits ------------------------------------------------------------
487 template <>
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
501 // descriptor*.
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.
511 template<>
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)
520 template <>
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);
528 template <>
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);
536 template <>
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,
541 param_type* r);
542 static void Log(const param_type& p, std::string* l);
545 template <>
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);
553 template <>
554 struct SimilarTypeTraits<base::PlatformFileError> {
555 typedef int Type;
558 template <>
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);
566 template <>
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);
574 template <>
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);
582 template <>
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) {
588 return true;
590 static void Log(const param_type& p, std::string* l) {
594 template <class A>
595 struct ParamTraits< Tuple1<A> > {
596 typedef Tuple1<A> param_type;
597 static void Write(Message* m, const param_type& p) {
598 WriteParam(m, p.a);
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) {
604 LogParam(p.a, 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) {
612 WriteParam(m, p.a);
613 WriteParam(m, p.b);
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) {
620 LogParam(p.a, l);
621 l->append(", ");
622 LogParam(p.b, 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) {
630 WriteParam(m, p.a);
631 WriteParam(m, p.b);
632 WriteParam(m, p.c);
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) {
640 LogParam(p.a, l);
641 l->append(", ");
642 LogParam(p.b, l);
643 l->append(", ");
644 LogParam(p.c, 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) {
652 WriteParam(m, p.a);
653 WriteParam(m, p.b);
654 WriteParam(m, p.c);
655 WriteParam(m, p.d);
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) {
664 LogParam(p.a, l);
665 l->append(", ");
666 LogParam(p.b, l);
667 l->append(", ");
668 LogParam(p.c, l);
669 l->append(", ");
670 LogParam(p.d, 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) {
678 WriteParam(m, p.a);
679 WriteParam(m, p.b);
680 WriteParam(m, p.c);
681 WriteParam(m, p.d);
682 WriteParam(m, p.e);
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) {
692 LogParam(p.a, l);
693 l->append(", ");
694 LogParam(p.b, l);
695 l->append(", ");
696 LogParam(p.c, l);
697 l->append(", ");
698 LogParam(p.d, l);
699 l->append(", ");
700 LogParam(p.e, 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.
709 template<>
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);
717 template <>
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);
725 template <>
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 ---------------------------------------------------------
734 #if defined(OS_WIN)
735 template <>
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);
743 template <>
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);
751 template <>
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 {
766 public:
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())
784 l->append(", ");
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);
806 msg->set_dont_log();
807 reply->set_sync_log_data(data);
810 #else
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) {}
818 #endif
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 {
825 public:
826 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
828 bool SerializeOutputParameters(const IPC::Message& msg, PickleIterator iter) {
829 return ReadParam(&msg, &iter, &out_);
832 RefTuple out_;
835 // Used for synchronous messages.
836 template <class SendParamType, class ReplyParamType>
837 class SyncMessageSchema {
838 public:
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(
846 const Message* msg,
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,
852 Method func) {
853 Message* reply = SyncMessage::GenerateReply(msg);
854 if (ok) {
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);
859 } else {
860 NOTREACHED() << "Error deserializing message " << msg->type();
861 reply->set_reply_error();
863 sender->Send(reply);
864 return ok;
867 template<class T, class Method>
868 static bool DispatchDelayReplyWithSendParams(bool ok,
869 const SendParam& send_params,
870 const Message* msg, T* obj,
871 Method func) {
872 Message* reply = SyncMessage::GenerateReply(msg);
873 if (ok) {
874 Tuple1<Message&> t = MakeRefTuple(*reply);
875 ConnectMessageAndReply(msg, reply);
876 DispatchToMethod(obj, func, send_params, &t);
877 } else {
878 NOTREACHED() << "Error deserializing message " << msg->type();
879 reply->set_reply_error();
880 obj->Send(reply);
882 return ok;
885 template<typename TA>
886 static void WriteReplyParams(Message* reply, TA a) {
887 ReplyParam p(a);
888 WriteParam(reply, p);
891 template<typename TA, typename TB>
892 static void WriteReplyParams(Message* reply, TA a, TB b) {
893 ReplyParam p(a, 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);
916 } // namespace IPC
918 #endif // IPC_IPC_MESSAGE_UTILS_H_