blob: 3d638757fb250b672ee0d539725035a0cb51f60e [file] [log] [blame]
[email protected]663bd9e2011-03-21 01:07:011// Copyright (c) 2011 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 <map>
[email protected]96da6962010-05-13 19:10:3411#include <set>
[email protected]663bd9e2011-03-21 01:07:0112#include <string>
13#include <vector>
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]ca97f302011-01-20 13:57:0568 SpeechInputMsgStart,
[email protected]f0557932011-01-25 20:20:5169 PepperMsgStart,
[email protected]663bd9e2011-03-21 01:07:0170 AutofillMsgStart,
[email protected]fa685ff2011-02-17 19:47:1371 SafeBrowsingMsgStart,
[email protected]6c54e7e42011-03-02 20:52:3472 P2PMsgStart,
[email protected]db803aae2011-03-05 02:00:4273 SocketStreamMsgStart,
[email protected]94dc971d2011-03-05 19:08:3274 ResourceMsgStart,
[email protected]172f1552011-03-07 21:58:1675 FileSystemMsgStart,
[email protected]ff47b2962011-03-07 23:51:4976 ChildProcessMsgStart,
[email protected]7e3589742011-03-10 18:49:1777 ClipboardMsgStart,
[email protected]db10d8f2011-03-14 00:21:4778 BlobMsgStart,
[email protected]e93e04e2011-03-14 00:27:1079 AppCacheMsgStart,
[email protected]e7c21b812011-03-19 18:03:3080 DeviceOrientationMsgStart,
81 DesktopNotificationMsgStart,
82 GeolocationMsgStart,
[email protected]4460ee52011-03-21 19:19:2483 AudioMsgStart,
[email protected]778574e2011-03-21 22:03:5084 ChromeMsgStart,
[email protected]59f4f2fa2011-03-23 01:00:5585 DragMsgStart,
[email protected]1375e3ab2011-03-24 17:07:2286 PrintMsgStart,
[email protected]3e267192011-03-25 01:55:4587 SpellCheckMsgStart,
[email protected]e503a122011-03-17 18:20:5288 LastIPCMsgStart // Must come last.
[email protected]f91cb992009-02-04 20:10:1289};
90
[email protected]7a4de7a62010-08-17 18:38:2491class DictionaryValue;
92class FilePath;
93class ListValue;
94class NullableString16;
95
96namespace base {
97class Time;
[email protected]d84e48b2010-10-21 22:04:5298class TimeDelta;
[email protected]7a4de7a62010-08-17 18:38:2499struct FileDescriptor;
100}
101
initial.commit09911bf2008-07-26 23:55:29102namespace IPC {
103
[email protected]7a4de7a62010-08-17 18:38:24104struct ChannelHandle;
105
initial.commit09911bf2008-07-26 23:55:29106//-----------------------------------------------------------------------------
107// An iterator class for reading the fields contained within a Message.
108
109class MessageIterator {
110 public:
[email protected]e1981f432008-08-12 15:22:13111 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
initial.commit09911bf2008-07-26 23:55:29112 }
113 int NextInt() const {
[email protected]9422b7dc2009-12-30 20:09:02114 int val = -1;
initial.commit09911bf2008-07-26 23:55:29115 if (!msg_.ReadInt(&iter_, &val))
116 NOTREACHED();
117 return val;
118 }
initial.commit09911bf2008-07-26 23:55:29119 const std::string NextString() const {
120 std::string val;
121 if (!msg_.ReadString(&iter_, &val))
122 NOTREACHED();
123 return val;
124 }
125 const std::wstring NextWString() const {
126 std::wstring val;
127 if (!msg_.ReadWString(&iter_, &val))
128 NOTREACHED();
129 return val;
130 }
[email protected]225c8f52010-02-05 22:23:20131 void NextData(const char** data, int* length) const {
initial.commit09911bf2008-07-26 23:55:29132 if (!msg_.ReadData(&iter_, data, length)) {
133 NOTREACHED();
134 }
135 }
136 private:
137 const Message& msg_;
138 mutable void* iter_;
139};
140
141//-----------------------------------------------------------------------------
[email protected]6476c72c2011-02-11 18:46:19142// A dummy struct to place first just to allow leading commas for all
143// members in the macro-generated constructor initializer lists.
144struct NoParams {
145};
146
147//-----------------------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19148// ParamTraits specializations, etc.
149
[email protected]7d5c3ac2009-02-04 08:58:19150template <class P>
151static inline void WriteParam(Message* m, const P& p) {
[email protected]7b291f92009-08-14 05:43:53152 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53153 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
[email protected]7d5c3ac2009-02-04 08:58:19154}
155
156template <class P>
[email protected]1e86aa62009-04-24 21:22:33157static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
158 P* p) {
[email protected]7b291f92009-08-14 05:43:53159 typedef typename SimilarTypeTraits<P>::Type Type;
160 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
[email protected]7d5c3ac2009-02-04 08:58:19161}
162
163template <class P>
[email protected]252cad62010-08-18 18:33:57164static inline void LogParam(const P& p, std::string* l) {
[email protected]7b291f92009-08-14 05:43:53165 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53166 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19167}
168
169template <>
170struct ParamTraits<bool> {
171 typedef bool param_type;
172 static void Write(Message* m, const param_type& p) {
173 m->WriteBool(p);
174 }
175 static bool Read(const Message* m, void** iter, param_type* r) {
176 return m->ReadBool(iter, r);
177 }
[email protected]252cad62010-08-18 18:33:57178 static void Log(const param_type& p, std::string* l) {
179 l->append(p ? "true" : "false");
[email protected]7d5c3ac2009-02-04 08:58:19180 }
181};
182
183template <>
184struct ParamTraits<int> {
185 typedef int param_type;
186 static void Write(Message* m, const param_type& p) {
187 m->WriteInt(p);
188 }
189 static bool Read(const Message* m, void** iter, param_type* r) {
190 return m->ReadInt(iter, r);
191 }
[email protected]252cad62010-08-18 18:33:57192 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19193};
194
195template <>
[email protected]63263f92009-07-28 19:35:08196struct ParamTraits<unsigned int> {
197 typedef unsigned int param_type;
198 static void Write(Message* m, const param_type& p) {
199 m->WriteInt(p);
200 }
201 static bool Read(const Message* m, void** iter, param_type* r) {
202 return m->ReadInt(iter, reinterpret_cast<int*>(r));
203 }
[email protected]252cad62010-08-18 18:33:57204 static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08205};
206
207template <>
[email protected]7d5c3ac2009-02-04 08:58:19208struct ParamTraits<long> {
209 typedef long param_type;
210 static void Write(Message* m, const param_type& p) {
211 m->WriteLong(p);
212 }
213 static bool Read(const Message* m, void** iter, param_type* r) {
214 return m->ReadLong(iter, r);
215 }
[email protected]252cad62010-08-18 18:33:57216 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19217};
218
[email protected]140c3032009-06-26 18:22:54219template <>
220struct ParamTraits<unsigned long> {
221 typedef unsigned long param_type;
222 static void Write(Message* m, const param_type& p) {
223 m->WriteLong(p);
224 }
225 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]63263f92009-07-28 19:35:08226 return m->ReadLong(iter, reinterpret_cast<long*>(r));
[email protected]140c3032009-06-26 18:22:54227 }
[email protected]252cad62010-08-18 18:33:57228 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19229};
230
231template <>
[email protected]63263f92009-07-28 19:35:08232struct ParamTraits<long long> {
233 typedef long long param_type;
[email protected]7d5c3ac2009-02-04 08:58:19234 static void Write(Message* m, const param_type& p) {
235 m->WriteInt64(static_cast<int64>(p));
236 }
237 static bool Read(const Message* m, void** iter, param_type* r) {
238 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
239 }
[email protected]252cad62010-08-18 18:33:57240 static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08241};
242
243template <>
244struct ParamTraits<unsigned long long> {
245 typedef unsigned long long param_type;
246 static void Write(Message* m, const param_type& p) {
247 m->WriteInt64(p);
248 }
249 static bool Read(const Message* m, void** iter, param_type* r) {
250 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
251 }
[email protected]252cad62010-08-18 18:33:57252 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19253};
254
[email protected]43a40202010-11-12 16:25:01255template <>
256struct ParamTraits<unsigned short> {
257 typedef unsigned short param_type;
258 static void Write(Message* m, const param_type& p);
259 static bool Read(const Message* m, void** iter, param_type* r);
260 static void Log(const param_type& p, std::string* l);
261};
262
[email protected]20199662010-06-17 03:29:26263// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
264// should be sure to check the sanity of these values after receiving them over
265// IPC.
266template <>
267struct ParamTraits<float> {
268 typedef float param_type;
269 static void Write(Message* m, const param_type& p) {
270 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
271 }
272 static bool Read(const Message* m, void** iter, param_type* r) {
273 const char *data;
274 int data_size;
275 if (!m->ReadData(iter, &data, &data_size) ||
276 data_size != sizeof(param_type)) {
277 NOTREACHED();
278 return false;
279 }
280 memcpy(r, data, sizeof(param_type));
281 return true;
282 }
[email protected]252cad62010-08-18 18:33:57283 static void Log(const param_type& p, std::string* l) {
284 l->append(StringPrintf("%e", p));
[email protected]20199662010-06-17 03:29:26285 }
286};
287
[email protected]7d5c3ac2009-02-04 08:58:19288template <>
289struct ParamTraits<double> {
290 typedef double param_type;
291 static void Write(Message* m, const param_type& p) {
292 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
293 }
294 static bool Read(const Message* m, void** iter, param_type* r) {
295 const char *data;
[email protected]20199662010-06-17 03:29:26296 int data_size;
297 if (!m->ReadData(iter, &data, &data_size) ||
298 data_size != sizeof(param_type)) {
[email protected]7d5c3ac2009-02-04 08:58:19299 NOTREACHED();
[email protected]20199662010-06-17 03:29:26300 return false;
[email protected]7d5c3ac2009-02-04 08:58:19301 }
[email protected]20199662010-06-17 03:29:26302 memcpy(r, data, sizeof(param_type));
303 return true;
[email protected]7d5c3ac2009-02-04 08:58:19304 }
[email protected]252cad62010-08-18 18:33:57305 static void Log(const param_type& p, std::string* l) {
306 l->append(StringPrintf("%e", p));
[email protected]7d5c3ac2009-02-04 08:58:19307 }
308};
309
310template <>
[email protected]7d5c3ac2009-02-04 08:58:19311struct ParamTraits<base::Time> {
312 typedef base::Time param_type;
[email protected]7a4de7a62010-08-17 18:38:24313 static void Write(Message* m, const param_type& p);
314 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57315 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19316};
317
[email protected]d84e48b2010-10-21 22:04:52318template <>
319struct ParamTraits<base::TimeDelta> {
320 typedef base::TimeDelta param_type;
321 static void Write(Message* m, const param_type& p);
322 static bool Read(const Message* m, void** iter, param_type* r);
323 static void Log(const param_type& p, std::string* l);
324};
325
[email protected]7d5c3ac2009-02-04 08:58:19326#if defined(OS_WIN)
327template <>
328struct ParamTraits<LOGFONT> {
329 typedef LOGFONT param_type;
330 static void Write(Message* m, const param_type& p) {
331 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
332 }
333 static bool Read(const Message* m, void** iter, param_type* r) {
334 const char *data;
335 int data_size = 0;
336 bool result = m->ReadData(iter, &data, &data_size);
337 if (result && data_size == sizeof(LOGFONT)) {
338 memcpy(r, data, sizeof(LOGFONT));
339 } else {
340 result = false;
341 NOTREACHED();
342 }
343
344 return result;
345 }
[email protected]252cad62010-08-18 18:33:57346 static void Log(const param_type& p, std::string* l) {
347 l->append(StringPrintf("<LOGFONT>"));
[email protected]7d5c3ac2009-02-04 08:58:19348 }
349};
350
351template <>
352struct ParamTraits<MSG> {
353 typedef MSG param_type;
354 static void Write(Message* m, const param_type& p) {
355 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
356 }
357 static bool Read(const Message* m, void** iter, param_type* r) {
358 const char *data;
359 int data_size = 0;
360 bool result = m->ReadData(iter, &data, &data_size);
361 if (result && data_size == sizeof(MSG)) {
362 memcpy(r, data, sizeof(MSG));
363 } else {
364 result = false;
365 NOTREACHED();
366 }
367
368 return result;
369 }
[email protected]252cad62010-08-18 18:33:57370 static void Log(const param_type& p, std::string* l) {
371 l->append("<MSG>");
[email protected]7a4de7a62010-08-17 18:38:24372 }
[email protected]7d5c3ac2009-02-04 08:58:19373};
374#endif // defined(OS_WIN)
375
376template <>
[email protected]584f2b22009-05-21 01:01:59377struct ParamTraits<DictionaryValue> {
378 typedef DictionaryValue param_type;
379 static void Write(Message* m, const param_type& p);
380 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57381 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59382};
383
384template <>
385struct ParamTraits<ListValue> {
386 typedef ListValue param_type;
387 static void Write(Message* m, const param_type& p);
388 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57389 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59390};
391
392template <>
[email protected]7d5c3ac2009-02-04 08:58:19393struct ParamTraits<std::string> {
394 typedef std::string param_type;
395 static void Write(Message* m, const param_type& p) {
396 m->WriteString(p);
397 }
398 static bool Read(const Message* m, void** iter, param_type* r) {
399 return m->ReadString(iter, r);
400 }
[email protected]252cad62010-08-18 18:33:57401 static void Log(const param_type& p, std::string* l) {
402 l->append(p);
[email protected]7d5c3ac2009-02-04 08:58:19403 }
404};
405
[email protected]3dd7a7a2009-07-27 21:09:07406template<typename CharType>
[email protected]252cad62010-08-18 18:33:57407static void LogBytes(const std::vector<CharType>& data, std::string* out) {
[email protected]3dd7a7a2009-07-27 21:09:07408#if defined(OS_WIN)
409 // Windows has a GUI for logging, which can handle arbitrary binary data.
410 for (size_t i = 0; i < data.size(); ++i)
411 out->push_back(data[i]);
412#else
413 // On POSIX, we log to stdout, which we assume can display ASCII.
414 static const size_t kMaxBytesToLog = 100;
415 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
416 if (isprint(data[i]))
417 out->push_back(data[i]);
418 else
[email protected]252cad62010-08-18 18:33:57419 out->append(StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
[email protected]3dd7a7a2009-07-27 21:09:07420 }
421 if (data.size() > kMaxBytesToLog) {
422 out->append(
[email protected]252cad62010-08-18 18:33:57423 StringPrintf(" and %u more bytes",
[email protected]3dd7a7a2009-07-27 21:09:07424 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
425 }
426#endif
427}
428
[email protected]7d5c3ac2009-02-04 08:58:19429template <>
430struct ParamTraits<std::vector<unsigned char> > {
431 typedef std::vector<unsigned char> param_type;
432 static void Write(Message* m, const param_type& p) {
[email protected]f6b8ce32011-03-02 00:03:18433 if (p.empty()) {
[email protected]7d5c3ac2009-02-04 08:58:19434 m->WriteData(NULL, 0);
435 } else {
436 m->WriteData(reinterpret_cast<const char*>(&p.front()),
437 static_cast<int>(p.size()));
438 }
439 }
440 static bool Read(const Message* m, void** iter, param_type* r) {
441 const char *data;
442 int data_size = 0;
443 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
444 return false;
445 r->resize(data_size);
446 if (data_size)
447 memcpy(&r->front(), data, data_size);
448 return true;
449 }
[email protected]252cad62010-08-18 18:33:57450 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07451 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19452 }
453};
454
455template <>
456struct ParamTraits<std::vector<char> > {
457 typedef std::vector<char> param_type;
458 static void Write(Message* m, const param_type& p) {
[email protected]f6b8ce32011-03-02 00:03:18459 if (p.empty()) {
[email protected]7d5c3ac2009-02-04 08:58:19460 m->WriteData(NULL, 0);
461 } else {
462 m->WriteData(&p.front(), static_cast<int>(p.size()));
463 }
464 }
465 static bool Read(const Message* m, void** iter, param_type* r) {
466 const char *data;
467 int data_size = 0;
468 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
469 return false;
470 r->resize(data_size);
471 if (data_size)
472 memcpy(&r->front(), data, data_size);
473 return true;
474 }
[email protected]252cad62010-08-18 18:33:57475 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07476 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19477 }
478};
479
480template <class P>
481struct ParamTraits<std::vector<P> > {
482 typedef std::vector<P> param_type;
483 static void Write(Message* m, const param_type& p) {
484 WriteParam(m, static_cast<int>(p.size()));
485 for (size_t i = 0; i < p.size(); i++)
486 WriteParam(m, p[i]);
487 }
488 static bool Read(const Message* m, void** iter, param_type* r) {
489 int size;
[email protected]86440f52009-12-31 05:17:23490 // ReadLength() checks for < 0 itself.
[email protected]7d5c3ac2009-02-04 08:58:19491 if (!m->ReadLength(iter, &size))
492 return false;
493 // Resizing beforehand is not safe, see BUG 1006367 for details.
[email protected]86440f52009-12-31 05:17:23494 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
495 return false;
496 r->resize(size);
497 for (int i = 0; i < size; i++) {
498 if (!ReadParam(m, iter, &(*r)[i]))
499 return false;
[email protected]7d5c3ac2009-02-04 08:58:19500 }
501 return true;
502 }
[email protected]252cad62010-08-18 18:33:57503 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19504 for (size_t i = 0; i < p.size(); ++i) {
505 if (i != 0)
[email protected]252cad62010-08-18 18:33:57506 l->append(" ");
[email protected]7d5c3ac2009-02-04 08:58:19507 LogParam((p[i]), l);
508 }
509 }
510};
511
[email protected]96da6962010-05-13 19:10:34512template <class P>
513struct ParamTraits<std::set<P> > {
514 typedef std::set<P> 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);
520 }
521 static bool Read(const Message* m, void** iter, param_type* r) {
522 int size;
523 if (!m->ReadLength(iter, &size))
524 return false;
525 for (int i = 0; i < size; ++i) {
526 P item;
527 if (!ReadParam(m, iter, &item))
528 return false;
529 r->insert(item);
530 }
531 return true;
532 }
[email protected]252cad62010-08-18 18:33:57533 static void Log(const param_type& p, std::string* l) {
534 l->append("<std::set>");
[email protected]96da6962010-05-13 19:10:34535 }
536};
537
538
[email protected]7d5c3ac2009-02-04 08:58:19539template <class K, class V>
540struct ParamTraits<std::map<K, V> > {
541 typedef std::map<K, V> param_type;
542 static void Write(Message* m, const param_type& p) {
543 WriteParam(m, static_cast<int>(p.size()));
544 typename param_type::const_iterator iter;
545 for (iter = p.begin(); iter != p.end(); ++iter) {
546 WriteParam(m, iter->first);
547 WriteParam(m, iter->second);
548 }
549 }
550 static bool Read(const Message* m, void** iter, param_type* r) {
551 int size;
552 if (!ReadParam(m, iter, &size) || size < 0)
553 return false;
554 for (int i = 0; i < size; ++i) {
555 K k;
556 if (!ReadParam(m, iter, &k))
557 return false;
558 V& value = (*r)[k];
559 if (!ReadParam(m, iter, &value))
560 return false;
561 }
562 return true;
563 }
[email protected]252cad62010-08-18 18:33:57564 static void Log(const param_type& p, std::string* l) {
565 l->append("<std::map>");
[email protected]7d5c3ac2009-02-04 08:58:19566 }
567};
568
[email protected]eb47a132009-03-04 00:39:56569
[email protected]7d5c3ac2009-02-04 08:58:19570template <>
571struct ParamTraits<std::wstring> {
572 typedef std::wstring param_type;
573 static void Write(Message* m, const param_type& p) {
574 m->WriteWString(p);
575 }
576 static bool Read(const Message* m, void** iter, param_type* r) {
577 return m->ReadWString(iter, r);
578 }
[email protected]252cad62010-08-18 18:33:57579 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19580};
581
[email protected]a5da6d612009-08-04 02:00:56582template <class A, class B>
583struct ParamTraits<std::pair<A, B> > {
584 typedef std::pair<A, B> param_type;
585 static void Write(Message* m, const param_type& p) {
586 WriteParam(m, p.first);
587 WriteParam(m, p.second);
588 }
589 static bool Read(const Message* m, void** iter, param_type* r) {
590 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
591 }
[email protected]252cad62010-08-18 18:33:57592 static void Log(const param_type& p, std::string* l) {
593 l->append("(");
[email protected]a5da6d612009-08-04 02:00:56594 LogParam(p.first, l);
[email protected]252cad62010-08-18 18:33:57595 l->append(", ");
[email protected]a5da6d612009-08-04 02:00:56596 LogParam(p.second, l);
[email protected]252cad62010-08-18 18:33:57597 l->append(")");
[email protected]a5da6d612009-08-04 02:00:56598 }
599};
600
[email protected]15bf8712009-08-27 00:55:02601template <>
602struct ParamTraits<NullableString16> {
603 typedef NullableString16 param_type;
[email protected]7a4de7a62010-08-17 18:38:24604 static void Write(Message* m, const param_type& p);
605 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57606 static void Log(const param_type& p, std::string* l);
[email protected]15bf8712009-08-27 00:55:02607};
608
[email protected]eb47a132009-03-04 00:39:56609// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
610// need this trait.
611#if !defined(WCHAR_T_IS_UTF16)
[email protected]eb47a132009-03-04 00:39:56612template <>
613struct ParamTraits<string16> {
614 typedef string16 param_type;
615 static void Write(Message* m, const param_type& p) {
[email protected]3a2a5d22009-03-04 03:36:36616 m->WriteString16(p);
[email protected]eb47a132009-03-04 00:39:56617 }
618 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]3a2a5d22009-03-04 03:36:36619 return m->ReadString16(iter, r);
[email protected]eb47a132009-03-04 00:39:56620 }
[email protected]252cad62010-08-18 18:33:57621 static void Log(const param_type& p, std::string* l);
[email protected]eb47a132009-03-04 00:39:56622};
[email protected]eb47a132009-03-04 00:39:56623#endif
624
[email protected]7d5c3ac2009-02-04 08:58:19625// and, a few more useful types...
626#if defined(OS_WIN)
627template <>
628struct ParamTraits<HANDLE> {
629 typedef HANDLE param_type;
630 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35631 // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
632 // bit systems.
633 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 }
[email protected]252cad62010-08-18 18:33:57639 static void Log(const param_type& p, std::string* l) {
640 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19641 }
642};
643
644template <>
645struct ParamTraits<HCURSOR> {
646 typedef HCURSOR param_type;
647 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35648 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19649 }
650 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35651 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
652 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19653 }
[email protected]252cad62010-08-18 18:33:57654 static void Log(const param_type& p, std::string* l) {
655 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19656 }
657};
658
659template <>
[email protected]7d5c3ac2009-02-04 08:58:19660struct ParamTraits<HACCEL> {
661 typedef HACCEL param_type;
662 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35663 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19664 }
665 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35666 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
667 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19668 }
669};
670
671template <>
672struct ParamTraits<POINT> {
673 typedef POINT param_type;
674 static void Write(Message* m, const param_type& p) {
675 m->WriteInt(p.x);
676 m->WriteInt(p.y);
677 }
678 static bool Read(const Message* m, void** iter, param_type* r) {
679 int x, y;
680 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
681 return false;
682 r->x = x;
683 r->y = y;
684 return true;
685 }
[email protected]252cad62010-08-18 18:33:57686 static void Log(const param_type& p, std::string* l) {
687 l->append(StringPrintf("(%d, %d)", p.x, p.y));
[email protected]7d5c3ac2009-02-04 08:58:19688 }
689};
690#endif // defined(OS_WIN)
691
692template <>
693struct ParamTraits<FilePath> {
694 typedef FilePath param_type;
[email protected]7a4de7a62010-08-17 18:38:24695 static void Write(Message* m, const param_type& p);
696 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57697 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19698};
699
[email protected]526776c2009-02-07 00:39:26700#if defined(OS_POSIX)
[email protected]2749885f2009-03-05 21:40:11701// FileDescriptors may be serialised over IPC channels on POSIX. On the
702// receiving side, the FileDescriptor is a valid duplicate of the file
703// descriptor which was transmitted: *it is not just a copy of the integer like
704// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
705// this case, the receiving end will see a value of -1. *Zero is a valid file
706// descriptor*.
707//
708// The received file descriptor will have the |auto_close| flag set to true. The
709// code which handles the message is responsible for taking ownership of it.
710// File descriptors are OS resources and must be closed when no longer needed.
711//
712// When sending a file descriptor, the file descriptor must be valid at the time
713// of transmission. Since transmission is not synchronous, one should consider
714// dup()ing any file descriptors to be transmitted and setting the |auto_close|
715// flag, which causes the file descriptor to be closed after writing.
[email protected]526776c2009-02-07 00:39:26716template<>
[email protected]5fe733de2009-02-11 18:59:20717struct ParamTraits<base::FileDescriptor> {
718 typedef base::FileDescriptor param_type;
[email protected]7a4de7a62010-08-17 18:38:24719 static void Write(Message* m, const param_type& p);
720 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57721 static void Log(const param_type& p, std::string* l);
[email protected]526776c2009-02-07 00:39:26722};
[email protected]379e7a52010-03-09 00:38:41723#endif // defined(OS_POSIX)
[email protected]526776c2009-02-07 00:39:26724
[email protected]d2e884d2009-06-22 20:37:52725// A ChannelHandle is basically a platform-inspecific wrapper around the
726// fact that IPC endpoints are handled specially on POSIX. See above comments
727// on FileDescriptor for more background.
728template<>
729struct ParamTraits<IPC::ChannelHandle> {
730 typedef ChannelHandle param_type;
[email protected]7a4de7a62010-08-17 18:38:24731 static void Write(Message* m, const param_type& p);
732 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57733 static void Log(const param_type& p, std::string* l);
[email protected]d2e884d2009-06-22 20:37:52734};
735
[email protected]7d5c3ac2009-02-04 08:58:19736#if defined(OS_WIN)
737template <>
738struct ParamTraits<XFORM> {
739 typedef XFORM param_type;
740 static void Write(Message* m, const param_type& p) {
741 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
742 }
743 static bool Read(const Message* m, void** iter, param_type* r) {
744 const char *data;
745 int data_size = 0;
746 bool result = m->ReadData(iter, &data, &data_size);
747 if (result && data_size == sizeof(XFORM)) {
748 memcpy(r, data, sizeof(XFORM));
749 } else {
750 result = false;
751 NOTREACHED();
752 }
753
754 return result;
755 }
[email protected]252cad62010-08-18 18:33:57756 static void Log(const param_type& p, std::string* l) {
757 l->append("<XFORM>");
[email protected]7d5c3ac2009-02-04 08:58:19758 }
759};
760#endif // defined(OS_WIN)
761
[email protected]7d5c3ac2009-02-04 08:58:19762struct LogData {
[email protected]20f0487a2010-09-30 20:06:30763 LogData();
764 ~LogData();
765
[email protected]9a3a293b2009-06-04 22:28:16766 std::string channel;
[email protected]8bef70e2009-04-14 19:11:24767 int32 routing_id;
[email protected]168ae922009-12-04 18:08:45768 uint32 type; // "User-defined" message type, from ipc_message.h.
[email protected]252cad62010-08-18 18:33:57769 std::string flags;
[email protected]7d5c3ac2009-02-04 08:58:19770 int64 sent; // Time that the message was sent (i.e. at Send()).
771 int64 receive; // Time before it was dispatched (i.e. before calling
772 // OnMessageReceived).
773 int64 dispatch; // Time after it was dispatched (i.e. after calling
774 // OnMessageReceived).
[email protected]252cad62010-08-18 18:33:57775 std::string message_name;
776 std::string params;
[email protected]7d5c3ac2009-02-04 08:58:19777};
778
779template <>
780struct ParamTraits<LogData> {
781 typedef LogData param_type;
[email protected]20f0487a2010-09-30 20:06:30782 static void Write(Message* m, const param_type& p);
783 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57784 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19785 // Doesn't make sense to implement this!
786 }
787};
788
[email protected]eb47a132009-03-04 00:39:56789template <>
[email protected]503683f2009-02-26 09:13:01790struct ParamTraits<Message> {
791 static void Write(Message* m, const Message& p) {
[email protected]8a861402011-01-28 19:59:11792 DCHECK(p.size() <= INT_MAX);
793 int message_size = static_cast<int>(p.size());
794 m->WriteInt(message_size);
795 m->WriteData(reinterpret_cast<const char*>(p.data()), message_size);
[email protected]503683f2009-02-26 09:13:01796 }
797 static bool Read(const Message* m, void** iter, Message* r) {
798 int size;
799 if (!m->ReadInt(iter, &size))
800 return false;
801 const char* data;
802 if (!m->ReadData(iter, &data, &size))
803 return false;
804 *r = Message(data, size);
805 return true;
806 }
[email protected]252cad62010-08-18 18:33:57807 static void Log(const Message& p, std::string* l) {
808 l->append("<IPC::Message>");
[email protected]503683f2009-02-26 09:13:01809 }
810};
811
812template <>
[email protected]7d5c3ac2009-02-04 08:58:19813struct ParamTraits<Tuple0> {
814 typedef Tuple0 param_type;
815 static void Write(Message* m, const param_type& p) {
816 }
817 static bool Read(const Message* m, void** iter, param_type* r) {
818 return true;
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 }
822};
823
824template <class A>
825struct ParamTraits< Tuple1<A> > {
826 typedef Tuple1<A> param_type;
827 static void Write(Message* m, const param_type& p) {
828 WriteParam(m, p.a);
829 }
830 static bool Read(const Message* m, void** iter, param_type* r) {
831 return ReadParam(m, iter, &r->a);
832 }
[email protected]252cad62010-08-18 18:33:57833 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19834 LogParam(p.a, l);
835 }
836};
837
838template <class A, class B>
839struct ParamTraits< Tuple2<A, B> > {
840 typedef Tuple2<A, B> param_type;
841 static void Write(Message* m, const param_type& p) {
842 WriteParam(m, p.a);
843 WriteParam(m, p.b);
844 }
845 static bool Read(const Message* m, void** iter, param_type* r) {
846 return (ReadParam(m, iter, &r->a) &&
847 ReadParam(m, iter, &r->b));
848 }
[email protected]252cad62010-08-18 18:33:57849 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19850 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57851 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19852 LogParam(p.b, l);
853 }
854};
855
856template <class A, class B, class C>
857struct ParamTraits< Tuple3<A, B, C> > {
858 typedef Tuple3<A, B, C> param_type;
859 static void Write(Message* m, const param_type& p) {
860 WriteParam(m, p.a);
861 WriteParam(m, p.b);
862 WriteParam(m, p.c);
863 }
864 static bool Read(const Message* m, void** iter, param_type* r) {
865 return (ReadParam(m, iter, &r->a) &&
866 ReadParam(m, iter, &r->b) &&
867 ReadParam(m, iter, &r->c));
868 }
[email protected]252cad62010-08-18 18:33:57869 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19870 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57871 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19872 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57873 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19874 LogParam(p.c, l);
875 }
876};
877
878template <class A, class B, class C, class D>
879struct ParamTraits< Tuple4<A, B, C, D> > {
880 typedef Tuple4<A, B, C, D> param_type;
881 static void Write(Message* m, const param_type& p) {
882 WriteParam(m, p.a);
883 WriteParam(m, p.b);
884 WriteParam(m, p.c);
885 WriteParam(m, p.d);
886 }
887 static bool Read(const Message* m, void** iter, param_type* r) {
888 return (ReadParam(m, iter, &r->a) &&
889 ReadParam(m, iter, &r->b) &&
890 ReadParam(m, iter, &r->c) &&
891 ReadParam(m, iter, &r->d));
892 }
[email protected]252cad62010-08-18 18:33:57893 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19894 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57895 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19896 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57897 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19898 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57899 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19900 LogParam(p.d, l);
901 }
902};
903
904template <class A, class B, class C, class D, class E>
905struct ParamTraits< Tuple5<A, B, C, D, E> > {
906 typedef Tuple5<A, B, C, D, E> param_type;
907 static void Write(Message* m, const param_type& p) {
908 WriteParam(m, p.a);
909 WriteParam(m, p.b);
910 WriteParam(m, p.c);
911 WriteParam(m, p.d);
912 WriteParam(m, p.e);
913 }
914 static bool Read(const Message* m, void** iter, param_type* r) {
915 return (ReadParam(m, iter, &r->a) &&
916 ReadParam(m, iter, &r->b) &&
917 ReadParam(m, iter, &r->c) &&
918 ReadParam(m, iter, &r->d) &&
919 ReadParam(m, iter, &r->e));
920 }
[email protected]252cad62010-08-18 18:33:57921 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19922 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57923 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19924 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57925 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19926 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57927 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19928 LogParam(p.d, l);
[email protected]252cad62010-08-18 18:33:57929 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19930 LogParam(p.e, l);
931 }
932};
933
[email protected]7d5c3ac2009-02-04 08:58:19934//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:29935// Generic message subclasses
936
937// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:24938template <class ParamType>
initial.commit09911bf2008-07-26 23:55:29939class MessageWithTuple : public Message {
940 public:
[email protected]81a34412009-01-05 19:17:24941 typedef ParamType Param;
[email protected]7a4de7a62010-08-17 18:38:24942 typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
[email protected]81a34412009-01-05 19:17:24943
[email protected]7a4de7a62010-08-17 18:38:24944 // The constructor and the Read() method's templated implementations are in
945 // ipc_message_utils_impl.h. The subclass constructor and Log() methods call
946 // the templated versions of these and make sure there are instantiations in
947 // those translation units.
948 MessageWithTuple(int32 routing_id, uint32 type, const RefParam& p);
[email protected]071b4b92010-08-09 16:06:58949
[email protected]7a4de7a62010-08-17 18:38:24950 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:29951
952 // Generic dispatcher. Should cover most cases.
[email protected]65412272010-12-21 20:03:24953 template<class T, class S, class Method>
954 static bool Dispatch(const Message* msg, T* obj, S* sender, Method func) {
initial.commit09911bf2008-07-26 23:55:29955 Param p;
956 if (Read(msg, &p)) {
957 DispatchToMethod(obj, func, p);
958 return true;
959 }
960 return false;
961 }
962
963 // The following dispatchers exist for the case where the callback function
964 // needs the message as well. They assume that "Param" is a type of Tuple
965 // (except the one arg case, as there is no Tuple1).
[email protected]65412272010-12-21 20:03:24966 template<class T, class S, typename TA>
967 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29968 void (T::*func)(const Message&, TA)) {
969 Param p;
970 if (Read(msg, &p)) {
[email protected]c2fe31542009-05-20 18:24:14971 (obj->*func)(*msg, p.a);
initial.commit09911bf2008-07-26 23:55:29972 return true;
973 }
974 return false;
975 }
976
[email protected]65412272010-12-21 20:03:24977 template<class T, class S, typename TA, typename TB>
978 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29979 void (T::*func)(const Message&, TA, TB)) {
980 Param p;
981 if (Read(msg, &p)) {
982 (obj->*func)(*msg, p.a, p.b);
983 return true;
984 }
985 return false;
986 }
987
[email protected]65412272010-12-21 20:03:24988 template<class T, class S, typename TA, typename TB, typename TC>
989 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29990 void (T::*func)(const Message&, TA, TB, TC)) {
991 Param p;
992 if (Read(msg, &p)) {
993 (obj->*func)(*msg, p.a, p.b, p.c);
994 return true;
995 }
996 return false;
997 }
998
[email protected]65412272010-12-21 20:03:24999 template<class T, class S, typename TA, typename TB, typename TC, typename TD>
1000 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:291001 void (T::*func)(const Message&, TA, TB, TC, TD)) {
1002 Param p;
1003 if (Read(msg, &p)) {
1004 (obj->*func)(*msg, p.a, p.b, p.c, p.d);
1005 return true;
1006 }
1007 return false;
1008 }
1009
[email protected]65412272010-12-21 20:03:241010 template<class T, class S, typename TA, typename TB, typename TC, typename TD,
initial.commit09911bf2008-07-26 23:55:291011 typename TE>
[email protected]65412272010-12-21 20:03:241012 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:291013 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
1014 Param p;
1015 if (Read(msg, &p)) {
1016 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
1017 return true;
1018 }
1019 return false;
1020 }
1021
[email protected]deb57402009-02-06 01:35:301022 // Functions used to do manual unpacking. Only used by the automation code,
1023 // these should go away once that code uses SyncChannel.
1024 template<typename TA, typename TB>
1025 static bool Read(const IPC::Message* msg, TA* a, TB* b) {
1026 ParamType params;
1027 if (!Read(msg, &params))
1028 return false;
1029 *a = params.a;
1030 *b = params.b;
1031 return true;
1032 }
1033
1034 template<typename TA, typename TB, typename TC>
1035 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
1036 ParamType params;
1037 if (!Read(msg, &params))
1038 return false;
1039 *a = params.a;
1040 *b = params.b;
1041 *c = params.c;
1042 return true;
1043 }
1044
1045 template<typename TA, typename TB, typename TC, typename TD>
1046 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) {
1047 ParamType params;
1048 if (!Read(msg, &params))
1049 return false;
1050 *a = params.a;
1051 *b = params.b;
1052 *c = params.c;
1053 *d = params.d;
1054 return true;
1055 }
1056
1057 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1058 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) {
1059 ParamType params;
1060 if (!Read(msg, &params))
1061 return false;
1062 *a = params.a;
1063 *b = params.b;
1064 *c = params.c;
1065 *d = params.d;
1066 *e = params.e;
1067 return true;
1068 }
initial.commit09911bf2008-07-26 23:55:291069};
1070
[email protected]7a4de7a62010-08-17 18:38:241071// defined in ipc_logging.cc
1072void GenerateLogData(const std::string& channel, const Message& message,
1073 LogData* data);
1074
1075
1076#if defined(IPC_MESSAGE_LOG_ENABLED)
[email protected]252cad62010-08-18 18:33:571077inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
1078 const std::string& output_params = msg->output_params();
[email protected]7a4de7a62010-08-17 18:38:241079 if (!l->empty() && !output_params.empty())
[email protected]252cad62010-08-18 18:33:571080 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:241081
1082 l->append(output_params);
1083}
1084
1085template <class ReplyParamType>
1086inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1087 const Message* msg) {
1088 if (msg->received_time() != 0) {
[email protected]252cad62010-08-18 18:33:571089 std::string output_params;
[email protected]7a4de7a62010-08-17 18:38:241090 LogParam(reply_params, &output_params);
1091 msg->set_output_params(output_params);
1092 }
1093}
1094
1095inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
1096 if (msg->sent_time()) {
1097 // Don't log the sync message after dispatch, as we don't have the
1098 // output parameters at that point. Instead, save its data and log it
1099 // with the outgoing reply message when it's sent.
1100 LogData* data = new LogData;
1101 GenerateLogData("", *msg, data);
1102 msg->set_dont_log();
1103 reply->set_sync_log_data(data);
1104 }
1105}
1106#else
[email protected]252cad62010-08-18 18:33:571107inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
[email protected]7a4de7a62010-08-17 18:38:241108
1109template <class ReplyParamType>
1110inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1111 const Message* msg) {}
1112
1113inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1114#endif
1115
initial.commit09911bf2008-07-26 23:55:291116// This class assumes that its template argument is a RefTuple (a Tuple with
[email protected]7a4de7a62010-08-17 18:38:241117// reference elements). This would go into ipc_message_utils_impl.h, but it is
1118// also used by chrome_frame.
initial.commit09911bf2008-07-26 23:55:291119template <class RefTuple>
1120class ParamDeserializer : public MessageReplyDeserializer {
1121 public:
[email protected]e1981f432008-08-12 15:22:131122 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:291123
1124 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1125 return ReadParam(&msg, &iter, &out_);
1126 }
1127
1128 RefTuple out_;
1129};
1130
initial.commit09911bf2008-07-26 23:55:291131// Used for synchronous messages.
[email protected]75e5a872009-04-02 23:56:111132template <class SendParamType, class ReplyParamType>
initial.commit09911bf2008-07-26 23:55:291133class MessageWithReply : public SyncMessage {
1134 public:
[email protected]75e5a872009-04-02 23:56:111135 typedef SendParamType SendParam;
[email protected]7a4de7a62010-08-17 18:38:241136 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
[email protected]75e5a872009-04-02 23:56:111137 typedef ReplyParamType ReplyParam;
1138
[email protected]168ae922009-12-04 18:08:451139 MessageWithReply(int32 routing_id, uint32 type,
[email protected]7a4de7a62010-08-17 18:38:241140 const RefSendParam& send, const ReplyParam& reply);
1141 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
1142 static bool ReadReplyParam(
1143 const Message* msg,
1144 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:291145
[email protected]65412272010-12-21 20:03:241146 template<class T, class S, class Method>
1147 static bool Dispatch(const Message* msg, T* obj, S* sender, Method func) {
initial.commit09911bf2008-07-26 23:55:291148 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291149 Message* reply = GenerateReply(msg);
1150 bool error;
[email protected]7a4de7a62010-08-17 18:38:241151 if (ReadSendParam(msg, &send_params)) {
1152 typename TupleTypes<ReplyParam>::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:291153 DispatchToMethod(obj, func, send_params, &reply_params);
1154 WriteParam(reply, reply_params);
1155 error = false;
[email protected]7a4de7a62010-08-17 18:38:241156 LogReplyParamsToMessage(reply_params, msg);
initial.commit09911bf2008-07-26 23:55:291157 } else {
1158 NOTREACHED() << "Error deserializing message " << msg->type();
1159 reply->set_reply_error();
1160 error = true;
1161 }
1162
[email protected]65412272010-12-21 20:03:241163 sender->Send(reply);
initial.commit09911bf2008-07-26 23:55:291164 return !error;
1165 }
1166
1167 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191168 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291169 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291170 Message* reply = GenerateReply(msg);
1171 bool error;
[email protected]7a4de7a62010-08-17 18:38:241172 if (ReadSendParam(msg, &send_params)) {
initial.commit09911bf2008-07-26 23:55:291173 Tuple1<Message&> t = MakeRefTuple(*reply);
[email protected]7a4de7a62010-08-17 18:38:241174 ConnectMessageAndReply(msg, reply);
initial.commit09911bf2008-07-26 23:55:291175 DispatchToMethod(obj, func, send_params, &t);
1176 error = false;
1177 } else {
1178 NOTREACHED() << "Error deserializing message " << msg->type();
1179 reply->set_reply_error();
1180 obj->Send(reply);
1181 error = true;
1182 }
1183 return !error;
1184 }
1185
1186 template<typename TA>
1187 static void WriteReplyParams(Message* reply, TA a) {
1188 ReplyParam p(a);
1189 WriteParam(reply, p);
1190 }
1191
1192 template<typename TA, typename TB>
1193 static void WriteReplyParams(Message* reply, TA a, TB b) {
1194 ReplyParam p(a, b);
1195 WriteParam(reply, p);
1196 }
1197
1198 template<typename TA, typename TB, typename TC>
1199 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1200 ReplyParam p(a, b, c);
1201 WriteParam(reply, p);
1202 }
1203
1204 template<typename TA, typename TB, typename TC, typename TD>
1205 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1206 ReplyParam p(a, b, c, d);
1207 WriteParam(reply, p);
1208 }
1209
1210 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1211 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1212 ReplyParam p(a, b, c, d, e);
1213 WriteParam(reply, p);
1214 }
1215};
1216
[email protected]7d5c3ac2009-02-04 08:58:191217//-----------------------------------------------------------------------------
1218
[email protected]3178f4e22008-08-05 21:20:411219} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291220
[email protected]946d1b22009-07-22 23:57:211221#endif // IPC_IPC_MESSAGE_UTILS_H_