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, ¶ms)) 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, ¶ms)) 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, ¶ms)) 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, ¶ms)) 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_