Initialize Tizen 2.3
[external/chromium.git] / ipc / ipc_message_utils.h
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.
4
5 #ifndef IPC_IPC_MESSAGE_UTILS_H_
6 #define IPC_IPC_MESSAGE_UTILS_H_
7 #pragma once
8
9 #include <algorithm>
10 #include <map>
11 #include <set>
12 #include <string>
13 #include <vector>
14
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"
23
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));
37 #else
38 #define IPC_MSG_NOINLINE  __attribute__((noinline));
39 #endif
40 #elif defined(COMPILER_MSVC)
41 // MSVC++ doesn't do this.
42 #define IPC_MSG_NOINLINE
43 #else
44 #error "Please add the noinline property for your new compiler here."
45 #endif
46
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,
53   LastIPCMsgStart
54 };
55
56 class FilePath;
57 class NullableString16;
58
59 namespace base {
60 class DictionaryValue;
61 class ListValue;
62 class Time;
63 class TimeDelta;
64 struct FileDescriptor;
65 }
66
67 namespace IPC {
68
69 struct ChannelHandle;
70
71 //-----------------------------------------------------------------------------
72 // An iterator class for reading the fields contained within a Message.
73
74 class MessageIterator {
75  public:
76   explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
77   }
78   int NextInt() const {
79     int val = -1;
80     if (!msg_.ReadInt(&iter_, &val))
81       NOTREACHED();
82     return val;
83   }
84 /*
85   const std::string NextString() const {
86     std::string val;
87     if (!msg_.ReadString(&iter_, &val))
88       NOTREACHED();
89     return val;
90   }
91   const std::wstring NextWString() const {
92     std::wstring val;
93     if (!msg_.ReadWString(&iter_, &val))
94       NOTREACHED();
95     return val;
96   }
97 */
98   void NextData(const char** data, int* length) const {
99     if (!msg_.ReadData(&iter_, data, length)) {
100       NOTREACHED();
101     }
102   }
103  private:
104   const Message& msg_;
105   mutable void* iter_;
106 };
107
108 //-----------------------------------------------------------------------------
109 // A dummy struct to place first just to allow leading commas for all
110 // members in the macro-generated constructor initializer lists.
111 struct NoParams {
112 };
113
114 //-----------------------------------------------------------------------------
115 // ParamTraits specializations, etc.
116
117 template <class P>
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));
121 }
122
123 template <class P>
124 static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
125                                                 P* p) {
126   typedef typename SimilarTypeTraits<P>::Type Type;
127   return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
128 }
129
130
131 template <class 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);
135 }
136
137
138 template <>
139 struct ParamTraits<bool> {
140   typedef bool param_type;
141   static void Write(Message* m, const param_type& p) {
142     m->WriteBool(p);
143   }
144   static bool Read(const Message* m, void** iter, param_type* r) {
145     return m->ReadBool(iter, r);
146   }
147   static void Log(const param_type& p, std::string* l) {
148     l->append(p ? "true" : "false");
149   }
150 };
151
152 template <>
153 struct ParamTraits<int> {
154   typedef int param_type;
155   static void Write(Message* m, const param_type& p) {
156     m->WriteInt(p);
157   }
158   static bool Read(const Message* m, void** iter, param_type* r) {
159     return m->ReadInt(iter, r);
160   }
161   IPC_EXPORT static void Log(const param_type& p, std::string* l);
162 };
163
164 template <>
165 struct ParamTraits<unsigned int> {
166   typedef unsigned int param_type;
167   static void Write(Message* m, const param_type& p) {
168     m->WriteInt(p);
169   }
170   static bool Read(const Message* m, void** iter, param_type* r) {
171     return m->ReadInt(iter, reinterpret_cast<int*>(r));
172   }
173   IPC_EXPORT static void Log(const param_type& p, std::string* l);
174 };
175
176 template <>
177 struct ParamTraits<long> {
178   typedef long param_type;
179   static void Write(Message* m, const param_type& p) {
180     m->WriteLong(p);
181   }
182   static bool Read(const Message* m, void** iter, param_type* r) {
183     return m->ReadLong(iter, r);
184   }
185   IPC_EXPORT static void Log(const param_type& p, std::string* l);
186 };
187
188 template <>
189 struct ParamTraits<unsigned long> {
190   typedef unsigned long param_type;
191   static void Write(Message* m, const param_type& p) {
192     m->WriteLong(p);
193   }
194   static bool Read(const Message* m, void** iter, param_type* r) {
195     return m->ReadLong(iter, reinterpret_cast<long*>(r));
196   }
197   IPC_EXPORT static void Log(const param_type& p, std::string* l);
198 };
199
200 template <>
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));
205   }
206   static bool Read(const Message* m, void** iter, param_type* r) {
207     return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
208   }
209   IPC_EXPORT static void Log(const param_type& p, std::string* l);
210 };
211
212 template <>
213 struct ParamTraits<unsigned long long> {
214   typedef unsigned long long param_type;
215   static void Write(Message* m, const param_type& p) {
216     m->WriteInt64(p);
217   }
218   static bool Read(const Message* m, void** iter, param_type* r) {
219     return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
220   }
221   IPC_EXPORT static void Log(const param_type& p, std::string* l);
222 };
223
224 template <>
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);
230 };
231
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
234 // IPC.
235 template <>
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));
240   }
241   static bool Read(const Message* m, void** iter, param_type* r) {
242     const char *data;
243     int data_size;
244     if (!m->ReadData(iter, &data, &data_size) ||
245         data_size != sizeof(param_type)) {
246       NOTREACHED();
247       return false;
248     }
249     memcpy(r, data, sizeof(param_type));
250     return true;
251   }
252
253   static void Log(const param_type& p, std::string* l) {
254       //l->append(StringPrintf("%e", p));
255   }
256
257 };
258
259 template <>
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));
264   }
265   static bool Read(const Message* m, void** iter, param_type* r) {
266     const char *data;
267     int data_size;
268     if (!m->ReadData(iter, &data, &data_size) ||
269         data_size != sizeof(param_type)) {
270       NOTREACHED();
271       return false;
272     }
273     memcpy(r, data, sizeof(param_type));
274     return true;
275   }
276
277   static void Log(const param_type& p, std::string* l) {
278       //l->append(StringPrintf("%e", p));
279   }
280
281 };
282
283 /*
284 template <>
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);
290 };
291
292 template <>
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);
298 };
299
300 #if defined(OS_WIN)
301 template <>
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));
306   }
307   static bool Read(const Message* m, void** iter, param_type* r) {
308     const char *data;
309     int data_size = 0;
310     bool result = m->ReadData(iter, &data, &data_size);
311     if (result && data_size == sizeof(LOGFONT)) {
312       memcpy(r, data, sizeof(LOGFONT));
313     } else {
314       result = false;
315       NOTREACHED();
316     }
317
318     return result;
319   }
320   static void Log(const param_type& p, std::string* l) {
321 //    l->append(StringPrintf("<LOGFONT>"));
322   }
323 };
324
325 template <>
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));
330   }
331   static bool Read(const Message* m, void** iter, param_type* r) {
332     const char *data;
333     int data_size = 0;
334     bool result = m->ReadData(iter, &data, &data_size);
335     if (result && data_size == sizeof(MSG)) {
336       memcpy(r, data, sizeof(MSG));
337     } else {
338       result = false;
339       NOTREACHED();
340     }
341
342     return result;
343   }
344   static void Log(const param_type& p, std::string* l) {
345     l->append("<MSG>");
346   }
347 };
348 #endif  // defined(OS_WIN)
349
350 template <>
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);
356 };
357
358 template <>
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);
364 };
365
366 */
367 template <>
368 struct ParamTraits<std::string> {
369   typedef std::string param_type;
370   static void Write(Message* m, const param_type& p) {
371     m->WriteString(p);
372   }
373   static bool Read(const Message* m, void** iter, param_type* r) {
374     return m->ReadString(iter, r);
375   }
376   static void Log(const param_type& p, std::string* l) {
377     l->append(p);
378   }
379 };
380
381 /*
382 template<typename CharType>
383 static void LogBytes(const std::vector<CharType>& data, std::string* out) {
384 #if defined(OS_WIN)
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]);
388 #else
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]);
394     else
395     {
396         // out->append(StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
397     }
398   }
399   if (data.size() > kMaxBytesToLog) {
400 //    out->append(
401 //        StringPrintf(" and %u more bytes",
402 //                     static_cast<unsigned>(data.size() - kMaxBytesToLog)));
403   }
404 #endif
405 }
406 */
407
408 template <>
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) {
412     if (p.empty()) {
413       m->WriteData(NULL, 0);
414     } else {
415       m->WriteData(reinterpret_cast<const char*>(&p.front()),
416                    static_cast<int>(p.size()));
417     }
418   }
419   static bool Read(const Message* m, void** iter, param_type* r) {
420     const char *data;
421     int data_size = 0;
422     if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
423       return false;
424     r->resize(data_size);
425     if (data_size)
426       memcpy(&r->front(), data, data_size);
427     return true;
428   }
429   static void Log(const param_type& p, std::string* l) {
430       // LogBytes(p, l);
431   }
432 };
433
434 template <>
435 struct ParamTraits<std::vector<char> > {
436   typedef std::vector<char> param_type;
437   static void Write(Message* m, const param_type& p) {
438     if (p.empty()) {
439       m->WriteData(NULL, 0);
440     } else {
441       m->WriteData(&p.front(), static_cast<int>(p.size()));
442     }
443   }
444   static bool Read(const Message* m, void** iter, param_type* r) {
445     const char *data;
446     int data_size = 0;
447     if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
448       return false;
449     r->resize(data_size);
450     if (data_size)
451       memcpy(&r->front(), data, data_size);
452     return true;
453   }
454   static void Log(const param_type& p, std::string* l) {
455       //LogBytes(p, l);
456   }
457 };
458
459 template <class P>
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++)
465       WriteParam(m, p[i]);
466   }
467   static bool Read(const Message* m, void** iter, param_type* r) {
468     int size;
469     // ReadLength() checks for < 0 itself.
470     if (!m->ReadLength(iter, &size))
471       return false;
472     // Resizing beforehand is not safe, see BUG 1006367 for details.
473     if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
474       return false;
475     r->resize(size);
476     for (int i = 0; i < size; i++) {
477       if (!ReadParam(m, iter, &(*r)[i]))
478         return false;
479     }
480     return true;
481   }
482   static void Log(const param_type& p, std::string* l) {
483 //    for (size_t i = 0; i < p.size(); ++i) {
484 //      if (i != 0)
485 //        l->append(" ");
486 //      LogParam((p[i]), l);
487 //    }
488   }
489 };
490
491 /*
492 template <class P>
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);
500   }
501   static bool Read(const Message* m, void** iter, param_type* r) {
502     int size;
503     if (!m->ReadLength(iter, &size))
504       return false;
505     for (int i = 0; i < size; ++i) {
506       P item;
507       if (!ReadParam(m, iter, &item))
508         return false;
509       r->insert(item);
510     }
511     return true;
512   }
513   static void Log(const param_type& p, std::string* l) {
514     l->append("<std::set>");
515   }
516 };
517
518
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);
528     }
529   }
530   static bool Read(const Message* m, void** iter, param_type* r) {
531     int size;
532     if (!ReadParam(m, iter, &size) || size < 0)
533       return false;
534     for (int i = 0; i < size; ++i) {
535       K k;
536       if (!ReadParam(m, iter, &k))
537         return false;
538       V& value = (*r)[k];
539       if (!ReadParam(m, iter, &value))
540         return false;
541     }
542     return true;
543   }
544   static void Log(const param_type& p, std::string* l) {
545     l->append("<std::map>");
546   }
547 };
548
549
550 template <>
551 struct ParamTraits<std::wstring> {
552   typedef std::wstring param_type;
553   static void Write(Message* m, const param_type& p) {
554     m->WriteWString(p);
555   }
556   static bool Read(const Message* m, void** iter, param_type* r) {
557     return m->ReadWString(iter, r);
558   }
559   IPC_EXPORT static void Log(const param_type& p, std::string* l);
560 };
561
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);
568   }
569   static bool Read(const Message* m, void** iter, param_type* r) {
570     return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
571   }
572   static void Log(const param_type& p, std::string* l) {
573     l->append("(");
574     LogParam(p.first, l);
575     l->append(", ");
576     LogParam(p.second, l);
577     l->append(")");
578   }
579 };
580
581 template <>
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);
587 };
588
589 // If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
590 // need this trait.
591 #if !defined(WCHAR_T_IS_UTF16)
592 template <>
593 struct ParamTraits<string16> {
594   typedef string16 param_type;
595   static void Write(Message* m, const param_type& p) {
596     m->WriteString16(p);
597   }
598   static bool Read(const Message* m, void** iter, param_type* r) {
599     return m->ReadString16(iter, r);
600   }
601   IPC_EXPORT static void Log(const param_type& p, std::string* l);
602 };
603 #endif
604
605 // and, a few more useful types...
606 #if defined(OS_WIN)
607 template <>
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
612     // bit systems.
613     m->WriteUInt32(reinterpret_cast<uint32>(p));
614   }
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));
618   }
619   static void Log(const param_type& p, std::string* l) {
620 //    l->append(StringPrintf("0x%X", p));
621   }
622 };
623
624 template <>
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));
629   }
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));
633   }
634   static void Log(const param_type& p, std::string* l) {
635 //    l->append(StringPrintf("0x%X", p));
636   }
637 };
638
639 template <>
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));
644   }
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));
648   }
649 };
650
651 template <>
652 struct ParamTraits<POINT> {
653   typedef POINT param_type;
654   static void Write(Message* m, const param_type& p) {
655     m->WriteInt(p.x);
656     m->WriteInt(p.y);
657   }
658   static bool Read(const Message* m, void** iter, param_type* r) {
659     int x, y;
660     if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
661       return false;
662     r->x = x;
663     r->y = y;
664     return true;
665   }
666   static void Log(const param_type& p, std::string* l) {
667 //    l->append(StringPrintf("(%d, %d)", p.x, p.y));
668   }
669 };
670 #endif  // defined(OS_WIN)
671
672 template <>
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);
678 };
679
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
686 // descriptor*.
687 //
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.
691 //
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.
696 template<>
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);
702 };
703 #endif  // defined(OS_POSIX)
704
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.
708 template<>
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);
714 };
715
716 #if defined(OS_WIN)
717 template <>
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));
722   }
723   static bool Read(const Message* m, void** iter, param_type* r) {
724     const char *data;
725     int data_size = 0;
726     bool result = m->ReadData(iter, &data, &data_size);
727     if (result && data_size == sizeof(XFORM)) {
728       memcpy(r, data, sizeof(XFORM));
729     } else {
730       result = false;
731       NOTREACHED();
732     }
733
734     return result;
735   }
736   static void Log(const param_type& p, std::string* l) {
737     l->append("<XFORM>");
738   }
739 };
740 #endif  // defined(OS_WIN)
741
742 struct IPC_EXPORT LogData {
743   LogData();
744   ~LogData();
745
746   std::string channel;
747   int32 routing_id;
748   uint32 type;  // "User-defined" message type, from ipc_message.h.
749   std::string flags;
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;
756   std::string params;
757 };
758
759 template <>
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!
766   }
767 };
768
769 */
770 template <>
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);
777   }
778   static bool Read(const Message* m, void** iter, Message* r) {
779     int size;
780     if (!m->ReadInt(iter, &size))
781       return false;
782     const char* data;
783     if (!m->ReadData(iter, &data, &size))
784       return false;
785     *r = Message(data, size);
786     return true;
787   }
788   static void Log(const Message& p, std::string* l) {
789     l->append("<IPC::Message>");
790   }
791 };
792
793 template <>
794 struct ParamTraits<Tuple0> {
795   typedef Tuple0 param_type;
796   static void Write(Message* m, const param_type& p) {
797   }
798   static bool Read(const Message* m, void** iter, param_type* r) {
799     return true;
800   }
801   static void Log(const param_type& p, std::string* l) {
802   }
803 };
804
805 template <class A>
806 struct ParamTraits< Tuple1<A> > {
807   typedef Tuple1<A> param_type;
808   static void Write(Message* m, const param_type& p) {
809     WriteParam(m, p.a);
810   }
811   static bool Read(const Message* m, void** iter, param_type* r) {
812     return ReadParam(m, iter, &r->a);
813   }
814   static void Log(const param_type& p, std::string* l) {
815     LogParam(p.a, l);
816   }
817 };
818
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) {
823     WriteParam(m, p.a);
824     WriteParam(m, p.b);
825   }
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));
829   }
830   static void Log(const param_type& p, std::string* l) {
831     LogParam(p.a, l);
832     l->append(", ");
833     LogParam(p.b, l);
834   }
835 };
836
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) {
841     WriteParam(m, p.a);
842     WriteParam(m, p.b);
843     WriteParam(m, p.c);
844   }
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));
849   }
850   static void Log(const param_type& p, std::string* l) {
851     LogParam(p.a, l);
852     l->append(", ");
853     LogParam(p.b, l);
854     l->append(", ");
855     LogParam(p.c, l);
856   }
857 };
858
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) {
863     WriteParam(m, p.a);
864     WriteParam(m, p.b);
865     WriteParam(m, p.c);
866     WriteParam(m, p.d);
867   }
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));
873   }
874   static void Log(const param_type& p, std::string* l) {
875     LogParam(p.a, l);
876     l->append(", ");
877     LogParam(p.b, l);
878     l->append(", ");
879     LogParam(p.c, l);
880     l->append(", ");
881     LogParam(p.d, l);
882   }
883 };
884
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) {
889     WriteParam(m, p.a);
890     WriteParam(m, p.b);
891     WriteParam(m, p.c);
892     WriteParam(m, p.d);
893     WriteParam(m, p.e);
894   }
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));
901   }
902   static void Log(const param_type& p, std::string* l) {
903     LogParam(p.a, l);
904     l->append(", ");
905     LogParam(p.b, l);
906     l->append(", ");
907     LogParam(p.c, l);
908     l->append(", ");
909     LogParam(p.d, l);
910     l->append(", ");
911     LogParam(p.e, l);
912   }
913 };
914
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) {
919     WriteParam(m, p.a);
920     WriteParam(m, p.b);
921     WriteParam(m, p.c);
922     WriteParam(m, p.d);
923     WriteParam(m, p.e);
924     WriteParam(m, p.f);
925   }
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));
933   }
934   static void Log(const param_type& p, std::string* l) {
935     LogParam(p.a, l);
936     l->append(", ");
937     LogParam(p.b, l);
938     l->append(", ");
939     LogParam(p.c, l);
940     l->append(", ");
941     LogParam(p.d, l);
942     l->append(", ");
943     LogParam(p.e, l);
944     l->append(", ");
945     LogParam(p.f, l);
946   }
947 };
948
949 //-----------------------------------------------------------------------------
950 // Generic message subclasses
951
952 // Used for asynchronous messages.
953 template <class ParamType>
954 class __attribute__((visibility("default"))) MessageWithTuple : public Message {
955  public:
956   typedef ParamType Param;
957   typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
958
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);
964
965   static bool Read(const Message* msg, Param* p)
966   { // Put definition into class so that Dispatch method could use it.
967     void* iter = NULL;
968     if (ReadParam(msg, &iter, p))
969       return true;
970     NOTREACHED() << "Error deserializing message " << msg->type();
971     return false;
972   } IPC_MSG_NOINLINE;
973
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) {
977     Param p;
978     if (Read(msg, &p)) {
979       DispatchToMethod(obj, func, p);
980       return true;
981     }
982     return false;
983   }
984
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)) {
991     Param p;
992     if (Read(msg, &p)) {
993       (obj->*func)(*msg, p.a);
994       return true;
995     }
996     return false;
997   }
998
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)) {
1002     Param p;
1003     if (Read(msg, &p)) {
1004       (obj->*func)(*msg, p.a, p.b);
1005       return true;
1006     }
1007     return false;
1008   }
1009
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)) {
1013     Param p;
1014     if (Read(msg, &p)) {
1015       (obj->*func)(*msg, p.a, p.b, p.c);
1016       return true;
1017     }
1018     return false;
1019   }
1020
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)) {
1024     Param p;
1025     if (Read(msg, &p)) {
1026       (obj->*func)(*msg, p.a, p.b, p.c, p.d);
1027       return true;
1028     }
1029     return false;
1030   }
1031
1032   template<class T, class S, typename TA, typename TB, typename TC, typename TD,
1033            typename TE>
1034   static bool Dispatch(const Message* msg, T* obj, S* sender,
1035                        void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
1036     Param p;
1037     if (Read(msg, &p)) {
1038       (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
1039       return true;
1040     }
1041     return false;
1042   }
1043
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) {
1048     ParamType params;
1049     if (!Read(msg, &params))
1050       return false;
1051     *a = params.a;
1052     *b = params.b;
1053     return true;
1054   }
1055
1056   template<typename TA, typename TB, typename TC>
1057   static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
1058     ParamType params;
1059     if (!Read(msg, &params))
1060       return false;
1061     *a = params.a;
1062     *b = params.b;
1063     *c = params.c;
1064     return true;
1065   }
1066
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) {
1069     ParamType params;
1070     if (!Read(msg, &params))
1071       return false;
1072     *a = params.a;
1073     *b = params.b;
1074     *c = params.c;
1075     *d = params.d;
1076     return true;
1077   }
1078
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) {
1081     ParamType params;
1082     if (!Read(msg, &params))
1083       return false;
1084     *a = params.a;
1085     *b = params.b;
1086     *c = params.c;
1087     *d = params.d;
1088     *e = params.e;
1089     return true;
1090   }
1091 };
1092
1093 // defined in ipc_logging.cc
1094 IPC_EXPORT void GenerateLogData(const std::string& channel,
1095                                 const Message& message,
1096                                 LogData* data);
1097
1098
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())
1103     l->append(", ");
1104
1105   l->append(output_params);
1106 }
1107
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);
1115   }
1116 }
1117
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);
1127   }
1128 }
1129 #else
1130 inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
1131
1132 template <class ReplyParamType>
1133 inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1134                                     const Message* msg) {}
1135
1136 inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1137 #endif
1138
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 {
1144  public:
1145   explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
1146
1147   bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1148     return ReadParam(&msg, &iter, &out_);
1149   }
1150
1151   RefTuple out_;
1152 };
1153
1154 // Used for synchronous messages.
1155 template <class SendParamType, class ReplyParamType>
1156 class __attribute__((visibility("default"))) MessageWithReply : public SyncMessage {
1157  public:
1158   typedef SendParamType SendParam;
1159   typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
1160   typedef ReplyParamType ReplyParam;
1161
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);
1168   } IPC_MSG_NOINLINE;
1169   static bool ReadReplyParam(
1170       const Message* msg,
1171       typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
1172
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);
1177     bool error;
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);
1182       error = false;
1183       LogReplyParamsToMessage(reply_params, msg);
1184     } else {
1185       NOTREACHED() << "Error deserializing message " << msg->type();
1186       reply->set_reply_error();
1187       error = true;
1188     }
1189
1190     sender->Send(reply);
1191     return !error;
1192   }
1193
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);
1198     bool error;
1199     if (ReadSendParam(msg, &send_params)) {
1200       Tuple1<Message&> t = MakeRefTuple(*reply);
1201       ConnectMessageAndReply(msg, reply);
1202       DispatchToMethod(obj, func, send_params, &t);
1203       error = false;
1204     } else {
1205       NOTREACHED() << "Error deserializing message " << msg->type();
1206       reply->set_reply_error();
1207       obj->Send(reply);
1208       error = true;
1209     }
1210     return !error;
1211   }
1212
1213   template<typename TA>
1214   static void WriteReplyParams(Message* reply, TA a) {
1215     ReplyParam p(a);
1216     WriteParam(reply, p);
1217   }
1218
1219   template<typename TA, typename TB>
1220   static void WriteReplyParams(Message* reply, TA a, TB b) {
1221     ReplyParam p(a, b);
1222     WriteParam(reply, p);
1223   }
1224
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);
1229   }
1230
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);
1235   }
1236
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);
1241   }
1242 };
1243
1244 //-----------------------------------------------------------------------------
1245
1246 }  // namespace IPC
1247
1248 #endif  // IPC_IPC_MESSAGE_UTILS_H_