blob: c353e956ba2761d72bb81d627b8f2542f60d2815 [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]44c49c92011-03-28 16:17:2388 ExtensionMsgStart,
[email protected]e1a59a22011-04-12 01:36:2589 VideoCaptureMsgStart,
[email protected]10e5cf12011-04-13 04:10:4090 QuotaMsgStart,
[email protected]ae4efe42011-04-18 21:28:0591 IconMsgStart,
[email protected]e503a122011-03-17 18:20:5292 LastIPCMsgStart // Must come last.
[email protected]f91cb992009-02-04 20:10:1293};
94
[email protected]7a4de7a62010-08-17 18:38:2495class DictionaryValue;
96class FilePath;
97class ListValue;
98class NullableString16;
99
100namespace base {
101class Time;
[email protected]d84e48b2010-10-21 22:04:52102class TimeDelta;
[email protected]7a4de7a62010-08-17 18:38:24103struct FileDescriptor;
104}
105
initial.commit09911bf2008-07-26 23:55:29106namespace IPC {
107
[email protected]7a4de7a62010-08-17 18:38:24108struct ChannelHandle;
109
initial.commit09911bf2008-07-26 23:55:29110//-----------------------------------------------------------------------------
111// An iterator class for reading the fields contained within a Message.
112
113class MessageIterator {
114 public:
[email protected]e1981f432008-08-12 15:22:13115 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
initial.commit09911bf2008-07-26 23:55:29116 }
117 int NextInt() const {
[email protected]9422b7dc2009-12-30 20:09:02118 int val = -1;
initial.commit09911bf2008-07-26 23:55:29119 if (!msg_.ReadInt(&iter_, &val))
120 NOTREACHED();
121 return val;
122 }
initial.commit09911bf2008-07-26 23:55:29123 const std::string NextString() const {
124 std::string val;
125 if (!msg_.ReadString(&iter_, &val))
126 NOTREACHED();
127 return val;
128 }
129 const std::wstring NextWString() const {
130 std::wstring val;
131 if (!msg_.ReadWString(&iter_, &val))
132 NOTREACHED();
133 return val;
134 }
[email protected]225c8f52010-02-05 22:23:20135 void NextData(const char** data, int* length) const {
initial.commit09911bf2008-07-26 23:55:29136 if (!msg_.ReadData(&iter_, data, length)) {
137 NOTREACHED();
138 }
139 }
140 private:
141 const Message& msg_;
142 mutable void* iter_;
143};
144
145//-----------------------------------------------------------------------------
[email protected]6476c72c2011-02-11 18:46:19146// A dummy struct to place first just to allow leading commas for all
147// members in the macro-generated constructor initializer lists.
148struct NoParams {
149};
150
151//-----------------------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19152// ParamTraits specializations, etc.
153
[email protected]7d5c3ac2009-02-04 08:58:19154template <class P>
155static inline void WriteParam(Message* m, const P& p) {
[email protected]7b291f92009-08-14 05:43:53156 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53157 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
[email protected]7d5c3ac2009-02-04 08:58:19158}
159
160template <class P>
[email protected]1e86aa62009-04-24 21:22:33161static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
162 P* p) {
[email protected]7b291f92009-08-14 05:43:53163 typedef typename SimilarTypeTraits<P>::Type Type;
164 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
[email protected]7d5c3ac2009-02-04 08:58:19165}
166
167template <class P>
[email protected]252cad62010-08-18 18:33:57168static inline void LogParam(const P& p, std::string* l) {
[email protected]7b291f92009-08-14 05:43:53169 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53170 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19171}
172
173template <>
174struct ParamTraits<bool> {
175 typedef bool param_type;
176 static void Write(Message* m, const param_type& p) {
177 m->WriteBool(p);
178 }
179 static bool Read(const Message* m, void** iter, param_type* r) {
180 return m->ReadBool(iter, r);
181 }
[email protected]252cad62010-08-18 18:33:57182 static void Log(const param_type& p, std::string* l) {
183 l->append(p ? "true" : "false");
[email protected]7d5c3ac2009-02-04 08:58:19184 }
185};
186
187template <>
188struct ParamTraits<int> {
189 typedef int param_type;
190 static void Write(Message* m, const param_type& p) {
191 m->WriteInt(p);
192 }
193 static bool Read(const Message* m, void** iter, param_type* r) {
194 return m->ReadInt(iter, r);
195 }
[email protected]252cad62010-08-18 18:33:57196 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19197};
198
199template <>
[email protected]63263f92009-07-28 19:35:08200struct ParamTraits<unsigned int> {
201 typedef unsigned int param_type;
202 static void Write(Message* m, const param_type& p) {
203 m->WriteInt(p);
204 }
205 static bool Read(const Message* m, void** iter, param_type* r) {
206 return m->ReadInt(iter, reinterpret_cast<int*>(r));
207 }
[email protected]252cad62010-08-18 18:33:57208 static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08209};
210
211template <>
[email protected]7d5c3ac2009-02-04 08:58:19212struct ParamTraits<long> {
213 typedef long param_type;
214 static void Write(Message* m, const param_type& p) {
215 m->WriteLong(p);
216 }
217 static bool Read(const Message* m, void** iter, param_type* r) {
218 return m->ReadLong(iter, r);
219 }
[email protected]252cad62010-08-18 18:33:57220 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19221};
222
[email protected]140c3032009-06-26 18:22:54223template <>
224struct ParamTraits<unsigned long> {
225 typedef unsigned long param_type;
226 static void Write(Message* m, const param_type& p) {
227 m->WriteLong(p);
228 }
229 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]63263f92009-07-28 19:35:08230 return m->ReadLong(iter, reinterpret_cast<long*>(r));
[email protected]140c3032009-06-26 18:22:54231 }
[email protected]252cad62010-08-18 18:33:57232 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19233};
234
235template <>
[email protected]63263f92009-07-28 19:35:08236struct ParamTraits<long long> {
237 typedef long long param_type;
[email protected]7d5c3ac2009-02-04 08:58:19238 static void Write(Message* m, const param_type& p) {
239 m->WriteInt64(static_cast<int64>(p));
240 }
241 static bool Read(const Message* m, void** iter, param_type* r) {
242 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
243 }
[email protected]252cad62010-08-18 18:33:57244 static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08245};
246
247template <>
248struct ParamTraits<unsigned long long> {
249 typedef unsigned long long param_type;
250 static void Write(Message* m, const param_type& p) {
251 m->WriteInt64(p);
252 }
253 static bool Read(const Message* m, void** iter, param_type* r) {
254 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
255 }
[email protected]252cad62010-08-18 18:33:57256 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19257};
258
[email protected]43a40202010-11-12 16:25:01259template <>
260struct ParamTraits<unsigned short> {
261 typedef unsigned short param_type;
262 static void Write(Message* m, const param_type& p);
263 static bool Read(const Message* m, void** iter, param_type* r);
264 static void Log(const param_type& p, std::string* l);
265};
266
[email protected]20199662010-06-17 03:29:26267// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
268// should be sure to check the sanity of these values after receiving them over
269// IPC.
270template <>
271struct ParamTraits<float> {
272 typedef float param_type;
273 static void Write(Message* m, const param_type& p) {
274 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
275 }
276 static bool Read(const Message* m, void** iter, param_type* r) {
277 const char *data;
278 int data_size;
279 if (!m->ReadData(iter, &data, &data_size) ||
280 data_size != sizeof(param_type)) {
281 NOTREACHED();
282 return false;
283 }
284 memcpy(r, data, sizeof(param_type));
285 return true;
286 }
[email protected]252cad62010-08-18 18:33:57287 static void Log(const param_type& p, std::string* l) {
288 l->append(StringPrintf("%e", p));
[email protected]20199662010-06-17 03:29:26289 }
290};
291
[email protected]7d5c3ac2009-02-04 08:58:19292template <>
293struct ParamTraits<double> {
294 typedef double param_type;
295 static void Write(Message* m, const param_type& p) {
296 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
297 }
298 static bool Read(const Message* m, void** iter, param_type* r) {
299 const char *data;
[email protected]20199662010-06-17 03:29:26300 int data_size;
301 if (!m->ReadData(iter, &data, &data_size) ||
302 data_size != sizeof(param_type)) {
[email protected]7d5c3ac2009-02-04 08:58:19303 NOTREACHED();
[email protected]20199662010-06-17 03:29:26304 return false;
[email protected]7d5c3ac2009-02-04 08:58:19305 }
[email protected]20199662010-06-17 03:29:26306 memcpy(r, data, sizeof(param_type));
307 return true;
[email protected]7d5c3ac2009-02-04 08:58:19308 }
[email protected]252cad62010-08-18 18:33:57309 static void Log(const param_type& p, std::string* l) {
310 l->append(StringPrintf("%e", p));
[email protected]7d5c3ac2009-02-04 08:58:19311 }
312};
313
314template <>
[email protected]7d5c3ac2009-02-04 08:58:19315struct ParamTraits<base::Time> {
316 typedef base::Time param_type;
[email protected]7a4de7a62010-08-17 18:38:24317 static void Write(Message* m, const param_type& p);
318 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57319 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19320};
321
[email protected]d84e48b2010-10-21 22:04:52322template <>
323struct ParamTraits<base::TimeDelta> {
324 typedef base::TimeDelta param_type;
325 static void Write(Message* m, const param_type& p);
326 static bool Read(const Message* m, void** iter, param_type* r);
327 static void Log(const param_type& p, std::string* l);
328};
329
[email protected]7d5c3ac2009-02-04 08:58:19330#if defined(OS_WIN)
331template <>
332struct ParamTraits<LOGFONT> {
333 typedef LOGFONT param_type;
334 static void Write(Message* m, const param_type& p) {
335 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
336 }
337 static bool Read(const Message* m, void** iter, param_type* r) {
338 const char *data;
339 int data_size = 0;
340 bool result = m->ReadData(iter, &data, &data_size);
341 if (result && data_size == sizeof(LOGFONT)) {
342 memcpy(r, data, sizeof(LOGFONT));
343 } else {
344 result = false;
345 NOTREACHED();
346 }
347
348 return result;
349 }
[email protected]252cad62010-08-18 18:33:57350 static void Log(const param_type& p, std::string* l) {
351 l->append(StringPrintf("<LOGFONT>"));
[email protected]7d5c3ac2009-02-04 08:58:19352 }
353};
354
355template <>
356struct ParamTraits<MSG> {
357 typedef MSG param_type;
358 static void Write(Message* m, const param_type& p) {
359 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
360 }
361 static bool Read(const Message* m, void** iter, param_type* r) {
362 const char *data;
363 int data_size = 0;
364 bool result = m->ReadData(iter, &data, &data_size);
365 if (result && data_size == sizeof(MSG)) {
366 memcpy(r, data, sizeof(MSG));
367 } else {
368 result = false;
369 NOTREACHED();
370 }
371
372 return result;
373 }
[email protected]252cad62010-08-18 18:33:57374 static void Log(const param_type& p, std::string* l) {
375 l->append("<MSG>");
[email protected]7a4de7a62010-08-17 18:38:24376 }
[email protected]7d5c3ac2009-02-04 08:58:19377};
378#endif // defined(OS_WIN)
379
380template <>
[email protected]584f2b22009-05-21 01:01:59381struct ParamTraits<DictionaryValue> {
382 typedef DictionaryValue param_type;
383 static void Write(Message* m, const param_type& p);
384 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57385 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59386};
387
388template <>
389struct ParamTraits<ListValue> {
390 typedef ListValue param_type;
391 static void Write(Message* m, const param_type& p);
392 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57393 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59394};
395
396template <>
[email protected]7d5c3ac2009-02-04 08:58:19397struct ParamTraits<std::string> {
398 typedef std::string param_type;
399 static void Write(Message* m, const param_type& p) {
400 m->WriteString(p);
401 }
402 static bool Read(const Message* m, void** iter, param_type* r) {
403 return m->ReadString(iter, r);
404 }
[email protected]252cad62010-08-18 18:33:57405 static void Log(const param_type& p, std::string* l) {
406 l->append(p);
[email protected]7d5c3ac2009-02-04 08:58:19407 }
408};
409
[email protected]3dd7a7a2009-07-27 21:09:07410template<typename CharType>
[email protected]252cad62010-08-18 18:33:57411static void LogBytes(const std::vector<CharType>& data, std::string* out) {
[email protected]3dd7a7a2009-07-27 21:09:07412#if defined(OS_WIN)
413 // Windows has a GUI for logging, which can handle arbitrary binary data.
414 for (size_t i = 0; i < data.size(); ++i)
415 out->push_back(data[i]);
416#else
417 // On POSIX, we log to stdout, which we assume can display ASCII.
418 static const size_t kMaxBytesToLog = 100;
419 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
420 if (isprint(data[i]))
421 out->push_back(data[i]);
422 else
[email protected]252cad62010-08-18 18:33:57423 out->append(StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
[email protected]3dd7a7a2009-07-27 21:09:07424 }
425 if (data.size() > kMaxBytesToLog) {
426 out->append(
[email protected]252cad62010-08-18 18:33:57427 StringPrintf(" and %u more bytes",
[email protected]3dd7a7a2009-07-27 21:09:07428 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
429 }
430#endif
431}
432
[email protected]7d5c3ac2009-02-04 08:58:19433template <>
434struct ParamTraits<std::vector<unsigned char> > {
435 typedef std::vector<unsigned char> param_type;
436 static void Write(Message* m, const param_type& p) {
[email protected]f6b8ce32011-03-02 00:03:18437 if (p.empty()) {
[email protected]7d5c3ac2009-02-04 08:58:19438 m->WriteData(NULL, 0);
439 } else {
440 m->WriteData(reinterpret_cast<const char*>(&p.front()),
441 static_cast<int>(p.size()));
442 }
443 }
444 static bool Read(const Message* m, void** iter, param_type* r) {
445 const char *data;
446 int data_size = 0;
447 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
448 return false;
449 r->resize(data_size);
450 if (data_size)
451 memcpy(&r->front(), data, data_size);
452 return true;
453 }
[email protected]252cad62010-08-18 18:33:57454 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07455 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19456 }
457};
458
459template <>
460struct ParamTraits<std::vector<char> > {
461 typedef std::vector<char> param_type;
462 static void Write(Message* m, const param_type& p) {
[email protected]f6b8ce32011-03-02 00:03:18463 if (p.empty()) {
[email protected]7d5c3ac2009-02-04 08:58:19464 m->WriteData(NULL, 0);
465 } else {
466 m->WriteData(&p.front(), static_cast<int>(p.size()));
467 }
468 }
469 static bool Read(const Message* m, void** iter, param_type* r) {
470 const char *data;
471 int data_size = 0;
472 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
473 return false;
474 r->resize(data_size);
475 if (data_size)
476 memcpy(&r->front(), data, data_size);
477 return true;
478 }
[email protected]252cad62010-08-18 18:33:57479 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07480 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19481 }
482};
483
484template <class P>
485struct ParamTraits<std::vector<P> > {
486 typedef std::vector<P> param_type;
487 static void Write(Message* m, const param_type& p) {
488 WriteParam(m, static_cast<int>(p.size()));
489 for (size_t i = 0; i < p.size(); i++)
490 WriteParam(m, p[i]);
491 }
492 static bool Read(const Message* m, void** iter, param_type* r) {
493 int size;
[email protected]86440f52009-12-31 05:17:23494 // ReadLength() checks for < 0 itself.
[email protected]7d5c3ac2009-02-04 08:58:19495 if (!m->ReadLength(iter, &size))
496 return false;
497 // Resizing beforehand is not safe, see BUG 1006367 for details.
[email protected]86440f52009-12-31 05:17:23498 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
499 return false;
500 r->resize(size);
501 for (int i = 0; i < size; i++) {
502 if (!ReadParam(m, iter, &(*r)[i]))
503 return false;
[email protected]7d5c3ac2009-02-04 08:58:19504 }
505 return true;
506 }
[email protected]252cad62010-08-18 18:33:57507 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19508 for (size_t i = 0; i < p.size(); ++i) {
509 if (i != 0)
[email protected]252cad62010-08-18 18:33:57510 l->append(" ");
[email protected]7d5c3ac2009-02-04 08:58:19511 LogParam((p[i]), l);
512 }
513 }
514};
515
[email protected]96da6962010-05-13 19:10:34516template <class P>
517struct ParamTraits<std::set<P> > {
518 typedef std::set<P> param_type;
519 static void Write(Message* m, const param_type& p) {
520 WriteParam(m, static_cast<int>(p.size()));
521 typename param_type::const_iterator iter;
522 for (iter = p.begin(); iter != p.end(); ++iter)
523 WriteParam(m, *iter);
524 }
525 static bool Read(const Message* m, void** iter, param_type* r) {
526 int size;
527 if (!m->ReadLength(iter, &size))
528 return false;
529 for (int i = 0; i < size; ++i) {
530 P item;
531 if (!ReadParam(m, iter, &item))
532 return false;
533 r->insert(item);
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::set>");
[email protected]96da6962010-05-13 19:10:34539 }
540};
541
542
[email protected]7d5c3ac2009-02-04 08:58:19543template <class K, class V>
544struct ParamTraits<std::map<K, V> > {
545 typedef std::map<K, V> param_type;
546 static void Write(Message* m, const param_type& p) {
547 WriteParam(m, static_cast<int>(p.size()));
548 typename param_type::const_iterator iter;
549 for (iter = p.begin(); iter != p.end(); ++iter) {
550 WriteParam(m, iter->first);
551 WriteParam(m, iter->second);
552 }
553 }
554 static bool Read(const Message* m, void** iter, param_type* r) {
555 int size;
556 if (!ReadParam(m, iter, &size) || size < 0)
557 return false;
558 for (int i = 0; i < size; ++i) {
559 K k;
560 if (!ReadParam(m, iter, &k))
561 return false;
562 V& value = (*r)[k];
563 if (!ReadParam(m, iter, &value))
564 return false;
565 }
566 return true;
567 }
[email protected]252cad62010-08-18 18:33:57568 static void Log(const param_type& p, std::string* l) {
569 l->append("<std::map>");
[email protected]7d5c3ac2009-02-04 08:58:19570 }
571};
572
[email protected]eb47a132009-03-04 00:39:56573
[email protected]7d5c3ac2009-02-04 08:58:19574template <>
575struct ParamTraits<std::wstring> {
576 typedef std::wstring param_type;
577 static void Write(Message* m, const param_type& p) {
578 m->WriteWString(p);
579 }
580 static bool Read(const Message* m, void** iter, param_type* r) {
581 return m->ReadWString(iter, r);
582 }
[email protected]252cad62010-08-18 18:33:57583 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19584};
585
[email protected]a5da6d612009-08-04 02:00:56586template <class A, class B>
587struct ParamTraits<std::pair<A, B> > {
588 typedef std::pair<A, B> param_type;
589 static void Write(Message* m, const param_type& p) {
590 WriteParam(m, p.first);
591 WriteParam(m, p.second);
592 }
593 static bool Read(const Message* m, void** iter, param_type* r) {
594 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
595 }
[email protected]252cad62010-08-18 18:33:57596 static void Log(const param_type& p, std::string* l) {
597 l->append("(");
[email protected]a5da6d612009-08-04 02:00:56598 LogParam(p.first, l);
[email protected]252cad62010-08-18 18:33:57599 l->append(", ");
[email protected]a5da6d612009-08-04 02:00:56600 LogParam(p.second, l);
[email protected]252cad62010-08-18 18:33:57601 l->append(")");
[email protected]a5da6d612009-08-04 02:00:56602 }
603};
604
[email protected]15bf8712009-08-27 00:55:02605template <>
606struct ParamTraits<NullableString16> {
607 typedef NullableString16 param_type;
[email protected]7a4de7a62010-08-17 18:38:24608 static void Write(Message* m, const param_type& p);
609 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57610 static void Log(const param_type& p, std::string* l);
[email protected]15bf8712009-08-27 00:55:02611};
612
[email protected]eb47a132009-03-04 00:39:56613// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
614// need this trait.
615#if !defined(WCHAR_T_IS_UTF16)
[email protected]eb47a132009-03-04 00:39:56616template <>
617struct ParamTraits<string16> {
618 typedef string16 param_type;
619 static void Write(Message* m, const param_type& p) {
[email protected]3a2a5d22009-03-04 03:36:36620 m->WriteString16(p);
[email protected]eb47a132009-03-04 00:39:56621 }
622 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]3a2a5d22009-03-04 03:36:36623 return m->ReadString16(iter, r);
[email protected]eb47a132009-03-04 00:39:56624 }
[email protected]252cad62010-08-18 18:33:57625 static void Log(const param_type& p, std::string* l);
[email protected]eb47a132009-03-04 00:39:56626};
[email protected]eb47a132009-03-04 00:39:56627#endif
628
[email protected]7d5c3ac2009-02-04 08:58:19629// and, a few more useful types...
630#if defined(OS_WIN)
631template <>
632struct ParamTraits<HANDLE> {
633 typedef HANDLE param_type;
634 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35635 // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
636 // bit systems.
637 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19638 }
639 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35640 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
641 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19642 }
[email protected]252cad62010-08-18 18:33:57643 static void Log(const param_type& p, std::string* l) {
644 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19645 }
646};
647
648template <>
649struct ParamTraits<HCURSOR> {
650 typedef HCURSOR param_type;
651 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35652 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19653 }
654 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35655 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
656 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19657 }
[email protected]252cad62010-08-18 18:33:57658 static void Log(const param_type& p, std::string* l) {
659 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19660 }
661};
662
663template <>
[email protected]7d5c3ac2009-02-04 08:58:19664struct ParamTraits<HACCEL> {
665 typedef HACCEL param_type;
666 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35667 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19668 }
669 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35670 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
671 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19672 }
673};
674
675template <>
676struct ParamTraits<POINT> {
677 typedef POINT param_type;
678 static void Write(Message* m, const param_type& p) {
679 m->WriteInt(p.x);
680 m->WriteInt(p.y);
681 }
682 static bool Read(const Message* m, void** iter, param_type* r) {
683 int x, y;
684 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
685 return false;
686 r->x = x;
687 r->y = y;
688 return true;
689 }
[email protected]252cad62010-08-18 18:33:57690 static void Log(const param_type& p, std::string* l) {
691 l->append(StringPrintf("(%d, %d)", p.x, p.y));
[email protected]7d5c3ac2009-02-04 08:58:19692 }
693};
694#endif // defined(OS_WIN)
695
696template <>
697struct ParamTraits<FilePath> {
698 typedef FilePath param_type;
[email protected]7a4de7a62010-08-17 18:38:24699 static void Write(Message* m, const param_type& p);
700 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57701 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19702};
703
[email protected]526776c2009-02-07 00:39:26704#if defined(OS_POSIX)
[email protected]2749885f2009-03-05 21:40:11705// FileDescriptors may be serialised over IPC channels on POSIX. On the
706// receiving side, the FileDescriptor is a valid duplicate of the file
707// descriptor which was transmitted: *it is not just a copy of the integer like
708// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
709// this case, the receiving end will see a value of -1. *Zero is a valid file
710// descriptor*.
711//
712// The received file descriptor will have the |auto_close| flag set to true. The
713// code which handles the message is responsible for taking ownership of it.
714// File descriptors are OS resources and must be closed when no longer needed.
715//
716// When sending a file descriptor, the file descriptor must be valid at the time
717// of transmission. Since transmission is not synchronous, one should consider
718// dup()ing any file descriptors to be transmitted and setting the |auto_close|
719// flag, which causes the file descriptor to be closed after writing.
[email protected]526776c2009-02-07 00:39:26720template<>
[email protected]5fe733de2009-02-11 18:59:20721struct ParamTraits<base::FileDescriptor> {
722 typedef base::FileDescriptor param_type;
[email protected]7a4de7a62010-08-17 18:38:24723 static void Write(Message* m, const param_type& p);
724 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57725 static void Log(const param_type& p, std::string* l);
[email protected]526776c2009-02-07 00:39:26726};
[email protected]379e7a52010-03-09 00:38:41727#endif // defined(OS_POSIX)
[email protected]526776c2009-02-07 00:39:26728
[email protected]d2e884d2009-06-22 20:37:52729// A ChannelHandle is basically a platform-inspecific wrapper around the
730// fact that IPC endpoints are handled specially on POSIX. See above comments
731// on FileDescriptor for more background.
732template<>
733struct ParamTraits<IPC::ChannelHandle> {
734 typedef ChannelHandle param_type;
[email protected]7a4de7a62010-08-17 18:38:24735 static void Write(Message* m, const param_type& p);
736 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57737 static void Log(const param_type& p, std::string* l);
[email protected]d2e884d2009-06-22 20:37:52738};
739
[email protected]7d5c3ac2009-02-04 08:58:19740#if defined(OS_WIN)
741template <>
742struct ParamTraits<XFORM> {
743 typedef XFORM param_type;
744 static void Write(Message* m, const param_type& p) {
745 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
746 }
747 static bool Read(const Message* m, void** iter, param_type* r) {
748 const char *data;
749 int data_size = 0;
750 bool result = m->ReadData(iter, &data, &data_size);
751 if (result && data_size == sizeof(XFORM)) {
752 memcpy(r, data, sizeof(XFORM));
753 } else {
754 result = false;
755 NOTREACHED();
756 }
757
758 return result;
759 }
[email protected]252cad62010-08-18 18:33:57760 static void Log(const param_type& p, std::string* l) {
761 l->append("<XFORM>");
[email protected]7d5c3ac2009-02-04 08:58:19762 }
763};
764#endif // defined(OS_WIN)
765
[email protected]7d5c3ac2009-02-04 08:58:19766struct LogData {
[email protected]20f0487a2010-09-30 20:06:30767 LogData();
768 ~LogData();
769
[email protected]9a3a293b2009-06-04 22:28:16770 std::string channel;
[email protected]8bef70e2009-04-14 19:11:24771 int32 routing_id;
[email protected]168ae922009-12-04 18:08:45772 uint32 type; // "User-defined" message type, from ipc_message.h.
[email protected]252cad62010-08-18 18:33:57773 std::string flags;
[email protected]7d5c3ac2009-02-04 08:58:19774 int64 sent; // Time that the message was sent (i.e. at Send()).
775 int64 receive; // Time before it was dispatched (i.e. before calling
776 // OnMessageReceived).
777 int64 dispatch; // Time after it was dispatched (i.e. after calling
778 // OnMessageReceived).
[email protected]252cad62010-08-18 18:33:57779 std::string message_name;
780 std::string params;
[email protected]7d5c3ac2009-02-04 08:58:19781};
782
783template <>
784struct ParamTraits<LogData> {
785 typedef LogData param_type;
[email protected]20f0487a2010-09-30 20:06:30786 static void Write(Message* m, const param_type& p);
787 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57788 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19789 // Doesn't make sense to implement this!
790 }
791};
792
[email protected]eb47a132009-03-04 00:39:56793template <>
[email protected]503683f2009-02-26 09:13:01794struct ParamTraits<Message> {
795 static void Write(Message* m, const Message& p) {
[email protected]8a861402011-01-28 19:59:11796 DCHECK(p.size() <= INT_MAX);
797 int message_size = static_cast<int>(p.size());
798 m->WriteInt(message_size);
799 m->WriteData(reinterpret_cast<const char*>(p.data()), message_size);
[email protected]503683f2009-02-26 09:13:01800 }
801 static bool Read(const Message* m, void** iter, Message* r) {
802 int size;
803 if (!m->ReadInt(iter, &size))
804 return false;
805 const char* data;
806 if (!m->ReadData(iter, &data, &size))
807 return false;
808 *r = Message(data, size);
809 return true;
810 }
[email protected]252cad62010-08-18 18:33:57811 static void Log(const Message& p, std::string* l) {
812 l->append("<IPC::Message>");
[email protected]503683f2009-02-26 09:13:01813 }
814};
815
816template <>
[email protected]7d5c3ac2009-02-04 08:58:19817struct ParamTraits<Tuple0> {
818 typedef Tuple0 param_type;
819 static void Write(Message* m, const param_type& p) {
820 }
821 static bool Read(const Message* m, void** iter, param_type* r) {
822 return true;
823 }
[email protected]252cad62010-08-18 18:33:57824 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19825 }
826};
827
828template <class A>
829struct ParamTraits< Tuple1<A> > {
830 typedef Tuple1<A> param_type;
831 static void Write(Message* m, const param_type& p) {
832 WriteParam(m, p.a);
833 }
834 static bool Read(const Message* m, void** iter, param_type* r) {
835 return ReadParam(m, iter, &r->a);
836 }
[email protected]252cad62010-08-18 18:33:57837 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19838 LogParam(p.a, l);
839 }
840};
841
842template <class A, class B>
843struct ParamTraits< Tuple2<A, B> > {
844 typedef Tuple2<A, B> param_type;
845 static void Write(Message* m, const param_type& p) {
846 WriteParam(m, p.a);
847 WriteParam(m, p.b);
848 }
849 static bool Read(const Message* m, void** iter, param_type* r) {
850 return (ReadParam(m, iter, &r->a) &&
851 ReadParam(m, iter, &r->b));
852 }
[email protected]252cad62010-08-18 18:33:57853 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19854 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57855 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19856 LogParam(p.b, l);
857 }
858};
859
860template <class A, class B, class C>
861struct ParamTraits< Tuple3<A, B, C> > {
862 typedef Tuple3<A, B, C> param_type;
863 static void Write(Message* m, const param_type& p) {
864 WriteParam(m, p.a);
865 WriteParam(m, p.b);
866 WriteParam(m, p.c);
867 }
868 static bool Read(const Message* m, void** iter, param_type* r) {
869 return (ReadParam(m, iter, &r->a) &&
870 ReadParam(m, iter, &r->b) &&
871 ReadParam(m, iter, &r->c));
872 }
[email protected]252cad62010-08-18 18:33:57873 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19874 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57875 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19876 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57877 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19878 LogParam(p.c, l);
879 }
880};
881
882template <class A, class B, class C, class D>
883struct ParamTraits< Tuple4<A, B, C, D> > {
884 typedef Tuple4<A, B, C, D> param_type;
885 static void Write(Message* m, const param_type& p) {
886 WriteParam(m, p.a);
887 WriteParam(m, p.b);
888 WriteParam(m, p.c);
889 WriteParam(m, p.d);
890 }
891 static bool Read(const Message* m, void** iter, param_type* r) {
892 return (ReadParam(m, iter, &r->a) &&
893 ReadParam(m, iter, &r->b) &&
894 ReadParam(m, iter, &r->c) &&
895 ReadParam(m, iter, &r->d));
896 }
[email protected]252cad62010-08-18 18:33:57897 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19898 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57899 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19900 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57901 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19902 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57903 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19904 LogParam(p.d, l);
905 }
906};
907
908template <class A, class B, class C, class D, class E>
909struct ParamTraits< Tuple5<A, B, C, D, E> > {
910 typedef Tuple5<A, B, C, D, E> param_type;
911 static void Write(Message* m, const param_type& p) {
912 WriteParam(m, p.a);
913 WriteParam(m, p.b);
914 WriteParam(m, p.c);
915 WriteParam(m, p.d);
916 WriteParam(m, p.e);
917 }
918 static bool Read(const Message* m, void** iter, param_type* r) {
919 return (ReadParam(m, iter, &r->a) &&
920 ReadParam(m, iter, &r->b) &&
921 ReadParam(m, iter, &r->c) &&
922 ReadParam(m, iter, &r->d) &&
923 ReadParam(m, iter, &r->e));
924 }
[email protected]252cad62010-08-18 18:33:57925 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19926 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57927 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19928 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57929 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19930 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57931 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19932 LogParam(p.d, l);
[email protected]252cad62010-08-18 18:33:57933 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19934 LogParam(p.e, l);
935 }
936};
937
[email protected]7d5c3ac2009-02-04 08:58:19938//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:29939// Generic message subclasses
940
941// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:24942template <class ParamType>
initial.commit09911bf2008-07-26 23:55:29943class MessageWithTuple : public Message {
944 public:
[email protected]81a34412009-01-05 19:17:24945 typedef ParamType Param;
[email protected]7a4de7a62010-08-17 18:38:24946 typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
[email protected]81a34412009-01-05 19:17:24947
[email protected]7a4de7a62010-08-17 18:38:24948 // The constructor and the Read() method's templated implementations are in
949 // ipc_message_utils_impl.h. The subclass constructor and Log() methods call
950 // the templated versions of these and make sure there are instantiations in
951 // those translation units.
952 MessageWithTuple(int32 routing_id, uint32 type, const RefParam& p);
[email protected]071b4b92010-08-09 16:06:58953
[email protected]7a4de7a62010-08-17 18:38:24954 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:29955
956 // Generic dispatcher. Should cover most cases.
[email protected]65412272010-12-21 20:03:24957 template<class T, class S, class Method>
958 static bool Dispatch(const Message* msg, T* obj, S* sender, Method func) {
initial.commit09911bf2008-07-26 23:55:29959 Param p;
960 if (Read(msg, &p)) {
961 DispatchToMethod(obj, func, p);
962 return true;
963 }
964 return false;
965 }
966
967 // The following dispatchers exist for the case where the callback function
968 // needs the message as well. They assume that "Param" is a type of Tuple
969 // (except the one arg case, as there is no Tuple1).
[email protected]65412272010-12-21 20:03:24970 template<class T, class S, typename TA>
971 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29972 void (T::*func)(const Message&, TA)) {
973 Param p;
974 if (Read(msg, &p)) {
[email protected]c2fe31542009-05-20 18:24:14975 (obj->*func)(*msg, p.a);
initial.commit09911bf2008-07-26 23:55:29976 return true;
977 }
978 return false;
979 }
980
[email protected]65412272010-12-21 20:03:24981 template<class T, class S, typename TA, typename TB>
982 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29983 void (T::*func)(const Message&, TA, TB)) {
984 Param p;
985 if (Read(msg, &p)) {
986 (obj->*func)(*msg, p.a, p.b);
987 return true;
988 }
989 return false;
990 }
991
[email protected]65412272010-12-21 20:03:24992 template<class T, class S, typename TA, typename TB, typename TC>
993 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29994 void (T::*func)(const Message&, TA, TB, TC)) {
995 Param p;
996 if (Read(msg, &p)) {
997 (obj->*func)(*msg, p.a, p.b, p.c);
998 return true;
999 }
1000 return false;
1001 }
1002
[email protected]65412272010-12-21 20:03:241003 template<class T, class S, typename TA, typename TB, typename TC, typename TD>
1004 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:291005 void (T::*func)(const Message&, TA, TB, TC, TD)) {
1006 Param p;
1007 if (Read(msg, &p)) {
1008 (obj->*func)(*msg, p.a, p.b, p.c, p.d);
1009 return true;
1010 }
1011 return false;
1012 }
1013
[email protected]65412272010-12-21 20:03:241014 template<class T, class S, typename TA, typename TB, typename TC, typename TD,
initial.commit09911bf2008-07-26 23:55:291015 typename TE>
[email protected]65412272010-12-21 20:03:241016 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:291017 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
1018 Param p;
1019 if (Read(msg, &p)) {
1020 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
1021 return true;
1022 }
1023 return false;
1024 }
1025
[email protected]deb57402009-02-06 01:35:301026 // Functions used to do manual unpacking. Only used by the automation code,
1027 // these should go away once that code uses SyncChannel.
1028 template<typename TA, typename TB>
1029 static bool Read(const IPC::Message* msg, TA* a, TB* b) {
1030 ParamType params;
1031 if (!Read(msg, &params))
1032 return false;
1033 *a = params.a;
1034 *b = params.b;
1035 return true;
1036 }
1037
1038 template<typename TA, typename TB, typename TC>
1039 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
1040 ParamType params;
1041 if (!Read(msg, &params))
1042 return false;
1043 *a = params.a;
1044 *b = params.b;
1045 *c = params.c;
1046 return true;
1047 }
1048
1049 template<typename TA, typename TB, typename TC, typename TD>
1050 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) {
1051 ParamType params;
1052 if (!Read(msg, &params))
1053 return false;
1054 *a = params.a;
1055 *b = params.b;
1056 *c = params.c;
1057 *d = params.d;
1058 return true;
1059 }
1060
1061 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1062 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) {
1063 ParamType params;
1064 if (!Read(msg, &params))
1065 return false;
1066 *a = params.a;
1067 *b = params.b;
1068 *c = params.c;
1069 *d = params.d;
1070 *e = params.e;
1071 return true;
1072 }
initial.commit09911bf2008-07-26 23:55:291073};
1074
[email protected]7a4de7a62010-08-17 18:38:241075// defined in ipc_logging.cc
1076void GenerateLogData(const std::string& channel, const Message& message,
1077 LogData* data);
1078
1079
1080#if defined(IPC_MESSAGE_LOG_ENABLED)
[email protected]252cad62010-08-18 18:33:571081inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
1082 const std::string& output_params = msg->output_params();
[email protected]7a4de7a62010-08-17 18:38:241083 if (!l->empty() && !output_params.empty())
[email protected]252cad62010-08-18 18:33:571084 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:241085
1086 l->append(output_params);
1087}
1088
1089template <class ReplyParamType>
1090inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1091 const Message* msg) {
1092 if (msg->received_time() != 0) {
[email protected]252cad62010-08-18 18:33:571093 std::string output_params;
[email protected]7a4de7a62010-08-17 18:38:241094 LogParam(reply_params, &output_params);
1095 msg->set_output_params(output_params);
1096 }
1097}
1098
1099inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
1100 if (msg->sent_time()) {
1101 // Don't log the sync message after dispatch, as we don't have the
1102 // output parameters at that point. Instead, save its data and log it
1103 // with the outgoing reply message when it's sent.
1104 LogData* data = new LogData;
1105 GenerateLogData("", *msg, data);
1106 msg->set_dont_log();
1107 reply->set_sync_log_data(data);
1108 }
1109}
1110#else
[email protected]252cad62010-08-18 18:33:571111inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
[email protected]7a4de7a62010-08-17 18:38:241112
1113template <class ReplyParamType>
1114inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1115 const Message* msg) {}
1116
1117inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1118#endif
1119
initial.commit09911bf2008-07-26 23:55:291120// This class assumes that its template argument is a RefTuple (a Tuple with
[email protected]7a4de7a62010-08-17 18:38:241121// reference elements). This would go into ipc_message_utils_impl.h, but it is
1122// also used by chrome_frame.
initial.commit09911bf2008-07-26 23:55:291123template <class RefTuple>
1124class ParamDeserializer : public MessageReplyDeserializer {
1125 public:
[email protected]e1981f432008-08-12 15:22:131126 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:291127
1128 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1129 return ReadParam(&msg, &iter, &out_);
1130 }
1131
1132 RefTuple out_;
1133};
1134
initial.commit09911bf2008-07-26 23:55:291135// Used for synchronous messages.
[email protected]75e5a872009-04-02 23:56:111136template <class SendParamType, class ReplyParamType>
initial.commit09911bf2008-07-26 23:55:291137class MessageWithReply : public SyncMessage {
1138 public:
[email protected]75e5a872009-04-02 23:56:111139 typedef SendParamType SendParam;
[email protected]7a4de7a62010-08-17 18:38:241140 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
[email protected]75e5a872009-04-02 23:56:111141 typedef ReplyParamType ReplyParam;
1142
[email protected]168ae922009-12-04 18:08:451143 MessageWithReply(int32 routing_id, uint32 type,
[email protected]7a4de7a62010-08-17 18:38:241144 const RefSendParam& send, const ReplyParam& reply);
1145 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
1146 static bool ReadReplyParam(
1147 const Message* msg,
1148 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:291149
[email protected]65412272010-12-21 20:03:241150 template<class T, class S, class Method>
1151 static bool Dispatch(const Message* msg, T* obj, S* sender, Method func) {
initial.commit09911bf2008-07-26 23:55:291152 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291153 Message* reply = GenerateReply(msg);
1154 bool error;
[email protected]7a4de7a62010-08-17 18:38:241155 if (ReadSendParam(msg, &send_params)) {
1156 typename TupleTypes<ReplyParam>::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:291157 DispatchToMethod(obj, func, send_params, &reply_params);
1158 WriteParam(reply, reply_params);
1159 error = false;
[email protected]7a4de7a62010-08-17 18:38:241160 LogReplyParamsToMessage(reply_params, msg);
initial.commit09911bf2008-07-26 23:55:291161 } else {
1162 NOTREACHED() << "Error deserializing message " << msg->type();
1163 reply->set_reply_error();
1164 error = true;
1165 }
1166
[email protected]65412272010-12-21 20:03:241167 sender->Send(reply);
initial.commit09911bf2008-07-26 23:55:291168 return !error;
1169 }
1170
1171 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191172 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291173 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291174 Message* reply = GenerateReply(msg);
1175 bool error;
[email protected]7a4de7a62010-08-17 18:38:241176 if (ReadSendParam(msg, &send_params)) {
initial.commit09911bf2008-07-26 23:55:291177 Tuple1<Message&> t = MakeRefTuple(*reply);
[email protected]7a4de7a62010-08-17 18:38:241178 ConnectMessageAndReply(msg, reply);
initial.commit09911bf2008-07-26 23:55:291179 DispatchToMethod(obj, func, send_params, &t);
1180 error = false;
1181 } else {
1182 NOTREACHED() << "Error deserializing message " << msg->type();
1183 reply->set_reply_error();
1184 obj->Send(reply);
1185 error = true;
1186 }
1187 return !error;
1188 }
1189
1190 template<typename TA>
1191 static void WriteReplyParams(Message* reply, TA a) {
1192 ReplyParam p(a);
1193 WriteParam(reply, p);
1194 }
1195
1196 template<typename TA, typename TB>
1197 static void WriteReplyParams(Message* reply, TA a, TB b) {
1198 ReplyParam p(a, b);
1199 WriteParam(reply, p);
1200 }
1201
1202 template<typename TA, typename TB, typename TC>
1203 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1204 ReplyParam p(a, b, c);
1205 WriteParam(reply, p);
1206 }
1207
1208 template<typename TA, typename TB, typename TC, typename TD>
1209 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1210 ReplyParam p(a, b, c, d);
1211 WriteParam(reply, p);
1212 }
1213
1214 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1215 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1216 ReplyParam p(a, b, c, d, e);
1217 WriteParam(reply, p);
1218 }
1219};
1220
[email protected]7d5c3ac2009-02-04 08:58:191221//-----------------------------------------------------------------------------
1222
[email protected]3178f4e22008-08-05 21:20:411223} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291224
[email protected]946d1b22009-07-22 23:57:211225#endif // IPC_IPC_MESSAGE_UTILS_H_