1 // Copyright (c) 2011 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_
15 #include "base/compiler_specific.h"
16 //#include "base/format_macros.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_param_traits.h"
22 #include "ipc/ipc_sync_message.h"
24 #if defined(COMPILER_GCC)
25 // GCC "helpfully" tries to inline template methods in release mode. Except we
26 // want the majority of the template junk being expanded once in the
27 // implementation file (and only provide the definitions in
28 // ipc_message_utils_impl.h in those files) and exported, instead of expanded
29 // at every call site. Special note: GCC happily accepts the attribute before
30 // the method declaration, but only acts on it if it is after.
31 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 40500
32 // Starting in gcc 4.5, the noinline no longer implies the concept covered by
33 // the introduced noclone attribute, which will create specialized versions of
34 // functions/methods when certain types are constant.
35 // www.gnu.org/software/gcc/gcc-4.5/changes.html
36 #define IPC_MSG_NOINLINE __attribute__((noinline, noclone));
38 #define IPC_MSG_NOINLINE __attribute__((noinline));
40 #elif defined(COMPILER_MSVC)
41 // MSVC++ doesn't do this.
42 #define IPC_MSG_NOINLINE
44 #error "Please add the noinline property for your new compiler here."
47 // Used by IPC_BEGIN_MESSAGES so that each message class starts from a unique
48 // base. Messages have unique IDs across channels in order for the IPC logging
49 // code to figure out the message class from its ID.
50 enum IPCMessageStart {
51 AutomationMsgStart = 0,
52 CmcStrRegistryManagerStart,
57 class NullableString16;
60 class DictionaryValue;
64 struct FileDescriptor;
71 //-----------------------------------------------------------------------------
72 // An iterator class for reading the fields contained within a Message.
74 class MessageIterator {
76 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
80 if (!msg_.ReadInt(&iter_, &val))
85 const std::string NextString() const {
87 if (!msg_.ReadString(&iter_, &val))
91 const std::wstring NextWString() const {
93 if (!msg_.ReadWString(&iter_, &val))
98 void NextData(const char** data, int* length) const {
99 if (!msg_.ReadData(&iter_, data, length)) {
108 //-----------------------------------------------------------------------------
109 // A dummy struct to place first just to allow leading commas for all
110 // members in the macro-generated constructor initializer lists.
114 //-----------------------------------------------------------------------------
115 // ParamTraits specializations, etc.
118 static inline void WriteParam(Message* m, const P& p) {
119 typedef typename SimilarTypeTraits<P>::Type Type;
120 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
124 static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
126 typedef typename SimilarTypeTraits<P>::Type Type;
127 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
132 static inline void LogParam(const P& p, std::string* l) {
133 typedef typename SimilarTypeTraits<P>::Type Type;
134 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
139 struct ParamTraits<bool> {
140 typedef bool param_type;
141 static void Write(Message* m, const param_type& p) {
144 static bool Read(const Message* m, void** iter, param_type* r) {
145 return m->ReadBool(iter, r);
147 static void Log(const param_type& p, std::string* l) {
148 l->append(p ? "true" : "false");
153 struct ParamTraits<int> {
154 typedef int param_type;
155 static void Write(Message* m, const param_type& p) {
158 static bool Read(const Message* m, void** iter, param_type* r) {
159 return m->ReadInt(iter, r);
161 IPC_EXPORT static void Log(const param_type& p, std::string* l);
165 struct ParamTraits<unsigned int> {
166 typedef unsigned int param_type;
167 static void Write(Message* m, const param_type& p) {
170 static bool Read(const Message* m, void** iter, param_type* r) {
171 return m->ReadInt(iter, reinterpret_cast<int*>(r));
173 IPC_EXPORT static void Log(const param_type& p, std::string* l);
177 struct ParamTraits<long> {
178 typedef long param_type;
179 static void Write(Message* m, const param_type& p) {
182 static bool Read(const Message* m, void** iter, param_type* r) {
183 return m->ReadLong(iter, r);
185 IPC_EXPORT static void Log(const param_type& p, std::string* l);
189 struct ParamTraits<unsigned long> {
190 typedef unsigned long param_type;
191 static void Write(Message* m, const param_type& p) {
194 static bool Read(const Message* m, void** iter, param_type* r) {
195 return m->ReadLong(iter, reinterpret_cast<long*>(r));
197 IPC_EXPORT static void Log(const param_type& p, std::string* l);
201 struct ParamTraits<long long> {
202 typedef long long param_type;
203 static void Write(Message* m, const param_type& p) {
204 m->WriteInt64(static_cast<int64>(p));
206 static bool Read(const Message* m, void** iter, param_type* r) {
207 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
209 IPC_EXPORT static void Log(const param_type& p, std::string* l);
213 struct ParamTraits<unsigned long long> {
214 typedef unsigned long long param_type;
215 static void Write(Message* m, const param_type& p) {
218 static bool Read(const Message* m, void** iter, param_type* r) {
219 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
221 IPC_EXPORT static void Log(const param_type& p, std::string* l);
225 struct IPC_EXPORT ParamTraits<unsigned short> {
226 typedef unsigned short param_type;
227 static void Write(Message* m, const param_type& p);
228 static bool Read(const Message* m, void** iter, param_type* r);
229 static void Log(const param_type& p, std::string* l);
232 // Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
233 // should be sure to check the sanity of these values after receiving them over
236 struct ParamTraits<float> {
237 typedef float param_type;
238 static void Write(Message* m, const param_type& p) {
239 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
241 static bool Read(const Message* m, void** iter, param_type* r) {
244 if (!m->ReadData(iter, &data, &data_size) ||
245 data_size != sizeof(param_type)) {
249 memcpy(r, data, sizeof(param_type));
253 static void Log(const param_type& p, std::string* l) {
254 //l->append(StringPrintf("%e", p));
260 struct ParamTraits<double> {
261 typedef double param_type;
262 static void Write(Message* m, const param_type& p) {
263 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
265 static bool Read(const Message* m, void** iter, param_type* r) {
268 if (!m->ReadData(iter, &data, &data_size) ||
269 data_size != sizeof(param_type)) {
273 memcpy(r, data, sizeof(param_type));
277 static void Log(const param_type& p, std::string* l) {
278 //l->append(StringPrintf("%e", p));
285 struct IPC_EXPORT ParamTraits<base::Time> {
286 typedef base::Time param_type;
287 static void Write(Message* m, const param_type& p);
288 static bool Read(const Message* m, void** iter, param_type* r);
289 static void Log(const param_type& p, std::string* l);
293 struct IPC_EXPORT ParamTraits<base::TimeDelta> {
294 typedef base::TimeDelta param_type;
295 static void Write(Message* m, const param_type& p);
296 static bool Read(const Message* m, void** iter, param_type* r);
297 static void Log(const param_type& p, std::string* l);
302 struct ParamTraits<LOGFONT> {
303 typedef LOGFONT param_type;
304 static void Write(Message* m, const param_type& p) {
305 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
307 static bool Read(const Message* m, void** iter, param_type* r) {
310 bool result = m->ReadData(iter, &data, &data_size);
311 if (result && data_size == sizeof(LOGFONT)) {
312 memcpy(r, data, sizeof(LOGFONT));
320 static void Log(const param_type& p, std::string* l) {
321 // l->append(StringPrintf("<LOGFONT>"));
326 struct ParamTraits<MSG> {
327 typedef MSG param_type;
328 static void Write(Message* m, const param_type& p) {
329 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
331 static bool Read(const Message* m, void** iter, param_type* r) {
334 bool result = m->ReadData(iter, &data, &data_size);
335 if (result && data_size == sizeof(MSG)) {
336 memcpy(r, data, sizeof(MSG));
344 static void Log(const param_type& p, std::string* l) {
348 #endif // defined(OS_WIN)
351 struct IPC_EXPORT ParamTraits<base::DictionaryValue> {
352 typedef base::DictionaryValue param_type;
353 static void Write(Message* m, const param_type& p);
354 static bool Read(const Message* m, void** iter, param_type* r);
355 static void Log(const param_type& p, std::string* l);
359 struct IPC_EXPORT ParamTraits<base::ListValue> {
360 typedef base::ListValue param_type;
361 static void Write(Message* m, const param_type& p);
362 static bool Read(const Message* m, void** iter, param_type* r);
363 static void Log(const param_type& p, std::string* l);
368 struct ParamTraits<std::string> {
369 typedef std::string param_type;
370 static void Write(Message* m, const param_type& p) {
373 static bool Read(const Message* m, void** iter, param_type* r) {
374 return m->ReadString(iter, r);
376 static void Log(const param_type& p, std::string* l) {
382 template<typename CharType>
383 static void LogBytes(const std::vector<CharType>& data, std::string* out) {
385 // Windows has a GUI for logging, which can handle arbitrary binary data.
386 for (size_t i = 0; i < data.size(); ++i)
387 out->push_back(data[i]);
389 // On POSIX, we log to stdout, which we assume can display ASCII.
390 static const size_t kMaxBytesToLog = 100;
391 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
392 if (isprint(data[i]))
393 out->push_back(data[i]);
396 // out->append(StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
399 if (data.size() > kMaxBytesToLog) {
401 // StringPrintf(" and %u more bytes",
402 // static_cast<unsigned>(data.size() - kMaxBytesToLog)));
409 struct ParamTraits<std::vector<unsigned char> > {
410 typedef std::vector<unsigned char> param_type;
411 static void Write(Message* m, const param_type& p) {
413 m->WriteData(NULL, 0);
415 m->WriteData(reinterpret_cast<const char*>(&p.front()),
416 static_cast<int>(p.size()));
419 static bool Read(const Message* m, void** iter, param_type* r) {
422 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
424 r->resize(data_size);
426 memcpy(&r->front(), data, data_size);
429 static void Log(const param_type& p, std::string* l) {
435 struct ParamTraits<std::vector<char> > {
436 typedef std::vector<char> param_type;
437 static void Write(Message* m, const param_type& p) {
439 m->WriteData(NULL, 0);
441 m->WriteData(&p.front(), static_cast<int>(p.size()));
444 static bool Read(const Message* m, void** iter, param_type* r) {
447 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
449 r->resize(data_size);
451 memcpy(&r->front(), data, data_size);
454 static void Log(const param_type& p, std::string* l) {
460 struct ParamTraits<std::vector<P> > {
461 typedef std::vector<P> param_type;
462 static void Write(Message* m, const param_type& p) {
463 WriteParam(m, static_cast<int>(p.size()));
464 for (size_t i = 0; i < p.size(); i++)
467 static bool Read(const Message* m, void** iter, param_type* r) {
469 // ReadLength() checks for < 0 itself.
470 if (!m->ReadLength(iter, &size))
472 // Resizing beforehand is not safe, see BUG 1006367 for details.
473 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
476 for (int i = 0; i < size; i++) {
477 if (!ReadParam(m, iter, &(*r)[i]))
482 static void Log(const param_type& p, std::string* l) {
483 // for (size_t i = 0; i < p.size(); ++i) {
486 // LogParam((p[i]), l);
493 struct ParamTraits<std::set<P> > {
494 typedef std::set<P> param_type;
495 static void Write(Message* m, const param_type& p) {
496 WriteParam(m, static_cast<int>(p.size()));
497 typename param_type::const_iterator iter;
498 for (iter = p.begin(); iter != p.end(); ++iter)
499 WriteParam(m, *iter);
501 static bool Read(const Message* m, void** iter, param_type* r) {
503 if (!m->ReadLength(iter, &size))
505 for (int i = 0; i < size; ++i) {
507 if (!ReadParam(m, iter, &item))
513 static void Log(const param_type& p, std::string* l) {
514 l->append("<std::set>");
519 template <class K, class V>
520 struct ParamTraits<std::map<K, V> > {
521 typedef std::map<K, V> param_type;
522 static void Write(Message* m, const param_type& p) {
523 WriteParam(m, static_cast<int>(p.size()));
524 typename param_type::const_iterator iter;
525 for (iter = p.begin(); iter != p.end(); ++iter) {
526 WriteParam(m, iter->first);
527 WriteParam(m, iter->second);
530 static bool Read(const Message* m, void** iter, param_type* r) {
532 if (!ReadParam(m, iter, &size) || size < 0)
534 for (int i = 0; i < size; ++i) {
536 if (!ReadParam(m, iter, &k))
539 if (!ReadParam(m, iter, &value))
544 static void Log(const param_type& p, std::string* l) {
545 l->append("<std::map>");
551 struct ParamTraits<std::wstring> {
552 typedef std::wstring param_type;
553 static void Write(Message* m, const param_type& p) {
556 static bool Read(const Message* m, void** iter, param_type* r) {
557 return m->ReadWString(iter, r);
559 IPC_EXPORT static void Log(const param_type& p, std::string* l);
562 template <class A, class B>
563 struct ParamTraits<std::pair<A, B> > {
564 typedef std::pair<A, B> param_type;
565 static void Write(Message* m, const param_type& p) {
566 WriteParam(m, p.first);
567 WriteParam(m, p.second);
569 static bool Read(const Message* m, void** iter, param_type* r) {
570 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
572 static void Log(const param_type& p, std::string* l) {
574 LogParam(p.first, l);
576 LogParam(p.second, l);
582 struct IPC_EXPORT ParamTraits<NullableString16> {
583 typedef NullableString16 param_type;
584 static void Write(Message* m, const param_type& p);
585 static bool Read(const Message* m, void** iter, param_type* r);
586 static void Log(const param_type& p, std::string* l);
589 // If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
591 #if !defined(WCHAR_T_IS_UTF16)
593 struct ParamTraits<string16> {
594 typedef string16 param_type;
595 static void Write(Message* m, const param_type& p) {
598 static bool Read(const Message* m, void** iter, param_type* r) {
599 return m->ReadString16(iter, r);
601 IPC_EXPORT static void Log(const param_type& p, std::string* l);
605 // and, a few more useful types...
608 struct ParamTraits<HANDLE> {
609 typedef HANDLE param_type;
610 static void Write(Message* m, const param_type& p) {
611 // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
613 m->WriteUInt32(reinterpret_cast<uint32>(p));
615 static bool Read(const Message* m, void** iter, param_type* r) {
616 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
617 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
619 static void Log(const param_type& p, std::string* l) {
620 // l->append(StringPrintf("0x%X", p));
625 struct ParamTraits<HCURSOR> {
626 typedef HCURSOR param_type;
627 static void Write(Message* m, const param_type& p) {
628 m->WriteUInt32(reinterpret_cast<uint32>(p));
630 static bool Read(const Message* m, void** iter, param_type* r) {
631 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
632 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
634 static void Log(const param_type& p, std::string* l) {
635 // l->append(StringPrintf("0x%X", p));
640 struct ParamTraits<HACCEL> {
641 typedef HACCEL param_type;
642 static void Write(Message* m, const param_type& p) {
643 m->WriteUInt32(reinterpret_cast<uint32>(p));
645 static bool Read(const Message* m, void** iter, param_type* r) {
646 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
647 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
652 struct ParamTraits<POINT> {
653 typedef POINT param_type;
654 static void Write(Message* m, const param_type& p) {
658 static bool Read(const Message* m, void** iter, param_type* r) {
660 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
666 static void Log(const param_type& p, std::string* l) {
667 // l->append(StringPrintf("(%d, %d)", p.x, p.y));
670 #endif // defined(OS_WIN)
673 struct IPC_EXPORT ParamTraits<FilePath> {
674 typedef FilePath param_type;
675 static void Write(Message* m, const param_type& p);
676 static bool Read(const Message* m, void** iter, param_type* r);
677 static void Log(const param_type& p, std::string* l);
680 #if defined(OS_POSIX)
681 // FileDescriptors may be serialised over IPC channels on POSIX. On the
682 // receiving side, the FileDescriptor is a valid duplicate of the file
683 // descriptor which was transmitted: *it is not just a copy of the integer like
684 // HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
685 // this case, the receiving end will see a value of -1. *Zero is a valid file
688 // The received file descriptor will have the |auto_close| flag set to true. The
689 // code which handles the message is responsible for taking ownership of it.
690 // File descriptors are OS resources and must be closed when no longer needed.
692 // When sending a file descriptor, the file descriptor must be valid at the time
693 // of transmission. Since transmission is not synchronous, one should consider
694 // dup()ing any file descriptors to be transmitted and setting the |auto_close|
695 // flag, which causes the file descriptor to be closed after writing.
697 struct IPC_EXPORT ParamTraits<base::FileDescriptor> {
698 typedef base::FileDescriptor param_type;
699 static void Write(Message* m, const param_type& p);
700 static bool Read(const Message* m, void** iter, param_type* r);
701 static void Log(const param_type& p, std::string* l);
703 #endif // defined(OS_POSIX)
705 // A ChannelHandle is basically a platform-inspecific wrapper around the
706 // fact that IPC endpoints are handled specially on POSIX. See above comments
707 // on FileDescriptor for more background.
709 struct IPC_EXPORT ParamTraits<IPC::ChannelHandle> {
710 typedef ChannelHandle param_type;
711 static void Write(Message* m, const param_type& p);
712 static bool Read(const Message* m, void** iter, param_type* r);
713 static void Log(const param_type& p, std::string* l);
718 struct ParamTraits<XFORM> {
719 typedef XFORM param_type;
720 static void Write(Message* m, const param_type& p) {
721 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
723 static bool Read(const Message* m, void** iter, param_type* r) {
726 bool result = m->ReadData(iter, &data, &data_size);
727 if (result && data_size == sizeof(XFORM)) {
728 memcpy(r, data, sizeof(XFORM));
736 static void Log(const param_type& p, std::string* l) {
737 l->append("<XFORM>");
740 #endif // defined(OS_WIN)
742 struct IPC_EXPORT LogData {
748 uint32 type; // "User-defined" message type, from ipc_message.h.
750 int64 sent; // Time that the message was sent (i.e. at Send()).
751 int64 receive; // Time before it was dispatched (i.e. before calling
752 // OnMessageReceived).
753 int64 dispatch; // Time after it was dispatched (i.e. after calling
754 // OnMessageReceived).
755 std::string message_name;
760 struct IPC_EXPORT ParamTraits<LogData> {
761 typedef LogData param_type;
762 static void Write(Message* m, const param_type& p);
763 static bool Read(const Message* m, void** iter, param_type* r);
764 static void Log(const param_type& p, std::string* l) {
765 // Doesn't make sense to implement this!
771 struct ParamTraits<Message> {
772 static void Write(Message* m, const Message& p) {
773 DCHECK(p.size() <= INT_MAX);
774 int message_size = static_cast<int>(p.size());
775 m->WriteInt(message_size);
776 m->WriteData(reinterpret_cast<const char*>(p.data()), message_size);
778 static bool Read(const Message* m, void** iter, Message* r) {
780 if (!m->ReadInt(iter, &size))
783 if (!m->ReadData(iter, &data, &size))
785 *r = Message(data, size);
788 static void Log(const Message& p, std::string* l) {
789 l->append("<IPC::Message>");
794 struct ParamTraits<Tuple0> {
795 typedef Tuple0 param_type;
796 static void Write(Message* m, const param_type& p) {
798 static bool Read(const Message* m, void** iter, param_type* r) {
801 static void Log(const param_type& p, std::string* l) {
806 struct ParamTraits< Tuple1<A> > {
807 typedef Tuple1<A> param_type;
808 static void Write(Message* m, const param_type& p) {
811 static bool Read(const Message* m, void** iter, param_type* r) {
812 return ReadParam(m, iter, &r->a);
814 static void Log(const param_type& p, std::string* l) {
819 template <class A, class B>
820 struct ParamTraits< Tuple2<A, B> > {
821 typedef Tuple2<A, B> param_type;
822 static void Write(Message* m, const param_type& p) {
826 static bool Read(const Message* m, void** iter, param_type* r) {
827 return (ReadParam(m, iter, &r->a) &&
828 ReadParam(m, iter, &r->b));
830 static void Log(const param_type& p, std::string* l) {
837 template <class A, class B, class C>
838 struct ParamTraits< Tuple3<A, B, C> > {
839 typedef Tuple3<A, B, C> param_type;
840 static void Write(Message* m, const param_type& p) {
845 static bool Read(const Message* m, void** iter, param_type* r) {
846 return (ReadParam(m, iter, &r->a) &&
847 ReadParam(m, iter, &r->b) &&
848 ReadParam(m, iter, &r->c));
850 static void Log(const param_type& p, std::string* l) {
859 template <class A, class B, class C, class D>
860 struct ParamTraits< Tuple4<A, B, C, D> > {
861 typedef Tuple4<A, B, C, D> param_type;
862 static void Write(Message* m, const param_type& p) {
868 static bool Read(const Message* m, void** iter, param_type* r) {
869 return (ReadParam(m, iter, &r->a) &&
870 ReadParam(m, iter, &r->b) &&
871 ReadParam(m, iter, &r->c) &&
872 ReadParam(m, iter, &r->d));
874 static void Log(const param_type& p, std::string* l) {
885 template <class A, class B, class C, class D, class E>
886 struct ParamTraits< Tuple5<A, B, C, D, E> > {
887 typedef Tuple5<A, B, C, D, E> param_type;
888 static void Write(Message* m, const param_type& p) {
895 static bool Read(const Message* m, void** iter, param_type* r) {
896 return (ReadParam(m, iter, &r->a) &&
897 ReadParam(m, iter, &r->b) &&
898 ReadParam(m, iter, &r->c) &&
899 ReadParam(m, iter, &r->d) &&
900 ReadParam(m, iter, &r->e));
902 static void Log(const param_type& p, std::string* l) {
915 template <class A, class B, class C, class D, class E, class F>
916 struct ParamTraits< Tuple6<A, B, C, D, E, F> > {
917 typedef Tuple6<A, B, C, D, E, F> param_type;
918 static void Write(Message* m, const param_type& p) {
926 static bool Read(const Message* m, void** iter, param_type* r) {
927 return (ReadParam(m, iter, &r->a) &&
928 ReadParam(m, iter, &r->b) &&
929 ReadParam(m, iter, &r->c) &&
930 ReadParam(m, iter, &r->d) &&
931 ReadParam(m, iter, &r->e) &&
932 ReadParam(m, iter, &r->f));
934 static void Log(const param_type& p, std::string* l) {
949 //-----------------------------------------------------------------------------
950 // Generic message subclasses
952 // Used for asynchronous messages.
953 template <class ParamType>
954 class __attribute__((visibility("default"))) MessageWithTuple : public Message {
956 typedef ParamType Param;
957 typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
959 // The constructor and the Read() method's templated implementations are in
960 // ipc_message_utils_impl.h. The subclass constructor and Log() methods call
961 // the templated versions of these and make sure there are instantiations in
962 // those translation units.
963 MessageWithTuple(int32 routing_id, uint32 type, const RefParam& p);
965 static bool Read(const Message* msg, Param* p)
966 { // Put definition into class so that Dispatch method could use it.
968 if (ReadParam(msg, &iter, p))
970 NOTREACHED() << "Error deserializing message " << msg->type();
974 // Generic dispatcher. Should cover most cases.
975 template<class T, class S, class Method>
976 static bool Dispatch(const Message* msg, T* obj, S* sender, Method func) {
979 DispatchToMethod(obj, func, p);
985 // The following dispatchers exist for the case where the callback function
986 // needs the message as well. They assume that "Param" is a type of Tuple
987 // (except the one arg case, as there is no Tuple1).
988 template<class T, class S, typename TA>
989 static bool Dispatch(const Message* msg, T* obj, S* sender,
990 void (T::*func)(const Message&, TA)) {
993 (obj->*func)(*msg, p.a);
999 template<class T, class S, typename TA, typename TB>
1000 static bool Dispatch(const Message* msg, T* obj, S* sender,
1001 void (T::*func)(const Message&, TA, TB)) {
1003 if (Read(msg, &p)) {
1004 (obj->*func)(*msg, p.a, p.b);
1010 template<class T, class S, typename TA, typename TB, typename TC>
1011 static bool Dispatch(const Message* msg, T* obj, S* sender,
1012 void (T::*func)(const Message&, TA, TB, TC)) {
1014 if (Read(msg, &p)) {
1015 (obj->*func)(*msg, p.a, p.b, p.c);
1021 template<class T, class S, typename TA, typename TB, typename TC, typename TD>
1022 static bool Dispatch(const Message* msg, T* obj, S* sender,
1023 void (T::*func)(const Message&, TA, TB, TC, TD)) {
1025 if (Read(msg, &p)) {
1026 (obj->*func)(*msg, p.a, p.b, p.c, p.d);
1032 template<class T, class S, typename TA, typename TB, typename TC, typename TD,
1034 static bool Dispatch(const Message* msg, T* obj, S* sender,
1035 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
1037 if (Read(msg, &p)) {
1038 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
1044 // Functions used to do manual unpacking. Only used by the automation code,
1045 // these should go away once that code uses SyncChannel.
1046 template<typename TA, typename TB>
1047 static bool Read(const IPC::Message* msg, TA* a, TB* b) {
1049 if (!Read(msg, ¶ms))
1056 template<typename TA, typename TB, typename TC>
1057 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
1059 if (!Read(msg, ¶ms))
1067 template<typename TA, typename TB, typename TC, typename TD>
1068 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) {
1070 if (!Read(msg, ¶ms))
1079 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1080 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) {
1082 if (!Read(msg, ¶ms))
1093 // defined in ipc_logging.cc
1094 IPC_EXPORT void GenerateLogData(const std::string& channel,
1095 const Message& message,
1099 #if defined(IPC_MESSAGE_LOG_ENABLED)
1100 inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
1101 const std::string& output_params = msg->output_params();
1102 if (!l->empty() && !output_params.empty())
1105 l->append(output_params);
1108 template <class ReplyParamType>
1109 inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1110 const Message* msg) {
1111 if (msg->received_time() != 0) {
1112 std::string output_params;
1113 LogParam(reply_params, &output_params);
1114 msg->set_output_params(output_params);
1118 inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
1119 if (msg->sent_time()) {
1120 // Don't log the sync message after dispatch, as we don't have the
1121 // output parameters at that point. Instead, save its data and log it
1122 // with the outgoing reply message when it's sent.
1123 LogData* data = new LogData;
1124 GenerateLogData("", *msg, data);
1125 msg->set_dont_log();
1126 reply->set_sync_log_data(data);
1130 inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
1132 template <class ReplyParamType>
1133 inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1134 const Message* msg) {}
1136 inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1139 // This class assumes that its template argument is a RefTuple (a Tuple with
1140 // reference elements). This would go into ipc_message_utils_impl.h, but it is
1141 // also used by chrome_frame.
1142 template <class RefTuple>
1143 class ParamDeserializer : public MessageReplyDeserializer {
1145 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
1147 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1148 return ReadParam(&msg, &iter, &out_);
1154 // Used for synchronous messages.
1155 template <class SendParamType, class ReplyParamType>
1156 class __attribute__((visibility("default"))) MessageWithReply : public SyncMessage {
1158 typedef SendParamType SendParam;
1159 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
1160 typedef ReplyParamType ReplyParam;
1162 MessageWithReply(int32 routing_id, uint32 type,
1163 const RefSendParam& send, const ReplyParam& reply);
1164 static bool ReadSendParam(const Message* msg, SendParam* p)
1165 { // Put definition into class so that Dispatch method could use it.
1166 void* iter = SyncMessage::GetDataIterator(msg);
1167 return ReadParam(msg, &iter, p);
1169 static bool ReadReplyParam(
1171 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
1173 template<class T, class S, class Method>
1174 static bool Dispatch(const Message* msg, T* obj, S* sender, Method func) {
1175 SendParam send_params;
1176 Message* reply = GenerateReply(msg);
1178 if (ReadSendParam(msg, &send_params)) {
1179 typename TupleTypes<ReplyParam>::ValueTuple reply_params;
1180 DispatchToMethod(obj, func, send_params, &reply_params);
1181 WriteParam(reply, reply_params);
1183 LogReplyParamsToMessage(reply_params, msg);
1185 NOTREACHED() << "Error deserializing message " << msg->type();
1186 reply->set_reply_error();
1190 sender->Send(reply);
1194 template<class T, class Method>
1195 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
1196 SendParam send_params;
1197 Message* reply = GenerateReply(msg);
1199 if (ReadSendParam(msg, &send_params)) {
1200 Tuple1<Message&> t = MakeRefTuple(*reply);
1201 ConnectMessageAndReply(msg, reply);
1202 DispatchToMethod(obj, func, send_params, &t);
1205 NOTREACHED() << "Error deserializing message " << msg->type();
1206 reply->set_reply_error();
1213 template<typename TA>
1214 static void WriteReplyParams(Message* reply, TA a) {
1216 WriteParam(reply, p);
1219 template<typename TA, typename TB>
1220 static void WriteReplyParams(Message* reply, TA a, TB b) {
1222 WriteParam(reply, p);
1225 template<typename TA, typename TB, typename TC>
1226 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1227 ReplyParam p(a, b, c);
1228 WriteParam(reply, p);
1231 template<typename TA, typename TB, typename TC, typename TD>
1232 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1233 ReplyParam p(a, b, c, d);
1234 WriteParam(reply, p);
1237 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1238 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1239 ReplyParam p(a, b, c, d, e);
1240 WriteParam(reply, p);
1244 //-----------------------------------------------------------------------------
1248 #endif // IPC_IPC_MESSAGE_UTILS_H_