blob: c55650713224184bcf13f10358b5e7e81800fdd9 [file] [log] [blame]
[email protected]225c8f52010-02-05 22:23:201// Copyright (c) 2010 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]946d1b22009-07-22 23:57:215#ifndef IPC_IPC_MESSAGE_UTILS_H_
6#define IPC_IPC_MESSAGE_UTILS_H_
[email protected]32b76ef2010-07-26 23:08:247#pragma once
initial.commit09911bf2008-07-26 23:55:298
[email protected]379e7a52010-03-09 00:38:419#include <algorithm>
initial.commit09911bf2008-07-26 23:55:2910#include <string>
11#include <vector>
12#include <map>
[email protected]96da6962010-05-13 19:10:3413#include <set>
initial.commit09911bf2008-07-26 23:55:2914
[email protected]dce5df52009-06-29 17:58:2515#include "base/format_macros.h"
[email protected]eb47a132009-03-04 00:39:5616#include "base/string16.h"
[email protected]dce5df52009-06-29 17:58:2517#include "base/string_util.h"
initial.commit09911bf2008-07-26 23:55:2918#include "base/tuple.h"
[email protected]939856a2010-08-24 20:29:0219#include "ipc/ipc_param_traits.h"
[email protected]0cfe5dae2010-08-17 00:24:5420#include "ipc/ipc_sync_message.h"
[email protected]55b4e212010-08-13 20:43:5821
[email protected]7a4de7a62010-08-17 18:38:2422#if defined(COMPILER_GCC)
23// GCC "helpfully" tries to inline template methods in release mode. Except we
24// want the majority of the template junk being expanded once in the
25// implementation file (and only provide the definitions in
26// ipc_message_utils_impl.h in those files) and exported, instead of expanded
27// at every call site. Special note: GCC happily accepts the attribute before
28// the method declaration, but only acts on it if it is after.
[email protected]efafbbd2010-08-19 20:23:2529#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 40500
30// Starting in gcc 4.5, the noinline no longer implies the concept covered by
31// the introduced noclone attribute, which will create specialized versions of
32// functions/methods when certain types are constant.
33// www.gnu.org/software/gcc/gcc-4.5/changes.html
34#define IPC_MSG_NOINLINE __attribute__((noinline, noclone));
35#else
[email protected]7a4de7a62010-08-17 18:38:2436#define IPC_MSG_NOINLINE __attribute__((noinline));
[email protected]efafbbd2010-08-19 20:23:2537#endif
[email protected]7a4de7a62010-08-17 18:38:2438#elif defined(COMPILER_MSVC)
39// MSVC++ doesn't do this.
40#define IPC_MSG_NOINLINE
41#else
42#error "Please add the noinline property for your new compiler here."
43#endif
44
[email protected]f91cb992009-02-04 20:10:1245// Used by IPC_BEGIN_MESSAGES so that each message class starts from a unique
46// base. Messages have unique IDs across channels in order for the IPC logging
47// code to figure out the message class from its ID.
48enum IPCMessageStart {
[email protected]f91cb992009-02-04 20:10:1249 AutomationMsgStart = 0,
50 ViewMsgStart,
[email protected]f91cb992009-02-04 20:10:1251 PluginMsgStart,
[email protected]21fa3a12010-12-08 23:34:1652 ProfileImportMsgStart,
[email protected]f91cb992009-02-04 20:10:1253 TestMsgStart,
[email protected]21fa3a12010-12-08 23:34:1654 DevToolsMsgStart,
[email protected]eb47a132009-03-04 00:39:5655 WorkerMsgStart,
[email protected]21fa3a12010-12-08 23:34:1656 NaClMsgStart,
[email protected]60f14392009-12-15 20:46:3257 UtilityMsgStart,
[email protected]c0fc0942010-01-13 00:55:3758 GpuMsgStart,
[email protected]38fe1962010-07-31 07:57:0059 ServiceMsgStart,
[email protected]709a847e2010-11-10 01:16:1160 PpapiMsgStart,
[email protected]21fa3a12010-12-08 23:34:1661 FirefoxImporterUnittestMsgStart,
[email protected]9f547bf2010-12-13 17:00:4262 FileUtilitiesMsgStart,
63 MimeRegistryMsgStart,
[email protected]26a9acf2010-12-13 19:35:0564 DatabaseMsgStart,
[email protected]f91cb992009-02-04 20:10:1265};
66
[email protected]7a4de7a62010-08-17 18:38:2467class DictionaryValue;
68class FilePath;
69class ListValue;
70class NullableString16;
71
72namespace base {
73class Time;
[email protected]d84e48b2010-10-21 22:04:5274class TimeDelta;
[email protected]7a4de7a62010-08-17 18:38:2475struct FileDescriptor;
76}
77
initial.commit09911bf2008-07-26 23:55:2978namespace IPC {
79
[email protected]7a4de7a62010-08-17 18:38:2480struct ChannelHandle;
81
initial.commit09911bf2008-07-26 23:55:2982//-----------------------------------------------------------------------------
83// An iterator class for reading the fields contained within a Message.
84
85class MessageIterator {
86 public:
[email protected]e1981f432008-08-12 15:22:1387 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
initial.commit09911bf2008-07-26 23:55:2988 }
89 int NextInt() const {
[email protected]9422b7dc2009-12-30 20:09:0290 int val = -1;
initial.commit09911bf2008-07-26 23:55:2991 if (!msg_.ReadInt(&iter_, &val))
92 NOTREACHED();
93 return val;
94 }
initial.commit09911bf2008-07-26 23:55:2995 const std::string NextString() const {
96 std::string val;
97 if (!msg_.ReadString(&iter_, &val))
98 NOTREACHED();
99 return val;
100 }
101 const std::wstring NextWString() const {
102 std::wstring val;
103 if (!msg_.ReadWString(&iter_, &val))
104 NOTREACHED();
105 return val;
106 }
[email protected]225c8f52010-02-05 22:23:20107 void NextData(const char** data, int* length) const {
initial.commit09911bf2008-07-26 23:55:29108 if (!msg_.ReadData(&iter_, data, length)) {
109 NOTREACHED();
110 }
111 }
112 private:
113 const Message& msg_;
114 mutable void* iter_;
115};
116
117//-----------------------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19118// ParamTraits specializations, etc.
119
[email protected]7d5c3ac2009-02-04 08:58:19120template <class P>
121static inline void WriteParam(Message* m, const P& p) {
[email protected]7b291f92009-08-14 05:43:53122 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53123 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
[email protected]7d5c3ac2009-02-04 08:58:19124}
125
126template <class P>
[email protected]1e86aa62009-04-24 21:22:33127static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
128 P* p) {
[email protected]7b291f92009-08-14 05:43:53129 typedef typename SimilarTypeTraits<P>::Type Type;
130 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
[email protected]7d5c3ac2009-02-04 08:58:19131}
132
133template <class P>
[email protected]252cad62010-08-18 18:33:57134static inline void LogParam(const P& p, std::string* l) {
[email protected]7b291f92009-08-14 05:43:53135 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53136 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19137}
138
139template <>
140struct ParamTraits<bool> {
141 typedef bool param_type;
142 static void Write(Message* m, const param_type& p) {
143 m->WriteBool(p);
144 }
145 static bool Read(const Message* m, void** iter, param_type* r) {
146 return m->ReadBool(iter, r);
147 }
[email protected]252cad62010-08-18 18:33:57148 static void Log(const param_type& p, std::string* l) {
149 l->append(p ? "true" : "false");
[email protected]7d5c3ac2009-02-04 08:58:19150 }
151};
152
153template <>
154struct ParamTraits<int> {
155 typedef int param_type;
156 static void Write(Message* m, const param_type& p) {
157 m->WriteInt(p);
158 }
159 static bool Read(const Message* m, void** iter, param_type* r) {
160 return m->ReadInt(iter, r);
161 }
[email protected]252cad62010-08-18 18:33:57162 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19163};
164
165template <>
[email protected]63263f92009-07-28 19:35:08166struct ParamTraits<unsigned int> {
167 typedef unsigned int param_type;
168 static void Write(Message* m, const param_type& p) {
169 m->WriteInt(p);
170 }
171 static bool Read(const Message* m, void** iter, param_type* r) {
172 return m->ReadInt(iter, reinterpret_cast<int*>(r));
173 }
[email protected]252cad62010-08-18 18:33:57174 static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08175};
176
177template <>
[email protected]7d5c3ac2009-02-04 08:58:19178struct ParamTraits<long> {
179 typedef long param_type;
180 static void Write(Message* m, const param_type& p) {
181 m->WriteLong(p);
182 }
183 static bool Read(const Message* m, void** iter, param_type* r) {
184 return m->ReadLong(iter, r);
185 }
[email protected]252cad62010-08-18 18:33:57186 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19187};
188
[email protected]140c3032009-06-26 18:22:54189template <>
190struct ParamTraits<unsigned long> {
191 typedef unsigned long param_type;
192 static void Write(Message* m, const param_type& p) {
193 m->WriteLong(p);
194 }
195 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]63263f92009-07-28 19:35:08196 return m->ReadLong(iter, reinterpret_cast<long*>(r));
[email protected]140c3032009-06-26 18:22:54197 }
[email protected]252cad62010-08-18 18:33:57198 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19199};
200
201template <>
[email protected]63263f92009-07-28 19:35:08202struct ParamTraits<long long> {
203 typedef long long param_type;
[email protected]7d5c3ac2009-02-04 08:58:19204 static void Write(Message* m, const param_type& p) {
205 m->WriteInt64(static_cast<int64>(p));
206 }
207 static bool Read(const Message* m, void** iter, param_type* r) {
208 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
209 }
[email protected]252cad62010-08-18 18:33:57210 static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08211};
212
213template <>
214struct ParamTraits<unsigned long long> {
215 typedef unsigned long long param_type;
216 static void Write(Message* m, const param_type& p) {
217 m->WriteInt64(p);
218 }
219 static bool Read(const Message* m, void** iter, param_type* r) {
220 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
221 }
[email protected]252cad62010-08-18 18:33:57222 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19223};
224
[email protected]43a40202010-11-12 16:25:01225template <>
226struct ParamTraits<unsigned short> {
227 typedef unsigned short param_type;
228 static void Write(Message* m, const param_type& p);
229 static bool Read(const Message* m, void** iter, param_type* r);
230 static void Log(const param_type& p, std::string* l);
231};
232
[email protected]20199662010-06-17 03:29:26233// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
234// should be sure to check the sanity of these values after receiving them over
235// IPC.
236template <>
237struct ParamTraits<float> {
238 typedef float param_type;
239 static void Write(Message* m, const param_type& p) {
240 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
241 }
242 static bool Read(const Message* m, void** iter, param_type* r) {
243 const char *data;
244 int data_size;
245 if (!m->ReadData(iter, &data, &data_size) ||
246 data_size != sizeof(param_type)) {
247 NOTREACHED();
248 return false;
249 }
250 memcpy(r, data, sizeof(param_type));
251 return true;
252 }
[email protected]252cad62010-08-18 18:33:57253 static void Log(const param_type& p, std::string* l) {
254 l->append(StringPrintf("%e", p));
[email protected]20199662010-06-17 03:29:26255 }
256};
257
[email protected]7d5c3ac2009-02-04 08:58:19258template <>
259struct ParamTraits<double> {
260 typedef double param_type;
261 static void Write(Message* m, const param_type& p) {
262 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
263 }
264 static bool Read(const Message* m, void** iter, param_type* r) {
265 const char *data;
[email protected]20199662010-06-17 03:29:26266 int data_size;
267 if (!m->ReadData(iter, &data, &data_size) ||
268 data_size != sizeof(param_type)) {
[email protected]7d5c3ac2009-02-04 08:58:19269 NOTREACHED();
[email protected]20199662010-06-17 03:29:26270 return false;
[email protected]7d5c3ac2009-02-04 08:58:19271 }
[email protected]20199662010-06-17 03:29:26272 memcpy(r, data, sizeof(param_type));
273 return true;
[email protected]7d5c3ac2009-02-04 08:58:19274 }
[email protected]252cad62010-08-18 18:33:57275 static void Log(const param_type& p, std::string* l) {
276 l->append(StringPrintf("%e", p));
[email protected]7d5c3ac2009-02-04 08:58:19277 }
278};
279
280template <>
[email protected]7d5c3ac2009-02-04 08:58:19281struct ParamTraits<base::Time> {
282 typedef base::Time param_type;
[email protected]7a4de7a62010-08-17 18:38:24283 static void Write(Message* m, const param_type& p);
284 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57285 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19286};
287
[email protected]d84e48b2010-10-21 22:04:52288template <>
289struct ParamTraits<base::TimeDelta> {
290 typedef base::TimeDelta param_type;
291 static void Write(Message* m, const param_type& p);
292 static bool Read(const Message* m, void** iter, param_type* r);
293 static void Log(const param_type& p, std::string* l);
294};
295
[email protected]7d5c3ac2009-02-04 08:58:19296#if defined(OS_WIN)
297template <>
298struct ParamTraits<LOGFONT> {
299 typedef LOGFONT param_type;
300 static void Write(Message* m, const param_type& p) {
301 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
302 }
303 static bool Read(const Message* m, void** iter, param_type* r) {
304 const char *data;
305 int data_size = 0;
306 bool result = m->ReadData(iter, &data, &data_size);
307 if (result && data_size == sizeof(LOGFONT)) {
308 memcpy(r, data, sizeof(LOGFONT));
309 } else {
310 result = false;
311 NOTREACHED();
312 }
313
314 return result;
315 }
[email protected]252cad62010-08-18 18:33:57316 static void Log(const param_type& p, std::string* l) {
317 l->append(StringPrintf("<LOGFONT>"));
[email protected]7d5c3ac2009-02-04 08:58:19318 }
319};
320
321template <>
322struct ParamTraits<MSG> {
323 typedef MSG param_type;
324 static void Write(Message* m, const param_type& p) {
325 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
326 }
327 static bool Read(const Message* m, void** iter, param_type* r) {
328 const char *data;
329 int data_size = 0;
330 bool result = m->ReadData(iter, &data, &data_size);
331 if (result && data_size == sizeof(MSG)) {
332 memcpy(r, data, sizeof(MSG));
333 } else {
334 result = false;
335 NOTREACHED();
336 }
337
338 return result;
339 }
[email protected]252cad62010-08-18 18:33:57340 static void Log(const param_type& p, std::string* l) {
341 l->append("<MSG>");
[email protected]7a4de7a62010-08-17 18:38:24342 }
[email protected]7d5c3ac2009-02-04 08:58:19343};
344#endif // defined(OS_WIN)
345
346template <>
[email protected]584f2b22009-05-21 01:01:59347struct ParamTraits<DictionaryValue> {
348 typedef DictionaryValue param_type;
349 static void Write(Message* m, const param_type& p);
350 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57351 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59352};
353
354template <>
355struct ParamTraits<ListValue> {
356 typedef ListValue param_type;
357 static void Write(Message* m, const param_type& p);
358 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57359 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59360};
361
362template <>
[email protected]7d5c3ac2009-02-04 08:58:19363struct ParamTraits<std::string> {
364 typedef std::string param_type;
365 static void Write(Message* m, const param_type& p) {
366 m->WriteString(p);
367 }
368 static bool Read(const Message* m, void** iter, param_type* r) {
369 return m->ReadString(iter, r);
370 }
[email protected]252cad62010-08-18 18:33:57371 static void Log(const param_type& p, std::string* l) {
372 l->append(p);
[email protected]7d5c3ac2009-02-04 08:58:19373 }
374};
375
[email protected]3dd7a7a2009-07-27 21:09:07376template<typename CharType>
[email protected]252cad62010-08-18 18:33:57377static void LogBytes(const std::vector<CharType>& data, std::string* out) {
[email protected]3dd7a7a2009-07-27 21:09:07378#if defined(OS_WIN)
379 // Windows has a GUI for logging, which can handle arbitrary binary data.
380 for (size_t i = 0; i < data.size(); ++i)
381 out->push_back(data[i]);
382#else
383 // On POSIX, we log to stdout, which we assume can display ASCII.
384 static const size_t kMaxBytesToLog = 100;
385 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
386 if (isprint(data[i]))
387 out->push_back(data[i]);
388 else
[email protected]252cad62010-08-18 18:33:57389 out->append(StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
[email protected]3dd7a7a2009-07-27 21:09:07390 }
391 if (data.size() > kMaxBytesToLog) {
392 out->append(
[email protected]252cad62010-08-18 18:33:57393 StringPrintf(" and %u more bytes",
[email protected]3dd7a7a2009-07-27 21:09:07394 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
395 }
396#endif
397}
398
[email protected]7d5c3ac2009-02-04 08:58:19399template <>
400struct ParamTraits<std::vector<unsigned char> > {
401 typedef std::vector<unsigned char> param_type;
402 static void Write(Message* m, const param_type& p) {
403 if (p.size() == 0) {
404 m->WriteData(NULL, 0);
405 } else {
406 m->WriteData(reinterpret_cast<const char*>(&p.front()),
407 static_cast<int>(p.size()));
408 }
409 }
410 static bool Read(const Message* m, void** iter, param_type* r) {
411 const char *data;
412 int data_size = 0;
413 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
414 return false;
415 r->resize(data_size);
416 if (data_size)
417 memcpy(&r->front(), data, data_size);
418 return true;
419 }
[email protected]252cad62010-08-18 18:33:57420 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07421 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19422 }
423};
424
425template <>
426struct ParamTraits<std::vector<char> > {
427 typedef std::vector<char> param_type;
428 static void Write(Message* m, const param_type& p) {
429 if (p.size() == 0) {
430 m->WriteData(NULL, 0);
431 } else {
432 m->WriteData(&p.front(), static_cast<int>(p.size()));
433 }
434 }
435 static bool Read(const Message* m, void** iter, param_type* r) {
436 const char *data;
437 int data_size = 0;
438 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
439 return false;
440 r->resize(data_size);
441 if (data_size)
442 memcpy(&r->front(), data, data_size);
443 return true;
444 }
[email protected]252cad62010-08-18 18:33:57445 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07446 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19447 }
448};
449
450template <class P>
451struct ParamTraits<std::vector<P> > {
452 typedef std::vector<P> param_type;
453 static void Write(Message* m, const param_type& p) {
454 WriteParam(m, static_cast<int>(p.size()));
455 for (size_t i = 0; i < p.size(); i++)
456 WriteParam(m, p[i]);
457 }
458 static bool Read(const Message* m, void** iter, param_type* r) {
459 int size;
[email protected]86440f52009-12-31 05:17:23460 // ReadLength() checks for < 0 itself.
[email protected]7d5c3ac2009-02-04 08:58:19461 if (!m->ReadLength(iter, &size))
462 return false;
463 // Resizing beforehand is not safe, see BUG 1006367 for details.
[email protected]86440f52009-12-31 05:17:23464 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
465 return false;
466 r->resize(size);
467 for (int i = 0; i < size; i++) {
468 if (!ReadParam(m, iter, &(*r)[i]))
469 return false;
[email protected]7d5c3ac2009-02-04 08:58:19470 }
471 return true;
472 }
[email protected]252cad62010-08-18 18:33:57473 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19474 for (size_t i = 0; i < p.size(); ++i) {
475 if (i != 0)
[email protected]252cad62010-08-18 18:33:57476 l->append(" ");
[email protected]7d5c3ac2009-02-04 08:58:19477 LogParam((p[i]), l);
478 }
479 }
480};
481
[email protected]96da6962010-05-13 19:10:34482template <class P>
483struct ParamTraits<std::set<P> > {
484 typedef std::set<P> param_type;
485 static void Write(Message* m, const param_type& p) {
486 WriteParam(m, static_cast<int>(p.size()));
487 typename param_type::const_iterator iter;
488 for (iter = p.begin(); iter != p.end(); ++iter)
489 WriteParam(m, *iter);
490 }
491 static bool Read(const Message* m, void** iter, param_type* r) {
492 int size;
493 if (!m->ReadLength(iter, &size))
494 return false;
495 for (int i = 0; i < size; ++i) {
496 P item;
497 if (!ReadParam(m, iter, &item))
498 return false;
499 r->insert(item);
500 }
501 return true;
502 }
[email protected]252cad62010-08-18 18:33:57503 static void Log(const param_type& p, std::string* l) {
504 l->append("<std::set>");
[email protected]96da6962010-05-13 19:10:34505 }
506};
507
508
[email protected]7d5c3ac2009-02-04 08:58:19509template <class K, class V>
510struct ParamTraits<std::map<K, V> > {
511 typedef std::map<K, V> param_type;
512 static void Write(Message* m, const param_type& p) {
513 WriteParam(m, static_cast<int>(p.size()));
514 typename param_type::const_iterator iter;
515 for (iter = p.begin(); iter != p.end(); ++iter) {
516 WriteParam(m, iter->first);
517 WriteParam(m, iter->second);
518 }
519 }
520 static bool Read(const Message* m, void** iter, param_type* r) {
521 int size;
522 if (!ReadParam(m, iter, &size) || size < 0)
523 return false;
524 for (int i = 0; i < size; ++i) {
525 K k;
526 if (!ReadParam(m, iter, &k))
527 return false;
528 V& value = (*r)[k];
529 if (!ReadParam(m, iter, &value))
530 return false;
531 }
532 return true;
533 }
[email protected]252cad62010-08-18 18:33:57534 static void Log(const param_type& p, std::string* l) {
535 l->append("<std::map>");
[email protected]7d5c3ac2009-02-04 08:58:19536 }
537};
538
[email protected]eb47a132009-03-04 00:39:56539
[email protected]7d5c3ac2009-02-04 08:58:19540template <>
541struct ParamTraits<std::wstring> {
542 typedef std::wstring param_type;
543 static void Write(Message* m, const param_type& p) {
544 m->WriteWString(p);
545 }
546 static bool Read(const Message* m, void** iter, param_type* r) {
547 return m->ReadWString(iter, r);
548 }
[email protected]252cad62010-08-18 18:33:57549 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19550};
551
[email protected]a5da6d612009-08-04 02:00:56552template <class A, class B>
553struct ParamTraits<std::pair<A, B> > {
554 typedef std::pair<A, B> param_type;
555 static void Write(Message* m, const param_type& p) {
556 WriteParam(m, p.first);
557 WriteParam(m, p.second);
558 }
559 static bool Read(const Message* m, void** iter, param_type* r) {
560 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
561 }
[email protected]252cad62010-08-18 18:33:57562 static void Log(const param_type& p, std::string* l) {
563 l->append("(");
[email protected]a5da6d612009-08-04 02:00:56564 LogParam(p.first, l);
[email protected]252cad62010-08-18 18:33:57565 l->append(", ");
[email protected]a5da6d612009-08-04 02:00:56566 LogParam(p.second, l);
[email protected]252cad62010-08-18 18:33:57567 l->append(")");
[email protected]a5da6d612009-08-04 02:00:56568 }
569};
570
[email protected]15bf8712009-08-27 00:55:02571template <>
572struct ParamTraits<NullableString16> {
573 typedef NullableString16 param_type;
[email protected]7a4de7a62010-08-17 18:38:24574 static void Write(Message* m, const param_type& p);
575 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57576 static void Log(const param_type& p, std::string* l);
[email protected]15bf8712009-08-27 00:55:02577};
578
[email protected]eb47a132009-03-04 00:39:56579// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
580// need this trait.
581#if !defined(WCHAR_T_IS_UTF16)
[email protected]eb47a132009-03-04 00:39:56582template <>
583struct ParamTraits<string16> {
584 typedef string16 param_type;
585 static void Write(Message* m, const param_type& p) {
[email protected]3a2a5d22009-03-04 03:36:36586 m->WriteString16(p);
[email protected]eb47a132009-03-04 00:39:56587 }
588 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]3a2a5d22009-03-04 03:36:36589 return m->ReadString16(iter, r);
[email protected]eb47a132009-03-04 00:39:56590 }
[email protected]252cad62010-08-18 18:33:57591 static void Log(const param_type& p, std::string* l);
[email protected]eb47a132009-03-04 00:39:56592};
[email protected]eb47a132009-03-04 00:39:56593#endif
594
[email protected]7d5c3ac2009-02-04 08:58:19595// and, a few more useful types...
596#if defined(OS_WIN)
597template <>
598struct ParamTraits<HANDLE> {
599 typedef HANDLE param_type;
600 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35601 // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
602 // bit systems.
603 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19604 }
605 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35606 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
607 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19608 }
[email protected]252cad62010-08-18 18:33:57609 static void Log(const param_type& p, std::string* l) {
610 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19611 }
612};
613
614template <>
615struct ParamTraits<HCURSOR> {
616 typedef HCURSOR param_type;
617 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35618 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19619 }
620 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35621 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
622 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19623 }
[email protected]252cad62010-08-18 18:33:57624 static void Log(const param_type& p, std::string* l) {
625 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19626 }
627};
628
629template <>
[email protected]7d5c3ac2009-02-04 08:58:19630struct ParamTraits<HACCEL> {
631 typedef HACCEL param_type;
632 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35633 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19634 }
635 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35636 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
637 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19638 }
639};
640
641template <>
642struct ParamTraits<POINT> {
643 typedef POINT param_type;
644 static void Write(Message* m, const param_type& p) {
645 m->WriteInt(p.x);
646 m->WriteInt(p.y);
647 }
648 static bool Read(const Message* m, void** iter, param_type* r) {
649 int x, y;
650 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
651 return false;
652 r->x = x;
653 r->y = y;
654 return true;
655 }
[email protected]252cad62010-08-18 18:33:57656 static void Log(const param_type& p, std::string* l) {
657 l->append(StringPrintf("(%d, %d)", p.x, p.y));
[email protected]7d5c3ac2009-02-04 08:58:19658 }
659};
660#endif // defined(OS_WIN)
661
662template <>
663struct ParamTraits<FilePath> {
664 typedef FilePath param_type;
[email protected]7a4de7a62010-08-17 18:38:24665 static void Write(Message* m, const param_type& p);
666 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57667 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19668};
669
[email protected]526776c2009-02-07 00:39:26670#if defined(OS_POSIX)
[email protected]2749885f2009-03-05 21:40:11671// FileDescriptors may be serialised over IPC channels on POSIX. On the
672// receiving side, the FileDescriptor is a valid duplicate of the file
673// descriptor which was transmitted: *it is not just a copy of the integer like
674// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
675// this case, the receiving end will see a value of -1. *Zero is a valid file
676// descriptor*.
677//
678// The received file descriptor will have the |auto_close| flag set to true. The
679// code which handles the message is responsible for taking ownership of it.
680// File descriptors are OS resources and must be closed when no longer needed.
681//
682// When sending a file descriptor, the file descriptor must be valid at the time
683// of transmission. Since transmission is not synchronous, one should consider
684// dup()ing any file descriptors to be transmitted and setting the |auto_close|
685// flag, which causes the file descriptor to be closed after writing.
[email protected]526776c2009-02-07 00:39:26686template<>
[email protected]5fe733de2009-02-11 18:59:20687struct ParamTraits<base::FileDescriptor> {
688 typedef base::FileDescriptor param_type;
[email protected]7a4de7a62010-08-17 18:38:24689 static void Write(Message* m, const param_type& p);
690 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57691 static void Log(const param_type& p, std::string* l);
[email protected]526776c2009-02-07 00:39:26692};
[email protected]379e7a52010-03-09 00:38:41693#endif // defined(OS_POSIX)
[email protected]526776c2009-02-07 00:39:26694
[email protected]d2e884d2009-06-22 20:37:52695// A ChannelHandle is basically a platform-inspecific wrapper around the
696// fact that IPC endpoints are handled specially on POSIX. See above comments
697// on FileDescriptor for more background.
698template<>
699struct ParamTraits<IPC::ChannelHandle> {
700 typedef ChannelHandle param_type;
[email protected]7a4de7a62010-08-17 18:38:24701 static void Write(Message* m, const param_type& p);
702 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57703 static void Log(const param_type& p, std::string* l);
[email protected]d2e884d2009-06-22 20:37:52704};
705
[email protected]7d5c3ac2009-02-04 08:58:19706#if defined(OS_WIN)
707template <>
708struct ParamTraits<XFORM> {
709 typedef XFORM param_type;
710 static void Write(Message* m, const param_type& p) {
711 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
712 }
713 static bool Read(const Message* m, void** iter, param_type* r) {
714 const char *data;
715 int data_size = 0;
716 bool result = m->ReadData(iter, &data, &data_size);
717 if (result && data_size == sizeof(XFORM)) {
718 memcpy(r, data, sizeof(XFORM));
719 } else {
720 result = false;
721 NOTREACHED();
722 }
723
724 return result;
725 }
[email protected]252cad62010-08-18 18:33:57726 static void Log(const param_type& p, std::string* l) {
727 l->append("<XFORM>");
[email protected]7d5c3ac2009-02-04 08:58:19728 }
729};
730#endif // defined(OS_WIN)
731
[email protected]7d5c3ac2009-02-04 08:58:19732struct LogData {
[email protected]20f0487a2010-09-30 20:06:30733 LogData();
734 ~LogData();
735
[email protected]9a3a293b2009-06-04 22:28:16736 std::string channel;
[email protected]8bef70e2009-04-14 19:11:24737 int32 routing_id;
[email protected]168ae922009-12-04 18:08:45738 uint32 type; // "User-defined" message type, from ipc_message.h.
[email protected]252cad62010-08-18 18:33:57739 std::string flags;
[email protected]7d5c3ac2009-02-04 08:58:19740 int64 sent; // Time that the message was sent (i.e. at Send()).
741 int64 receive; // Time before it was dispatched (i.e. before calling
742 // OnMessageReceived).
743 int64 dispatch; // Time after it was dispatched (i.e. after calling
744 // OnMessageReceived).
[email protected]252cad62010-08-18 18:33:57745 std::string message_name;
746 std::string params;
[email protected]7d5c3ac2009-02-04 08:58:19747};
748
749template <>
750struct ParamTraits<LogData> {
751 typedef LogData param_type;
[email protected]20f0487a2010-09-30 20:06:30752 static void Write(Message* m, const param_type& p);
753 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57754 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19755 // Doesn't make sense to implement this!
756 }
757};
758
[email protected]eb47a132009-03-04 00:39:56759template <>
[email protected]503683f2009-02-26 09:13:01760struct ParamTraits<Message> {
761 static void Write(Message* m, const Message& p) {
762 m->WriteInt(p.size());
763 m->WriteData(reinterpret_cast<const char*>(p.data()), p.size());
764 }
765 static bool Read(const Message* m, void** iter, Message* r) {
766 int size;
767 if (!m->ReadInt(iter, &size))
768 return false;
769 const char* data;
770 if (!m->ReadData(iter, &data, &size))
771 return false;
772 *r = Message(data, size);
773 return true;
774 }
[email protected]252cad62010-08-18 18:33:57775 static void Log(const Message& p, std::string* l) {
776 l->append("<IPC::Message>");
[email protected]503683f2009-02-26 09:13:01777 }
778};
779
780template <>
[email protected]7d5c3ac2009-02-04 08:58:19781struct ParamTraits<Tuple0> {
782 typedef Tuple0 param_type;
783 static void Write(Message* m, const param_type& p) {
784 }
785 static bool Read(const Message* m, void** iter, param_type* r) {
786 return true;
787 }
[email protected]252cad62010-08-18 18:33:57788 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19789 }
790};
791
792template <class A>
793struct ParamTraits< Tuple1<A> > {
794 typedef Tuple1<A> param_type;
795 static void Write(Message* m, const param_type& p) {
796 WriteParam(m, p.a);
797 }
798 static bool Read(const Message* m, void** iter, param_type* r) {
799 return ReadParam(m, iter, &r->a);
800 }
[email protected]252cad62010-08-18 18:33:57801 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19802 LogParam(p.a, l);
803 }
804};
805
806template <class A, class B>
807struct ParamTraits< Tuple2<A, B> > {
808 typedef Tuple2<A, B> param_type;
809 static void Write(Message* m, const param_type& p) {
810 WriteParam(m, p.a);
811 WriteParam(m, p.b);
812 }
813 static bool Read(const Message* m, void** iter, param_type* r) {
814 return (ReadParam(m, iter, &r->a) &&
815 ReadParam(m, iter, &r->b));
816 }
[email protected]252cad62010-08-18 18:33:57817 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19818 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57819 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19820 LogParam(p.b, l);
821 }
822};
823
824template <class A, class B, class C>
825struct ParamTraits< Tuple3<A, B, C> > {
826 typedef Tuple3<A, B, C> param_type;
827 static void Write(Message* m, const param_type& p) {
828 WriteParam(m, p.a);
829 WriteParam(m, p.b);
830 WriteParam(m, p.c);
831 }
832 static bool Read(const Message* m, void** iter, param_type* r) {
833 return (ReadParam(m, iter, &r->a) &&
834 ReadParam(m, iter, &r->b) &&
835 ReadParam(m, iter, &r->c));
836 }
[email protected]252cad62010-08-18 18:33:57837 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19838 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57839 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19840 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57841 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19842 LogParam(p.c, l);
843 }
844};
845
846template <class A, class B, class C, class D>
847struct ParamTraits< Tuple4<A, B, C, D> > {
848 typedef Tuple4<A, B, C, D> param_type;
849 static void Write(Message* m, const param_type& p) {
850 WriteParam(m, p.a);
851 WriteParam(m, p.b);
852 WriteParam(m, p.c);
853 WriteParam(m, p.d);
854 }
855 static bool Read(const Message* m, void** iter, param_type* r) {
856 return (ReadParam(m, iter, &r->a) &&
857 ReadParam(m, iter, &r->b) &&
858 ReadParam(m, iter, &r->c) &&
859 ReadParam(m, iter, &r->d));
860 }
[email protected]252cad62010-08-18 18:33:57861 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19862 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57863 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19864 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57865 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19866 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57867 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19868 LogParam(p.d, l);
869 }
870};
871
872template <class A, class B, class C, class D, class E>
873struct ParamTraits< Tuple5<A, B, C, D, E> > {
874 typedef Tuple5<A, B, C, D, E> param_type;
875 static void Write(Message* m, const param_type& p) {
876 WriteParam(m, p.a);
877 WriteParam(m, p.b);
878 WriteParam(m, p.c);
879 WriteParam(m, p.d);
880 WriteParam(m, p.e);
881 }
882 static bool Read(const Message* m, void** iter, param_type* r) {
883 return (ReadParam(m, iter, &r->a) &&
884 ReadParam(m, iter, &r->b) &&
885 ReadParam(m, iter, &r->c) &&
886 ReadParam(m, iter, &r->d) &&
887 ReadParam(m, iter, &r->e));
888 }
[email protected]252cad62010-08-18 18:33:57889 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19890 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57891 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19892 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57893 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19894 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57895 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19896 LogParam(p.d, l);
[email protected]252cad62010-08-18 18:33:57897 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19898 LogParam(p.e, l);
899 }
900};
901
[email protected]7d5c3ac2009-02-04 08:58:19902//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:29903// Generic message subclasses
904
905// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:24906template <class ParamType>
initial.commit09911bf2008-07-26 23:55:29907class MessageWithTuple : public Message {
908 public:
[email protected]81a34412009-01-05 19:17:24909 typedef ParamType Param;
[email protected]7a4de7a62010-08-17 18:38:24910 typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
[email protected]81a34412009-01-05 19:17:24911
[email protected]7a4de7a62010-08-17 18:38:24912 // The constructor and the Read() method's templated implementations are in
913 // ipc_message_utils_impl.h. The subclass constructor and Log() methods call
914 // the templated versions of these and make sure there are instantiations in
915 // those translation units.
916 MessageWithTuple(int32 routing_id, uint32 type, const RefParam& p);
[email protected]071b4b92010-08-09 16:06:58917
[email protected]7a4de7a62010-08-17 18:38:24918 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:29919
920 // Generic dispatcher. Should cover most cases.
921 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:19922 static bool Dispatch(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:29923 Param p;
924 if (Read(msg, &p)) {
925 DispatchToMethod(obj, func, p);
926 return true;
927 }
928 return false;
929 }
930
931 // The following dispatchers exist for the case where the callback function
932 // needs the message as well. They assume that "Param" is a type of Tuple
933 // (except the one arg case, as there is no Tuple1).
934 template<class T, typename TA>
[email protected]7d5c3ac2009-02-04 08:58:19935 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:29936 void (T::*func)(const Message&, TA)) {
937 Param p;
938 if (Read(msg, &p)) {
[email protected]c2fe31542009-05-20 18:24:14939 (obj->*func)(*msg, p.a);
initial.commit09911bf2008-07-26 23:55:29940 return true;
941 }
942 return false;
943 }
944
945 template<class T, typename TA, typename TB>
[email protected]7d5c3ac2009-02-04 08:58:19946 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:29947 void (T::*func)(const Message&, TA, TB)) {
948 Param p;
949 if (Read(msg, &p)) {
950 (obj->*func)(*msg, p.a, p.b);
951 return true;
952 }
953 return false;
954 }
955
956 template<class T, typename TA, typename TB, typename TC>
[email protected]7d5c3ac2009-02-04 08:58:19957 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:29958 void (T::*func)(const Message&, TA, TB, TC)) {
959 Param p;
960 if (Read(msg, &p)) {
961 (obj->*func)(*msg, p.a, p.b, p.c);
962 return true;
963 }
964 return false;
965 }
966
967 template<class T, typename TA, typename TB, typename TC, typename TD>
[email protected]7d5c3ac2009-02-04 08:58:19968 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:29969 void (T::*func)(const Message&, TA, TB, TC, TD)) {
970 Param p;
971 if (Read(msg, &p)) {
972 (obj->*func)(*msg, p.a, p.b, p.c, p.d);
973 return true;
974 }
975 return false;
976 }
977
978 template<class T, typename TA, typename TB, typename TC, typename TD,
979 typename TE>
[email protected]7d5c3ac2009-02-04 08:58:19980 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:29981 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
982 Param p;
983 if (Read(msg, &p)) {
984 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
985 return true;
986 }
987 return false;
988 }
989
[email protected]deb57402009-02-06 01:35:30990 // Functions used to do manual unpacking. Only used by the automation code,
991 // these should go away once that code uses SyncChannel.
992 template<typename TA, typename TB>
993 static bool Read(const IPC::Message* msg, TA* a, TB* b) {
994 ParamType params;
995 if (!Read(msg, &params))
996 return false;
997 *a = params.a;
998 *b = params.b;
999 return true;
1000 }
1001
1002 template<typename TA, typename TB, typename TC>
1003 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
1004 ParamType params;
1005 if (!Read(msg, &params))
1006 return false;
1007 *a = params.a;
1008 *b = params.b;
1009 *c = params.c;
1010 return true;
1011 }
1012
1013 template<typename TA, typename TB, typename TC, typename TD>
1014 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) {
1015 ParamType params;
1016 if (!Read(msg, &params))
1017 return false;
1018 *a = params.a;
1019 *b = params.b;
1020 *c = params.c;
1021 *d = params.d;
1022 return true;
1023 }
1024
1025 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1026 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) {
1027 ParamType params;
1028 if (!Read(msg, &params))
1029 return false;
1030 *a = params.a;
1031 *b = params.b;
1032 *c = params.c;
1033 *d = params.d;
1034 *e = params.e;
1035 return true;
1036 }
initial.commit09911bf2008-07-26 23:55:291037};
1038
[email protected]7a4de7a62010-08-17 18:38:241039// defined in ipc_logging.cc
1040void GenerateLogData(const std::string& channel, const Message& message,
1041 LogData* data);
1042
1043
1044#if defined(IPC_MESSAGE_LOG_ENABLED)
[email protected]252cad62010-08-18 18:33:571045inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
1046 const std::string& output_params = msg->output_params();
[email protected]7a4de7a62010-08-17 18:38:241047 if (!l->empty() && !output_params.empty())
[email protected]252cad62010-08-18 18:33:571048 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:241049
1050 l->append(output_params);
1051}
1052
1053template <class ReplyParamType>
1054inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1055 const Message* msg) {
1056 if (msg->received_time() != 0) {
[email protected]252cad62010-08-18 18:33:571057 std::string output_params;
[email protected]7a4de7a62010-08-17 18:38:241058 LogParam(reply_params, &output_params);
1059 msg->set_output_params(output_params);
1060 }
1061}
1062
1063inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
1064 if (msg->sent_time()) {
1065 // Don't log the sync message after dispatch, as we don't have the
1066 // output parameters at that point. Instead, save its data and log it
1067 // with the outgoing reply message when it's sent.
1068 LogData* data = new LogData;
1069 GenerateLogData("", *msg, data);
1070 msg->set_dont_log();
1071 reply->set_sync_log_data(data);
1072 }
1073}
1074#else
[email protected]252cad62010-08-18 18:33:571075inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
[email protected]7a4de7a62010-08-17 18:38:241076
1077template <class ReplyParamType>
1078inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1079 const Message* msg) {}
1080
1081inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1082#endif
1083
initial.commit09911bf2008-07-26 23:55:291084// This class assumes that its template argument is a RefTuple (a Tuple with
[email protected]7a4de7a62010-08-17 18:38:241085// reference elements). This would go into ipc_message_utils_impl.h, but it is
1086// also used by chrome_frame.
initial.commit09911bf2008-07-26 23:55:291087template <class RefTuple>
1088class ParamDeserializer : public MessageReplyDeserializer {
1089 public:
[email protected]e1981f432008-08-12 15:22:131090 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:291091
1092 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1093 return ReadParam(&msg, &iter, &out_);
1094 }
1095
1096 RefTuple out_;
1097};
1098
initial.commit09911bf2008-07-26 23:55:291099// Used for synchronous messages.
[email protected]75e5a872009-04-02 23:56:111100template <class SendParamType, class ReplyParamType>
initial.commit09911bf2008-07-26 23:55:291101class MessageWithReply : public SyncMessage {
1102 public:
[email protected]75e5a872009-04-02 23:56:111103 typedef SendParamType SendParam;
[email protected]7a4de7a62010-08-17 18:38:241104 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
[email protected]75e5a872009-04-02 23:56:111105 typedef ReplyParamType ReplyParam;
1106
[email protected]168ae922009-12-04 18:08:451107 MessageWithReply(int32 routing_id, uint32 type,
[email protected]7a4de7a62010-08-17 18:38:241108 const RefSendParam& send, const ReplyParam& reply);
1109 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
1110 static bool ReadReplyParam(
1111 const Message* msg,
1112 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:291113
1114 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191115 static bool Dispatch(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291116 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291117 Message* reply = GenerateReply(msg);
1118 bool error;
[email protected]7a4de7a62010-08-17 18:38:241119 if (ReadSendParam(msg, &send_params)) {
1120 typename TupleTypes<ReplyParam>::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:291121 DispatchToMethod(obj, func, send_params, &reply_params);
1122 WriteParam(reply, reply_params);
1123 error = false;
[email protected]7a4de7a62010-08-17 18:38:241124 LogReplyParamsToMessage(reply_params, msg);
initial.commit09911bf2008-07-26 23:55:291125 } else {
1126 NOTREACHED() << "Error deserializing message " << msg->type();
1127 reply->set_reply_error();
1128 error = true;
1129 }
1130
1131 obj->Send(reply);
1132 return !error;
1133 }
1134
1135 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191136 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291137 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291138 Message* reply = GenerateReply(msg);
1139 bool error;
[email protected]7a4de7a62010-08-17 18:38:241140 if (ReadSendParam(msg, &send_params)) {
initial.commit09911bf2008-07-26 23:55:291141 Tuple1<Message&> t = MakeRefTuple(*reply);
[email protected]7a4de7a62010-08-17 18:38:241142 ConnectMessageAndReply(msg, reply);
initial.commit09911bf2008-07-26 23:55:291143 DispatchToMethod(obj, func, send_params, &t);
1144 error = false;
1145 } else {
1146 NOTREACHED() << "Error deserializing message " << msg->type();
1147 reply->set_reply_error();
1148 obj->Send(reply);
1149 error = true;
1150 }
1151 return !error;
1152 }
1153
1154 template<typename TA>
1155 static void WriteReplyParams(Message* reply, TA a) {
1156 ReplyParam p(a);
1157 WriteParam(reply, p);
1158 }
1159
1160 template<typename TA, typename TB>
1161 static void WriteReplyParams(Message* reply, TA a, TB b) {
1162 ReplyParam p(a, b);
1163 WriteParam(reply, p);
1164 }
1165
1166 template<typename TA, typename TB, typename TC>
1167 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1168 ReplyParam p(a, b, c);
1169 WriteParam(reply, p);
1170 }
1171
1172 template<typename TA, typename TB, typename TC, typename TD>
1173 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1174 ReplyParam p(a, b, c, d);
1175 WriteParam(reply, p);
1176 }
1177
1178 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1179 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1180 ReplyParam p(a, b, c, d, e);
1181 WriteParam(reply, p);
1182 }
1183};
1184
[email protected]7d5c3ac2009-02-04 08:58:191185//-----------------------------------------------------------------------------
1186
[email protected]3178f4e22008-08-05 21:20:411187} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291188
[email protected]946d1b22009-07-22 23:57:211189#endif // IPC_IPC_MESSAGE_UTILS_H_