blob: 1aff1290c70e610c70d45d952128c43c63abb38c [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]d4cff272011-05-02 15:46:0192 TextInputClientMsgStart,
[email protected]e503a122011-03-17 18:20:5293 LastIPCMsgStart // Must come last.
[email protected]f91cb992009-02-04 20:10:1294};
95
[email protected]7a4de7a62010-08-17 18:38:2496class DictionaryValue;
97class FilePath;
98class ListValue;
99class NullableString16;
100
101namespace base {
102class Time;
[email protected]d84e48b2010-10-21 22:04:52103class TimeDelta;
[email protected]7a4de7a62010-08-17 18:38:24104struct FileDescriptor;
105}
106
initial.commit09911bf2008-07-26 23:55:29107namespace IPC {
108
[email protected]7a4de7a62010-08-17 18:38:24109struct ChannelHandle;
110
initial.commit09911bf2008-07-26 23:55:29111//-----------------------------------------------------------------------------
112// An iterator class for reading the fields contained within a Message.
113
114class MessageIterator {
115 public:
[email protected]e1981f432008-08-12 15:22:13116 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
initial.commit09911bf2008-07-26 23:55:29117 }
118 int NextInt() const {
[email protected]9422b7dc2009-12-30 20:09:02119 int val = -1;
initial.commit09911bf2008-07-26 23:55:29120 if (!msg_.ReadInt(&iter_, &val))
121 NOTREACHED();
122 return val;
123 }
initial.commit09911bf2008-07-26 23:55:29124 const std::string NextString() const {
125 std::string val;
126 if (!msg_.ReadString(&iter_, &val))
127 NOTREACHED();
128 return val;
129 }
130 const std::wstring NextWString() const {
131 std::wstring val;
132 if (!msg_.ReadWString(&iter_, &val))
133 NOTREACHED();
134 return val;
135 }
[email protected]225c8f52010-02-05 22:23:20136 void NextData(const char** data, int* length) const {
initial.commit09911bf2008-07-26 23:55:29137 if (!msg_.ReadData(&iter_, data, length)) {
138 NOTREACHED();
139 }
140 }
141 private:
142 const Message& msg_;
143 mutable void* iter_;
144};
145
146//-----------------------------------------------------------------------------
[email protected]6476c72c2011-02-11 18:46:19147// A dummy struct to place first just to allow leading commas for all
148// members in the macro-generated constructor initializer lists.
149struct NoParams {
150};
151
152//-----------------------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19153// ParamTraits specializations, etc.
154
[email protected]7d5c3ac2009-02-04 08:58:19155template <class P>
156static inline void WriteParam(Message* m, const P& p) {
[email protected]7b291f92009-08-14 05:43:53157 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53158 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
[email protected]7d5c3ac2009-02-04 08:58:19159}
160
161template <class P>
[email protected]1e86aa62009-04-24 21:22:33162static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
163 P* p) {
[email protected]7b291f92009-08-14 05:43:53164 typedef typename SimilarTypeTraits<P>::Type Type;
165 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
[email protected]7d5c3ac2009-02-04 08:58:19166}
167
168template <class P>
[email protected]252cad62010-08-18 18:33:57169static inline void LogParam(const P& p, std::string* l) {
[email protected]7b291f92009-08-14 05:43:53170 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53171 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19172}
173
174template <>
175struct ParamTraits<bool> {
176 typedef bool param_type;
177 static void Write(Message* m, const param_type& p) {
178 m->WriteBool(p);
179 }
180 static bool Read(const Message* m, void** iter, param_type* r) {
181 return m->ReadBool(iter, r);
182 }
[email protected]252cad62010-08-18 18:33:57183 static void Log(const param_type& p, std::string* l) {
184 l->append(p ? "true" : "false");
[email protected]7d5c3ac2009-02-04 08:58:19185 }
186};
187
188template <>
189struct ParamTraits<int> {
190 typedef int param_type;
191 static void Write(Message* m, const param_type& p) {
192 m->WriteInt(p);
193 }
194 static bool Read(const Message* m, void** iter, param_type* r) {
195 return m->ReadInt(iter, r);
196 }
[email protected]252cad62010-08-18 18:33:57197 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19198};
199
200template <>
[email protected]63263f92009-07-28 19:35:08201struct ParamTraits<unsigned int> {
202 typedef unsigned int param_type;
203 static void Write(Message* m, const param_type& p) {
204 m->WriteInt(p);
205 }
206 static bool Read(const Message* m, void** iter, param_type* r) {
207 return m->ReadInt(iter, reinterpret_cast<int*>(r));
208 }
[email protected]252cad62010-08-18 18:33:57209 static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08210};
211
212template <>
[email protected]7d5c3ac2009-02-04 08:58:19213struct ParamTraits<long> {
214 typedef long param_type;
215 static void Write(Message* m, const param_type& p) {
216 m->WriteLong(p);
217 }
218 static bool Read(const Message* m, void** iter, param_type* r) {
219 return m->ReadLong(iter, r);
220 }
[email protected]252cad62010-08-18 18:33:57221 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19222};
223
[email protected]140c3032009-06-26 18:22:54224template <>
225struct ParamTraits<unsigned long> {
226 typedef unsigned long param_type;
227 static void Write(Message* m, const param_type& p) {
228 m->WriteLong(p);
229 }
230 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]63263f92009-07-28 19:35:08231 return m->ReadLong(iter, reinterpret_cast<long*>(r));
[email protected]140c3032009-06-26 18:22:54232 }
[email protected]252cad62010-08-18 18:33:57233 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19234};
235
236template <>
[email protected]63263f92009-07-28 19:35:08237struct ParamTraits<long long> {
238 typedef long long param_type;
[email protected]7d5c3ac2009-02-04 08:58:19239 static void Write(Message* m, const param_type& p) {
240 m->WriteInt64(static_cast<int64>(p));
241 }
242 static bool Read(const Message* m, void** iter, param_type* r) {
243 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
244 }
[email protected]252cad62010-08-18 18:33:57245 static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08246};
247
248template <>
249struct ParamTraits<unsigned long long> {
250 typedef unsigned long long param_type;
251 static void Write(Message* m, const param_type& p) {
252 m->WriteInt64(p);
253 }
254 static bool Read(const Message* m, void** iter, param_type* r) {
255 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
256 }
[email protected]252cad62010-08-18 18:33:57257 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19258};
259
[email protected]43a40202010-11-12 16:25:01260template <>
261struct ParamTraits<unsigned short> {
262 typedef unsigned short param_type;
263 static void Write(Message* m, const param_type& p);
264 static bool Read(const Message* m, void** iter, param_type* r);
265 static void Log(const param_type& p, std::string* l);
266};
267
[email protected]20199662010-06-17 03:29:26268// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
269// should be sure to check the sanity of these values after receiving them over
270// IPC.
271template <>
272struct ParamTraits<float> {
273 typedef float param_type;
274 static void Write(Message* m, const param_type& p) {
275 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
276 }
277 static bool Read(const Message* m, void** iter, param_type* r) {
278 const char *data;
279 int data_size;
280 if (!m->ReadData(iter, &data, &data_size) ||
281 data_size != sizeof(param_type)) {
282 NOTREACHED();
283 return false;
284 }
285 memcpy(r, data, sizeof(param_type));
286 return true;
287 }
[email protected]252cad62010-08-18 18:33:57288 static void Log(const param_type& p, std::string* l) {
289 l->append(StringPrintf("%e", p));
[email protected]20199662010-06-17 03:29:26290 }
291};
292
[email protected]7d5c3ac2009-02-04 08:58:19293template <>
294struct ParamTraits<double> {
295 typedef double param_type;
296 static void Write(Message* m, const param_type& p) {
297 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
298 }
299 static bool Read(const Message* m, void** iter, param_type* r) {
300 const char *data;
[email protected]20199662010-06-17 03:29:26301 int data_size;
302 if (!m->ReadData(iter, &data, &data_size) ||
303 data_size != sizeof(param_type)) {
[email protected]7d5c3ac2009-02-04 08:58:19304 NOTREACHED();
[email protected]20199662010-06-17 03:29:26305 return false;
[email protected]7d5c3ac2009-02-04 08:58:19306 }
[email protected]20199662010-06-17 03:29:26307 memcpy(r, data, sizeof(param_type));
308 return true;
[email protected]7d5c3ac2009-02-04 08:58:19309 }
[email protected]252cad62010-08-18 18:33:57310 static void Log(const param_type& p, std::string* l) {
311 l->append(StringPrintf("%e", p));
[email protected]7d5c3ac2009-02-04 08:58:19312 }
313};
314
315template <>
[email protected]7d5c3ac2009-02-04 08:58:19316struct ParamTraits<base::Time> {
317 typedef base::Time param_type;
[email protected]7a4de7a62010-08-17 18:38:24318 static void Write(Message* m, const param_type& p);
319 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57320 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19321};
322
[email protected]d84e48b2010-10-21 22:04:52323template <>
324struct ParamTraits<base::TimeDelta> {
325 typedef base::TimeDelta param_type;
326 static void Write(Message* m, const param_type& p);
327 static bool Read(const Message* m, void** iter, param_type* r);
328 static void Log(const param_type& p, std::string* l);
329};
330
[email protected]7d5c3ac2009-02-04 08:58:19331#if defined(OS_WIN)
332template <>
333struct ParamTraits<LOGFONT> {
334 typedef LOGFONT param_type;
335 static void Write(Message* m, const param_type& p) {
336 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
337 }
338 static bool Read(const Message* m, void** iter, param_type* r) {
339 const char *data;
340 int data_size = 0;
341 bool result = m->ReadData(iter, &data, &data_size);
342 if (result && data_size == sizeof(LOGFONT)) {
343 memcpy(r, data, sizeof(LOGFONT));
344 } else {
345 result = false;
346 NOTREACHED();
347 }
348
349 return result;
350 }
[email protected]252cad62010-08-18 18:33:57351 static void Log(const param_type& p, std::string* l) {
352 l->append(StringPrintf("<LOGFONT>"));
[email protected]7d5c3ac2009-02-04 08:58:19353 }
354};
355
356template <>
357struct ParamTraits<MSG> {
358 typedef MSG param_type;
359 static void Write(Message* m, const param_type& p) {
360 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
361 }
362 static bool Read(const Message* m, void** iter, param_type* r) {
363 const char *data;
364 int data_size = 0;
365 bool result = m->ReadData(iter, &data, &data_size);
366 if (result && data_size == sizeof(MSG)) {
367 memcpy(r, data, sizeof(MSG));
368 } else {
369 result = false;
370 NOTREACHED();
371 }
372
373 return result;
374 }
[email protected]252cad62010-08-18 18:33:57375 static void Log(const param_type& p, std::string* l) {
376 l->append("<MSG>");
[email protected]7a4de7a62010-08-17 18:38:24377 }
[email protected]7d5c3ac2009-02-04 08:58:19378};
379#endif // defined(OS_WIN)
380
381template <>
[email protected]584f2b22009-05-21 01:01:59382struct ParamTraits<DictionaryValue> {
383 typedef DictionaryValue param_type;
384 static void Write(Message* m, const param_type& p);
385 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57386 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59387};
388
389template <>
390struct ParamTraits<ListValue> {
391 typedef ListValue param_type;
392 static void Write(Message* m, const param_type& p);
393 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57394 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59395};
396
397template <>
[email protected]7d5c3ac2009-02-04 08:58:19398struct ParamTraits<std::string> {
399 typedef std::string param_type;
400 static void Write(Message* m, const param_type& p) {
401 m->WriteString(p);
402 }
403 static bool Read(const Message* m, void** iter, param_type* r) {
404 return m->ReadString(iter, r);
405 }
[email protected]252cad62010-08-18 18:33:57406 static void Log(const param_type& p, std::string* l) {
407 l->append(p);
[email protected]7d5c3ac2009-02-04 08:58:19408 }
409};
410
[email protected]3dd7a7a2009-07-27 21:09:07411template<typename CharType>
[email protected]252cad62010-08-18 18:33:57412static void LogBytes(const std::vector<CharType>& data, std::string* out) {
[email protected]3dd7a7a2009-07-27 21:09:07413#if defined(OS_WIN)
414 // Windows has a GUI for logging, which can handle arbitrary binary data.
415 for (size_t i = 0; i < data.size(); ++i)
416 out->push_back(data[i]);
417#else
418 // On POSIX, we log to stdout, which we assume can display ASCII.
419 static const size_t kMaxBytesToLog = 100;
420 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
421 if (isprint(data[i]))
422 out->push_back(data[i]);
423 else
[email protected]252cad62010-08-18 18:33:57424 out->append(StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
[email protected]3dd7a7a2009-07-27 21:09:07425 }
426 if (data.size() > kMaxBytesToLog) {
427 out->append(
[email protected]252cad62010-08-18 18:33:57428 StringPrintf(" and %u more bytes",
[email protected]3dd7a7a2009-07-27 21:09:07429 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
430 }
431#endif
432}
433
[email protected]7d5c3ac2009-02-04 08:58:19434template <>
435struct ParamTraits<std::vector<unsigned char> > {
436 typedef std::vector<unsigned char> param_type;
437 static void Write(Message* m, const param_type& p) {
[email protected]f6b8ce32011-03-02 00:03:18438 if (p.empty()) {
[email protected]7d5c3ac2009-02-04 08:58:19439 m->WriteData(NULL, 0);
440 } else {
441 m->WriteData(reinterpret_cast<const char*>(&p.front()),
442 static_cast<int>(p.size()));
443 }
444 }
445 static bool Read(const Message* m, void** iter, param_type* r) {
446 const char *data;
447 int data_size = 0;
448 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
449 return false;
450 r->resize(data_size);
451 if (data_size)
452 memcpy(&r->front(), data, data_size);
453 return true;
454 }
[email protected]252cad62010-08-18 18:33:57455 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07456 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19457 }
458};
459
460template <>
461struct ParamTraits<std::vector<char> > {
462 typedef std::vector<char> param_type;
463 static void Write(Message* m, const param_type& p) {
[email protected]f6b8ce32011-03-02 00:03:18464 if (p.empty()) {
[email protected]7d5c3ac2009-02-04 08:58:19465 m->WriteData(NULL, 0);
466 } else {
467 m->WriteData(&p.front(), static_cast<int>(p.size()));
468 }
469 }
470 static bool Read(const Message* m, void** iter, param_type* r) {
471 const char *data;
472 int data_size = 0;
473 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
474 return false;
475 r->resize(data_size);
476 if (data_size)
477 memcpy(&r->front(), data, data_size);
478 return true;
479 }
[email protected]252cad62010-08-18 18:33:57480 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07481 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19482 }
483};
484
485template <class P>
486struct ParamTraits<std::vector<P> > {
487 typedef std::vector<P> param_type;
488 static void Write(Message* m, const param_type& p) {
489 WriteParam(m, static_cast<int>(p.size()));
490 for (size_t i = 0; i < p.size(); i++)
491 WriteParam(m, p[i]);
492 }
493 static bool Read(const Message* m, void** iter, param_type* r) {
494 int size;
[email protected]86440f52009-12-31 05:17:23495 // ReadLength() checks for < 0 itself.
[email protected]7d5c3ac2009-02-04 08:58:19496 if (!m->ReadLength(iter, &size))
497 return false;
498 // Resizing beforehand is not safe, see BUG 1006367 for details.
[email protected]86440f52009-12-31 05:17:23499 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
500 return false;
501 r->resize(size);
502 for (int i = 0; i < size; i++) {
503 if (!ReadParam(m, iter, &(*r)[i]))
504 return false;
[email protected]7d5c3ac2009-02-04 08:58:19505 }
506 return true;
507 }
[email protected]252cad62010-08-18 18:33:57508 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19509 for (size_t i = 0; i < p.size(); ++i) {
510 if (i != 0)
[email protected]252cad62010-08-18 18:33:57511 l->append(" ");
[email protected]7d5c3ac2009-02-04 08:58:19512 LogParam((p[i]), l);
513 }
514 }
515};
516
[email protected]96da6962010-05-13 19:10:34517template <class P>
518struct ParamTraits<std::set<P> > {
519 typedef std::set<P> param_type;
520 static void Write(Message* m, const param_type& p) {
521 WriteParam(m, static_cast<int>(p.size()));
522 typename param_type::const_iterator iter;
523 for (iter = p.begin(); iter != p.end(); ++iter)
524 WriteParam(m, *iter);
525 }
526 static bool Read(const Message* m, void** iter, param_type* r) {
527 int size;
528 if (!m->ReadLength(iter, &size))
529 return false;
530 for (int i = 0; i < size; ++i) {
531 P item;
532 if (!ReadParam(m, iter, &item))
533 return false;
534 r->insert(item);
535 }
536 return true;
537 }
[email protected]252cad62010-08-18 18:33:57538 static void Log(const param_type& p, std::string* l) {
539 l->append("<std::set>");
[email protected]96da6962010-05-13 19:10:34540 }
541};
542
543
[email protected]7d5c3ac2009-02-04 08:58:19544template <class K, class V>
545struct ParamTraits<std::map<K, V> > {
546 typedef std::map<K, V> param_type;
547 static void Write(Message* m, const param_type& p) {
548 WriteParam(m, static_cast<int>(p.size()));
549 typename param_type::const_iterator iter;
550 for (iter = p.begin(); iter != p.end(); ++iter) {
551 WriteParam(m, iter->first);
552 WriteParam(m, iter->second);
553 }
554 }
555 static bool Read(const Message* m, void** iter, param_type* r) {
556 int size;
557 if (!ReadParam(m, iter, &size) || size < 0)
558 return false;
559 for (int i = 0; i < size; ++i) {
560 K k;
561 if (!ReadParam(m, iter, &k))
562 return false;
563 V& value = (*r)[k];
564 if (!ReadParam(m, iter, &value))
565 return false;
566 }
567 return true;
568 }
[email protected]252cad62010-08-18 18:33:57569 static void Log(const param_type& p, std::string* l) {
570 l->append("<std::map>");
[email protected]7d5c3ac2009-02-04 08:58:19571 }
572};
573
[email protected]eb47a132009-03-04 00:39:56574
[email protected]7d5c3ac2009-02-04 08:58:19575template <>
576struct ParamTraits<std::wstring> {
577 typedef std::wstring param_type;
578 static void Write(Message* m, const param_type& p) {
579 m->WriteWString(p);
580 }
581 static bool Read(const Message* m, void** iter, param_type* r) {
582 return m->ReadWString(iter, r);
583 }
[email protected]252cad62010-08-18 18:33:57584 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19585};
586
[email protected]a5da6d612009-08-04 02:00:56587template <class A, class B>
588struct ParamTraits<std::pair<A, B> > {
589 typedef std::pair<A, B> param_type;
590 static void Write(Message* m, const param_type& p) {
591 WriteParam(m, p.first);
592 WriteParam(m, p.second);
593 }
594 static bool Read(const Message* m, void** iter, param_type* r) {
595 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
596 }
[email protected]252cad62010-08-18 18:33:57597 static void Log(const param_type& p, std::string* l) {
598 l->append("(");
[email protected]a5da6d612009-08-04 02:00:56599 LogParam(p.first, l);
[email protected]252cad62010-08-18 18:33:57600 l->append(", ");
[email protected]a5da6d612009-08-04 02:00:56601 LogParam(p.second, l);
[email protected]252cad62010-08-18 18:33:57602 l->append(")");
[email protected]a5da6d612009-08-04 02:00:56603 }
604};
605
[email protected]15bf8712009-08-27 00:55:02606template <>
607struct ParamTraits<NullableString16> {
608 typedef NullableString16 param_type;
[email protected]7a4de7a62010-08-17 18:38:24609 static void Write(Message* m, const param_type& p);
610 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57611 static void Log(const param_type& p, std::string* l);
[email protected]15bf8712009-08-27 00:55:02612};
613
[email protected]eb47a132009-03-04 00:39:56614// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
615// need this trait.
616#if !defined(WCHAR_T_IS_UTF16)
[email protected]eb47a132009-03-04 00:39:56617template <>
618struct ParamTraits<string16> {
619 typedef string16 param_type;
620 static void Write(Message* m, const param_type& p) {
[email protected]3a2a5d22009-03-04 03:36:36621 m->WriteString16(p);
[email protected]eb47a132009-03-04 00:39:56622 }
623 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]3a2a5d22009-03-04 03:36:36624 return m->ReadString16(iter, r);
[email protected]eb47a132009-03-04 00:39:56625 }
[email protected]252cad62010-08-18 18:33:57626 static void Log(const param_type& p, std::string* l);
[email protected]eb47a132009-03-04 00:39:56627};
[email protected]eb47a132009-03-04 00:39:56628#endif
629
[email protected]7d5c3ac2009-02-04 08:58:19630// and, a few more useful types...
631#if defined(OS_WIN)
632template <>
633struct ParamTraits<HANDLE> {
634 typedef HANDLE param_type;
635 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35636 // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
637 // bit systems.
638 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19639 }
640 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35641 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
642 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19643 }
[email protected]252cad62010-08-18 18:33:57644 static void Log(const param_type& p, std::string* l) {
645 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19646 }
647};
648
649template <>
650struct ParamTraits<HCURSOR> {
651 typedef HCURSOR param_type;
652 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35653 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19654 }
655 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35656 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
657 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19658 }
[email protected]252cad62010-08-18 18:33:57659 static void Log(const param_type& p, std::string* l) {
660 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19661 }
662};
663
664template <>
[email protected]7d5c3ac2009-02-04 08:58:19665struct ParamTraits<HACCEL> {
666 typedef HACCEL param_type;
667 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35668 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19669 }
670 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35671 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
672 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19673 }
674};
675
676template <>
677struct ParamTraits<POINT> {
678 typedef POINT param_type;
679 static void Write(Message* m, const param_type& p) {
680 m->WriteInt(p.x);
681 m->WriteInt(p.y);
682 }
683 static bool Read(const Message* m, void** iter, param_type* r) {
684 int x, y;
685 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
686 return false;
687 r->x = x;
688 r->y = y;
689 return true;
690 }
[email protected]252cad62010-08-18 18:33:57691 static void Log(const param_type& p, std::string* l) {
692 l->append(StringPrintf("(%d, %d)", p.x, p.y));
[email protected]7d5c3ac2009-02-04 08:58:19693 }
694};
695#endif // defined(OS_WIN)
696
697template <>
698struct ParamTraits<FilePath> {
699 typedef FilePath param_type;
[email protected]7a4de7a62010-08-17 18:38:24700 static void Write(Message* m, const param_type& p);
701 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57702 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19703};
704
[email protected]526776c2009-02-07 00:39:26705#if defined(OS_POSIX)
[email protected]2749885f2009-03-05 21:40:11706// FileDescriptors may be serialised over IPC channels on POSIX. On the
707// receiving side, the FileDescriptor is a valid duplicate of the file
708// descriptor which was transmitted: *it is not just a copy of the integer like
709// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
710// this case, the receiving end will see a value of -1. *Zero is a valid file
711// descriptor*.
712//
713// The received file descriptor will have the |auto_close| flag set to true. The
714// code which handles the message is responsible for taking ownership of it.
715// File descriptors are OS resources and must be closed when no longer needed.
716//
717// When sending a file descriptor, the file descriptor must be valid at the time
718// of transmission. Since transmission is not synchronous, one should consider
719// dup()ing any file descriptors to be transmitted and setting the |auto_close|
720// flag, which causes the file descriptor to be closed after writing.
[email protected]526776c2009-02-07 00:39:26721template<>
[email protected]5fe733de2009-02-11 18:59:20722struct ParamTraits<base::FileDescriptor> {
723 typedef base::FileDescriptor param_type;
[email protected]7a4de7a62010-08-17 18:38:24724 static void Write(Message* m, const param_type& p);
725 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57726 static void Log(const param_type& p, std::string* l);
[email protected]526776c2009-02-07 00:39:26727};
[email protected]379e7a52010-03-09 00:38:41728#endif // defined(OS_POSIX)
[email protected]526776c2009-02-07 00:39:26729
[email protected]d2e884d2009-06-22 20:37:52730// A ChannelHandle is basically a platform-inspecific wrapper around the
731// fact that IPC endpoints are handled specially on POSIX. See above comments
732// on FileDescriptor for more background.
733template<>
734struct ParamTraits<IPC::ChannelHandle> {
735 typedef ChannelHandle param_type;
[email protected]7a4de7a62010-08-17 18:38:24736 static void Write(Message* m, const param_type& p);
737 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57738 static void Log(const param_type& p, std::string* l);
[email protected]d2e884d2009-06-22 20:37:52739};
740
[email protected]7d5c3ac2009-02-04 08:58:19741#if defined(OS_WIN)
742template <>
743struct ParamTraits<XFORM> {
744 typedef XFORM param_type;
745 static void Write(Message* m, const param_type& p) {
746 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
747 }
748 static bool Read(const Message* m, void** iter, param_type* r) {
749 const char *data;
750 int data_size = 0;
751 bool result = m->ReadData(iter, &data, &data_size);
752 if (result && data_size == sizeof(XFORM)) {
753 memcpy(r, data, sizeof(XFORM));
754 } else {
755 result = false;
756 NOTREACHED();
757 }
758
759 return result;
760 }
[email protected]252cad62010-08-18 18:33:57761 static void Log(const param_type& p, std::string* l) {
762 l->append("<XFORM>");
[email protected]7d5c3ac2009-02-04 08:58:19763 }
764};
765#endif // defined(OS_WIN)
766
[email protected]7d5c3ac2009-02-04 08:58:19767struct LogData {
[email protected]20f0487a2010-09-30 20:06:30768 LogData();
769 ~LogData();
770
[email protected]9a3a293b2009-06-04 22:28:16771 std::string channel;
[email protected]8bef70e2009-04-14 19:11:24772 int32 routing_id;
[email protected]168ae922009-12-04 18:08:45773 uint32 type; // "User-defined" message type, from ipc_message.h.
[email protected]252cad62010-08-18 18:33:57774 std::string flags;
[email protected]7d5c3ac2009-02-04 08:58:19775 int64 sent; // Time that the message was sent (i.e. at Send()).
776 int64 receive; // Time before it was dispatched (i.e. before calling
777 // OnMessageReceived).
778 int64 dispatch; // Time after it was dispatched (i.e. after calling
779 // OnMessageReceived).
[email protected]252cad62010-08-18 18:33:57780 std::string message_name;
781 std::string params;
[email protected]7d5c3ac2009-02-04 08:58:19782};
783
784template <>
785struct ParamTraits<LogData> {
786 typedef LogData param_type;
[email protected]20f0487a2010-09-30 20:06:30787 static void Write(Message* m, const param_type& p);
788 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57789 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19790 // Doesn't make sense to implement this!
791 }
792};
793
[email protected]eb47a132009-03-04 00:39:56794template <>
[email protected]503683f2009-02-26 09:13:01795struct ParamTraits<Message> {
796 static void Write(Message* m, const Message& p) {
[email protected]8a861402011-01-28 19:59:11797 DCHECK(p.size() <= INT_MAX);
798 int message_size = static_cast<int>(p.size());
799 m->WriteInt(message_size);
800 m->WriteData(reinterpret_cast<const char*>(p.data()), message_size);
[email protected]503683f2009-02-26 09:13:01801 }
802 static bool Read(const Message* m, void** iter, Message* r) {
803 int size;
804 if (!m->ReadInt(iter, &size))
805 return false;
806 const char* data;
807 if (!m->ReadData(iter, &data, &size))
808 return false;
809 *r = Message(data, size);
810 return true;
811 }
[email protected]252cad62010-08-18 18:33:57812 static void Log(const Message& p, std::string* l) {
813 l->append("<IPC::Message>");
[email protected]503683f2009-02-26 09:13:01814 }
815};
816
817template <>
[email protected]7d5c3ac2009-02-04 08:58:19818struct ParamTraits<Tuple0> {
819 typedef Tuple0 param_type;
820 static void Write(Message* m, const param_type& p) {
821 }
822 static bool Read(const Message* m, void** iter, param_type* r) {
823 return true;
824 }
[email protected]252cad62010-08-18 18:33:57825 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19826 }
827};
828
829template <class A>
830struct ParamTraits< Tuple1<A> > {
831 typedef Tuple1<A> param_type;
832 static void Write(Message* m, const param_type& p) {
833 WriteParam(m, p.a);
834 }
835 static bool Read(const Message* m, void** iter, param_type* r) {
836 return ReadParam(m, iter, &r->a);
837 }
[email protected]252cad62010-08-18 18:33:57838 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19839 LogParam(p.a, l);
840 }
841};
842
843template <class A, class B>
844struct ParamTraits< Tuple2<A, B> > {
845 typedef Tuple2<A, B> param_type;
846 static void Write(Message* m, const param_type& p) {
847 WriteParam(m, p.a);
848 WriteParam(m, p.b);
849 }
850 static bool Read(const Message* m, void** iter, param_type* r) {
851 return (ReadParam(m, iter, &r->a) &&
852 ReadParam(m, iter, &r->b));
853 }
[email protected]252cad62010-08-18 18:33:57854 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19855 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57856 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19857 LogParam(p.b, l);
858 }
859};
860
861template <class A, class B, class C>
862struct ParamTraits< Tuple3<A, B, C> > {
863 typedef Tuple3<A, B, C> param_type;
864 static void Write(Message* m, const param_type& p) {
865 WriteParam(m, p.a);
866 WriteParam(m, p.b);
867 WriteParam(m, p.c);
868 }
869 static bool Read(const Message* m, void** iter, param_type* r) {
870 return (ReadParam(m, iter, &r->a) &&
871 ReadParam(m, iter, &r->b) &&
872 ReadParam(m, iter, &r->c));
873 }
[email protected]252cad62010-08-18 18:33:57874 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19875 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57876 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19877 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57878 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19879 LogParam(p.c, l);
880 }
881};
882
883template <class A, class B, class C, class D>
884struct ParamTraits< Tuple4<A, B, C, D> > {
885 typedef Tuple4<A, B, C, D> param_type;
886 static void Write(Message* m, const param_type& p) {
887 WriteParam(m, p.a);
888 WriteParam(m, p.b);
889 WriteParam(m, p.c);
890 WriteParam(m, p.d);
891 }
892 static bool Read(const Message* m, void** iter, param_type* r) {
893 return (ReadParam(m, iter, &r->a) &&
894 ReadParam(m, iter, &r->b) &&
895 ReadParam(m, iter, &r->c) &&
896 ReadParam(m, iter, &r->d));
897 }
[email protected]252cad62010-08-18 18:33:57898 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19899 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57900 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19901 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57902 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19903 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57904 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19905 LogParam(p.d, l);
906 }
907};
908
909template <class A, class B, class C, class D, class E>
910struct ParamTraits< Tuple5<A, B, C, D, E> > {
911 typedef Tuple5<A, B, C, D, E> param_type;
912 static void Write(Message* m, const param_type& p) {
913 WriteParam(m, p.a);
914 WriteParam(m, p.b);
915 WriteParam(m, p.c);
916 WriteParam(m, p.d);
917 WriteParam(m, p.e);
918 }
919 static bool Read(const Message* m, void** iter, param_type* r) {
920 return (ReadParam(m, iter, &r->a) &&
921 ReadParam(m, iter, &r->b) &&
922 ReadParam(m, iter, &r->c) &&
923 ReadParam(m, iter, &r->d) &&
924 ReadParam(m, iter, &r->e));
925 }
[email protected]252cad62010-08-18 18:33:57926 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19927 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57928 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19929 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57930 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19931 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57932 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19933 LogParam(p.d, l);
[email protected]252cad62010-08-18 18:33:57934 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19935 LogParam(p.e, l);
936 }
937};
938
[email protected]7d5c3ac2009-02-04 08:58:19939//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:29940// Generic message subclasses
941
942// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:24943template <class ParamType>
initial.commit09911bf2008-07-26 23:55:29944class MessageWithTuple : public Message {
945 public:
[email protected]81a34412009-01-05 19:17:24946 typedef ParamType Param;
[email protected]7a4de7a62010-08-17 18:38:24947 typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
[email protected]81a34412009-01-05 19:17:24948
[email protected]7a4de7a62010-08-17 18:38:24949 // The constructor and the Read() method's templated implementations are in
950 // ipc_message_utils_impl.h. The subclass constructor and Log() methods call
951 // the templated versions of these and make sure there are instantiations in
952 // those translation units.
953 MessageWithTuple(int32 routing_id, uint32 type, const RefParam& p);
[email protected]071b4b92010-08-09 16:06:58954
[email protected]7a4de7a62010-08-17 18:38:24955 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:29956
957 // Generic dispatcher. Should cover most cases.
[email protected]65412272010-12-21 20:03:24958 template<class T, class S, class Method>
959 static bool Dispatch(const Message* msg, T* obj, S* sender, Method func) {
initial.commit09911bf2008-07-26 23:55:29960 Param p;
961 if (Read(msg, &p)) {
962 DispatchToMethod(obj, func, p);
963 return true;
964 }
965 return false;
966 }
967
968 // The following dispatchers exist for the case where the callback function
969 // needs the message as well. They assume that "Param" is a type of Tuple
970 // (except the one arg case, as there is no Tuple1).
[email protected]65412272010-12-21 20:03:24971 template<class T, class S, typename TA>
972 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29973 void (T::*func)(const Message&, TA)) {
974 Param p;
975 if (Read(msg, &p)) {
[email protected]c2fe31542009-05-20 18:24:14976 (obj->*func)(*msg, p.a);
initial.commit09911bf2008-07-26 23:55:29977 return true;
978 }
979 return false;
980 }
981
[email protected]65412272010-12-21 20:03:24982 template<class T, class S, typename TA, typename TB>
983 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29984 void (T::*func)(const Message&, TA, TB)) {
985 Param p;
986 if (Read(msg, &p)) {
987 (obj->*func)(*msg, p.a, p.b);
988 return true;
989 }
990 return false;
991 }
992
[email protected]65412272010-12-21 20:03:24993 template<class T, class S, typename TA, typename TB, typename TC>
994 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29995 void (T::*func)(const Message&, TA, TB, TC)) {
996 Param p;
997 if (Read(msg, &p)) {
998 (obj->*func)(*msg, p.a, p.b, p.c);
999 return true;
1000 }
1001 return false;
1002 }
1003
[email protected]65412272010-12-21 20:03:241004 template<class T, class S, typename TA, typename TB, typename TC, typename TD>
1005 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:291006 void (T::*func)(const Message&, TA, TB, TC, TD)) {
1007 Param p;
1008 if (Read(msg, &p)) {
1009 (obj->*func)(*msg, p.a, p.b, p.c, p.d);
1010 return true;
1011 }
1012 return false;
1013 }
1014
[email protected]65412272010-12-21 20:03:241015 template<class T, class S, typename TA, typename TB, typename TC, typename TD,
initial.commit09911bf2008-07-26 23:55:291016 typename TE>
[email protected]65412272010-12-21 20:03:241017 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:291018 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
1019 Param p;
1020 if (Read(msg, &p)) {
1021 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
1022 return true;
1023 }
1024 return false;
1025 }
1026
[email protected]deb57402009-02-06 01:35:301027 // Functions used to do manual unpacking. Only used by the automation code,
1028 // these should go away once that code uses SyncChannel.
1029 template<typename TA, typename TB>
1030 static bool Read(const IPC::Message* msg, TA* a, TB* b) {
1031 ParamType params;
1032 if (!Read(msg, &params))
1033 return false;
1034 *a = params.a;
1035 *b = params.b;
1036 return true;
1037 }
1038
1039 template<typename TA, typename TB, typename TC>
1040 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
1041 ParamType params;
1042 if (!Read(msg, &params))
1043 return false;
1044 *a = params.a;
1045 *b = params.b;
1046 *c = params.c;
1047 return true;
1048 }
1049
1050 template<typename TA, typename TB, typename TC, typename TD>
1051 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) {
1052 ParamType params;
1053 if (!Read(msg, &params))
1054 return false;
1055 *a = params.a;
1056 *b = params.b;
1057 *c = params.c;
1058 *d = params.d;
1059 return true;
1060 }
1061
1062 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1063 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) {
1064 ParamType params;
1065 if (!Read(msg, &params))
1066 return false;
1067 *a = params.a;
1068 *b = params.b;
1069 *c = params.c;
1070 *d = params.d;
1071 *e = params.e;
1072 return true;
1073 }
initial.commit09911bf2008-07-26 23:55:291074};
1075
[email protected]7a4de7a62010-08-17 18:38:241076// defined in ipc_logging.cc
1077void GenerateLogData(const std::string& channel, const Message& message,
1078 LogData* data);
1079
1080
1081#if defined(IPC_MESSAGE_LOG_ENABLED)
[email protected]252cad62010-08-18 18:33:571082inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
1083 const std::string& output_params = msg->output_params();
[email protected]7a4de7a62010-08-17 18:38:241084 if (!l->empty() && !output_params.empty())
[email protected]252cad62010-08-18 18:33:571085 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:241086
1087 l->append(output_params);
1088}
1089
1090template <class ReplyParamType>
1091inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1092 const Message* msg) {
1093 if (msg->received_time() != 0) {
[email protected]252cad62010-08-18 18:33:571094 std::string output_params;
[email protected]7a4de7a62010-08-17 18:38:241095 LogParam(reply_params, &output_params);
1096 msg->set_output_params(output_params);
1097 }
1098}
1099
1100inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
1101 if (msg->sent_time()) {
1102 // Don't log the sync message after dispatch, as we don't have the
1103 // output parameters at that point. Instead, save its data and log it
1104 // with the outgoing reply message when it's sent.
1105 LogData* data = new LogData;
1106 GenerateLogData("", *msg, data);
1107 msg->set_dont_log();
1108 reply->set_sync_log_data(data);
1109 }
1110}
1111#else
[email protected]252cad62010-08-18 18:33:571112inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
[email protected]7a4de7a62010-08-17 18:38:241113
1114template <class ReplyParamType>
1115inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1116 const Message* msg) {}
1117
1118inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1119#endif
1120
initial.commit09911bf2008-07-26 23:55:291121// This class assumes that its template argument is a RefTuple (a Tuple with
[email protected]7a4de7a62010-08-17 18:38:241122// reference elements). This would go into ipc_message_utils_impl.h, but it is
1123// also used by chrome_frame.
initial.commit09911bf2008-07-26 23:55:291124template <class RefTuple>
1125class ParamDeserializer : public MessageReplyDeserializer {
1126 public:
[email protected]e1981f432008-08-12 15:22:131127 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:291128
1129 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1130 return ReadParam(&msg, &iter, &out_);
1131 }
1132
1133 RefTuple out_;
1134};
1135
initial.commit09911bf2008-07-26 23:55:291136// Used for synchronous messages.
[email protected]75e5a872009-04-02 23:56:111137template <class SendParamType, class ReplyParamType>
initial.commit09911bf2008-07-26 23:55:291138class MessageWithReply : public SyncMessage {
1139 public:
[email protected]75e5a872009-04-02 23:56:111140 typedef SendParamType SendParam;
[email protected]7a4de7a62010-08-17 18:38:241141 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
[email protected]75e5a872009-04-02 23:56:111142 typedef ReplyParamType ReplyParam;
1143
[email protected]168ae922009-12-04 18:08:451144 MessageWithReply(int32 routing_id, uint32 type,
[email protected]7a4de7a62010-08-17 18:38:241145 const RefSendParam& send, const ReplyParam& reply);
1146 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
1147 static bool ReadReplyParam(
1148 const Message* msg,
1149 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:291150
[email protected]65412272010-12-21 20:03:241151 template<class T, class S, class Method>
1152 static bool Dispatch(const Message* msg, T* obj, S* sender, Method func) {
initial.commit09911bf2008-07-26 23:55:291153 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291154 Message* reply = GenerateReply(msg);
1155 bool error;
[email protected]7a4de7a62010-08-17 18:38:241156 if (ReadSendParam(msg, &send_params)) {
1157 typename TupleTypes<ReplyParam>::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:291158 DispatchToMethod(obj, func, send_params, &reply_params);
1159 WriteParam(reply, reply_params);
1160 error = false;
[email protected]7a4de7a62010-08-17 18:38:241161 LogReplyParamsToMessage(reply_params, msg);
initial.commit09911bf2008-07-26 23:55:291162 } else {
1163 NOTREACHED() << "Error deserializing message " << msg->type();
1164 reply->set_reply_error();
1165 error = true;
1166 }
1167
[email protected]65412272010-12-21 20:03:241168 sender->Send(reply);
initial.commit09911bf2008-07-26 23:55:291169 return !error;
1170 }
1171
1172 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191173 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291174 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291175 Message* reply = GenerateReply(msg);
1176 bool error;
[email protected]7a4de7a62010-08-17 18:38:241177 if (ReadSendParam(msg, &send_params)) {
initial.commit09911bf2008-07-26 23:55:291178 Tuple1<Message&> t = MakeRefTuple(*reply);
[email protected]7a4de7a62010-08-17 18:38:241179 ConnectMessageAndReply(msg, reply);
initial.commit09911bf2008-07-26 23:55:291180 DispatchToMethod(obj, func, send_params, &t);
1181 error = false;
1182 } else {
1183 NOTREACHED() << "Error deserializing message " << msg->type();
1184 reply->set_reply_error();
1185 obj->Send(reply);
1186 error = true;
1187 }
1188 return !error;
1189 }
1190
1191 template<typename TA>
1192 static void WriteReplyParams(Message* reply, TA a) {
1193 ReplyParam p(a);
1194 WriteParam(reply, p);
1195 }
1196
1197 template<typename TA, typename TB>
1198 static void WriteReplyParams(Message* reply, TA a, TB b) {
1199 ReplyParam p(a, b);
1200 WriteParam(reply, p);
1201 }
1202
1203 template<typename TA, typename TB, typename TC>
1204 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1205 ReplyParam p(a, b, c);
1206 WriteParam(reply, p);
1207 }
1208
1209 template<typename TA, typename TB, typename TC, typename TD>
1210 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1211 ReplyParam p(a, b, c, d);
1212 WriteParam(reply, p);
1213 }
1214
1215 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1216 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1217 ReplyParam p(a, b, c, d, e);
1218 WriteParam(reply, p);
1219 }
1220};
1221
[email protected]7d5c3ac2009-02-04 08:58:191222//-----------------------------------------------------------------------------
1223
[email protected]3178f4e22008-08-05 21:20:411224} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291225
[email protected]946d1b22009-07-22 23:57:211226#endif // IPC_IPC_MESSAGE_UTILS_H_