[Android] Expose FaviconService to Java for the Native NTP.
[chromium-blink-merge.git] / ipc / ipc_message_utils.h
blob7fda943f355a882533c2f8916d4ba8ce64d4186b
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/memory/scoped_vector.h"
16 #include "base/platform_file.h"
17 #include "base/strings/string16.h"
18 #include "base/strings/string_util.h"
19 #include "base/strings/stringprintf.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));
38 #else
39 #define IPC_MSG_NOINLINE __attribute__((noinline));
40 #endif
41 #elif defined(COMPILER_MSVC)
42 // MSVC++ doesn't do this.
43 #define IPC_MSG_NOINLINE
44 #else
45 #error "Please add the noinline property for your new compiler here."
46 #endif
48 namespace base {
49 class DictionaryValue;
50 class FilePath;
51 class ListValue;
52 class NullableString16;
53 class Time;
54 class TimeDelta;
55 class TimeTicks;
56 struct FileDescriptor;
59 namespace IPC {
61 struct ChannelHandle;
63 // -----------------------------------------------------------------------------
64 // How we send IPC message logs across channels.
65 struct IPC_EXPORT LogData {
66 LogData();
67 ~LogData();
69 std::string channel;
70 int32 routing_id;
71 uint32 type; // "User-defined" message type, from ipc_message.h.
72 std::string flags;
73 int64 sent; // Time that the message was sent (i.e. at Send()).
74 int64 receive; // Time before it was dispatched (i.e. before calling
75 // OnMessageReceived).
76 int64 dispatch; // Time after it was dispatched (i.e. after calling
77 // OnMessageReceived).
78 std::string message_name;
79 std::string params;
82 //-----------------------------------------------------------------------------
84 // A dummy struct to place first just to allow leading commas for all
85 // members in the macro-generated constructor initializer lists.
86 struct NoParams {
89 template <class P>
90 static inline void WriteParam(Message* m, const P& p) {
91 typedef typename SimilarTypeTraits<P>::Type Type;
92 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
95 template <class P>
96 static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m,
97 PickleIterator* iter,
98 P* p) {
99 typedef typename SimilarTypeTraits<P>::Type Type;
100 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
103 template <class P>
104 static inline void LogParam(const P& p, std::string* l) {
105 typedef typename SimilarTypeTraits<P>::Type Type;
106 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
109 // Primitive ParamTraits -------------------------------------------------------
111 template <>
112 struct ParamTraits<bool> {
113 typedef bool param_type;
114 static void Write(Message* m, const param_type& p) {
115 m->WriteBool(p);
117 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
118 return m->ReadBool(iter, r);
120 IPC_EXPORT static void Log(const param_type& p, std::string* l);
123 template <>
124 struct ParamTraits<int> {
125 typedef int param_type;
126 static void Write(Message* m, const param_type& p) {
127 m->WriteInt(p);
129 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
130 return m->ReadInt(iter, r);
132 IPC_EXPORT static void Log(const param_type& p, std::string* l);
135 template <>
136 struct ParamTraits<unsigned int> {
137 typedef unsigned int param_type;
138 static void Write(Message* m, const param_type& p) {
139 m->WriteInt(p);
141 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
142 return m->ReadInt(iter, reinterpret_cast<int*>(r));
144 IPC_EXPORT static void Log(const param_type& p, std::string* l);
147 template <>
148 struct ParamTraits<long> {
149 typedef long param_type;
150 static void Write(Message* m, const param_type& p) {
151 m->WriteLongUsingDangerousNonPortableLessPersistableForm(p);
153 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
154 return m->ReadLong(iter, r);
156 IPC_EXPORT static void Log(const param_type& p, std::string* l);
159 template <>
160 struct ParamTraits<unsigned long> {
161 typedef unsigned long param_type;
162 static void Write(Message* m, const param_type& p) {
163 m->WriteLongUsingDangerousNonPortableLessPersistableForm(p);
165 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
166 return m->ReadLong(iter, reinterpret_cast<long*>(r));
168 IPC_EXPORT static void Log(const param_type& p, std::string* l);
171 template <>
172 struct ParamTraits<long long> {
173 typedef long long param_type;
174 static void Write(Message* m, const param_type& p) {
175 m->WriteInt64(static_cast<int64>(p));
177 static bool Read(const Message* m, PickleIterator* iter,
178 param_type* r) {
179 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
181 IPC_EXPORT static void Log(const param_type& p, std::string* l);
184 template <>
185 struct ParamTraits<unsigned long long> {
186 typedef unsigned long long param_type;
187 static void Write(Message* m, const param_type& p) {
188 m->WriteInt64(p);
190 static bool Read(const Message* m, PickleIterator* iter,
191 param_type* r) {
192 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
194 IPC_EXPORT static void Log(const param_type& p, std::string* l);
197 template <>
198 struct IPC_EXPORT ParamTraits<unsigned short> {
199 typedef unsigned short param_type;
200 static void Write(Message* m, const param_type& p);
201 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
202 static void Log(const param_type& p, std::string* l);
205 // Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
206 // should be sure to check the sanity of these values after receiving them over
207 // IPC.
208 template <>
209 struct IPC_EXPORT ParamTraits<float> {
210 typedef float param_type;
211 static void Write(Message* m, const param_type& p);
212 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
213 static void Log(const param_type& p, std::string* l);
216 template <>
217 struct IPC_EXPORT ParamTraits<double> {
218 typedef double param_type;
219 static void Write(Message* m, const param_type& p);
220 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
221 static void Log(const param_type& p, std::string* l);
224 // STL ParamTraits -------------------------------------------------------------
226 template <>
227 struct ParamTraits<std::string> {
228 typedef std::string param_type;
229 static void Write(Message* m, const param_type& p) {
230 m->WriteString(p);
232 static bool Read(const Message* m, PickleIterator* iter,
233 param_type* r) {
234 return m->ReadString(iter, r);
236 IPC_EXPORT static void Log(const param_type& p, std::string* l);
239 template <>
240 struct ParamTraits<std::wstring> {
241 typedef std::wstring param_type;
242 static void Write(Message* m, const param_type& p) {
243 m->WriteWString(p);
245 static bool Read(const Message* m, PickleIterator* iter,
246 param_type* r) {
247 return m->ReadWString(iter, r);
249 IPC_EXPORT static void Log(const param_type& p, std::string* l);
252 // If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
253 // need this trait.
254 #if !defined(WCHAR_T_IS_UTF16)
255 template <>
256 struct ParamTraits<string16> {
257 typedef string16 param_type;
258 static void Write(Message* m, const param_type& p) {
259 m->WriteString16(p);
261 static bool Read(const Message* m, PickleIterator* iter,
262 param_type* r) {
263 return m->ReadString16(iter, r);
265 IPC_EXPORT static void Log(const param_type& p, std::string* l);
267 #endif
269 template <>
270 struct IPC_EXPORT ParamTraits<std::vector<char> > {
271 typedef std::vector<char> param_type;
272 static void Write(Message* m, const param_type& p);
273 static bool Read(const Message*, PickleIterator* iter, param_type* r);
274 static void Log(const param_type& p, std::string* l);
277 template <>
278 struct IPC_EXPORT ParamTraits<std::vector<unsigned char> > {
279 typedef std::vector<unsigned char> param_type;
280 static void Write(Message* m, const param_type& p);
281 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
282 static void Log(const param_type& p, std::string* l);
285 template <>
286 struct IPC_EXPORT ParamTraits<std::vector<bool> > {
287 typedef std::vector<bool> param_type;
288 static void Write(Message* m, const param_type& p);
289 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
290 static void Log(const param_type& p, std::string* l);
293 template <class P>
294 struct ParamTraits<std::vector<P> > {
295 typedef std::vector<P> param_type;
296 static void Write(Message* m, const param_type& p) {
297 WriteParam(m, static_cast<int>(p.size()));
298 for (size_t i = 0; i < p.size(); i++)
299 WriteParam(m, p[i]);
301 static bool Read(const Message* m, PickleIterator* iter,
302 param_type* r) {
303 int size;
304 // ReadLength() checks for < 0 itself.
305 if (!m->ReadLength(iter, &size))
306 return false;
307 // Resizing beforehand is not safe, see BUG 1006367 for details.
308 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
309 return false;
310 r->resize(size);
311 for (int i = 0; i < size; i++) {
312 if (!ReadParam(m, iter, &(*r)[i]))
313 return false;
315 return true;
317 static void Log(const param_type& p, std::string* l) {
318 for (size_t i = 0; i < p.size(); ++i) {
319 if (i != 0)
320 l->append(" ");
321 LogParam((p[i]), l);
326 template <class P>
327 struct ParamTraits<std::set<P> > {
328 typedef std::set<P> param_type;
329 static void Write(Message* m, const param_type& p) {
330 WriteParam(m, static_cast<int>(p.size()));
331 typename param_type::const_iterator iter;
332 for (iter = p.begin(); iter != p.end(); ++iter)
333 WriteParam(m, *iter);
335 static bool Read(const Message* m, PickleIterator* iter,
336 param_type* r) {
337 int size;
338 if (!m->ReadLength(iter, &size))
339 return false;
340 for (int i = 0; i < size; ++i) {
341 P item;
342 if (!ReadParam(m, iter, &item))
343 return false;
344 r->insert(item);
346 return true;
348 static void Log(const param_type& p, std::string* l) {
349 l->append("<std::set>");
353 template <class K, class V>
354 struct ParamTraits<std::map<K, V> > {
355 typedef std::map<K, V> param_type;
356 static void Write(Message* m, const param_type& p) {
357 WriteParam(m, static_cast<int>(p.size()));
358 typename param_type::const_iterator iter;
359 for (iter = p.begin(); iter != p.end(); ++iter) {
360 WriteParam(m, iter->first);
361 WriteParam(m, iter->second);
364 static bool Read(const Message* m, PickleIterator* iter,
365 param_type* r) {
366 int size;
367 if (!ReadParam(m, iter, &size) || size < 0)
368 return false;
369 for (int i = 0; i < size; ++i) {
370 K k;
371 if (!ReadParam(m, iter, &k))
372 return false;
373 V& value = (*r)[k];
374 if (!ReadParam(m, iter, &value))
375 return false;
377 return true;
379 static void Log(const param_type& p, std::string* l) {
380 l->append("<std::map>");
384 template <class A, class B>
385 struct ParamTraits<std::pair<A, B> > {
386 typedef std::pair<A, B> param_type;
387 static void Write(Message* m, const param_type& p) {
388 WriteParam(m, p.first);
389 WriteParam(m, p.second);
391 static bool Read(const Message* m, PickleIterator* iter,
392 param_type* r) {
393 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
395 static void Log(const param_type& p, std::string* l) {
396 l->append("(");
397 LogParam(p.first, l);
398 l->append(", ");
399 LogParam(p.second, l);
400 l->append(")");
404 // Base ParamTraits ------------------------------------------------------------
406 template <>
407 struct IPC_EXPORT ParamTraits<base::DictionaryValue> {
408 typedef base::DictionaryValue param_type;
409 static void Write(Message* m, const param_type& p);
410 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
411 static void Log(const param_type& p, std::string* l);
414 #if defined(OS_POSIX)
415 // FileDescriptors may be serialised over IPC channels on POSIX. On the
416 // receiving side, the FileDescriptor is a valid duplicate of the file
417 // descriptor which was transmitted: *it is not just a copy of the integer like
418 // HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
419 // this case, the receiving end will see a value of -1. *Zero is a valid file
420 // descriptor*.
422 // The received file descriptor will have the |auto_close| flag set to true. The
423 // code which handles the message is responsible for taking ownership of it.
424 // File descriptors are OS resources and must be closed when no longer needed.
426 // When sending a file descriptor, the file descriptor must be valid at the time
427 // of transmission. Since transmission is not synchronous, one should consider
428 // dup()ing any file descriptors to be transmitted and setting the |auto_close|
429 // flag, which causes the file descriptor to be closed after writing.
430 template<>
431 struct IPC_EXPORT ParamTraits<base::FileDescriptor> {
432 typedef base::FileDescriptor param_type;
433 static void Write(Message* m, const param_type& p);
434 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
435 static void Log(const param_type& p, std::string* l);
437 #endif // defined(OS_POSIX)
439 template <>
440 struct IPC_EXPORT ParamTraits<base::FilePath> {
441 typedef base::FilePath param_type;
442 static void Write(Message* m, const param_type& p);
443 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
444 static void Log(const param_type& p, std::string* l);
447 template <>
448 struct IPC_EXPORT ParamTraits<base::ListValue> {
449 typedef base::ListValue param_type;
450 static void Write(Message* m, const param_type& p);
451 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
452 static void Log(const param_type& p, std::string* l);
455 template <>
456 struct IPC_EXPORT ParamTraits<base::NullableString16> {
457 typedef base::NullableString16 param_type;
458 static void Write(Message* m, const param_type& p);
459 static bool Read(const Message* m, PickleIterator* iter,
460 param_type* r);
461 static void Log(const param_type& p, std::string* l);
464 template <>
465 struct IPC_EXPORT ParamTraits<base::PlatformFileInfo> {
466 typedef base::PlatformFileInfo param_type;
467 static void Write(Message* m, const param_type& p);
468 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
469 static void Log(const param_type& p, std::string* l);
472 template <>
473 struct SimilarTypeTraits<base::PlatformFileError> {
474 typedef int Type;
477 #if defined(OS_WIN)
478 template <>
479 struct SimilarTypeTraits<HWND> {
480 typedef HANDLE Type;
482 #endif // defined(OS_WIN)
484 template <>
485 struct IPC_EXPORT ParamTraits<base::Time> {
486 typedef base::Time param_type;
487 static void Write(Message* m, const param_type& p);
488 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
489 static void Log(const param_type& p, std::string* l);
492 template <>
493 struct IPC_EXPORT ParamTraits<base::TimeDelta> {
494 typedef base::TimeDelta param_type;
495 static void Write(Message* m, const param_type& p);
496 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
497 static void Log(const param_type& p, std::string* l);
500 template <>
501 struct IPC_EXPORT ParamTraits<base::TimeTicks> {
502 typedef base::TimeTicks param_type;
503 static void Write(Message* m, const param_type& p);
504 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
505 static void Log(const param_type& p, std::string* l);
508 template <>
509 struct ParamTraits<Tuple0> {
510 typedef Tuple0 param_type;
511 static void Write(Message* m, const param_type& p) {
513 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
514 return true;
516 static void Log(const param_type& p, std::string* l) {
520 template <class A>
521 struct ParamTraits< Tuple1<A> > {
522 typedef Tuple1<A> param_type;
523 static void Write(Message* m, const param_type& p) {
524 WriteParam(m, p.a);
526 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
527 return ReadParam(m, iter, &r->a);
529 static void Log(const param_type& p, std::string* l) {
530 LogParam(p.a, l);
534 template <class A, class B>
535 struct ParamTraits< Tuple2<A, B> > {
536 typedef Tuple2<A, B> param_type;
537 static void Write(Message* m, const param_type& p) {
538 WriteParam(m, p.a);
539 WriteParam(m, p.b);
541 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
542 return (ReadParam(m, iter, &r->a) &&
543 ReadParam(m, iter, &r->b));
545 static void Log(const param_type& p, std::string* l) {
546 LogParam(p.a, l);
547 l->append(", ");
548 LogParam(p.b, l);
552 template <class A, class B, class C>
553 struct ParamTraits< Tuple3<A, B, C> > {
554 typedef Tuple3<A, B, C> param_type;
555 static void Write(Message* m, const param_type& p) {
556 WriteParam(m, p.a);
557 WriteParam(m, p.b);
558 WriteParam(m, p.c);
560 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
561 return (ReadParam(m, iter, &r->a) &&
562 ReadParam(m, iter, &r->b) &&
563 ReadParam(m, iter, &r->c));
565 static void Log(const param_type& p, std::string* l) {
566 LogParam(p.a, l);
567 l->append(", ");
568 LogParam(p.b, l);
569 l->append(", ");
570 LogParam(p.c, l);
574 template <class A, class B, class C, class D>
575 struct ParamTraits< Tuple4<A, B, C, D> > {
576 typedef Tuple4<A, B, C, D> param_type;
577 static void Write(Message* m, const param_type& p) {
578 WriteParam(m, p.a);
579 WriteParam(m, p.b);
580 WriteParam(m, p.c);
581 WriteParam(m, p.d);
583 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
584 return (ReadParam(m, iter, &r->a) &&
585 ReadParam(m, iter, &r->b) &&
586 ReadParam(m, iter, &r->c) &&
587 ReadParam(m, iter, &r->d));
589 static void Log(const param_type& p, std::string* l) {
590 LogParam(p.a, l);
591 l->append(", ");
592 LogParam(p.b, l);
593 l->append(", ");
594 LogParam(p.c, l);
595 l->append(", ");
596 LogParam(p.d, l);
600 template <class A, class B, class C, class D, class E>
601 struct ParamTraits< Tuple5<A, B, C, D, E> > {
602 typedef Tuple5<A, B, C, D, E> param_type;
603 static void Write(Message* m, const param_type& p) {
604 WriteParam(m, p.a);
605 WriteParam(m, p.b);
606 WriteParam(m, p.c);
607 WriteParam(m, p.d);
608 WriteParam(m, p.e);
610 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
611 return (ReadParam(m, iter, &r->a) &&
612 ReadParam(m, iter, &r->b) &&
613 ReadParam(m, iter, &r->c) &&
614 ReadParam(m, iter, &r->d) &&
615 ReadParam(m, iter, &r->e));
617 static void Log(const param_type& p, std::string* l) {
618 LogParam(p.a, l);
619 l->append(", ");
620 LogParam(p.b, l);
621 l->append(", ");
622 LogParam(p.c, l);
623 l->append(", ");
624 LogParam(p.d, l);
625 l->append(", ");
626 LogParam(p.e, l);
630 template<class P>
631 struct ParamTraits<ScopedVector<P> > {
632 typedef ScopedVector<P> param_type;
633 static void Write(Message* m, const param_type& p) {
634 WriteParam(m, static_cast<int>(p.size()));
635 for (size_t i = 0; i < p.size(); i++)
636 WriteParam(m, *p[i]);
638 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
639 int size = 0;
640 if (!m->ReadLength(iter, &size))
641 return false;
642 if (INT_MAX/sizeof(P) <= static_cast<size_t>(size))
643 return false;
644 r->resize(size);
645 for (int i = 0; i < size; i++) {
646 (*r)[i] = new P();
647 if (!ReadParam(m, iter, (*r)[i]))
648 return false;
650 return true;
652 static void Log(const param_type& p, std::string* l) {
653 for (size_t i = 0; i < p.size(); ++i) {
654 if (i != 0)
655 l->append(" ");
656 LogParam(*p[i], l);
661 // IPC types ParamTraits -------------------------------------------------------
663 // A ChannelHandle is basically a platform-inspecific wrapper around the
664 // fact that IPC endpoints are handled specially on POSIX. See above comments
665 // on FileDescriptor for more background.
666 template<>
667 struct IPC_EXPORT ParamTraits<IPC::ChannelHandle> {
668 typedef ChannelHandle param_type;
669 static void Write(Message* m, const param_type& p);
670 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
671 static void Log(const param_type& p, std::string* l);
674 template <>
675 struct IPC_EXPORT ParamTraits<LogData> {
676 typedef LogData param_type;
677 static void Write(Message* m, const param_type& p);
678 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
679 static void Log(const param_type& p, std::string* l);
682 template <>
683 struct IPC_EXPORT ParamTraits<Message> {
684 static void Write(Message* m, const Message& p);
685 static bool Read(const Message* m, PickleIterator* iter, Message* r);
686 static void Log(const Message& p, std::string* l);
689 // Windows ParamTraits ---------------------------------------------------------
691 #if defined(OS_WIN)
692 template <>
693 struct IPC_EXPORT ParamTraits<HANDLE> {
694 typedef HANDLE param_type;
695 static void Write(Message* m, const param_type& p);
696 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
697 static void Log(const param_type& p, std::string* l);
700 template <>
701 struct IPC_EXPORT ParamTraits<LOGFONT> {
702 typedef LOGFONT param_type;
703 static void Write(Message* m, const param_type& p);
704 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
705 static void Log(const param_type& p, std::string* l);
708 template <>
709 struct IPC_EXPORT ParamTraits<MSG> {
710 typedef MSG param_type;
711 static void Write(Message* m, const param_type& p);
712 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
713 static void Log(const param_type& p, std::string* l);
715 #endif // defined(OS_WIN)
717 //-----------------------------------------------------------------------------
718 // Generic message subclasses
720 // Used for asynchronous messages.
721 template <class ParamType>
722 class MessageSchema {
723 public:
724 typedef ParamType Param;
725 typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
727 static void Write(Message* msg, const RefParam& p) IPC_MSG_NOINLINE;
728 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
731 // defined in ipc_logging.cc
732 IPC_EXPORT void GenerateLogData(const std::string& channel,
733 const Message& message,
734 LogData* data, bool get_params);
737 #if defined(IPC_MESSAGE_LOG_ENABLED)
738 inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
739 const std::string& output_params = msg->output_params();
740 if (!l->empty() && !output_params.empty())
741 l->append(", ");
743 l->append(output_params);
746 template <class ReplyParamType>
747 inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
748 const Message* msg) {
749 if (msg->received_time() != 0) {
750 std::string output_params;
751 LogParam(reply_params, &output_params);
752 msg->set_output_params(output_params);
756 inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
757 if (msg->sent_time()) {
758 // Don't log the sync message after dispatch, as we don't have the
759 // output parameters at that point. Instead, save its data and log it
760 // with the outgoing reply message when it's sent.
761 LogData* data = new LogData;
762 GenerateLogData("", *msg, data, true);
763 msg->set_dont_log();
764 reply->set_sync_log_data(data);
767 #else
768 inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
770 template <class ReplyParamType>
771 inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
772 const Message* msg) {}
774 inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
775 #endif
777 // This class assumes that its template argument is a RefTuple (a Tuple with
778 // reference elements). This would go into ipc_message_utils_impl.h, but it is
779 // also used by chrome_frame.
780 template <class RefTuple>
781 class ParamDeserializer : public MessageReplyDeserializer {
782 public:
783 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
785 bool SerializeOutputParameters(const IPC::Message& msg, PickleIterator iter) {
786 return ReadParam(&msg, &iter, &out_);
789 RefTuple out_;
792 // Used for synchronous messages.
793 template <class SendParamType, class ReplyParamType>
794 class SyncMessageSchema {
795 public:
796 typedef SendParamType SendParam;
797 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
798 typedef ReplyParamType ReplyParam;
800 static void Write(Message* msg, const RefSendParam& send) IPC_MSG_NOINLINE;
801 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
802 static bool ReadReplyParam(
803 const Message* msg,
804 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
806 template<class T, class S, class Method>
807 static bool DispatchWithSendParams(bool ok, const SendParam& send_params,
808 const Message* msg, T* obj, S* sender,
809 Method func) {
810 Message* reply = SyncMessage::GenerateReply(msg);
811 if (ok) {
812 typename TupleTypes<ReplyParam>::ValueTuple reply_params;
813 DispatchToMethod(obj, func, send_params, &reply_params);
814 WriteParam(reply, reply_params);
815 LogReplyParamsToMessage(reply_params, msg);
816 } else {
817 NOTREACHED() << "Error deserializing message " << msg->type();
818 reply->set_reply_error();
820 sender->Send(reply);
821 return ok;
824 template<class T, class Method>
825 static bool DispatchDelayReplyWithSendParams(bool ok,
826 const SendParam& send_params,
827 const Message* msg, T* obj,
828 Method func) {
829 Message* reply = SyncMessage::GenerateReply(msg);
830 if (ok) {
831 Tuple1<Message&> t = MakeRefTuple(*reply);
832 ConnectMessageAndReply(msg, reply);
833 DispatchToMethod(obj, func, send_params, &t);
834 } else {
835 NOTREACHED() << "Error deserializing message " << msg->type();
836 reply->set_reply_error();
837 obj->Send(reply);
839 return ok;
842 template<typename TA>
843 static void WriteReplyParams(Message* reply, TA a) {
844 ReplyParam p(a);
845 WriteParam(reply, p);
848 template<typename TA, typename TB>
849 static void WriteReplyParams(Message* reply, TA a, TB b) {
850 ReplyParam p(a, b);
851 WriteParam(reply, p);
854 template<typename TA, typename TB, typename TC>
855 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
856 ReplyParam p(a, b, c);
857 WriteParam(reply, p);
860 template<typename TA, typename TB, typename TC, typename TD>
861 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
862 ReplyParam p(a, b, c, d);
863 WriteParam(reply, p);
866 template<typename TA, typename TB, typename TC, typename TD, typename TE>
867 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
868 ReplyParam p(a, b, c, d, e);
869 WriteParam(reply, p);
873 } // namespace IPC
875 #endif // IPC_IPC_MESSAGE_UTILS_H_