ipc/chromium/src/chrome/common/ipc_message_utils.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/ipc/chromium/src/chrome/common/ipc_message_utils.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1334 @@
     1.4 +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
     1.5 +// Use of this source code is governed by a BSD-style license that can be
     1.6 +// found in the LICENSE file.
     1.7 +
     1.8 +#ifndef CHROME_COMMON_IPC_MESSAGE_UTILS_H_
     1.9 +#define CHROME_COMMON_IPC_MESSAGE_UTILS_H_
    1.10 +
    1.11 +#include <string>
    1.12 +#include <vector>
    1.13 +#include <map>
    1.14 +
    1.15 +#include "base/file_path.h"
    1.16 +#include "base/string_util.h"
    1.17 +#include "base/string16.h"
    1.18 +#include "base/tuple.h"
    1.19 +#include "base/time.h"
    1.20 +
    1.21 +#if defined(OS_POSIX)
    1.22 +#include "chrome/common/file_descriptor_set_posix.h"
    1.23 +#endif
    1.24 +#include "chrome/common/ipc_sync_message.h"
    1.25 +#include "chrome/common/transport_dib.h"
    1.26 +
    1.27 +namespace IPC {
    1.28 +
    1.29 +//-----------------------------------------------------------------------------
    1.30 +// An iterator class for reading the fields contained within a Message.
    1.31 +
    1.32 +class MessageIterator {
    1.33 + public:
    1.34 +  explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
    1.35 +  }
    1.36 +  int NextInt() const {
    1.37 +    int val;
    1.38 +    if (!msg_.ReadInt(&iter_, &val))
    1.39 +      NOTREACHED();
    1.40 +    return val;
    1.41 +  }
    1.42 +  intptr_t NextIntPtr() const {
    1.43 +    intptr_t val;
    1.44 +    if (!msg_.ReadIntPtr(&iter_, &val))
    1.45 +      NOTREACHED();
    1.46 +    return val;
    1.47 +  }
    1.48 +  const std::string NextString() const {
    1.49 +    std::string val;
    1.50 +    if (!msg_.ReadString(&iter_, &val))
    1.51 +      NOTREACHED();
    1.52 +    return val;
    1.53 +  }
    1.54 +  const std::wstring NextWString() const {
    1.55 +    std::wstring val;
    1.56 +    if (!msg_.ReadWString(&iter_, &val))
    1.57 +      NOTREACHED();
    1.58 +    return val;
    1.59 +  }
    1.60 +  const void NextData(const char** data, int* length) const {
    1.61 +    if (!msg_.ReadData(&iter_, data, length)) {
    1.62 +      NOTREACHED();
    1.63 +    }
    1.64 +  }
    1.65 + private:
    1.66 +  const Message& msg_;
    1.67 +  mutable void* iter_;
    1.68 +};
    1.69 +
    1.70 +//-----------------------------------------------------------------------------
    1.71 +// ParamTraits specializations, etc.
    1.72 +//
    1.73 +// The full set of types ParamTraits is specialized upon contains *possibly*
    1.74 +// repeated types: unsigned long may be uint32_t or size_t, unsigned long long
    1.75 +// may be uint64_t or size_t, nsresult may be uint32_t, and so on.  You can't
    1.76 +// have ParamTraits<unsigned int> *and* ParamTraits<uint32_t> if unsigned int
    1.77 +// is uint32_t -- that's multiple definitions, and you can only have one.
    1.78 +//
    1.79 +// You could use #ifs and macro conditions to avoid duplicates, but they'd be
    1.80 +// hairy: heavily dependent upon OS and compiler author choices, forced to
    1.81 +// address all conflicts by hand.  Happily there's a better way.  The basic
    1.82 +// idea looks like this, where T -> U represents T inheriting from U:
    1.83 +//
    1.84 +// class ParamTraits<P>
    1.85 +// |
    1.86 +// --> class ParamTraits1<P>
    1.87 +//     |
    1.88 +//     --> class ParamTraits2<P>
    1.89 +//         |
    1.90 +//         --> class ParamTraitsN<P> // or however many levels
    1.91 +//
    1.92 +// The default specialization of ParamTraits{M}<P> is an empty class that
    1.93 +// inherits from ParamTraits{M + 1}<P> (or nothing in the base case).
    1.94 +//
    1.95 +// Now partition the set of parameter types into sets without duplicates.
    1.96 +// Assign each set of types to a level M.  Then specialize ParamTraitsM for
    1.97 +// each of those types.  A reference to ParamTraits<P> will consist of some
    1.98 +// number of empty classes inheriting in sequence, ending in a non-empty
    1.99 +// ParamTraits{N}<P>.  It's okay for the parameter types to be duplicative:
   1.100 +// either name of a type will resolve to the same ParamTraits{N}<P>.
   1.101 +//
   1.102 +// The nice thing is that because templates are instantiated lazily, if we
   1.103 +// indeed have uint32_t == unsigned int, say, with the former in level N and
   1.104 +// the latter in M > N, ParamTraitsM<unsigned int> won't be created (as long as
   1.105 +// nobody uses ParamTraitsM<unsigned int>, but why would you), and no duplicate
   1.106 +// code will be compiled or extra symbols generated.  It's as efficient at
   1.107 +// runtime as manually figuring out and avoiding conflicts by #ifs.
   1.108 +//
   1.109 +// The scheme we follow below names the various classes according to the types
   1.110 +// in them, and the number of ParamTraits levels is larger, but otherwise it's
   1.111 +// exactly the above idea.
   1.112 +//
   1.113 +
   1.114 +template <class P> struct ParamTraits;
   1.115 +
   1.116 +template <class P>
   1.117 +static inline void WriteParam(Message* m, const P& p) {
   1.118 +  ParamTraits<P>::Write(m, p);
   1.119 +}
   1.120 +
   1.121 +template <class P>
   1.122 +static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
   1.123 +                                                P* p) {
   1.124 +  return ParamTraits<P>::Read(m, iter, p);
   1.125 +}
   1.126 +
   1.127 +template <class P>
   1.128 +static inline void LogParam(const P& p, std::wstring* l) {
   1.129 +  ParamTraits<P>::Log(p, l);
   1.130 +}
   1.131 +
   1.132 +// Fundamental types.
   1.133 +
   1.134 +template <class P>
   1.135 +struct ParamTraitsFundamental {};
   1.136 +
   1.137 +template <>
   1.138 +struct ParamTraitsFundamental<bool> {
   1.139 +  typedef bool param_type;
   1.140 +  static void Write(Message* m, const param_type& p) {
   1.141 +    m->WriteBool(p);
   1.142 +  }
   1.143 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.144 +    return m->ReadBool(iter, r);
   1.145 +  }
   1.146 +  static void Log(const param_type& p, std::wstring* l) {
   1.147 +    l->append(p ? L"true" : L"false");
   1.148 +  }
   1.149 +};
   1.150 +
   1.151 +template <>
   1.152 +struct ParamTraitsFundamental<int> {
   1.153 +  typedef int param_type;
   1.154 +  static void Write(Message* m, const param_type& p) {
   1.155 +    m->WriteInt(p);
   1.156 +  }
   1.157 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.158 +    return m->ReadInt(iter, r);
   1.159 +  }
   1.160 +  static void Log(const param_type& p, std::wstring* l) {
   1.161 +    l->append(StringPrintf(L"%d", p));
   1.162 +  }
   1.163 +};
   1.164 +
   1.165 +template <>
   1.166 +struct ParamTraitsFundamental<long> {
   1.167 +  typedef long param_type;
   1.168 +  static void Write(Message* m, const param_type& p) {
   1.169 +    m->WriteLong(p);
   1.170 +  }
   1.171 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.172 +    return m->ReadLong(iter, r);
   1.173 +  }
   1.174 +  static void Log(const param_type& p, std::wstring* l) {
   1.175 +    l->append(StringPrintf(L"%l", p));
   1.176 +  }
   1.177 +};
   1.178 +
   1.179 +template <>
   1.180 +struct ParamTraitsFundamental<unsigned long> {
   1.181 +  typedef unsigned long param_type;
   1.182 +  static void Write(Message* m, const param_type& p) {
   1.183 +    m->WriteULong(p);
   1.184 +  }
   1.185 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.186 +    return m->ReadULong(iter, r);
   1.187 +  }
   1.188 +  static void Log(const param_type& p, std::wstring* l) {
   1.189 +    l->append(StringPrintf(L"%ul", p));
   1.190 +  }
   1.191 +};
   1.192 +
   1.193 +template <>
   1.194 +struct ParamTraitsFundamental<long long> {
   1.195 +  typedef long long param_type;
   1.196 +  static void Write(Message* m, const param_type& p) {
   1.197 +    m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
   1.198 + }
   1.199 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.200 +    const char *data;
   1.201 +    int data_size = 0;
   1.202 +    bool result = m->ReadData(iter, &data, &data_size);
   1.203 +    if (result && data_size == sizeof(param_type)) {
   1.204 +      memcpy(r, data, sizeof(param_type));
   1.205 +    } else {
   1.206 +      result = false;
   1.207 +      NOTREACHED();
   1.208 +    }
   1.209 +    return result;
   1.210 +  }
   1.211 +  static void Log(const param_type& p, std::wstring* l) {
   1.212 +    l->append(StringPrintf(L"%ll", p));
   1.213 +  }
   1.214 +};
   1.215 +
   1.216 +template <>
   1.217 +struct ParamTraitsFundamental<unsigned long long> {
   1.218 +  typedef unsigned long long param_type;
   1.219 +  static void Write(Message* m, const param_type& p) {
   1.220 +    m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
   1.221 + }
   1.222 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.223 +    const char *data;
   1.224 +    int data_size = 0;
   1.225 +    bool result = m->ReadData(iter, &data, &data_size);
   1.226 +    if (result && data_size == sizeof(param_type)) {
   1.227 +      memcpy(r, data, sizeof(param_type));
   1.228 +    } else {
   1.229 +      result = false;
   1.230 +      NOTREACHED();
   1.231 +    }
   1.232 +    return result;
   1.233 +  }
   1.234 +  static void Log(const param_type& p, std::wstring* l) {
   1.235 +    l->append(StringPrintf(L"%ull", p));
   1.236 +  }
   1.237 +};
   1.238 +
   1.239 +template <>
   1.240 +struct ParamTraitsFundamental<double> {
   1.241 +  typedef double param_type;
   1.242 +  static void Write(Message* m, const param_type& p) {
   1.243 +    m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
   1.244 +  }
   1.245 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.246 +    const char *data;
   1.247 +    int data_size = 0;
   1.248 +    bool result = m->ReadData(iter, &data, &data_size);
   1.249 +    if (result && data_size == sizeof(param_type)) {
   1.250 +      memcpy(r, data, sizeof(param_type));
   1.251 +    } else {
   1.252 +      result = false;
   1.253 +      NOTREACHED();
   1.254 +    }
   1.255 +
   1.256 +    return result;
   1.257 +  }
   1.258 +  static void Log(const param_type& p, std::wstring* l) {
   1.259 +    l->append(StringPrintf(L"e", p));
   1.260 +  }
   1.261 +};
   1.262 +
   1.263 +// Fixed-size <stdint.h> types.
   1.264 +
   1.265 +template <class P>
   1.266 +struct ParamTraitsFixed : ParamTraitsFundamental<P> {};
   1.267 +
   1.268 +template <>
   1.269 +struct ParamTraitsFixed<int16_t> {
   1.270 +  typedef int16_t param_type;
   1.271 +  static void Write(Message* m, const param_type& p) {
   1.272 +    m->WriteInt16(p);
   1.273 +  }
   1.274 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.275 +    return m->ReadInt16(iter, r);
   1.276 +  }
   1.277 +  static void Log(const param_type& p, std::wstring* l) {
   1.278 +    l->append(StringPrintf(L"%hd", p));
   1.279 +  }
   1.280 +};
   1.281 +
   1.282 +template <>
   1.283 +struct ParamTraitsFixed<uint16_t> {
   1.284 +  typedef uint16_t param_type;
   1.285 +  static void Write(Message* m, const param_type& p) {
   1.286 +    m->WriteUInt16(p);
   1.287 +  }
   1.288 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.289 +    return m->ReadUInt16(iter, r);
   1.290 +  }
   1.291 +  static void Log(const param_type& p, std::wstring* l) {
   1.292 +    l->append(StringPrintf(L"%hu", p));
   1.293 +  }
   1.294 +};
   1.295 +
   1.296 +template <>
   1.297 +struct ParamTraitsFixed<uint32_t> {
   1.298 +  typedef uint32_t param_type;
   1.299 +  static void Write(Message* m, const param_type& p) {
   1.300 +    m->WriteUInt32(p);
   1.301 +  }
   1.302 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.303 +    return m->ReadUInt32(iter, r);
   1.304 +  }
   1.305 +  static void Log(const param_type& p, std::wstring* l) {
   1.306 +    l->append(StringPrintf(L"%u", p));
   1.307 +  }
   1.308 +};
   1.309 +
   1.310 +template <>
   1.311 +struct ParamTraitsFixed<int64_t> {
   1.312 +  typedef int64_t param_type;
   1.313 +  static void Write(Message* m, const param_type& p) {
   1.314 +    m->WriteInt64(p);
   1.315 +  }
   1.316 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.317 +    return m->ReadInt64(iter, r);
   1.318 +  }
   1.319 +  static void Log(const param_type& p, std::wstring* l) {
   1.320 +    l->append(StringPrintf(L"%" PRId64L, p));
   1.321 +  }
   1.322 +};
   1.323 +
   1.324 +template <>
   1.325 +struct ParamTraitsFixed<uint64_t> {
   1.326 +  typedef uint64_t param_type;
   1.327 +  static void Write(Message* m, const param_type& p) {
   1.328 +    m->WriteInt64(static_cast<int64_t>(p));
   1.329 +  }
   1.330 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.331 +    return m->ReadInt64(iter, reinterpret_cast<int64_t*>(r));
   1.332 +  }
   1.333 +  static void Log(const param_type& p, std::wstring* l) {
   1.334 +    l->append(StringPrintf(L"%" PRIu64L, p));
   1.335 +  }
   1.336 +};
   1.337 +
   1.338 +// Other standard C types.
   1.339 +
   1.340 +template <class P>
   1.341 +struct ParamTraitsLibC : ParamTraitsFixed<P> {};
   1.342 +
   1.343 +template <>
   1.344 +struct ParamTraitsLibC<size_t> {
   1.345 +  typedef size_t param_type;
   1.346 +  static void Write(Message* m, const param_type& p) {
   1.347 +    m->WriteSize(p);
   1.348 +  }
   1.349 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.350 +    return m->ReadSize(iter, r);
   1.351 +  }
   1.352 +  static void Log(const param_type& p, std::wstring* l) {
   1.353 +    l->append(StringPrintf(L"%u", p));
   1.354 +  }
   1.355 +};
   1.356 +
   1.357 +// std::* types.
   1.358 +
   1.359 +template <class P>
   1.360 +struct ParamTraitsStd : ParamTraitsLibC<P> {};
   1.361 +
   1.362 +template <>
   1.363 +struct ParamTraitsStd<std::string> {
   1.364 +  typedef std::string param_type;
   1.365 +  static void Write(Message* m, const param_type& p) {
   1.366 +    m->WriteString(p);
   1.367 +  }
   1.368 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.369 +    return m->ReadString(iter, r);
   1.370 +  }
   1.371 +  static void Log(const param_type& p, std::wstring* l) {
   1.372 +    l->append(UTF8ToWide(p));
   1.373 +  }
   1.374 +};
   1.375 +
   1.376 +template <>
   1.377 +struct ParamTraitsStd<std::wstring> {
   1.378 +  typedef std::wstring param_type;
   1.379 +  static void Write(Message* m, const param_type& p) {
   1.380 +    m->WriteWString(p);
   1.381 +  }
   1.382 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.383 +    return m->ReadWString(iter, r);
   1.384 +  }
   1.385 +  static void Log(const param_type& p, std::wstring* l) {
   1.386 +    l->append(p);
   1.387 +  }
   1.388 +};
   1.389 +
   1.390 +template <>
   1.391 +struct ParamTraitsStd<std::vector<unsigned char> > {
   1.392 +  typedef std::vector<unsigned char> param_type;
   1.393 +  static void Write(Message* m, const param_type& p) {
   1.394 +    if (p.size() == 0) {
   1.395 +      m->WriteData(NULL, 0);
   1.396 +    } else {
   1.397 +      m->WriteData(reinterpret_cast<const char*>(&p.front()),
   1.398 +                   static_cast<int>(p.size()));
   1.399 +    }
   1.400 +  }
   1.401 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.402 +    const char *data;
   1.403 +    int data_size = 0;
   1.404 +    if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
   1.405 +      return false;
   1.406 +    r->resize(data_size);
   1.407 +    if (data_size)
   1.408 +      memcpy(&r->front(), data, data_size);
   1.409 +    return true;
   1.410 +  }
   1.411 +  static void Log(const param_type& p, std::wstring* l) {
   1.412 +    for (size_t i = 0; i < p.size(); ++i)
   1.413 +      l->push_back(p[i]);
   1.414 +  }
   1.415 +};
   1.416 +
   1.417 +template <>
   1.418 +struct ParamTraitsStd<std::vector<char> > {
   1.419 +  typedef std::vector<char> param_type;
   1.420 +  static void Write(Message* m, const param_type& p) {
   1.421 +    if (p.size() == 0) {
   1.422 +      m->WriteData(NULL, 0);
   1.423 +    } else {
   1.424 +      m->WriteData(&p.front(), static_cast<int>(p.size()));
   1.425 +    }
   1.426 +  }
   1.427 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.428 +    const char *data;
   1.429 +    int data_size = 0;
   1.430 +    if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
   1.431 +      return false;
   1.432 +    r->resize(data_size);
   1.433 +    if (data_size)
   1.434 +      memcpy(&r->front(), data, data_size);
   1.435 +    return true;
   1.436 +  }
   1.437 +  static void Log(const param_type& p, std::wstring* l) {
   1.438 +    for (size_t i = 0; i < p.size(); ++i)
   1.439 +      l->push_back(p[i]);
   1.440 +  }
   1.441 +};
   1.442 +
   1.443 +template <class P>
   1.444 +struct ParamTraitsStd<std::vector<P> > {
   1.445 +  typedef std::vector<P> param_type;
   1.446 +  static void Write(Message* m, const param_type& p) {
   1.447 +    WriteParam(m, static_cast<int>(p.size()));
   1.448 +    for (size_t i = 0; i < p.size(); i++)
   1.449 +      WriteParam(m, p[i]);
   1.450 +  }
   1.451 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.452 +    int size;
   1.453 +    if (!m->ReadLength(iter, &size))
   1.454 +      return false;
   1.455 +    // Resizing beforehand is not safe, see BUG 1006367 for details.
   1.456 +    if (m->IteratorHasRoomFor(*iter, size * sizeof(P))) {
   1.457 +      r->resize(size);
   1.458 +      for (int i = 0; i < size; i++) {
   1.459 +        if (!ReadParam(m, iter, &(*r)[i]))
   1.460 +          return false;
   1.461 +      }
   1.462 +    } else {
   1.463 +      for (int i = 0; i < size; i++) {
   1.464 +        P element;
   1.465 +        if (!ReadParam(m, iter, &element))
   1.466 +          return false;
   1.467 +        r->push_back(element);
   1.468 +      }
   1.469 +    }
   1.470 +    return true;
   1.471 +  }
   1.472 +  static void Log(const param_type& p, std::wstring* l) {
   1.473 +    for (size_t i = 0; i < p.size(); ++i) {
   1.474 +      if (i != 0)
   1.475 +        l->append(L" ");
   1.476 +
   1.477 +      LogParam((p[i]), l);
   1.478 +    }
   1.479 +  }
   1.480 +};
   1.481 +
   1.482 +template <class K, class V>
   1.483 +struct ParamTraitsStd<std::map<K, V> > {
   1.484 +  typedef std::map<K, V> param_type;
   1.485 +  static void Write(Message* m, const param_type& p) {
   1.486 +    WriteParam(m, static_cast<int>(p.size()));
   1.487 +    typename param_type::const_iterator iter;
   1.488 +    for (iter = p.begin(); iter != p.end(); ++iter) {
   1.489 +      WriteParam(m, iter->first);
   1.490 +      WriteParam(m, iter->second);
   1.491 +    }
   1.492 +  }
   1.493 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.494 +    int size;
   1.495 +    if (!ReadParam(m, iter, &size) || size < 0)
   1.496 +      return false;
   1.497 +    for (int i = 0; i < size; ++i) {
   1.498 +      K k;
   1.499 +      if (!ReadParam(m, iter, &k))
   1.500 +        return false;
   1.501 +      V& value = (*r)[k];
   1.502 +      if (!ReadParam(m, iter, &value))
   1.503 +        return false;
   1.504 +    }
   1.505 +    return true;
   1.506 +  }
   1.507 +  static void Log(const param_type& p, std::wstring* l) {
   1.508 +    l->append(L"<std::map>");
   1.509 +  }
   1.510 +};
   1.511 +
   1.512 +// Windows-specific types.
   1.513 +
   1.514 +template <class P>
   1.515 +struct ParamTraitsWindows : ParamTraitsStd<P> {};
   1.516 +
   1.517 +#if defined(OS_WIN)
   1.518 +template <>
   1.519 +struct ParamTraitsWindows<LOGFONT> {
   1.520 +  typedef LOGFONT param_type;
   1.521 +  static void Write(Message* m, const param_type& p) {
   1.522 +    m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
   1.523 +  }
   1.524 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.525 +    const char *data;
   1.526 +    int data_size = 0;
   1.527 +    bool result = m->ReadData(iter, &data, &data_size);
   1.528 +    if (result && data_size == sizeof(LOGFONT)) {
   1.529 +      memcpy(r, data, sizeof(LOGFONT));
   1.530 +    } else {
   1.531 +      result = false;
   1.532 +      NOTREACHED();
   1.533 +    }
   1.534 +
   1.535 +    return result;
   1.536 +  }
   1.537 +  static void Log(const param_type& p, std::wstring* l) {
   1.538 +    l->append(StringPrintf(L"<LOGFONT>"));
   1.539 +  }
   1.540 +};
   1.541 +
   1.542 +template <>
   1.543 +struct ParamTraitsWindows<MSG> {
   1.544 +  typedef MSG param_type;
   1.545 +  static void Write(Message* m, const param_type& p) {
   1.546 +    m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
   1.547 +  }
   1.548 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.549 +    const char *data;
   1.550 +    int data_size = 0;
   1.551 +    bool result = m->ReadData(iter, &data, &data_size);
   1.552 +    if (result && data_size == sizeof(MSG)) {
   1.553 +      memcpy(r, data, sizeof(MSG));
   1.554 +    } else {
   1.555 +      result = false;
   1.556 +      NOTREACHED();
   1.557 +    }
   1.558 +
   1.559 +    return result;
   1.560 +  }
   1.561 +};
   1.562 +
   1.563 +template <>
   1.564 +struct ParamTraitsWindows<HANDLE> {
   1.565 +  typedef HANDLE param_type;
   1.566 +  static void Write(Message* m, const param_type& p) {
   1.567 +    m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
   1.568 +  }
   1.569 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.570 +    DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
   1.571 +    return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
   1.572 +  }
   1.573 +  static void Log(const param_type& p, std::wstring* l) {
   1.574 +    l->append(StringPrintf(L"0x%X", p));
   1.575 +  }
   1.576 +};
   1.577 +
   1.578 +template <>
   1.579 +struct ParamTraitsWindows<HCURSOR> {
   1.580 +  typedef HCURSOR param_type;
   1.581 +  static void Write(Message* m, const param_type& p) {
   1.582 +    m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
   1.583 +  }
   1.584 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.585 +    DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
   1.586 +    return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
   1.587 +  }
   1.588 +  static void Log(const param_type& p, std::wstring* l) {
   1.589 +    l->append(StringPrintf(L"0x%X", p));
   1.590 +  }
   1.591 +};
   1.592 +
   1.593 +template <>
   1.594 +struct ParamTraitsWindows<HWND> {
   1.595 +  typedef HWND param_type;
   1.596 +  static void Write(Message* m, const param_type& p) {
   1.597 +    m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
   1.598 +  }
   1.599 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.600 +    DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
   1.601 +    return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
   1.602 +  }
   1.603 +  static void Log(const param_type& p, std::wstring* l) {
   1.604 +    l->append(StringPrintf(L"0x%X", p));
   1.605 +  }
   1.606 +};
   1.607 +
   1.608 +template <>
   1.609 +struct ParamTraitsWindows<HACCEL> {
   1.610 +  typedef HACCEL param_type;
   1.611 +  static void Write(Message* m, const param_type& p) {
   1.612 +    m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
   1.613 +  }
   1.614 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.615 +    DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
   1.616 +    return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
   1.617 +  }
   1.618 +};
   1.619 +
   1.620 +template <>
   1.621 +struct ParamTraitsWindows<POINT> {
   1.622 +  typedef POINT param_type;
   1.623 +  static void Write(Message* m, const param_type& p) {
   1.624 +    m->WriteInt(p.x);
   1.625 +    m->WriteInt(p.y);
   1.626 +  }
   1.627 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.628 +    int x, y;
   1.629 +    if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
   1.630 +      return false;
   1.631 +    r->x = x;
   1.632 +    r->y = y;
   1.633 +    return true;
   1.634 +  }
   1.635 +  static void Log(const param_type& p, std::wstring* l) {
   1.636 +    l->append(StringPrintf(L"(%d, %d)", p.x, p.y));
   1.637 +  }
   1.638 +};
   1.639 +
   1.640 +template <>
   1.641 +struct ParamTraitsWindows<XFORM> {
   1.642 +  typedef XFORM param_type;
   1.643 +  static void Write(Message* m, const param_type& p) {
   1.644 +    m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
   1.645 +  }
   1.646 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.647 +    const char *data;
   1.648 +    int data_size = 0;
   1.649 +    bool result = m->ReadData(iter, &data, &data_size);
   1.650 +    if (result && data_size == sizeof(XFORM)) {
   1.651 +      memcpy(r, data, sizeof(XFORM));
   1.652 +    } else {
   1.653 +      result = false;
   1.654 +      NOTREACHED();
   1.655 +    }
   1.656 +
   1.657 +    return result;
   1.658 +  }
   1.659 +  static void Log(const param_type& p, std::wstring* l) {
   1.660 +    l->append(L"<XFORM>");
   1.661 +  }
   1.662 +};
   1.663 +#endif  // defined(OS_WIN)
   1.664 +
   1.665 +// Various ipc/chromium types.
   1.666 +
   1.667 +template <class P>
   1.668 +struct ParamTraitsIPC : ParamTraitsWindows<P> {};
   1.669 +
   1.670 +template <>
   1.671 +struct ParamTraitsIPC<base::Time> {
   1.672 +  typedef base::Time param_type;
   1.673 +  static inline void Write(Message* m, const param_type& p);
   1.674 +  static inline bool Read(const Message* m, void** iter, param_type* r);
   1.675 +  static inline void Log(const param_type& p, std::wstring* l);
   1.676 +};
   1.677 +
   1.678 +#if defined(OS_POSIX)
   1.679 +// FileDescriptors may be serialised over IPC channels on POSIX. On the
   1.680 +// receiving side, the FileDescriptor is a valid duplicate of the file
   1.681 +// descriptor which was transmitted: *it is not just a copy of the integer like
   1.682 +// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
   1.683 +// this case, the receiving end will see a value of -1. *Zero is a valid file
   1.684 +// descriptor*.
   1.685 +//
   1.686 +// The received file descriptor will have the |auto_close| flag set to true. The
   1.687 +// code which handles the message is responsible for taking ownership of it.
   1.688 +// File descriptors are OS resources and must be closed when no longer needed.
   1.689 +//
   1.690 +// When sending a file descriptor, the file descriptor must be valid at the time
   1.691 +// of transmission. Since transmission is not synchronous, one should consider
   1.692 +// dup()ing any file descriptors to be transmitted and setting the |auto_close|
   1.693 +// flag, which causes the file descriptor to be closed after writing.
   1.694 +template<>
   1.695 +struct ParamTraitsIPC<base::FileDescriptor> {
   1.696 +  typedef base::FileDescriptor param_type;
   1.697 +  static void Write(Message* m, const param_type& p) {
   1.698 +    const bool valid = p.fd >= 0;
   1.699 +    WriteParam(m, valid);
   1.700 +
   1.701 +    if (valid) {
   1.702 +      if (!m->WriteFileDescriptor(p)) {
   1.703 +        NOTREACHED() << "Too many file descriptors for one message!";
   1.704 +      }
   1.705 +    }
   1.706 +  }
   1.707 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.708 +    bool valid;
   1.709 +    if (!ReadParam(m, iter, &valid))
   1.710 +      return false;
   1.711 +
   1.712 +    if (!valid) {
   1.713 +      r->fd = -1;
   1.714 +      r->auto_close = false;
   1.715 +      return true;
   1.716 +    }
   1.717 +
   1.718 +    return m->ReadFileDescriptor(iter, r);
   1.719 +  }
   1.720 +  static void Log(const param_type& p, std::wstring* l) {
   1.721 +    if (p.auto_close) {
   1.722 +      l->append(StringPrintf(L"FD(%d auto-close)", p.fd));
   1.723 +    } else {
   1.724 +      l->append(StringPrintf(L"FD(%d)", p.fd));
   1.725 +    }
   1.726 +  }
   1.727 +};
   1.728 +#endif // defined(OS_POSIX)
   1.729 +
   1.730 +template <>
   1.731 +struct ParamTraitsIPC<FilePath> {
   1.732 +  typedef FilePath param_type;
   1.733 +  static void Write(Message* m, const param_type& p);
   1.734 +  static bool Read(const Message* m, void** iter, param_type* r);
   1.735 +  static void Log(const param_type& p, std::wstring* l);
   1.736 +};
   1.737 +
   1.738 +struct LogData {
   1.739 +  std::wstring channel;
   1.740 +  int32_t routing_id;
   1.741 +  uint16_t type;
   1.742 +  std::wstring flags;
   1.743 +  int64_t sent;  // Time that the message was sent (i.e. at Send()).
   1.744 +  int64_t receive;  // Time before it was dispatched (i.e. before calling
   1.745 +                  // OnMessageReceived).
   1.746 +  int64_t dispatch;  // Time after it was dispatched (i.e. after calling
   1.747 +                   // OnMessageReceived).
   1.748 +  std::wstring message_name;
   1.749 +  std::wstring params;
   1.750 +};
   1.751 +
   1.752 +template <>
   1.753 +struct ParamTraitsIPC<LogData> {
   1.754 +  typedef LogData param_type;
   1.755 +  static void Write(Message* m, const param_type& p) {
   1.756 +    WriteParam(m, p.channel);
   1.757 +    WriteParam(m, p.routing_id);
   1.758 +    WriteParam(m, static_cast<int>(p.type));
   1.759 +    WriteParam(m, p.flags);
   1.760 +    WriteParam(m, p.sent);
   1.761 +    WriteParam(m, p.receive);
   1.762 +    WriteParam(m, p.dispatch);
   1.763 +    WriteParam(m, p.params);
   1.764 +  }
   1.765 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.766 +    int type = 0;
   1.767 +    bool result =
   1.768 +      ReadParam(m, iter, &r->channel) &&
   1.769 +      ReadParam(m, iter, &r->routing_id) &&
   1.770 +      ReadParam(m, iter, &type) &&
   1.771 +      ReadParam(m, iter, &r->flags) &&
   1.772 +      ReadParam(m, iter, &r->sent) &&
   1.773 +      ReadParam(m, iter, &r->receive) &&
   1.774 +      ReadParam(m, iter, &r->dispatch) &&
   1.775 +      ReadParam(m, iter, &r->params);
   1.776 +    r->type = static_cast<uint16_t>(type);
   1.777 +    return result;
   1.778 +  }
   1.779 +  static void Log(const param_type& p, std::wstring* l) {
   1.780 +    // Doesn't make sense to implement this!
   1.781 +  }
   1.782 +};
   1.783 +
   1.784 +#if defined(OS_WIN)
   1.785 +template<>
   1.786 +struct ParamTraitsIPC<TransportDIB::Id> {
   1.787 +  typedef TransportDIB::Id param_type;
   1.788 +  static void Write(Message* m, const param_type& p) {
   1.789 +    WriteParam(m, p.handle);
   1.790 +    WriteParam(m, p.sequence_num);
   1.791 +  }
   1.792 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.793 +    return (ReadParam(m, iter, &r->handle) &&
   1.794 +            ReadParam(m, iter, &r->sequence_num));
   1.795 +  }
   1.796 +  static void Log(const param_type& p, std::wstring* l) {
   1.797 +    l->append(L"TransportDIB(");
   1.798 +    LogParam(p.handle, l);
   1.799 +    l->append(L", ");
   1.800 +    LogParam(p.sequence_num, l);
   1.801 +    l->append(L")");
   1.802 +  }
   1.803 +};
   1.804 +#endif
   1.805 +
   1.806 +template <>
   1.807 +struct ParamTraitsIPC<Message> {
   1.808 +  static void Write(Message* m, const Message& p) {
   1.809 +    m->WriteInt(p.size());
   1.810 +    m->WriteData(reinterpret_cast<const char*>(p.data()), p.size());
   1.811 +  }
   1.812 +  static bool Read(const Message* m, void** iter, Message* r) {
   1.813 +    int size;
   1.814 +    if (!m->ReadInt(iter, &size))
   1.815 +      return false;
   1.816 +    const char* data;
   1.817 +    if (!m->ReadData(iter, &data, &size))
   1.818 +      return false;
   1.819 +    *r = Message(data, size);
   1.820 +    return true;
   1.821 +  }
   1.822 +  static void Log(const Message& p, std::wstring* l) {
   1.823 +    l->append(L"<IPC::Message>");
   1.824 +  }
   1.825 +};
   1.826 +
   1.827 +template <>
   1.828 +struct ParamTraitsIPC<Tuple0> {
   1.829 +  typedef Tuple0 param_type;
   1.830 +  static void Write(Message* m, const param_type& p) {
   1.831 +  }
   1.832 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.833 +    return true;
   1.834 +  }
   1.835 +  static void Log(const param_type& p, std::wstring* l) {
   1.836 +  }
   1.837 +};
   1.838 +
   1.839 +template <class A>
   1.840 +struct ParamTraitsIPC< Tuple1<A> > {
   1.841 +  typedef Tuple1<A> param_type;
   1.842 +  static void Write(Message* m, const param_type& p) {
   1.843 +    WriteParam(m, p.a);
   1.844 +  }
   1.845 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.846 +    return ReadParam(m, iter, &r->a);
   1.847 +  }
   1.848 +  static void Log(const param_type& p, std::wstring* l) {
   1.849 +    LogParam(p.a, l);
   1.850 +  }
   1.851 +};
   1.852 +
   1.853 +template <class A, class B>
   1.854 +struct ParamTraitsIPC< Tuple2<A, B> > {
   1.855 +  typedef Tuple2<A, B> param_type;
   1.856 +  static void Write(Message* m, const param_type& p) {
   1.857 +    WriteParam(m, p.a);
   1.858 +    WriteParam(m, p.b);
   1.859 +  }
   1.860 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.861 +    return (ReadParam(m, iter, &r->a) &&
   1.862 +            ReadParam(m, iter, &r->b));
   1.863 +  }
   1.864 +  static void Log(const param_type& p, std::wstring* l) {
   1.865 +    LogParam(p.a, l);
   1.866 +    l->append(L", ");
   1.867 +    LogParam(p.b, l);
   1.868 +  }
   1.869 +};
   1.870 +
   1.871 +template <class A, class B, class C>
   1.872 +struct ParamTraitsIPC< Tuple3<A, B, C> > {
   1.873 +  typedef Tuple3<A, B, C> param_type;
   1.874 +  static void Write(Message* m, const param_type& p) {
   1.875 +    WriteParam(m, p.a);
   1.876 +    WriteParam(m, p.b);
   1.877 +    WriteParam(m, p.c);
   1.878 +  }
   1.879 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.880 +    return (ReadParam(m, iter, &r->a) &&
   1.881 +            ReadParam(m, iter, &r->b) &&
   1.882 +            ReadParam(m, iter, &r->c));
   1.883 +  }
   1.884 +  static void Log(const param_type& p, std::wstring* l) {
   1.885 +    LogParam(p.a, l);
   1.886 +    l->append(L", ");
   1.887 +    LogParam(p.b, l);
   1.888 +    l->append(L", ");
   1.889 +    LogParam(p.c, l);
   1.890 +  }
   1.891 +};
   1.892 +
   1.893 +template <class A, class B, class C, class D>
   1.894 +struct ParamTraitsIPC< Tuple4<A, B, C, D> > {
   1.895 +  typedef Tuple4<A, B, C, D> param_type;
   1.896 +  static void Write(Message* m, const param_type& p) {
   1.897 +    WriteParam(m, p.a);
   1.898 +    WriteParam(m, p.b);
   1.899 +    WriteParam(m, p.c);
   1.900 +    WriteParam(m, p.d);
   1.901 +  }
   1.902 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.903 +    return (ReadParam(m, iter, &r->a) &&
   1.904 +            ReadParam(m, iter, &r->b) &&
   1.905 +            ReadParam(m, iter, &r->c) &&
   1.906 +            ReadParam(m, iter, &r->d));
   1.907 +  }
   1.908 +  static void Log(const param_type& p, std::wstring* l) {
   1.909 +    LogParam(p.a, l);
   1.910 +    l->append(L", ");
   1.911 +    LogParam(p.b, l);
   1.912 +    l->append(L", ");
   1.913 +    LogParam(p.c, l);
   1.914 +    l->append(L", ");
   1.915 +    LogParam(p.d, l);
   1.916 +  }
   1.917 +};
   1.918 +
   1.919 +template <class A, class B, class C, class D, class E>
   1.920 +struct ParamTraitsIPC< Tuple5<A, B, C, D, E> > {
   1.921 +  typedef Tuple5<A, B, C, D, E> param_type;
   1.922 +  static void Write(Message* m, const param_type& p) {
   1.923 +    WriteParam(m, p.a);
   1.924 +    WriteParam(m, p.b);
   1.925 +    WriteParam(m, p.c);
   1.926 +    WriteParam(m, p.d);
   1.927 +    WriteParam(m, p.e);
   1.928 +  }
   1.929 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.930 +    return (ReadParam(m, iter, &r->a) &&
   1.931 +            ReadParam(m, iter, &r->b) &&
   1.932 +            ReadParam(m, iter, &r->c) &&
   1.933 +            ReadParam(m, iter, &r->d) &&
   1.934 +            ReadParam(m, iter, &r->e));
   1.935 +  }
   1.936 +  static void Log(const param_type& p, std::wstring* l) {
   1.937 +    LogParam(p.a, l);
   1.938 +    l->append(L", ");
   1.939 +    LogParam(p.b, l);
   1.940 +    l->append(L", ");
   1.941 +    LogParam(p.c, l);
   1.942 +    l->append(L", ");
   1.943 +    LogParam(p.d, l);
   1.944 +    l->append(L", ");
   1.945 +    LogParam(p.e, l);
   1.946 +  }
   1.947 +};
   1.948 +
   1.949 +template <class A, class B, class C, class D, class E, class F>
   1.950 +struct ParamTraitsIPC< Tuple6<A, B, C, D, E, F> > {
   1.951 +  typedef Tuple6<A, B, C, D, E, F> param_type;
   1.952 +  static void Write(Message* m, const param_type& p) {
   1.953 +    WriteParam(m, p.a);
   1.954 +    WriteParam(m, p.b);
   1.955 +    WriteParam(m, p.c);
   1.956 +    WriteParam(m, p.d);
   1.957 +    WriteParam(m, p.e);
   1.958 +    WriteParam(m, p.f);
   1.959 +  }
   1.960 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.961 +    return (ReadParam(m, iter, &r->a) &&
   1.962 +            ReadParam(m, iter, &r->b) &&
   1.963 +            ReadParam(m, iter, &r->c) &&
   1.964 +            ReadParam(m, iter, &r->d) &&
   1.965 +            ReadParam(m, iter, &r->e) &&
   1.966 +            ReadParam(m, iter, &r->f));
   1.967 +  }
   1.968 +  static void Log(const param_type& p, std::wstring* l) {
   1.969 +    LogParam(p.a, l);
   1.970 +    l->append(L", ");
   1.971 +    LogParam(p.b, l);
   1.972 +    l->append(L", ");
   1.973 +    LogParam(p.c, l);
   1.974 +    l->append(L", ");
   1.975 +    LogParam(p.d, l);
   1.976 +    l->append(L", ");
   1.977 +    LogParam(p.e, l);
   1.978 +    l->append(L", ");
   1.979 +    LogParam(p.f, l);
   1.980 +  }
   1.981 +};
   1.982 +
   1.983 +// Mozilla-specific types.
   1.984 +
   1.985 +template <class P>
   1.986 +struct ParamTraitsMozilla : ParamTraitsIPC<P> {};
   1.987 +
   1.988 +template <>
   1.989 +struct ParamTraitsMozilla<nsresult> {
   1.990 +  typedef nsresult param_type;
   1.991 +  static void Write(Message* m, const param_type& p) {
   1.992 +    m->WriteUInt32(static_cast<uint32_t>(p));
   1.993 +  }
   1.994 +  static bool Read(const Message* m, void** iter, param_type* r) {
   1.995 +    return m->ReadUInt32(iter, reinterpret_cast<uint32_t*>(r));
   1.996 +  }
   1.997 +  static void Log(const param_type& p, std::wstring* l) {
   1.998 +    l->append(StringPrintf(L"%u", static_cast<uint32_t>(p)));
   1.999 +  }
  1.1000 +};
  1.1001 +
  1.1002 +// Finally, ParamTraits itself.
  1.1003 +
  1.1004 +template <class P> struct ParamTraits : ParamTraitsMozilla<P> {};
  1.1005 +
  1.1006 +// Now go back and define inlines dependent upon various ParamTraits<P>.
  1.1007 +inline void
  1.1008 +ParamTraitsIPC<base::Time>::Write(Message* m, const param_type& p) {
  1.1009 +  ParamTraits<int64_t>::Write(m, p.ToInternalValue());
  1.1010 +}
  1.1011 +inline bool
  1.1012 +ParamTraitsIPC<base::Time>::Read(const Message* m, void** iter, param_type* r) {
  1.1013 +  int64_t value;
  1.1014 +  if (!ParamTraits<int64_t>::Read(m, iter, &value))
  1.1015 +    return false;
  1.1016 +  *r = base::Time::FromInternalValue(value);
  1.1017 +  return true;
  1.1018 +}
  1.1019 +inline void
  1.1020 +ParamTraitsIPC<base::Time>::Log(const param_type& p, std::wstring* l) {
  1.1021 +  ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
  1.1022 +}
  1.1023 +
  1.1024 +inline void
  1.1025 +ParamTraitsIPC<FilePath>::Write(Message* m, const param_type& p) {
  1.1026 +  ParamTraits<FilePath::StringType>::Write(m, p.value());
  1.1027 +}
  1.1028 +inline bool
  1.1029 +ParamTraitsIPC<FilePath>::Read(const Message* m, void** iter, param_type* r) {
  1.1030 +  FilePath::StringType value;
  1.1031 +  if (!ParamTraits<FilePath::StringType>::Read(m, iter, &value))
  1.1032 +    return false;
  1.1033 +  *r = FilePath(value);
  1.1034 +  return true;
  1.1035 +}
  1.1036 +inline void
  1.1037 +ParamTraitsIPC<FilePath>::Log(const param_type& p, std::wstring* l) {
  1.1038 +  ParamTraits<FilePath::StringType>::Log(p.value(), l);
  1.1039 +}
  1.1040 +
  1.1041 +//-----------------------------------------------------------------------------
  1.1042 +// Generic message subclasses
  1.1043 +
  1.1044 +// Used for asynchronous messages.
  1.1045 +template <class ParamType>
  1.1046 +class MessageWithTuple : public Message {
  1.1047 + public:
  1.1048 +  typedef ParamType Param;
  1.1049 +
  1.1050 +  MessageWithTuple(int32_t routing_id, uint16_t type, const Param& p)
  1.1051 +      : Message(routing_id, type, PRIORITY_NORMAL) {
  1.1052 +    WriteParam(this, p);
  1.1053 +  }
  1.1054 +
  1.1055 +  static bool Read(const Message* msg, Param* p) {
  1.1056 +    void* iter = NULL;
  1.1057 +    bool rv = ReadParam(msg, &iter, p);
  1.1058 +    DCHECK(rv) << "Error deserializing message " << msg->type();
  1.1059 +    return rv;
  1.1060 +  }
  1.1061 +
  1.1062 +  // Generic dispatcher.  Should cover most cases.
  1.1063 +  template<class T, class Method>
  1.1064 +  static bool Dispatch(const Message* msg, T* obj, Method func) {
  1.1065 +    Param p;
  1.1066 +    if (Read(msg, &p)) {
  1.1067 +      DispatchToMethod(obj, func, p);
  1.1068 +      return true;
  1.1069 +    }
  1.1070 +    return false;
  1.1071 +  }
  1.1072 +
  1.1073 +  // The following dispatchers exist for the case where the callback function
  1.1074 +  // needs the message as well.  They assume that "Param" is a type of Tuple
  1.1075 +  // (except the one arg case, as there is no Tuple1).
  1.1076 +  template<class T, typename TA>
  1.1077 +  static bool Dispatch(const Message* msg, T* obj,
  1.1078 +                       void (T::*func)(const Message&, TA)) {
  1.1079 +    Param p;
  1.1080 +    if (Read(msg, &p)) {
  1.1081 +      (obj->*func)(*msg, p);
  1.1082 +      return true;
  1.1083 +    }
  1.1084 +    return false;
  1.1085 +  }
  1.1086 +
  1.1087 +  template<class T, typename TA, typename TB>
  1.1088 +  static bool Dispatch(const Message* msg, T* obj,
  1.1089 +                       void (T::*func)(const Message&, TA, TB)) {
  1.1090 +    Param p;
  1.1091 +    if (Read(msg, &p)) {
  1.1092 +      (obj->*func)(*msg, p.a, p.b);
  1.1093 +      return true;
  1.1094 +    }
  1.1095 +    return false;
  1.1096 +  }
  1.1097 +
  1.1098 +  template<class T, typename TA, typename TB, typename TC>
  1.1099 +  static bool Dispatch(const Message* msg, T* obj,
  1.1100 +                       void (T::*func)(const Message&, TA, TB, TC)) {
  1.1101 +    Param p;
  1.1102 +    if (Read(msg, &p)) {
  1.1103 +      (obj->*func)(*msg, p.a, p.b, p.c);
  1.1104 +      return true;
  1.1105 +    }
  1.1106 +    return false;
  1.1107 +  }
  1.1108 +
  1.1109 +  template<class T, typename TA, typename TB, typename TC, typename TD>
  1.1110 +  static bool Dispatch(const Message* msg, T* obj,
  1.1111 +                       void (T::*func)(const Message&, TA, TB, TC, TD)) {
  1.1112 +    Param p;
  1.1113 +    if (Read(msg, &p)) {
  1.1114 +      (obj->*func)(*msg, p.a, p.b, p.c, p.d);
  1.1115 +      return true;
  1.1116 +    }
  1.1117 +    return false;
  1.1118 +  }
  1.1119 +
  1.1120 +  template<class T, typename TA, typename TB, typename TC, typename TD,
  1.1121 +           typename TE>
  1.1122 +  static bool Dispatch(const Message* msg, T* obj,
  1.1123 +                       void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
  1.1124 +    Param p;
  1.1125 +    if (Read(msg, &p)) {
  1.1126 +      (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
  1.1127 +      return true;
  1.1128 +    }
  1.1129 +    return false;
  1.1130 +  }
  1.1131 +
  1.1132 +  static void Log(const Message* msg, std::wstring* l) {
  1.1133 +    Param p;
  1.1134 +    if (Read(msg, &p))
  1.1135 +      LogParam(p, l);
  1.1136 +  }
  1.1137 +
  1.1138 +  // Functions used to do manual unpacking.  Only used by the automation code,
  1.1139 +  // these should go away once that code uses SyncChannel.
  1.1140 +  template<typename TA, typename TB>
  1.1141 +  static bool Read(const IPC::Message* msg, TA* a, TB* b) {
  1.1142 +    ParamType params;
  1.1143 +    if (!Read(msg, &params))
  1.1144 +      return false;
  1.1145 +    *a = params.a;
  1.1146 +    *b = params.b;
  1.1147 +    return true;
  1.1148 +  }
  1.1149 +
  1.1150 +  template<typename TA, typename TB, typename TC>
  1.1151 +  static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
  1.1152 +    ParamType params;
  1.1153 +    if (!Read(msg, &params))
  1.1154 +      return false;
  1.1155 +    *a = params.a;
  1.1156 +    *b = params.b;
  1.1157 +    *c = params.c;
  1.1158 +    return true;
  1.1159 +  }
  1.1160 +
  1.1161 +  template<typename TA, typename TB, typename TC, typename TD>
  1.1162 +  static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) {
  1.1163 +    ParamType params;
  1.1164 +    if (!Read(msg, &params))
  1.1165 +      return false;
  1.1166 +    *a = params.a;
  1.1167 +    *b = params.b;
  1.1168 +    *c = params.c;
  1.1169 +    *d = params.d;
  1.1170 +    return true;
  1.1171 +  }
  1.1172 +
  1.1173 +  template<typename TA, typename TB, typename TC, typename TD, typename TE>
  1.1174 +  static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) {
  1.1175 +    ParamType params;
  1.1176 +    if (!Read(msg, &params))
  1.1177 +      return false;
  1.1178 +    *a = params.a;
  1.1179 +    *b = params.b;
  1.1180 +    *c = params.c;
  1.1181 +    *d = params.d;
  1.1182 +    *e = params.e;
  1.1183 +    return true;
  1.1184 +  }
  1.1185 +};
  1.1186 +
  1.1187 +// This class assumes that its template argument is a RefTuple (a Tuple with
  1.1188 +// reference elements).
  1.1189 +template <class RefTuple>
  1.1190 +class ParamDeserializer : public MessageReplyDeserializer {
  1.1191 + public:
  1.1192 +  explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
  1.1193 +
  1.1194 +  bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
  1.1195 +    return ReadParam(&msg, &iter, &out_);
  1.1196 +  }
  1.1197 +
  1.1198 +  RefTuple out_;
  1.1199 +};
  1.1200 +
  1.1201 +// defined in ipc_logging.cc
  1.1202 +void GenerateLogData(const std::wstring& channel, const Message& message,
  1.1203 +                     LogData* data);
  1.1204 +
  1.1205 +// Used for synchronous messages.
  1.1206 +template <class SendParamType, class ReplyParamType>
  1.1207 +class MessageWithReply : public SyncMessage {
  1.1208 + public:
  1.1209 +  typedef SendParamType SendParam;
  1.1210 +  typedef ReplyParamType ReplyParam;
  1.1211 +
  1.1212 +  MessageWithReply(int32_t routing_id, uint16_t type,
  1.1213 +                   const SendParam& send, const ReplyParam& reply)
  1.1214 +      : SyncMessage(routing_id, type, PRIORITY_NORMAL,
  1.1215 +                    new ParamDeserializer<ReplyParam>(reply)) {
  1.1216 +    WriteParam(this, send);
  1.1217 +  }
  1.1218 +
  1.1219 +  static void Log(const Message* msg, std::wstring* l) {
  1.1220 +    if (msg->is_sync()) {
  1.1221 +      SendParam p;
  1.1222 +      void* iter = SyncMessage::GetDataIterator(msg);
  1.1223 +      if (ReadParam(msg, &iter, &p))
  1.1224 +        LogParam(p, l);
  1.1225 +
  1.1226 +#if defined(IPC_MESSAGE_LOG_ENABLED)
  1.1227 +      const std::wstring& output_params = msg->output_params();
  1.1228 +      if (!l->empty() && !output_params.empty())
  1.1229 +        l->append(L", ");
  1.1230 +
  1.1231 +      l->append(output_params);
  1.1232 +#endif
  1.1233 +    } else {
  1.1234 +      // This is an outgoing reply.  Now that we have the output parameters, we
  1.1235 +      // can finally log the message.
  1.1236 +      typename ReplyParam::ValueTuple p;
  1.1237 +      void* iter = SyncMessage::GetDataIterator(msg);
  1.1238 +      if (ReadParam(msg, &iter, &p))
  1.1239 +        LogParam(p, l);
  1.1240 +    }
  1.1241 +  }
  1.1242 +
  1.1243 +  template<class T, class Method>
  1.1244 +  static bool Dispatch(const Message* msg, T* obj, Method func) {
  1.1245 +    SendParam send_params;
  1.1246 +    void* iter = GetDataIterator(msg);
  1.1247 +    Message* reply = GenerateReply(msg);
  1.1248 +    bool error;
  1.1249 +    if (ReadParam(msg, &iter, &send_params)) {
  1.1250 +      typename ReplyParam::ValueTuple reply_params;
  1.1251 +      DispatchToMethod(obj, func, send_params, &reply_params);
  1.1252 +      WriteParam(reply, reply_params);
  1.1253 +      error = false;
  1.1254 +#ifdef IPC_MESSAGE_LOG_ENABLED
  1.1255 +      if (msg->received_time() != 0) {
  1.1256 +        std::wstring output_params;
  1.1257 +        LogParam(reply_params, &output_params);
  1.1258 +        msg->set_output_params(output_params);
  1.1259 +      }
  1.1260 +#endif
  1.1261 +    } else {
  1.1262 +      NOTREACHED() << "Error deserializing message " << msg->type();
  1.1263 +      reply->set_reply_error();
  1.1264 +      error = true;
  1.1265 +    }
  1.1266 +
  1.1267 +    obj->Send(reply);
  1.1268 +    return !error;
  1.1269 +  }
  1.1270 +
  1.1271 +  template<class T, class Method>
  1.1272 +  static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
  1.1273 +    SendParam send_params;
  1.1274 +    void* iter = GetDataIterator(msg);
  1.1275 +    Message* reply = GenerateReply(msg);
  1.1276 +    bool error;
  1.1277 +    if (ReadParam(msg, &iter, &send_params)) {
  1.1278 +      Tuple1<Message&> t = MakeRefTuple(*reply);
  1.1279 +
  1.1280 +#ifdef IPC_MESSAGE_LOG_ENABLED
  1.1281 +      if (msg->sent_time()) {
  1.1282 +        // Don't log the sync message after dispatch, as we don't have the
  1.1283 +        // output parameters at that point.  Instead, save its data and log it
  1.1284 +        // with the outgoing reply message when it's sent.
  1.1285 +        LogData* data = new LogData;
  1.1286 +        GenerateLogData(L"", *msg, data);
  1.1287 +        msg->set_dont_log();
  1.1288 +        reply->set_sync_log_data(data);
  1.1289 +      }
  1.1290 +#endif
  1.1291 +      DispatchToMethod(obj, func, send_params, &t);
  1.1292 +      error = false;
  1.1293 +    } else {
  1.1294 +      NOTREACHED() << "Error deserializing message " << msg->type();
  1.1295 +      reply->set_reply_error();
  1.1296 +      obj->Send(reply);
  1.1297 +      error = true;
  1.1298 +    }
  1.1299 +    return !error;
  1.1300 +  }
  1.1301 +
  1.1302 +  template<typename TA>
  1.1303 +  static void WriteReplyParams(Message* reply, TA a) {
  1.1304 +    ReplyParam p(a);
  1.1305 +    WriteParam(reply, p);
  1.1306 +  }
  1.1307 +
  1.1308 +  template<typename TA, typename TB>
  1.1309 +  static void WriteReplyParams(Message* reply, TA a, TB b) {
  1.1310 +    ReplyParam p(a, b);
  1.1311 +    WriteParam(reply, p);
  1.1312 +  }
  1.1313 +
  1.1314 +  template<typename TA, typename TB, typename TC>
  1.1315 +  static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
  1.1316 +    ReplyParam p(a, b, c);
  1.1317 +    WriteParam(reply, p);
  1.1318 +  }
  1.1319 +
  1.1320 +  template<typename TA, typename TB, typename TC, typename TD>
  1.1321 +  static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
  1.1322 +    ReplyParam p(a, b, c, d);
  1.1323 +    WriteParam(reply, p);
  1.1324 +  }
  1.1325 +
  1.1326 +  template<typename TA, typename TB, typename TC, typename TD, typename TE>
  1.1327 +  static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
  1.1328 +    ReplyParam p(a, b, c, d, e);
  1.1329 +    WriteParam(reply, p);
  1.1330 +  }
  1.1331 +};
  1.1332 +
  1.1333 +//-----------------------------------------------------------------------------
  1.1334 +
  1.1335 +}  // namespace IPC
  1.1336 +
  1.1337 +#endif  // CHROME_COMMON_IPC_MESSAGE_UTILS_H_

mercurial