blob: eef5a76651014613cd4d0f228789fab3a1abbce9 [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]56879f932010-12-13 21:05:3765 DOMStorageMsgStart,
[email protected]2ba871b2010-12-13 21:11:0066 IndexedDBMsgStart,
[email protected]61e78f12010-12-15 21:03:5567 PepperFileMsgStart,
[email protected]f91cb992009-02-04 20:10:1268};
69
[email protected]7a4de7a62010-08-17 18:38:2470class DictionaryValue;
71class FilePath;
72class ListValue;
73class NullableString16;
74
75namespace base {
76class Time;
[email protected]d84e48b2010-10-21 22:04:5277class TimeDelta;
[email protected]7a4de7a62010-08-17 18:38:2478struct FileDescriptor;
79}
80
initial.commit09911bf2008-07-26 23:55:2981namespace IPC {
82
[email protected]7a4de7a62010-08-17 18:38:2483struct ChannelHandle;
84
initial.commit09911bf2008-07-26 23:55:2985//-----------------------------------------------------------------------------
86// An iterator class for reading the fields contained within a Message.
87
88class MessageIterator {
89 public:
[email protected]e1981f432008-08-12 15:22:1390 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
initial.commit09911bf2008-07-26 23:55:2991 }
92 int NextInt() const {
[email protected]9422b7dc2009-12-30 20:09:0293 int val = -1;
initial.commit09911bf2008-07-26 23:55:2994 if (!msg_.ReadInt(&iter_, &val))
95 NOTREACHED();
96 return val;
97 }
initial.commit09911bf2008-07-26 23:55:2998 const std::string NextString() const {
99 std::string val;
100 if (!msg_.ReadString(&iter_, &val))
101 NOTREACHED();
102 return val;
103 }
104 const std::wstring NextWString() const {
105 std::wstring val;
106 if (!msg_.ReadWString(&iter_, &val))
107 NOTREACHED();
108 return val;
109 }
[email protected]225c8f52010-02-05 22:23:20110 void NextData(const char** data, int* length) const {
initial.commit09911bf2008-07-26 23:55:29111 if (!msg_.ReadData(&iter_, data, length)) {
112 NOTREACHED();
113 }
114 }
115 private:
116 const Message& msg_;
117 mutable void* iter_;
118};
119
120//-----------------------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19121// ParamTraits specializations, etc.
122
[email protected]7d5c3ac2009-02-04 08:58:19123template <class P>
124static inline void WriteParam(Message* m, const P& p) {
[email protected]7b291f92009-08-14 05:43:53125 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53126 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
[email protected]7d5c3ac2009-02-04 08:58:19127}
128
129template <class P>
[email protected]1e86aa62009-04-24 21:22:33130static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
131 P* p) {
[email protected]7b291f92009-08-14 05:43:53132 typedef typename SimilarTypeTraits<P>::Type Type;
133 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
[email protected]7d5c3ac2009-02-04 08:58:19134}
135
136template <class P>
[email protected]252cad62010-08-18 18:33:57137static inline void LogParam(const P& p, std::string* l) {
[email protected]7b291f92009-08-14 05:43:53138 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53139 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19140}
141
142template <>
143struct ParamTraits<bool> {
144 typedef bool param_type;
145 static void Write(Message* m, const param_type& p) {
146 m->WriteBool(p);
147 }
148 static bool Read(const Message* m, void** iter, param_type* r) {
149 return m->ReadBool(iter, r);
150 }
[email protected]252cad62010-08-18 18:33:57151 static void Log(const param_type& p, std::string* l) {
152 l->append(p ? "true" : "false");
[email protected]7d5c3ac2009-02-04 08:58:19153 }
154};
155
156template <>
157struct ParamTraits<int> {
158 typedef int param_type;
159 static void Write(Message* m, const param_type& p) {
160 m->WriteInt(p);
161 }
162 static bool Read(const Message* m, void** iter, param_type* r) {
163 return m->ReadInt(iter, r);
164 }
[email protected]252cad62010-08-18 18:33:57165 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19166};
167
168template <>
[email protected]63263f92009-07-28 19:35:08169struct ParamTraits<unsigned int> {
170 typedef unsigned int param_type;
171 static void Write(Message* m, const param_type& p) {
172 m->WriteInt(p);
173 }
174 static bool Read(const Message* m, void** iter, param_type* r) {
175 return m->ReadInt(iter, reinterpret_cast<int*>(r));
176 }
[email protected]252cad62010-08-18 18:33:57177 static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08178};
179
180template <>
[email protected]7d5c3ac2009-02-04 08:58:19181struct ParamTraits<long> {
182 typedef long param_type;
183 static void Write(Message* m, const param_type& p) {
184 m->WriteLong(p);
185 }
186 static bool Read(const Message* m, void** iter, param_type* r) {
187 return m->ReadLong(iter, r);
188 }
[email protected]252cad62010-08-18 18:33:57189 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19190};
191
[email protected]140c3032009-06-26 18:22:54192template <>
193struct ParamTraits<unsigned long> {
194 typedef unsigned long param_type;
195 static void Write(Message* m, const param_type& p) {
196 m->WriteLong(p);
197 }
198 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]63263f92009-07-28 19:35:08199 return m->ReadLong(iter, reinterpret_cast<long*>(r));
[email protected]140c3032009-06-26 18:22:54200 }
[email protected]252cad62010-08-18 18:33:57201 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19202};
203
204template <>
[email protected]63263f92009-07-28 19:35:08205struct ParamTraits<long long> {
206 typedef long long param_type;
[email protected]7d5c3ac2009-02-04 08:58:19207 static void Write(Message* m, const param_type& p) {
208 m->WriteInt64(static_cast<int64>(p));
209 }
210 static bool Read(const Message* m, void** iter, param_type* r) {
211 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
212 }
[email protected]252cad62010-08-18 18:33:57213 static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08214};
215
216template <>
217struct ParamTraits<unsigned long long> {
218 typedef unsigned long long param_type;
219 static void Write(Message* m, const param_type& p) {
220 m->WriteInt64(p);
221 }
222 static bool Read(const Message* m, void** iter, param_type* r) {
223 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
224 }
[email protected]252cad62010-08-18 18:33:57225 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19226};
227
[email protected]43a40202010-11-12 16:25:01228template <>
229struct ParamTraits<unsigned short> {
230 typedef unsigned short param_type;
231 static void Write(Message* m, const param_type& p);
232 static bool Read(const Message* m, void** iter, param_type* r);
233 static void Log(const param_type& p, std::string* l);
234};
235
[email protected]20199662010-06-17 03:29:26236// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
237// should be sure to check the sanity of these values after receiving them over
238// IPC.
239template <>
240struct ParamTraits<float> {
241 typedef float param_type;
242 static void Write(Message* m, const param_type& p) {
243 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
244 }
245 static bool Read(const Message* m, void** iter, param_type* r) {
246 const char *data;
247 int data_size;
248 if (!m->ReadData(iter, &data, &data_size) ||
249 data_size != sizeof(param_type)) {
250 NOTREACHED();
251 return false;
252 }
253 memcpy(r, data, sizeof(param_type));
254 return true;
255 }
[email protected]252cad62010-08-18 18:33:57256 static void Log(const param_type& p, std::string* l) {
257 l->append(StringPrintf("%e", p));
[email protected]20199662010-06-17 03:29:26258 }
259};
260
[email protected]7d5c3ac2009-02-04 08:58:19261template <>
262struct ParamTraits<double> {
263 typedef double param_type;
264 static void Write(Message* m, const param_type& p) {
265 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
266 }
267 static bool Read(const Message* m, void** iter, param_type* r) {
268 const char *data;
[email protected]20199662010-06-17 03:29:26269 int data_size;
270 if (!m->ReadData(iter, &data, &data_size) ||
271 data_size != sizeof(param_type)) {
[email protected]7d5c3ac2009-02-04 08:58:19272 NOTREACHED();
[email protected]20199662010-06-17 03:29:26273 return false;
[email protected]7d5c3ac2009-02-04 08:58:19274 }
[email protected]20199662010-06-17 03:29:26275 memcpy(r, data, sizeof(param_type));
276 return true;
[email protected]7d5c3ac2009-02-04 08:58:19277 }
[email protected]252cad62010-08-18 18:33:57278 static void Log(const param_type& p, std::string* l) {
279 l->append(StringPrintf("%e", p));
[email protected]7d5c3ac2009-02-04 08:58:19280 }
281};
282
283template <>
[email protected]7d5c3ac2009-02-04 08:58:19284struct ParamTraits<base::Time> {
285 typedef base::Time param_type;
[email protected]7a4de7a62010-08-17 18:38:24286 static void Write(Message* m, const param_type& p);
287 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57288 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19289};
290
[email protected]d84e48b2010-10-21 22:04:52291template <>
292struct ParamTraits<base::TimeDelta> {
293 typedef base::TimeDelta param_type;
294 static void Write(Message* m, const param_type& p);
295 static bool Read(const Message* m, void** iter, param_type* r);
296 static void Log(const param_type& p, std::string* l);
297};
298
[email protected]7d5c3ac2009-02-04 08:58:19299#if defined(OS_WIN)
300template <>
301struct ParamTraits<LOGFONT> {
302 typedef LOGFONT param_type;
303 static void Write(Message* m, const param_type& p) {
304 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
305 }
306 static bool Read(const Message* m, void** iter, param_type* r) {
307 const char *data;
308 int data_size = 0;
309 bool result = m->ReadData(iter, &data, &data_size);
310 if (result && data_size == sizeof(LOGFONT)) {
311 memcpy(r, data, sizeof(LOGFONT));
312 } else {
313 result = false;
314 NOTREACHED();
315 }
316
317 return result;
318 }
[email protected]252cad62010-08-18 18:33:57319 static void Log(const param_type& p, std::string* l) {
320 l->append(StringPrintf("<LOGFONT>"));
[email protected]7d5c3ac2009-02-04 08:58:19321 }
322};
323
324template <>
325struct ParamTraits<MSG> {
326 typedef MSG param_type;
327 static void Write(Message* m, const param_type& p) {
328 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
329 }
330 static bool Read(const Message* m, void** iter, param_type* r) {
331 const char *data;
332 int data_size = 0;
333 bool result = m->ReadData(iter, &data, &data_size);
334 if (result && data_size == sizeof(MSG)) {
335 memcpy(r, data, sizeof(MSG));
336 } else {
337 result = false;
338 NOTREACHED();
339 }
340
341 return result;
342 }
[email protected]252cad62010-08-18 18:33:57343 static void Log(const param_type& p, std::string* l) {
344 l->append("<MSG>");
[email protected]7a4de7a62010-08-17 18:38:24345 }
[email protected]7d5c3ac2009-02-04 08:58:19346};
347#endif // defined(OS_WIN)
348
349template <>
[email protected]584f2b22009-05-21 01:01:59350struct ParamTraits<DictionaryValue> {
351 typedef DictionaryValue param_type;
352 static void Write(Message* m, const param_type& p);
353 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57354 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59355};
356
357template <>
358struct ParamTraits<ListValue> {
359 typedef ListValue param_type;
360 static void Write(Message* m, const param_type& p);
361 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57362 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59363};
364
365template <>
[email protected]7d5c3ac2009-02-04 08:58:19366struct ParamTraits<std::string> {
367 typedef std::string param_type;
368 static void Write(Message* m, const param_type& p) {
369 m->WriteString(p);
370 }
371 static bool Read(const Message* m, void** iter, param_type* r) {
372 return m->ReadString(iter, r);
373 }
[email protected]252cad62010-08-18 18:33:57374 static void Log(const param_type& p, std::string* l) {
375 l->append(p);
[email protected]7d5c3ac2009-02-04 08:58:19376 }
377};
378
[email protected]3dd7a7a2009-07-27 21:09:07379template<typename CharType>
[email protected]252cad62010-08-18 18:33:57380static void LogBytes(const std::vector<CharType>& data, std::string* out) {
[email protected]3dd7a7a2009-07-27 21:09:07381#if defined(OS_WIN)
382 // Windows has a GUI for logging, which can handle arbitrary binary data.
383 for (size_t i = 0; i < data.size(); ++i)
384 out->push_back(data[i]);
385#else
386 // On POSIX, we log to stdout, which we assume can display ASCII.
387 static const size_t kMaxBytesToLog = 100;
388 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
389 if (isprint(data[i]))
390 out->push_back(data[i]);
391 else
[email protected]252cad62010-08-18 18:33:57392 out->append(StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
[email protected]3dd7a7a2009-07-27 21:09:07393 }
394 if (data.size() > kMaxBytesToLog) {
395 out->append(
[email protected]252cad62010-08-18 18:33:57396 StringPrintf(" and %u more bytes",
[email protected]3dd7a7a2009-07-27 21:09:07397 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
398 }
399#endif
400}
401
[email protected]7d5c3ac2009-02-04 08:58:19402template <>
403struct ParamTraits<std::vector<unsigned char> > {
404 typedef std::vector<unsigned char> param_type;
405 static void Write(Message* m, const param_type& p) {
406 if (p.size() == 0) {
407 m->WriteData(NULL, 0);
408 } else {
409 m->WriteData(reinterpret_cast<const char*>(&p.front()),
410 static_cast<int>(p.size()));
411 }
412 }
413 static bool Read(const Message* m, void** iter, param_type* r) {
414 const char *data;
415 int data_size = 0;
416 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
417 return false;
418 r->resize(data_size);
419 if (data_size)
420 memcpy(&r->front(), data, data_size);
421 return true;
422 }
[email protected]252cad62010-08-18 18:33:57423 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07424 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19425 }
426};
427
428template <>
429struct ParamTraits<std::vector<char> > {
430 typedef std::vector<char> param_type;
431 static void Write(Message* m, const param_type& p) {
432 if (p.size() == 0) {
433 m->WriteData(NULL, 0);
434 } else {
435 m->WriteData(&p.front(), static_cast<int>(p.size()));
436 }
437 }
438 static bool Read(const Message* m, void** iter, param_type* r) {
439 const char *data;
440 int data_size = 0;
441 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
442 return false;
443 r->resize(data_size);
444 if (data_size)
445 memcpy(&r->front(), data, data_size);
446 return true;
447 }
[email protected]252cad62010-08-18 18:33:57448 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07449 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19450 }
451};
452
453template <class P>
454struct ParamTraits<std::vector<P> > {
455 typedef std::vector<P> param_type;
456 static void Write(Message* m, const param_type& p) {
457 WriteParam(m, static_cast<int>(p.size()));
458 for (size_t i = 0; i < p.size(); i++)
459 WriteParam(m, p[i]);
460 }
461 static bool Read(const Message* m, void** iter, param_type* r) {
462 int size;
[email protected]86440f52009-12-31 05:17:23463 // ReadLength() checks for < 0 itself.
[email protected]7d5c3ac2009-02-04 08:58:19464 if (!m->ReadLength(iter, &size))
465 return false;
466 // Resizing beforehand is not safe, see BUG 1006367 for details.
[email protected]86440f52009-12-31 05:17:23467 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
468 return false;
469 r->resize(size);
470 for (int i = 0; i < size; i++) {
471 if (!ReadParam(m, iter, &(*r)[i]))
472 return false;
[email protected]7d5c3ac2009-02-04 08:58:19473 }
474 return true;
475 }
[email protected]252cad62010-08-18 18:33:57476 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19477 for (size_t i = 0; i < p.size(); ++i) {
478 if (i != 0)
[email protected]252cad62010-08-18 18:33:57479 l->append(" ");
[email protected]7d5c3ac2009-02-04 08:58:19480 LogParam((p[i]), l);
481 }
482 }
483};
484
[email protected]96da6962010-05-13 19:10:34485template <class P>
486struct ParamTraits<std::set<P> > {
487 typedef std::set<P> param_type;
488 static void Write(Message* m, const param_type& p) {
489 WriteParam(m, static_cast<int>(p.size()));
490 typename param_type::const_iterator iter;
491 for (iter = p.begin(); iter != p.end(); ++iter)
492 WriteParam(m, *iter);
493 }
494 static bool Read(const Message* m, void** iter, param_type* r) {
495 int size;
496 if (!m->ReadLength(iter, &size))
497 return false;
498 for (int i = 0; i < size; ++i) {
499 P item;
500 if (!ReadParam(m, iter, &item))
501 return false;
502 r->insert(item);
503 }
504 return true;
505 }
[email protected]252cad62010-08-18 18:33:57506 static void Log(const param_type& p, std::string* l) {
507 l->append("<std::set>");
[email protected]96da6962010-05-13 19:10:34508 }
509};
510
511
[email protected]7d5c3ac2009-02-04 08:58:19512template <class K, class V>
513struct ParamTraits<std::map<K, V> > {
514 typedef std::map<K, V> param_type;
515 static void Write(Message* m, const param_type& p) {
516 WriteParam(m, static_cast<int>(p.size()));
517 typename param_type::const_iterator iter;
518 for (iter = p.begin(); iter != p.end(); ++iter) {
519 WriteParam(m, iter->first);
520 WriteParam(m, iter->second);
521 }
522 }
523 static bool Read(const Message* m, void** iter, param_type* r) {
524 int size;
525 if (!ReadParam(m, iter, &size) || size < 0)
526 return false;
527 for (int i = 0; i < size; ++i) {
528 K k;
529 if (!ReadParam(m, iter, &k))
530 return false;
531 V& value = (*r)[k];
532 if (!ReadParam(m, iter, &value))
533 return false;
534 }
535 return true;
536 }
[email protected]252cad62010-08-18 18:33:57537 static void Log(const param_type& p, std::string* l) {
538 l->append("<std::map>");
[email protected]7d5c3ac2009-02-04 08:58:19539 }
540};
541
[email protected]eb47a132009-03-04 00:39:56542
[email protected]7d5c3ac2009-02-04 08:58:19543template <>
544struct ParamTraits<std::wstring> {
545 typedef std::wstring param_type;
546 static void Write(Message* m, const param_type& p) {
547 m->WriteWString(p);
548 }
549 static bool Read(const Message* m, void** iter, param_type* r) {
550 return m->ReadWString(iter, r);
551 }
[email protected]252cad62010-08-18 18:33:57552 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19553};
554
[email protected]a5da6d612009-08-04 02:00:56555template <class A, class B>
556struct ParamTraits<std::pair<A, B> > {
557 typedef std::pair<A, B> param_type;
558 static void Write(Message* m, const param_type& p) {
559 WriteParam(m, p.first);
560 WriteParam(m, p.second);
561 }
562 static bool Read(const Message* m, void** iter, param_type* r) {
563 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
564 }
[email protected]252cad62010-08-18 18:33:57565 static void Log(const param_type& p, std::string* l) {
566 l->append("(");
[email protected]a5da6d612009-08-04 02:00:56567 LogParam(p.first, l);
[email protected]252cad62010-08-18 18:33:57568 l->append(", ");
[email protected]a5da6d612009-08-04 02:00:56569 LogParam(p.second, l);
[email protected]252cad62010-08-18 18:33:57570 l->append(")");
[email protected]a5da6d612009-08-04 02:00:56571 }
572};
573
[email protected]15bf8712009-08-27 00:55:02574template <>
575struct ParamTraits<NullableString16> {
576 typedef NullableString16 param_type;
[email protected]7a4de7a62010-08-17 18:38:24577 static void Write(Message* m, const param_type& p);
578 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57579 static void Log(const param_type& p, std::string* l);
[email protected]15bf8712009-08-27 00:55:02580};
581
[email protected]eb47a132009-03-04 00:39:56582// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
583// need this trait.
584#if !defined(WCHAR_T_IS_UTF16)
[email protected]eb47a132009-03-04 00:39:56585template <>
586struct ParamTraits<string16> {
587 typedef string16 param_type;
588 static void Write(Message* m, const param_type& p) {
[email protected]3a2a5d22009-03-04 03:36:36589 m->WriteString16(p);
[email protected]eb47a132009-03-04 00:39:56590 }
591 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]3a2a5d22009-03-04 03:36:36592 return m->ReadString16(iter, r);
[email protected]eb47a132009-03-04 00:39:56593 }
[email protected]252cad62010-08-18 18:33:57594 static void Log(const param_type& p, std::string* l);
[email protected]eb47a132009-03-04 00:39:56595};
[email protected]eb47a132009-03-04 00:39:56596#endif
597
[email protected]7d5c3ac2009-02-04 08:58:19598// and, a few more useful types...
599#if defined(OS_WIN)
600template <>
601struct ParamTraits<HANDLE> {
602 typedef HANDLE param_type;
603 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35604 // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
605 // bit systems.
606 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19607 }
608 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35609 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
610 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19611 }
[email protected]252cad62010-08-18 18:33:57612 static void Log(const param_type& p, std::string* l) {
613 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19614 }
615};
616
617template <>
618struct ParamTraits<HCURSOR> {
619 typedef HCURSOR param_type;
620 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35621 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19622 }
623 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35624 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
625 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19626 }
[email protected]252cad62010-08-18 18:33:57627 static void Log(const param_type& p, std::string* l) {
628 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19629 }
630};
631
632template <>
[email protected]7d5c3ac2009-02-04 08:58:19633struct ParamTraits<HACCEL> {
634 typedef HACCEL param_type;
635 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35636 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19637 }
638 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35639 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
640 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19641 }
642};
643
644template <>
645struct ParamTraits<POINT> {
646 typedef POINT param_type;
647 static void Write(Message* m, const param_type& p) {
648 m->WriteInt(p.x);
649 m->WriteInt(p.y);
650 }
651 static bool Read(const Message* m, void** iter, param_type* r) {
652 int x, y;
653 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
654 return false;
655 r->x = x;
656 r->y = y;
657 return true;
658 }
[email protected]252cad62010-08-18 18:33:57659 static void Log(const param_type& p, std::string* l) {
660 l->append(StringPrintf("(%d, %d)", p.x, p.y));
[email protected]7d5c3ac2009-02-04 08:58:19661 }
662};
663#endif // defined(OS_WIN)
664
665template <>
666struct ParamTraits<FilePath> {
667 typedef FilePath param_type;
[email protected]7a4de7a62010-08-17 18:38:24668 static void Write(Message* m, const param_type& p);
669 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57670 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19671};
672
[email protected]526776c2009-02-07 00:39:26673#if defined(OS_POSIX)
[email protected]2749885f2009-03-05 21:40:11674// FileDescriptors may be serialised over IPC channels on POSIX. On the
675// receiving side, the FileDescriptor is a valid duplicate of the file
676// descriptor which was transmitted: *it is not just a copy of the integer like
677// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
678// this case, the receiving end will see a value of -1. *Zero is a valid file
679// descriptor*.
680//
681// The received file descriptor will have the |auto_close| flag set to true. The
682// code which handles the message is responsible for taking ownership of it.
683// File descriptors are OS resources and must be closed when no longer needed.
684//
685// When sending a file descriptor, the file descriptor must be valid at the time
686// of transmission. Since transmission is not synchronous, one should consider
687// dup()ing any file descriptors to be transmitted and setting the |auto_close|
688// flag, which causes the file descriptor to be closed after writing.
[email protected]526776c2009-02-07 00:39:26689template<>
[email protected]5fe733de2009-02-11 18:59:20690struct ParamTraits<base::FileDescriptor> {
691 typedef base::FileDescriptor param_type;
[email protected]7a4de7a62010-08-17 18:38:24692 static void Write(Message* m, const param_type& p);
693 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57694 static void Log(const param_type& p, std::string* l);
[email protected]526776c2009-02-07 00:39:26695};
[email protected]379e7a52010-03-09 00:38:41696#endif // defined(OS_POSIX)
[email protected]526776c2009-02-07 00:39:26697
[email protected]d2e884d2009-06-22 20:37:52698// A ChannelHandle is basically a platform-inspecific wrapper around the
699// fact that IPC endpoints are handled specially on POSIX. See above comments
700// on FileDescriptor for more background.
701template<>
702struct ParamTraits<IPC::ChannelHandle> {
703 typedef ChannelHandle param_type;
[email protected]7a4de7a62010-08-17 18:38:24704 static void Write(Message* m, const param_type& p);
705 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57706 static void Log(const param_type& p, std::string* l);
[email protected]d2e884d2009-06-22 20:37:52707};
708
[email protected]7d5c3ac2009-02-04 08:58:19709#if defined(OS_WIN)
710template <>
711struct ParamTraits<XFORM> {
712 typedef XFORM param_type;
713 static void Write(Message* m, const param_type& p) {
714 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
715 }
716 static bool Read(const Message* m, void** iter, param_type* r) {
717 const char *data;
718 int data_size = 0;
719 bool result = m->ReadData(iter, &data, &data_size);
720 if (result && data_size == sizeof(XFORM)) {
721 memcpy(r, data, sizeof(XFORM));
722 } else {
723 result = false;
724 NOTREACHED();
725 }
726
727 return result;
728 }
[email protected]252cad62010-08-18 18:33:57729 static void Log(const param_type& p, std::string* l) {
730 l->append("<XFORM>");
[email protected]7d5c3ac2009-02-04 08:58:19731 }
732};
733#endif // defined(OS_WIN)
734
[email protected]7d5c3ac2009-02-04 08:58:19735struct LogData {
[email protected]20f0487a2010-09-30 20:06:30736 LogData();
737 ~LogData();
738
[email protected]9a3a293b2009-06-04 22:28:16739 std::string channel;
[email protected]8bef70e2009-04-14 19:11:24740 int32 routing_id;
[email protected]168ae922009-12-04 18:08:45741 uint32 type; // "User-defined" message type, from ipc_message.h.
[email protected]252cad62010-08-18 18:33:57742 std::string flags;
[email protected]7d5c3ac2009-02-04 08:58:19743 int64 sent; // Time that the message was sent (i.e. at Send()).
744 int64 receive; // Time before it was dispatched (i.e. before calling
745 // OnMessageReceived).
746 int64 dispatch; // Time after it was dispatched (i.e. after calling
747 // OnMessageReceived).
[email protected]252cad62010-08-18 18:33:57748 std::string message_name;
749 std::string params;
[email protected]7d5c3ac2009-02-04 08:58:19750};
751
752template <>
753struct ParamTraits<LogData> {
754 typedef LogData param_type;
[email protected]20f0487a2010-09-30 20:06:30755 static void Write(Message* m, const param_type& p);
756 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57757 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19758 // Doesn't make sense to implement this!
759 }
760};
761
[email protected]eb47a132009-03-04 00:39:56762template <>
[email protected]503683f2009-02-26 09:13:01763struct ParamTraits<Message> {
764 static void Write(Message* m, const Message& p) {
765 m->WriteInt(p.size());
766 m->WriteData(reinterpret_cast<const char*>(p.data()), p.size());
767 }
768 static bool Read(const Message* m, void** iter, Message* r) {
769 int size;
770 if (!m->ReadInt(iter, &size))
771 return false;
772 const char* data;
773 if (!m->ReadData(iter, &data, &size))
774 return false;
775 *r = Message(data, size);
776 return true;
777 }
[email protected]252cad62010-08-18 18:33:57778 static void Log(const Message& p, std::string* l) {
779 l->append("<IPC::Message>");
[email protected]503683f2009-02-26 09:13:01780 }
781};
782
783template <>
[email protected]7d5c3ac2009-02-04 08:58:19784struct ParamTraits<Tuple0> {
785 typedef Tuple0 param_type;
786 static void Write(Message* m, const param_type& p) {
787 }
788 static bool Read(const Message* m, void** iter, param_type* r) {
789 return true;
790 }
[email protected]252cad62010-08-18 18:33:57791 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19792 }
793};
794
795template <class A>
796struct ParamTraits< Tuple1<A> > {
797 typedef Tuple1<A> param_type;
798 static void Write(Message* m, const param_type& p) {
799 WriteParam(m, p.a);
800 }
801 static bool Read(const Message* m, void** iter, param_type* r) {
802 return ReadParam(m, iter, &r->a);
803 }
[email protected]252cad62010-08-18 18:33:57804 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19805 LogParam(p.a, l);
806 }
807};
808
809template <class A, class B>
810struct ParamTraits< Tuple2<A, B> > {
811 typedef Tuple2<A, B> param_type;
812 static void Write(Message* m, const param_type& p) {
813 WriteParam(m, p.a);
814 WriteParam(m, p.b);
815 }
816 static bool Read(const Message* m, void** iter, param_type* r) {
817 return (ReadParam(m, iter, &r->a) &&
818 ReadParam(m, iter, &r->b));
819 }
[email protected]252cad62010-08-18 18:33:57820 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19821 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57822 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19823 LogParam(p.b, l);
824 }
825};
826
827template <class A, class B, class C>
828struct ParamTraits< Tuple3<A, B, C> > {
829 typedef Tuple3<A, B, C> param_type;
830 static void Write(Message* m, const param_type& p) {
831 WriteParam(m, p.a);
832 WriteParam(m, p.b);
833 WriteParam(m, p.c);
834 }
835 static bool Read(const Message* m, void** iter, param_type* r) {
836 return (ReadParam(m, iter, &r->a) &&
837 ReadParam(m, iter, &r->b) &&
838 ReadParam(m, iter, &r->c));
839 }
[email protected]252cad62010-08-18 18:33:57840 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19841 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57842 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19843 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57844 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19845 LogParam(p.c, l);
846 }
847};
848
849template <class A, class B, class C, class D>
850struct ParamTraits< Tuple4<A, B, C, D> > {
851 typedef Tuple4<A, B, C, D> param_type;
852 static void Write(Message* m, const param_type& p) {
853 WriteParam(m, p.a);
854 WriteParam(m, p.b);
855 WriteParam(m, p.c);
856 WriteParam(m, p.d);
857 }
858 static bool Read(const Message* m, void** iter, param_type* r) {
859 return (ReadParam(m, iter, &r->a) &&
860 ReadParam(m, iter, &r->b) &&
861 ReadParam(m, iter, &r->c) &&
862 ReadParam(m, iter, &r->d));
863 }
[email protected]252cad62010-08-18 18:33:57864 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19865 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57866 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19867 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57868 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19869 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57870 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19871 LogParam(p.d, l);
872 }
873};
874
875template <class A, class B, class C, class D, class E>
876struct ParamTraits< Tuple5<A, B, C, D, E> > {
877 typedef Tuple5<A, B, C, D, E> param_type;
878 static void Write(Message* m, const param_type& p) {
879 WriteParam(m, p.a);
880 WriteParam(m, p.b);
881 WriteParam(m, p.c);
882 WriteParam(m, p.d);
883 WriteParam(m, p.e);
884 }
885 static bool Read(const Message* m, void** iter, param_type* r) {
886 return (ReadParam(m, iter, &r->a) &&
887 ReadParam(m, iter, &r->b) &&
888 ReadParam(m, iter, &r->c) &&
889 ReadParam(m, iter, &r->d) &&
890 ReadParam(m, iter, &r->e));
891 }
[email protected]252cad62010-08-18 18:33:57892 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19893 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57894 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19895 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57896 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19897 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57898 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19899 LogParam(p.d, l);
[email protected]252cad62010-08-18 18:33:57900 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19901 LogParam(p.e, l);
902 }
903};
904
[email protected]7d5c3ac2009-02-04 08:58:19905//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:29906// Generic message subclasses
907
908// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:24909template <class ParamType>
initial.commit09911bf2008-07-26 23:55:29910class MessageWithTuple : public Message {
911 public:
[email protected]81a34412009-01-05 19:17:24912 typedef ParamType Param;
[email protected]7a4de7a62010-08-17 18:38:24913 typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
[email protected]81a34412009-01-05 19:17:24914
[email protected]7a4de7a62010-08-17 18:38:24915 // The constructor and the Read() method's templated implementations are in
916 // ipc_message_utils_impl.h. The subclass constructor and Log() methods call
917 // the templated versions of these and make sure there are instantiations in
918 // those translation units.
919 MessageWithTuple(int32 routing_id, uint32 type, const RefParam& p);
[email protected]071b4b92010-08-09 16:06:58920
[email protected]7a4de7a62010-08-17 18:38:24921 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:29922
923 // Generic dispatcher. Should cover most cases.
924 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:19925 static bool Dispatch(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:29926 Param p;
927 if (Read(msg, &p)) {
928 DispatchToMethod(obj, func, p);
929 return true;
930 }
931 return false;
932 }
933
934 // The following dispatchers exist for the case where the callback function
935 // needs the message as well. They assume that "Param" is a type of Tuple
936 // (except the one arg case, as there is no Tuple1).
937 template<class T, typename TA>
[email protected]7d5c3ac2009-02-04 08:58:19938 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:29939 void (T::*func)(const Message&, TA)) {
940 Param p;
941 if (Read(msg, &p)) {
[email protected]c2fe31542009-05-20 18:24:14942 (obj->*func)(*msg, p.a);
initial.commit09911bf2008-07-26 23:55:29943 return true;
944 }
945 return false;
946 }
947
948 template<class T, typename TA, typename TB>
[email protected]7d5c3ac2009-02-04 08:58:19949 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:29950 void (T::*func)(const Message&, TA, TB)) {
951 Param p;
952 if (Read(msg, &p)) {
953 (obj->*func)(*msg, p.a, p.b);
954 return true;
955 }
956 return false;
957 }
958
959 template<class T, typename TA, typename TB, typename TC>
[email protected]7d5c3ac2009-02-04 08:58:19960 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:29961 void (T::*func)(const Message&, TA, TB, TC)) {
962 Param p;
963 if (Read(msg, &p)) {
964 (obj->*func)(*msg, p.a, p.b, p.c);
965 return true;
966 }
967 return false;
968 }
969
970 template<class T, typename TA, typename TB, typename TC, typename TD>
[email protected]7d5c3ac2009-02-04 08:58:19971 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:29972 void (T::*func)(const Message&, TA, TB, TC, TD)) {
973 Param p;
974 if (Read(msg, &p)) {
975 (obj->*func)(*msg, p.a, p.b, p.c, p.d);
976 return true;
977 }
978 return false;
979 }
980
981 template<class T, typename TA, typename TB, typename TC, typename TD,
982 typename TE>
[email protected]7d5c3ac2009-02-04 08:58:19983 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:29984 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
985 Param p;
986 if (Read(msg, &p)) {
987 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
988 return true;
989 }
990 return false;
991 }
992
[email protected]deb57402009-02-06 01:35:30993 // Functions used to do manual unpacking. Only used by the automation code,
994 // these should go away once that code uses SyncChannel.
995 template<typename TA, typename TB>
996 static bool Read(const IPC::Message* msg, TA* a, TB* b) {
997 ParamType params;
998 if (!Read(msg, &params))
999 return false;
1000 *a = params.a;
1001 *b = params.b;
1002 return true;
1003 }
1004
1005 template<typename TA, typename TB, typename TC>
1006 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
1007 ParamType params;
1008 if (!Read(msg, &params))
1009 return false;
1010 *a = params.a;
1011 *b = params.b;
1012 *c = params.c;
1013 return true;
1014 }
1015
1016 template<typename TA, typename TB, typename TC, typename TD>
1017 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) {
1018 ParamType params;
1019 if (!Read(msg, &params))
1020 return false;
1021 *a = params.a;
1022 *b = params.b;
1023 *c = params.c;
1024 *d = params.d;
1025 return true;
1026 }
1027
1028 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1029 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) {
1030 ParamType params;
1031 if (!Read(msg, &params))
1032 return false;
1033 *a = params.a;
1034 *b = params.b;
1035 *c = params.c;
1036 *d = params.d;
1037 *e = params.e;
1038 return true;
1039 }
initial.commit09911bf2008-07-26 23:55:291040};
1041
[email protected]7a4de7a62010-08-17 18:38:241042// defined in ipc_logging.cc
1043void GenerateLogData(const std::string& channel, const Message& message,
1044 LogData* data);
1045
1046
1047#if defined(IPC_MESSAGE_LOG_ENABLED)
[email protected]252cad62010-08-18 18:33:571048inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
1049 const std::string& output_params = msg->output_params();
[email protected]7a4de7a62010-08-17 18:38:241050 if (!l->empty() && !output_params.empty())
[email protected]252cad62010-08-18 18:33:571051 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:241052
1053 l->append(output_params);
1054}
1055
1056template <class ReplyParamType>
1057inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1058 const Message* msg) {
1059 if (msg->received_time() != 0) {
[email protected]252cad62010-08-18 18:33:571060 std::string output_params;
[email protected]7a4de7a62010-08-17 18:38:241061 LogParam(reply_params, &output_params);
1062 msg->set_output_params(output_params);
1063 }
1064}
1065
1066inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
1067 if (msg->sent_time()) {
1068 // Don't log the sync message after dispatch, as we don't have the
1069 // output parameters at that point. Instead, save its data and log it
1070 // with the outgoing reply message when it's sent.
1071 LogData* data = new LogData;
1072 GenerateLogData("", *msg, data);
1073 msg->set_dont_log();
1074 reply->set_sync_log_data(data);
1075 }
1076}
1077#else
[email protected]252cad62010-08-18 18:33:571078inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
[email protected]7a4de7a62010-08-17 18:38:241079
1080template <class ReplyParamType>
1081inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1082 const Message* msg) {}
1083
1084inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1085#endif
1086
initial.commit09911bf2008-07-26 23:55:291087// This class assumes that its template argument is a RefTuple (a Tuple with
[email protected]7a4de7a62010-08-17 18:38:241088// reference elements). This would go into ipc_message_utils_impl.h, but it is
1089// also used by chrome_frame.
initial.commit09911bf2008-07-26 23:55:291090template <class RefTuple>
1091class ParamDeserializer : public MessageReplyDeserializer {
1092 public:
[email protected]e1981f432008-08-12 15:22:131093 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:291094
1095 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1096 return ReadParam(&msg, &iter, &out_);
1097 }
1098
1099 RefTuple out_;
1100};
1101
initial.commit09911bf2008-07-26 23:55:291102// Used for synchronous messages.
[email protected]75e5a872009-04-02 23:56:111103template <class SendParamType, class ReplyParamType>
initial.commit09911bf2008-07-26 23:55:291104class MessageWithReply : public SyncMessage {
1105 public:
[email protected]75e5a872009-04-02 23:56:111106 typedef SendParamType SendParam;
[email protected]7a4de7a62010-08-17 18:38:241107 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
[email protected]75e5a872009-04-02 23:56:111108 typedef ReplyParamType ReplyParam;
1109
[email protected]168ae922009-12-04 18:08:451110 MessageWithReply(int32 routing_id, uint32 type,
[email protected]7a4de7a62010-08-17 18:38:241111 const RefSendParam& send, const ReplyParam& reply);
1112 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
1113 static bool ReadReplyParam(
1114 const Message* msg,
1115 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:291116
1117 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191118 static bool Dispatch(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291119 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291120 Message* reply = GenerateReply(msg);
1121 bool error;
[email protected]7a4de7a62010-08-17 18:38:241122 if (ReadSendParam(msg, &send_params)) {
1123 typename TupleTypes<ReplyParam>::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:291124 DispatchToMethod(obj, func, send_params, &reply_params);
1125 WriteParam(reply, reply_params);
1126 error = false;
[email protected]7a4de7a62010-08-17 18:38:241127 LogReplyParamsToMessage(reply_params, msg);
initial.commit09911bf2008-07-26 23:55:291128 } else {
1129 NOTREACHED() << "Error deserializing message " << msg->type();
1130 reply->set_reply_error();
1131 error = true;
1132 }
1133
1134 obj->Send(reply);
1135 return !error;
1136 }
1137
1138 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191139 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291140 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291141 Message* reply = GenerateReply(msg);
1142 bool error;
[email protected]7a4de7a62010-08-17 18:38:241143 if (ReadSendParam(msg, &send_params)) {
initial.commit09911bf2008-07-26 23:55:291144 Tuple1<Message&> t = MakeRefTuple(*reply);
[email protected]7a4de7a62010-08-17 18:38:241145 ConnectMessageAndReply(msg, reply);
initial.commit09911bf2008-07-26 23:55:291146 DispatchToMethod(obj, func, send_params, &t);
1147 error = false;
1148 } else {
1149 NOTREACHED() << "Error deserializing message " << msg->type();
1150 reply->set_reply_error();
1151 obj->Send(reply);
1152 error = true;
1153 }
1154 return !error;
1155 }
1156
1157 template<typename TA>
1158 static void WriteReplyParams(Message* reply, TA a) {
1159 ReplyParam p(a);
1160 WriteParam(reply, p);
1161 }
1162
1163 template<typename TA, typename TB>
1164 static void WriteReplyParams(Message* reply, TA a, TB b) {
1165 ReplyParam p(a, b);
1166 WriteParam(reply, p);
1167 }
1168
1169 template<typename TA, typename TB, typename TC>
1170 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1171 ReplyParam p(a, b, c);
1172 WriteParam(reply, p);
1173 }
1174
1175 template<typename TA, typename TB, typename TC, typename TD>
1176 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1177 ReplyParam p(a, b, c, d);
1178 WriteParam(reply, p);
1179 }
1180
1181 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1182 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1183 ReplyParam p(a, b, c, d, e);
1184 WriteParam(reply, p);
1185 }
1186};
1187
[email protected]7d5c3ac2009-02-04 08:58:191188//-----------------------------------------------------------------------------
1189
[email protected]3178f4e22008-08-05 21:20:411190} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291191
[email protected]946d1b22009-07-22 23:57:211192#endif // IPC_IPC_MESSAGE_UTILS_H_