15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef IPC_IPC_MESSAGE_UTILS_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IPC_IPC_MESSAGE_UTILS_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/containers/small_map.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/files/file.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/format_macros.h"
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_vector.h"
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/tuple.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_message_start.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_param_traits.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_sync_message.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(COMPILER_GCC)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GCC "helpfully" tries to inline template methods in release mode. Except we
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// want the majority of the template junk being expanded once in the
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// implementation file (and only provide the definitions in
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ipc_message_utils_impl.h in those files) and exported, instead of expanded
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// at every call site. Special note: GCC happily accepts the attribute before
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the method declaration, but only acts on it if it is after.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 40500
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Starting in gcc 4.5, the noinline no longer implies the concept covered by
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the introduced noclone attribute, which will create specialized versions of
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// functions/methods when certain types are constant.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// www.gnu.org/software/gcc/gcc-4.5/changes.html
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IPC_MSG_NOINLINE  __attribute__((noinline, noclone));
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IPC_MSG_NOINLINE  __attribute__((noinline));
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(COMPILER_MSVC)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MSVC++ doesn't do this.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IPC_MSG_NOINLINE
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#error "Please add the noinline property for your new compiler here."
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DictionaryValue;
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FilePath;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ListValue;
547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class NullableString16;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Time;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TimeDelta;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TimeTicks;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct FileDescriptor;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace IPC {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ChannelHandle;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -----------------------------------------------------------------------------
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// How we send IPC message logs across channels.
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct IPC_EXPORT LogData {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogData();
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~LogData();
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string channel;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32 routing_id;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 type;  // "User-defined" message type, from ipc_message.h.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string flags;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 sent;  // Time that the message was sent (i.e. at Send()).
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 receive;  // Time before it was dispatched (i.e. before calling
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  // OnMessageReceived).
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 dispatch;  // Time after it was dispatched (i.e. after calling
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   // OnMessageReceived).
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string message_name;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string params;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//-----------------------------------------------------------------------------
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A dummy struct to place first just to allow leading commas for all
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// members in the macro-generated constructor initializer lists.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct NoParams {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class P>
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline void WriteParam(Message* m, const P& p) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef typename SimilarTypeTraits<P>::Type Type;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class P>
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                PickleIterator* iter,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                P* p) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef typename SimilarTypeTraits<P>::Type Type;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class P>
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline void LogParam(const P& p, std::string* l) {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef typename SimilarTypeTraits<P>::Type Type;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Primitive ParamTraits -------------------------------------------------------
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ParamTraits<bool> {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef bool param_type;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p) {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m->WriteBool(p);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return m->ReadBool(iter, r);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_EXPORT static void Log(const param_type& p, std::string* l);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstruct IPC_EXPORT ParamTraits<unsigned char> {
1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  typedef unsigned char param_type;
1287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static void Write(Message* m, const param_type& p);
1297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static bool Read(const Message* m, PickleIterator* iter, param_type* r);
1307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static void Log(const param_type& p, std::string* l);
1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch};
1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochtemplate <>
1347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstruct IPC_EXPORT ParamTraits<unsigned short> {
1357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  typedef unsigned short param_type;
1367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static void Write(Message* m, const param_type& p);
1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static bool Read(const Message* m, PickleIterator* iter, param_type* r);
1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static void Log(const param_type& p, std::string* l);
1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch};
1407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochtemplate <>
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ParamTraits<int> {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef int param_type;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p) {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m->WriteInt(p);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return m->ReadInt(iter, r);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_EXPORT static void Log(const param_type& p, std::string* l);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ParamTraits<unsigned int> {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef unsigned int param_type;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m->WriteInt(p);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return m->ReadInt(iter, reinterpret_cast<int*>(r));
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_EXPORT static void Log(const param_type& p, std::string* l);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ParamTraits<long> {
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef long param_type;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p) {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m->WriteLongUsingDangerousNonPortableLessPersistableForm(p);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return m->ReadLong(iter, r);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_EXPORT static void Log(const param_type& p, std::string* l);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ParamTraits<unsigned long> {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef unsigned long param_type;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p) {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m->WriteLongUsingDangerousNonPortableLessPersistableForm(p);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return m->ReadLong(iter, reinterpret_cast<long*>(r));
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_EXPORT static void Log(const param_type& p, std::string* l);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ParamTraits<long long> {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef long long param_type;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p) {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m->WriteInt64(static_cast<int64>(p));
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter,
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   param_type* r) {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_EXPORT static void Log(const param_type& p, std::string* l);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ParamTraits<unsigned long long> {
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef unsigned long long param_type;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p) {
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m->WriteInt64(p);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter,
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   param_type* r) {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_EXPORT static void Log(const param_type& p, std::string* l);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that the IPC layer doesn't sanitize NaNs and +/- INF values.  Clients
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// should be sure to check the sanity of these values after receiving them over
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IPC.
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct IPC_EXPORT ParamTraits<float> {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef float param_type;
2210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  static void Write(Message* m, const param_type& p) {
2220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    m->WriteFloat(p);
2230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
2240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
2250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return m->ReadFloat(iter, r);
2260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct IPC_EXPORT ParamTraits<double> {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef double param_type;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p);
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// STL ParamTraits -------------------------------------------------------------
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ParamTraits<std::string> {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::string param_type;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p) {
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m->WriteString(p);
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter,
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   param_type* r) {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return m->ReadString(iter, r);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_EXPORT static void Log(const param_type& p, std::string* l);
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ParamTraits<std::wstring> {
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::wstring param_type;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p) {
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m->WriteWString(p);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter,
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   param_type* r) {
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return m->ReadWString(iter, r);
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_EXPORT static void Log(const param_type& p, std::string* l);
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// need this trait.
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(WCHAR_T_IS_UTF16)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
270a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)struct ParamTraits<base::string16> {
271a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  typedef base::string16 param_type;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p) {
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    m->WriteString16(p);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter,
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   param_type* r) {
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return m->ReadString16(iter, r);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_EXPORT static void Log(const param_type& p, std::string* l);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct IPC_EXPORT ParamTraits<std::vector<char> > {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::vector<char> param_type;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p);
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message*, PickleIterator* iter, param_type* r);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct IPC_EXPORT ParamTraits<std::vector<unsigned char> > {
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::vector<unsigned char> param_type;
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p);
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r);
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l);
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct IPC_EXPORT ParamTraits<std::vector<bool> > {
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::vector<bool> param_type;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r);
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l);
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class P>
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ParamTraits<std::vector<P> > {
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::vector<P> param_type;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p) {
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteParam(m, static_cast<int>(p.size()));
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < p.size(); i++)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WriteParam(m, p[i]);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter,
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   param_type* r) {
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int size;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ReadLength() checks for < 0 itself.
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!m->ReadLength(iter, &size))
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resizing beforehand is not safe, see BUG 1006367 for details.
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    r->resize(size);
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < size; i++) {
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!ReadParam(m, iter, &(*r)[i]))
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l) {
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < p.size(); ++i) {
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (i != 0)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        l->append(" ");
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LogParam((p[i]), l);
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class P>
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ParamTraits<std::set<P> > {
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::set<P> param_type;
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p) {
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteParam(m, static_cast<int>(p.size()));
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typename param_type::const_iterator iter;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (iter = p.begin(); iter != p.end(); ++iter)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WriteParam(m, *iter);
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter,
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   param_type* r) {
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int size;
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!m->ReadLength(iter, &size))
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < size; ++i) {
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      P item;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!ReadParam(m, iter, &item))
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      r->insert(item);
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l) {
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    l->append("<std::set>");
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class K, class V>
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ParamTraits<std::map<K, V> > {
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<K, V> param_type;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p) {
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteParam(m, static_cast<int>(p.size()));
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typename param_type::const_iterator iter;
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (iter = p.begin(); iter != p.end(); ++iter) {
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WriteParam(m, iter->first);
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WriteParam(m, iter->second);
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter,
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   param_type* r) {
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int size;
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ReadParam(m, iter, &size) || size < 0)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < size; ++i) {
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      K k;
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!ReadParam(m, iter, &k))
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      V& value = (*r)[k];
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!ReadParam(m, iter, &value))
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l) {
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    l->append("<std::map>");
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class A, class B>
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ParamTraits<std::pair<A, B> > {
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::pair<A, B> param_type;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p) {
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteParam(m, p.first);
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteParam(m, p.second);
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter,
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   param_type* r) {
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l) {
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    l->append("(");
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LogParam(p.first, l);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    l->append(", ");
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LogParam(p.second, l);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    l->append(")");
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Base ParamTraits ------------------------------------------------------------
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct IPC_EXPORT ParamTraits<base::DictionaryValue> {
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::DictionaryValue param_type;
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p);
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r);
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l);
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FileDescriptors may be serialised over IPC channels on POSIX. On the
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// receiving side, the FileDescriptor is a valid duplicate of the file
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// descriptor which was transmitted: *it is not just a copy of the integer like
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this case, the receiving end will see a value of -1. *Zero is a valid file
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// descriptor*.
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The received file descriptor will have the |auto_close| flag set to true. The
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// code which handles the message is responsible for taking ownership of it.
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// File descriptors are OS resources and must be closed when no longer needed.
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// When sending a file descriptor, the file descriptor must be valid at the time
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of transmission. Since transmission is not synchronous, one should consider
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// dup()ing any file descriptors to be transmitted and setting the |auto_close|
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// flag, which causes the file descriptor to be closed after writing.
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<>
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct IPC_EXPORT ParamTraits<base::FileDescriptor> {
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::FileDescriptor param_type;
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p);
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r);
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l);
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(OS_POSIX)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct IPC_EXPORT ParamTraits<base::FilePath> {
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef base::FilePath param_type;
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p);
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r);
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l);
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct IPC_EXPORT ParamTraits<base::ListValue> {
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::ListValue param_type;
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p);
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r);
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l);
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
4707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)struct IPC_EXPORT ParamTraits<base::NullableString16> {
4717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef base::NullableString16 param_type;
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p);
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter,
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   param_type* r);
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l);
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct IPC_EXPORT ParamTraits<base::File::Info> {
4805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  typedef base::File::Info param_type;
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p);
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r);
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l);
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
4875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct SimilarTypeTraits<base::File::Error> {
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef int Type;
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <>
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct SimilarTypeTraits<HWND> {
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef HANDLE Type;
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // defined(OS_WIN)
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct IPC_EXPORT ParamTraits<base::Time> {
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::Time param_type;
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p);
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r);
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l);
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct IPC_EXPORT ParamTraits<base::TimeDelta> {
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::TimeDelta param_type;
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p);
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r);
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l);
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct IPC_EXPORT ParamTraits<base::TimeTicks> {
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::TimeTicks param_type;
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p);
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r);
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l);
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ParamTraits<Tuple0> {
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef Tuple0 param_type;
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p) {
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l) {
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class A>
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ParamTraits< Tuple1<A> > {
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef Tuple1<A> param_type;
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p) {
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteParam(m, p.a);
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ReadParam(m, iter, &r->a);
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l) {
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LogParam(p.a, l);
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class A, class B>
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ParamTraits< Tuple2<A, B> > {
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef Tuple2<A, B> param_type;
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p) {
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteParam(m, p.a);
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteParam(m, p.b);
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (ReadParam(m, iter, &r->a) &&
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ReadParam(m, iter, &r->b));
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l) {
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LogParam(p.a, l);
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    l->append(", ");
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LogParam(p.b, l);
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class A, class B, class C>
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ParamTraits< Tuple3<A, B, C> > {
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef Tuple3<A, B, C> param_type;
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p) {
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteParam(m, p.a);
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteParam(m, p.b);
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteParam(m, p.c);
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (ReadParam(m, iter, &r->a) &&
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ReadParam(m, iter, &r->b) &&
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ReadParam(m, iter, &r->c));
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l) {
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LogParam(p.a, l);
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    l->append(", ");
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LogParam(p.b, l);
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    l->append(", ");
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LogParam(p.c, l);
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class A, class B, class C, class D>
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ParamTraits< Tuple4<A, B, C, D> > {
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef Tuple4<A, B, C, D> param_type;
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p) {
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteParam(m, p.a);
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteParam(m, p.b);
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteParam(m, p.c);
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteParam(m, p.d);
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (ReadParam(m, iter, &r->a) &&
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ReadParam(m, iter, &r->b) &&
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ReadParam(m, iter, &r->c) &&
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ReadParam(m, iter, &r->d));
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l) {
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LogParam(p.a, l);
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    l->append(", ");
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LogParam(p.b, l);
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    l->append(", ");
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LogParam(p.c, l);
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    l->append(", ");
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LogParam(p.d, l);
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class A, class B, class C, class D, class E>
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ParamTraits< Tuple5<A, B, C, D, E> > {
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef Tuple5<A, B, C, D, E> param_type;
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p) {
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteParam(m, p.a);
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteParam(m, p.b);
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteParam(m, p.c);
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteParam(m, p.d);
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteParam(m, p.e);
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (ReadParam(m, iter, &r->a) &&
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ReadParam(m, iter, &r->b) &&
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ReadParam(m, iter, &r->c) &&
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ReadParam(m, iter, &r->d) &&
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ReadParam(m, iter, &r->e));
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l) {
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LogParam(p.a, l);
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    l->append(", ");
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LogParam(p.b, l);
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    l->append(", ");
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LogParam(p.c, l);
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    l->append(", ");
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LogParam(p.d, l);
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    l->append(", ");
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LogParam(p.e, l);
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template<class P>
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct ParamTraits<ScopedVector<P> > {
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef ScopedVector<P> param_type;
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static void Write(Message* m, const param_type& p) {
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WriteParam(m, static_cast<int>(p.size()));
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < p.size(); i++)
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      WriteParam(m, *p[i]);
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int size = 0;
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!m->ReadLength(iter, &size))
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (INT_MAX/sizeof(P) <= static_cast<size_t>(size))
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    r->resize(size);
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (int i = 0; i < size; i++) {
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (*r)[i] = new P();
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!ReadParam(m, iter, (*r)[i]))
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return false;
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static void Log(const param_type& p, std::string* l) {
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < p.size(); ++i) {
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (i != 0)
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        l->append(" ");
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LogParam(*p[i], l);
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
67523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)template <typename NormalMap,
67623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)          int kArraySize,
67723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)          typename EqualKey,
67823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)          typename MapInit>
67923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)struct ParamTraits<base::SmallMap<NormalMap, kArraySize, EqualKey, MapInit> > {
68023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  typedef base::SmallMap<NormalMap, kArraySize, EqualKey, MapInit> param_type;
68123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  typedef typename param_type::key_type K;
68223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  typedef typename param_type::data_type V;
68323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  static void Write(Message* m, const param_type& p) {
68423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    WriteParam(m, static_cast<int>(p.size()));
68523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    typename param_type::const_iterator iter;
68623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    for (iter = p.begin(); iter != p.end(); ++iter) {
68723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      WriteParam(m, iter->first);
68823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      WriteParam(m, iter->second);
68923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    }
69023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
69123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
69223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    int size;
69323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    if (!m->ReadLength(iter, &size))
69423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      return false;
69523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    for (int i = 0; i < size; ++i) {
69623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      K key;
69723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      if (!ReadParam(m, iter, &key))
69823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        return false;
69923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      V& value = (*r)[key];
70023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      if (!ReadParam(m, iter, &value))
70123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        return false;
70223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    }
70323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    return true;
70423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
70523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  static void Log(const param_type& p, std::string* l) {
70623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    l->append("<base::SmallMap>");
70723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
70823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)};
70923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
710cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)template <class P>
711cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)struct ParamTraits<scoped_ptr<P> > {
712cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  typedef scoped_ptr<P> param_type;
713cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  static void Write(Message* m, const param_type& p) {
714cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bool valid = !!p;
715cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    WriteParam(m, valid);
716cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (valid)
717cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      WriteParam(m, *p);
718cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
719cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
720cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bool valid = false;
721cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!ReadParam(m, iter, &valid))
722cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return false;
723cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
724cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!valid) {
725cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      r->reset();
726cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return true;
727cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
728cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
729cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    param_type temp(new P());
730cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!ReadParam(m, iter, temp.get()))
731cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return false;
732cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
733cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    r->swap(temp);
734cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return true;
735cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
736cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  static void Log(const param_type& p, std::string* l) {
737cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (p)
738cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      LogParam(*p, l);
739cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    else
740cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      l->append("NULL");
741cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
742cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
743cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IPC types ParamTraits -------------------------------------------------------
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A ChannelHandle is basically a platform-inspecific wrapper around the
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// fact that IPC endpoints are handled specially on POSIX.  See above comments
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// on FileDescriptor for more background.
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<>
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct IPC_EXPORT ParamTraits<IPC::ChannelHandle> {
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef ChannelHandle param_type;
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p);
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r);
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l);
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct IPC_EXPORT ParamTraits<LogData> {
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef LogData param_type;
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p);
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r);
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l);
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct IPC_EXPORT ParamTraits<Message> {
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const Message& p);
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, Message* r);
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const Message& p, std::string* l);
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Windows ParamTraits ---------------------------------------------------------
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct IPC_EXPORT ParamTraits<HANDLE> {
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef HANDLE param_type;
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p);
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r);
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l);
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct IPC_EXPORT ParamTraits<LOGFONT> {
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef LOGFONT param_type;
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p);
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r);
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l);
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <>
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct IPC_EXPORT ParamTraits<MSG> {
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef MSG param_type;
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* m, const param_type& p);
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* m, PickleIterator* iter, param_type* r);
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Log(const param_type& p, std::string* l);
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(OS_WIN)
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//-----------------------------------------------------------------------------
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Generic message subclasses
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Used for asynchronous messages.
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class ParamType>
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MessageSchema {
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef ParamType Param;
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* msg, const RefParam& p) IPC_MSG_NOINLINE;
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// defined in ipc_logging.cc
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IPC_EXPORT void GenerateLogData(const std::string& channel,
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const Message& message,
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                LogData* data, bool get_params);
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(IPC_MESSAGE_LOG_ENABLED)
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string& output_params = msg->output_params();
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!l->empty() && !output_params.empty())
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    l->append(", ");
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  l->append(output_params);
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class ReplyParamType>
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const Message* msg) {
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (msg->received_time() != 0) {
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string output_params;
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LogParam(reply_params, &output_params);
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    msg->set_output_params(output_params);
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (msg->sent_time()) {
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Don't log the sync message after dispatch, as we don't have the
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // output parameters at that point.  Instead, save its data and log it
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // with the outgoing reply message when it's sent.
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LogData* data = new LogData;
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GenerateLogData("", *msg, data, true);
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    msg->set_dont_log();
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    reply->set_sync_log_data(data);
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class ReplyParamType>
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const Message* msg) {}
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class assumes that its template argument is a RefTuple (a Tuple with
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reference elements). This would go into ipc_message_utils_impl.h, but it is
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// also used by chrome_frame.
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class RefTuple>
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ParamDeserializer : public MessageReplyDeserializer {
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool SerializeOutputParameters(const IPC::Message& msg, PickleIterator iter) {
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ReadParam(&msg, &iter, &out_);
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RefTuple out_;
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Used for synchronous messages.
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class SendParamType, class ReplyParamType>
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SyncMessageSchema {
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef SendParamType SendParam;
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef ReplyParamType ReplyParam;
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Write(Message* msg, const RefSendParam& send) IPC_MSG_NOINLINE;
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool ReadReplyParam(
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const Message* msg,
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<class T, class S, class Method>
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool DispatchWithSendParams(bool ok, const SendParam& send_params,
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const Message* msg, T* obj, S* sender,
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     Method func) {
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Message* reply = SyncMessage::GenerateReply(msg);
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ok) {
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      typename TupleTypes<ReplyParam>::ValueTuple reply_params;
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DispatchToMethod(obj, func, send_params, &reply_params);
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WriteParam(reply, reply_params);
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LogReplyParamsToMessage(reply_params, msg);
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED() << "Error deserializing message " << msg->type();
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reply->set_reply_error();
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sender->Send(reply);
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ok;
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<class T, class Method>
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool DispatchDelayReplyWithSendParams(bool ok,
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               const SendParam& send_params,
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               const Message* msg, T* obj,
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               Method func) {
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Message* reply = SyncMessage::GenerateReply(msg);
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ok) {
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Tuple1<Message&> t = MakeRefTuple(*reply);
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ConnectMessageAndReply(msg, reply);
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DispatchToMethod(obj, func, send_params, &t);
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED() << "Error deserializing message " << msg->type();
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reply->set_reply_error();
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      obj->Send(reply);
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ok;
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<typename TA>
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void WriteReplyParams(Message* reply, TA a) {
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReplyParam p(a);
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteParam(reply, p);
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<typename TA, typename TB>
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void WriteReplyParams(Message* reply, TA a, TB b) {
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReplyParam p(a, b);
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteParam(reply, p);
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<typename TA, typename TB, typename TC>
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReplyParam p(a, b, c);
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteParam(reply, p);
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<typename TA, typename TB, typename TC, typename TD>
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReplyParam p(a, b, c, d);
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteParam(reply, p);
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<typename TA, typename TB, typename TC, typename TD, typename TE>
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReplyParam p(a, b, c, d, e);
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteParam(reply, p);
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace IPC
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // IPC_IPC_MESSAGE_UTILS_H_
959