blob: 5bf587465e2ea91b08b7d612467a17f8ab9cf335 [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]6782f832011-05-10 04:06:0017#include "base/stringprintf.h"
[email protected]dce5df52009-06-29 17:58:2518#include "base/string_util.h"
initial.commit09911bf2008-07-26 23:55:2919#include "base/tuple.h"
[email protected]939856a2010-08-24 20:29:0220#include "ipc/ipc_param_traits.h"
[email protected]0cfe5dae2010-08-17 00:24:5421#include "ipc/ipc_sync_message.h"
[email protected]55b4e212010-08-13 20:43:5822
[email protected]7a4de7a62010-08-17 18:38:2423#if defined(COMPILER_GCC)
24// GCC "helpfully" tries to inline template methods in release mode. Except we
25// want the majority of the template junk being expanded once in the
26// implementation file (and only provide the definitions in
27// ipc_message_utils_impl.h in those files) and exported, instead of expanded
28// at every call site. Special note: GCC happily accepts the attribute before
29// the method declaration, but only acts on it if it is after.
[email protected]efafbbd2010-08-19 20:23:2530#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 40500
31// Starting in gcc 4.5, the noinline no longer implies the concept covered by
32// the introduced noclone attribute, which will create specialized versions of
33// functions/methods when certain types are constant.
34// www.gnu.org/software/gcc/gcc-4.5/changes.html
35#define IPC_MSG_NOINLINE __attribute__((noinline, noclone));
36#else
[email protected]7a4de7a62010-08-17 18:38:2437#define IPC_MSG_NOINLINE __attribute__((noinline));
[email protected]efafbbd2010-08-19 20:23:2538#endif
[email protected]7a4de7a62010-08-17 18:38:2439#elif defined(COMPILER_MSVC)
40// MSVC++ doesn't do this.
41#define IPC_MSG_NOINLINE
42#else
43#error "Please add the noinline property for your new compiler here."
44#endif
45
[email protected]f91cb992009-02-04 20:10:1246// Used by IPC_BEGIN_MESSAGES so that each message class starts from a unique
47// base. Messages have unique IDs across channels in order for the IPC logging
48// code to figure out the message class from its ID.
49enum IPCMessageStart {
[email protected]f91cb992009-02-04 20:10:1250 AutomationMsgStart = 0,
51 ViewMsgStart,
[email protected]f91cb992009-02-04 20:10:1252 PluginMsgStart,
[email protected]21fa3a12010-12-08 23:34:1653 ProfileImportMsgStart,
[email protected]f91cb992009-02-04 20:10:1254 TestMsgStart,
[email protected]21fa3a12010-12-08 23:34:1655 DevToolsMsgStart,
[email protected]eb47a132009-03-04 00:39:5656 WorkerMsgStart,
[email protected]21fa3a12010-12-08 23:34:1657 NaClMsgStart,
[email protected]60f14392009-12-15 20:46:3258 UtilityMsgStart,
[email protected]c0fc0942010-01-13 00:55:3759 GpuMsgStart,
[email protected]38fe1962010-07-31 07:57:0060 ServiceMsgStart,
[email protected]709a847e2010-11-10 01:16:1161 PpapiMsgStart,
[email protected]21fa3a12010-12-08 23:34:1662 FirefoxImporterUnittestMsgStart,
[email protected]9f547bf2010-12-13 17:00:4263 FileUtilitiesMsgStart,
64 MimeRegistryMsgStart,
[email protected]26a9acf2010-12-13 19:35:0565 DatabaseMsgStart,
[email protected]56879f932010-12-13 21:05:3766 DOMStorageMsgStart,
[email protected]2ba871b2010-12-13 21:11:0067 IndexedDBMsgStart,
[email protected]61e78f12010-12-15 21:03:5568 PepperFileMsgStart,
[email protected]ca97f302011-01-20 13:57:0569 SpeechInputMsgStart,
[email protected]f0557932011-01-25 20:20:5170 PepperMsgStart,
[email protected]663bd9e2011-03-21 01:07:0171 AutofillMsgStart,
[email protected]fa685ff2011-02-17 19:47:1372 SafeBrowsingMsgStart,
[email protected]6c54e7e42011-03-02 20:52:3473 P2PMsgStart,
[email protected]db803aae2011-03-05 02:00:4274 SocketStreamMsgStart,
[email protected]94dc971d2011-03-05 19:08:3275 ResourceMsgStart,
[email protected]172f1552011-03-07 21:58:1676 FileSystemMsgStart,
[email protected]ff47b2962011-03-07 23:51:4977 ChildProcessMsgStart,
[email protected]7e3589742011-03-10 18:49:1778 ClipboardMsgStart,
[email protected]db10d8f2011-03-14 00:21:4779 BlobMsgStart,
[email protected]e93e04e2011-03-14 00:27:1080 AppCacheMsgStart,
[email protected]e7c21b812011-03-19 18:03:3081 DeviceOrientationMsgStart,
82 DesktopNotificationMsgStart,
83 GeolocationMsgStart,
[email protected]4460ee52011-03-21 19:19:2484 AudioMsgStart,
[email protected]778574e2011-03-21 22:03:5085 ChromeMsgStart,
[email protected]59f4f2fa2011-03-23 01:00:5586 DragMsgStart,
[email protected]1375e3ab2011-03-24 17:07:2287 PrintMsgStart,
[email protected]3e267192011-03-25 01:55:4588 SpellCheckMsgStart,
[email protected]44c49c92011-03-28 16:17:2389 ExtensionMsgStart,
[email protected]e1a59a22011-04-12 01:36:2590 VideoCaptureMsgStart,
[email protected]10e5cf12011-04-13 04:10:4091 QuotaMsgStart,
[email protected]ae4efe42011-04-18 21:28:0592 IconMsgStart,
[email protected]d4cff272011-05-02 15:46:0193 TextInputClientMsgStart,
[email protected]e503a122011-03-17 18:20:5294 LastIPCMsgStart // Must come last.
[email protected]f91cb992009-02-04 20:10:1295};
96
[email protected]7a4de7a62010-08-17 18:38:2497class DictionaryValue;
98class FilePath;
99class ListValue;
100class NullableString16;
101
102namespace base {
103class Time;
[email protected]d84e48b2010-10-21 22:04:52104class TimeDelta;
[email protected]7a4de7a62010-08-17 18:38:24105struct FileDescriptor;
106}
107
initial.commit09911bf2008-07-26 23:55:29108namespace IPC {
109
[email protected]7a4de7a62010-08-17 18:38:24110struct ChannelHandle;
111
initial.commit09911bf2008-07-26 23:55:29112//-----------------------------------------------------------------------------
113// An iterator class for reading the fields contained within a Message.
114
115class MessageIterator {
116 public:
[email protected]e1981f432008-08-12 15:22:13117 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
initial.commit09911bf2008-07-26 23:55:29118 }
119 int NextInt() const {
[email protected]9422b7dc2009-12-30 20:09:02120 int val = -1;
initial.commit09911bf2008-07-26 23:55:29121 if (!msg_.ReadInt(&iter_, &val))
122 NOTREACHED();
123 return val;
124 }
initial.commit09911bf2008-07-26 23:55:29125 const std::string NextString() const {
126 std::string val;
127 if (!msg_.ReadString(&iter_, &val))
128 NOTREACHED();
129 return val;
130 }
131 const std::wstring NextWString() const {
132 std::wstring val;
133 if (!msg_.ReadWString(&iter_, &val))
134 NOTREACHED();
135 return val;
136 }
[email protected]225c8f52010-02-05 22:23:20137 void NextData(const char** data, int* length) const {
initial.commit09911bf2008-07-26 23:55:29138 if (!msg_.ReadData(&iter_, data, length)) {
139 NOTREACHED();
140 }
141 }
142 private:
143 const Message& msg_;
144 mutable void* iter_;
145};
146
147//-----------------------------------------------------------------------------
[email protected]6476c72c2011-02-11 18:46:19148// A dummy struct to place first just to allow leading commas for all
149// members in the macro-generated constructor initializer lists.
150struct NoParams {
151};
152
153//-----------------------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19154// ParamTraits specializations, etc.
155
[email protected]7d5c3ac2009-02-04 08:58:19156template <class P>
157static inline void WriteParam(Message* m, const P& p) {
[email protected]7b291f92009-08-14 05:43:53158 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53159 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
[email protected]7d5c3ac2009-02-04 08:58:19160}
161
162template <class P>
[email protected]1e86aa62009-04-24 21:22:33163static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
164 P* p) {
[email protected]7b291f92009-08-14 05:43:53165 typedef typename SimilarTypeTraits<P>::Type Type;
166 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
[email protected]7d5c3ac2009-02-04 08:58:19167}
168
169template <class P>
[email protected]252cad62010-08-18 18:33:57170static inline void LogParam(const P& p, std::string* l) {
[email protected]7b291f92009-08-14 05:43:53171 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53172 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19173}
174
175template <>
176struct ParamTraits<bool> {
177 typedef bool param_type;
178 static void Write(Message* m, const param_type& p) {
179 m->WriteBool(p);
180 }
181 static bool Read(const Message* m, void** iter, param_type* r) {
182 return m->ReadBool(iter, r);
183 }
[email protected]252cad62010-08-18 18:33:57184 static void Log(const param_type& p, std::string* l) {
185 l->append(p ? "true" : "false");
[email protected]7d5c3ac2009-02-04 08:58:19186 }
187};
188
189template <>
190struct ParamTraits<int> {
191 typedef int param_type;
192 static void Write(Message* m, const param_type& p) {
193 m->WriteInt(p);
194 }
195 static bool Read(const Message* m, void** iter, param_type* r) {
196 return m->ReadInt(iter, r);
197 }
[email protected]252cad62010-08-18 18:33:57198 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19199};
200
201template <>
[email protected]63263f92009-07-28 19:35:08202struct ParamTraits<unsigned int> {
203 typedef unsigned int param_type;
204 static void Write(Message* m, const param_type& p) {
205 m->WriteInt(p);
206 }
207 static bool Read(const Message* m, void** iter, param_type* r) {
208 return m->ReadInt(iter, reinterpret_cast<int*>(r));
209 }
[email protected]252cad62010-08-18 18:33:57210 static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08211};
212
213template <>
[email protected]7d5c3ac2009-02-04 08:58:19214struct ParamTraits<long> {
215 typedef long param_type;
216 static void Write(Message* m, const param_type& p) {
217 m->WriteLong(p);
218 }
219 static bool Read(const Message* m, void** iter, param_type* r) {
220 return m->ReadLong(iter, r);
221 }
[email protected]252cad62010-08-18 18:33:57222 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19223};
224
[email protected]140c3032009-06-26 18:22:54225template <>
226struct ParamTraits<unsigned long> {
227 typedef unsigned long param_type;
228 static void Write(Message* m, const param_type& p) {
229 m->WriteLong(p);
230 }
231 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]63263f92009-07-28 19:35:08232 return m->ReadLong(iter, reinterpret_cast<long*>(r));
[email protected]140c3032009-06-26 18:22:54233 }
[email protected]252cad62010-08-18 18:33:57234 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19235};
236
237template <>
[email protected]63263f92009-07-28 19:35:08238struct ParamTraits<long long> {
239 typedef long long param_type;
[email protected]7d5c3ac2009-02-04 08:58:19240 static void Write(Message* m, const param_type& p) {
241 m->WriteInt64(static_cast<int64>(p));
242 }
243 static bool Read(const Message* m, void** iter, param_type* r) {
244 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
245 }
[email protected]252cad62010-08-18 18:33:57246 static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08247};
248
249template <>
250struct ParamTraits<unsigned long long> {
251 typedef unsigned long long param_type;
252 static void Write(Message* m, const param_type& p) {
253 m->WriteInt64(p);
254 }
255 static bool Read(const Message* m, void** iter, param_type* r) {
256 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
257 }
[email protected]252cad62010-08-18 18:33:57258 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19259};
260
[email protected]43a40202010-11-12 16:25:01261template <>
262struct ParamTraits<unsigned short> {
263 typedef unsigned short param_type;
264 static void Write(Message* m, const param_type& p);
265 static bool Read(const Message* m, void** iter, param_type* r);
266 static void Log(const param_type& p, std::string* l);
267};
268
[email protected]20199662010-06-17 03:29:26269// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
270// should be sure to check the sanity of these values after receiving them over
271// IPC.
272template <>
273struct ParamTraits<float> {
274 typedef float param_type;
275 static void Write(Message* m, const param_type& p) {
276 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
277 }
278 static bool Read(const Message* m, void** iter, param_type* r) {
279 const char *data;
280 int data_size;
281 if (!m->ReadData(iter, &data, &data_size) ||
282 data_size != sizeof(param_type)) {
283 NOTREACHED();
284 return false;
285 }
286 memcpy(r, data, sizeof(param_type));
287 return true;
288 }
[email protected]252cad62010-08-18 18:33:57289 static void Log(const param_type& p, std::string* l) {
290 l->append(StringPrintf("%e", p));
[email protected]20199662010-06-17 03:29:26291 }
292};
293
[email protected]7d5c3ac2009-02-04 08:58:19294template <>
295struct ParamTraits<double> {
296 typedef double param_type;
297 static void Write(Message* m, const param_type& p) {
298 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
299 }
300 static bool Read(const Message* m, void** iter, param_type* r) {
301 const char *data;
[email protected]20199662010-06-17 03:29:26302 int data_size;
303 if (!m->ReadData(iter, &data, &data_size) ||
304 data_size != sizeof(param_type)) {
[email protected]7d5c3ac2009-02-04 08:58:19305 NOTREACHED();
[email protected]20199662010-06-17 03:29:26306 return false;
[email protected]7d5c3ac2009-02-04 08:58:19307 }
[email protected]20199662010-06-17 03:29:26308 memcpy(r, data, sizeof(param_type));
309 return true;
[email protected]7d5c3ac2009-02-04 08:58:19310 }
[email protected]252cad62010-08-18 18:33:57311 static void Log(const param_type& p, std::string* l) {
312 l->append(StringPrintf("%e", p));
[email protected]7d5c3ac2009-02-04 08:58:19313 }
314};
315
316template <>
[email protected]7d5c3ac2009-02-04 08:58:19317struct ParamTraits<base::Time> {
318 typedef base::Time param_type;
[email protected]7a4de7a62010-08-17 18:38:24319 static void Write(Message* m, const param_type& p);
320 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57321 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19322};
323
[email protected]d84e48b2010-10-21 22:04:52324template <>
325struct ParamTraits<base::TimeDelta> {
326 typedef base::TimeDelta param_type;
327 static void Write(Message* m, const param_type& p);
328 static bool Read(const Message* m, void** iter, param_type* r);
329 static void Log(const param_type& p, std::string* l);
330};
331
[email protected]7d5c3ac2009-02-04 08:58:19332#if defined(OS_WIN)
333template <>
334struct ParamTraits<LOGFONT> {
335 typedef LOGFONT param_type;
336 static void Write(Message* m, const param_type& p) {
337 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
338 }
339 static bool Read(const Message* m, void** iter, param_type* r) {
340 const char *data;
341 int data_size = 0;
342 bool result = m->ReadData(iter, &data, &data_size);
343 if (result && data_size == sizeof(LOGFONT)) {
344 memcpy(r, data, sizeof(LOGFONT));
345 } else {
346 result = false;
347 NOTREACHED();
348 }
349
350 return result;
351 }
[email protected]252cad62010-08-18 18:33:57352 static void Log(const param_type& p, std::string* l) {
353 l->append(StringPrintf("<LOGFONT>"));
[email protected]7d5c3ac2009-02-04 08:58:19354 }
355};
356
357template <>
358struct ParamTraits<MSG> {
359 typedef MSG param_type;
360 static void Write(Message* m, const param_type& p) {
361 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
362 }
363 static bool Read(const Message* m, void** iter, param_type* r) {
364 const char *data;
365 int data_size = 0;
366 bool result = m->ReadData(iter, &data, &data_size);
367 if (result && data_size == sizeof(MSG)) {
368 memcpy(r, data, sizeof(MSG));
369 } else {
370 result = false;
371 NOTREACHED();
372 }
373
374 return result;
375 }
[email protected]252cad62010-08-18 18:33:57376 static void Log(const param_type& p, std::string* l) {
377 l->append("<MSG>");
[email protected]7a4de7a62010-08-17 18:38:24378 }
[email protected]7d5c3ac2009-02-04 08:58:19379};
380#endif // defined(OS_WIN)
381
382template <>
[email protected]584f2b22009-05-21 01:01:59383struct ParamTraits<DictionaryValue> {
384 typedef DictionaryValue param_type;
385 static void Write(Message* m, const param_type& p);
386 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57387 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59388};
389
390template <>
391struct ParamTraits<ListValue> {
392 typedef ListValue param_type;
393 static void Write(Message* m, const param_type& p);
394 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57395 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59396};
397
398template <>
[email protected]7d5c3ac2009-02-04 08:58:19399struct ParamTraits<std::string> {
400 typedef std::string param_type;
401 static void Write(Message* m, const param_type& p) {
402 m->WriteString(p);
403 }
404 static bool Read(const Message* m, void** iter, param_type* r) {
405 return m->ReadString(iter, r);
406 }
[email protected]252cad62010-08-18 18:33:57407 static void Log(const param_type& p, std::string* l) {
408 l->append(p);
[email protected]7d5c3ac2009-02-04 08:58:19409 }
410};
411
[email protected]3dd7a7a2009-07-27 21:09:07412template<typename CharType>
[email protected]252cad62010-08-18 18:33:57413static void LogBytes(const std::vector<CharType>& data, std::string* out) {
[email protected]3dd7a7a2009-07-27 21:09:07414#if defined(OS_WIN)
415 // Windows has a GUI for logging, which can handle arbitrary binary data.
416 for (size_t i = 0; i < data.size(); ++i)
417 out->push_back(data[i]);
418#else
419 // On POSIX, we log to stdout, which we assume can display ASCII.
420 static const size_t kMaxBytesToLog = 100;
421 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
422 if (isprint(data[i]))
423 out->push_back(data[i]);
424 else
[email protected]252cad62010-08-18 18:33:57425 out->append(StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
[email protected]3dd7a7a2009-07-27 21:09:07426 }
427 if (data.size() > kMaxBytesToLog) {
428 out->append(
[email protected]252cad62010-08-18 18:33:57429 StringPrintf(" and %u more bytes",
[email protected]3dd7a7a2009-07-27 21:09:07430 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
431 }
432#endif
433}
434
[email protected]7d5c3ac2009-02-04 08:58:19435template <>
436struct ParamTraits<std::vector<unsigned char> > {
437 typedef std::vector<unsigned char> param_type;
438 static void Write(Message* m, const param_type& p) {
[email protected]f6b8ce32011-03-02 00:03:18439 if (p.empty()) {
[email protected]7d5c3ac2009-02-04 08:58:19440 m->WriteData(NULL, 0);
441 } else {
442 m->WriteData(reinterpret_cast<const char*>(&p.front()),
443 static_cast<int>(p.size()));
444 }
445 }
446 static bool Read(const Message* m, void** iter, param_type* r) {
447 const char *data;
448 int data_size = 0;
449 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
450 return false;
451 r->resize(data_size);
452 if (data_size)
453 memcpy(&r->front(), data, data_size);
454 return true;
455 }
[email protected]252cad62010-08-18 18:33:57456 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07457 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19458 }
459};
460
461template <>
462struct ParamTraits<std::vector<char> > {
463 typedef std::vector<char> param_type;
464 static void Write(Message* m, const param_type& p) {
[email protected]f6b8ce32011-03-02 00:03:18465 if (p.empty()) {
[email protected]7d5c3ac2009-02-04 08:58:19466 m->WriteData(NULL, 0);
467 } else {
468 m->WriteData(&p.front(), static_cast<int>(p.size()));
469 }
470 }
471 static bool Read(const Message* m, void** iter, param_type* r) {
472 const char *data;
473 int data_size = 0;
474 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
475 return false;
476 r->resize(data_size);
477 if (data_size)
478 memcpy(&r->front(), data, data_size);
479 return true;
480 }
[email protected]252cad62010-08-18 18:33:57481 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07482 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19483 }
484};
485
486template <class P>
487struct ParamTraits<std::vector<P> > {
488 typedef std::vector<P> param_type;
489 static void Write(Message* m, const param_type& p) {
490 WriteParam(m, static_cast<int>(p.size()));
491 for (size_t i = 0; i < p.size(); i++)
492 WriteParam(m, p[i]);
493 }
494 static bool Read(const Message* m, void** iter, param_type* r) {
495 int size;
[email protected]86440f52009-12-31 05:17:23496 // ReadLength() checks for < 0 itself.
[email protected]7d5c3ac2009-02-04 08:58:19497 if (!m->ReadLength(iter, &size))
498 return false;
499 // Resizing beforehand is not safe, see BUG 1006367 for details.
[email protected]86440f52009-12-31 05:17:23500 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
501 return false;
502 r->resize(size);
503 for (int i = 0; i < size; i++) {
504 if (!ReadParam(m, iter, &(*r)[i]))
505 return false;
[email protected]7d5c3ac2009-02-04 08:58:19506 }
507 return true;
508 }
[email protected]252cad62010-08-18 18:33:57509 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19510 for (size_t i = 0; i < p.size(); ++i) {
511 if (i != 0)
[email protected]252cad62010-08-18 18:33:57512 l->append(" ");
[email protected]7d5c3ac2009-02-04 08:58:19513 LogParam((p[i]), l);
514 }
515 }
516};
517
[email protected]96da6962010-05-13 19:10:34518template <class P>
519struct ParamTraits<std::set<P> > {
520 typedef std::set<P> param_type;
521 static void Write(Message* m, const param_type& p) {
522 WriteParam(m, static_cast<int>(p.size()));
523 typename param_type::const_iterator iter;
524 for (iter = p.begin(); iter != p.end(); ++iter)
525 WriteParam(m, *iter);
526 }
527 static bool Read(const Message* m, void** iter, param_type* r) {
528 int size;
529 if (!m->ReadLength(iter, &size))
530 return false;
531 for (int i = 0; i < size; ++i) {
532 P item;
533 if (!ReadParam(m, iter, &item))
534 return false;
535 r->insert(item);
536 }
537 return true;
538 }
[email protected]252cad62010-08-18 18:33:57539 static void Log(const param_type& p, std::string* l) {
540 l->append("<std::set>");
[email protected]96da6962010-05-13 19:10:34541 }
542};
543
544
[email protected]7d5c3ac2009-02-04 08:58:19545template <class K, class V>
546struct ParamTraits<std::map<K, V> > {
547 typedef std::map<K, V> param_type;
548 static void Write(Message* m, const param_type& p) {
549 WriteParam(m, static_cast<int>(p.size()));
550 typename param_type::const_iterator iter;
551 for (iter = p.begin(); iter != p.end(); ++iter) {
552 WriteParam(m, iter->first);
553 WriteParam(m, iter->second);
554 }
555 }
556 static bool Read(const Message* m, void** iter, param_type* r) {
557 int size;
558 if (!ReadParam(m, iter, &size) || size < 0)
559 return false;
560 for (int i = 0; i < size; ++i) {
561 K k;
562 if (!ReadParam(m, iter, &k))
563 return false;
564 V& value = (*r)[k];
565 if (!ReadParam(m, iter, &value))
566 return false;
567 }
568 return true;
569 }
[email protected]252cad62010-08-18 18:33:57570 static void Log(const param_type& p, std::string* l) {
571 l->append("<std::map>");
[email protected]7d5c3ac2009-02-04 08:58:19572 }
573};
574
[email protected]eb47a132009-03-04 00:39:56575
[email protected]7d5c3ac2009-02-04 08:58:19576template <>
577struct ParamTraits<std::wstring> {
578 typedef std::wstring param_type;
579 static void Write(Message* m, const param_type& p) {
580 m->WriteWString(p);
581 }
582 static bool Read(const Message* m, void** iter, param_type* r) {
583 return m->ReadWString(iter, r);
584 }
[email protected]252cad62010-08-18 18:33:57585 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19586};
587
[email protected]a5da6d612009-08-04 02:00:56588template <class A, class B>
589struct ParamTraits<std::pair<A, B> > {
590 typedef std::pair<A, B> param_type;
591 static void Write(Message* m, const param_type& p) {
592 WriteParam(m, p.first);
593 WriteParam(m, p.second);
594 }
595 static bool Read(const Message* m, void** iter, param_type* r) {
596 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
597 }
[email protected]252cad62010-08-18 18:33:57598 static void Log(const param_type& p, std::string* l) {
599 l->append("(");
[email protected]a5da6d612009-08-04 02:00:56600 LogParam(p.first, l);
[email protected]252cad62010-08-18 18:33:57601 l->append(", ");
[email protected]a5da6d612009-08-04 02:00:56602 LogParam(p.second, l);
[email protected]252cad62010-08-18 18:33:57603 l->append(")");
[email protected]a5da6d612009-08-04 02:00:56604 }
605};
606
[email protected]15bf8712009-08-27 00:55:02607template <>
608struct ParamTraits<NullableString16> {
609 typedef NullableString16 param_type;
[email protected]7a4de7a62010-08-17 18:38:24610 static void Write(Message* m, const param_type& p);
611 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57612 static void Log(const param_type& p, std::string* l);
[email protected]15bf8712009-08-27 00:55:02613};
614
[email protected]eb47a132009-03-04 00:39:56615// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
616// need this trait.
617#if !defined(WCHAR_T_IS_UTF16)
[email protected]eb47a132009-03-04 00:39:56618template <>
619struct ParamTraits<string16> {
620 typedef string16 param_type;
621 static void Write(Message* m, const param_type& p) {
[email protected]3a2a5d22009-03-04 03:36:36622 m->WriteString16(p);
[email protected]eb47a132009-03-04 00:39:56623 }
624 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]3a2a5d22009-03-04 03:36:36625 return m->ReadString16(iter, r);
[email protected]eb47a132009-03-04 00:39:56626 }
[email protected]252cad62010-08-18 18:33:57627 static void Log(const param_type& p, std::string* l);
[email protected]eb47a132009-03-04 00:39:56628};
[email protected]eb47a132009-03-04 00:39:56629#endif
630
[email protected]7d5c3ac2009-02-04 08:58:19631// and, a few more useful types...
632#if defined(OS_WIN)
633template <>
634struct ParamTraits<HANDLE> {
635 typedef HANDLE param_type;
636 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35637 // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
638 // bit systems.
639 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19640 }
641 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35642 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
643 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19644 }
[email protected]252cad62010-08-18 18:33:57645 static void Log(const param_type& p, std::string* l) {
646 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19647 }
648};
649
650template <>
651struct ParamTraits<HCURSOR> {
652 typedef HCURSOR param_type;
653 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35654 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19655 }
656 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35657 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
658 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19659 }
[email protected]252cad62010-08-18 18:33:57660 static void Log(const param_type& p, std::string* l) {
661 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19662 }
663};
664
665template <>
[email protected]7d5c3ac2009-02-04 08:58:19666struct ParamTraits<HACCEL> {
667 typedef HACCEL param_type;
668 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35669 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19670 }
671 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35672 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
673 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19674 }
675};
676
677template <>
678struct ParamTraits<POINT> {
679 typedef POINT param_type;
680 static void Write(Message* m, const param_type& p) {
681 m->WriteInt(p.x);
682 m->WriteInt(p.y);
683 }
684 static bool Read(const Message* m, void** iter, param_type* r) {
685 int x, y;
686 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
687 return false;
688 r->x = x;
689 r->y = y;
690 return true;
691 }
[email protected]252cad62010-08-18 18:33:57692 static void Log(const param_type& p, std::string* l) {
693 l->append(StringPrintf("(%d, %d)", p.x, p.y));
[email protected]7d5c3ac2009-02-04 08:58:19694 }
695};
696#endif // defined(OS_WIN)
697
698template <>
699struct ParamTraits<FilePath> {
700 typedef FilePath param_type;
[email protected]7a4de7a62010-08-17 18:38:24701 static void Write(Message* m, const param_type& p);
702 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57703 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19704};
705
[email protected]526776c2009-02-07 00:39:26706#if defined(OS_POSIX)
[email protected]2749885f2009-03-05 21:40:11707// FileDescriptors may be serialised over IPC channels on POSIX. On the
708// receiving side, the FileDescriptor is a valid duplicate of the file
709// descriptor which was transmitted: *it is not just a copy of the integer like
710// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
711// this case, the receiving end will see a value of -1. *Zero is a valid file
712// descriptor*.
713//
714// The received file descriptor will have the |auto_close| flag set to true. The
715// code which handles the message is responsible for taking ownership of it.
716// File descriptors are OS resources and must be closed when no longer needed.
717//
718// When sending a file descriptor, the file descriptor must be valid at the time
719// of transmission. Since transmission is not synchronous, one should consider
720// dup()ing any file descriptors to be transmitted and setting the |auto_close|
721// flag, which causes the file descriptor to be closed after writing.
[email protected]526776c2009-02-07 00:39:26722template<>
[email protected]5fe733de2009-02-11 18:59:20723struct ParamTraits<base::FileDescriptor> {
724 typedef base::FileDescriptor param_type;
[email protected]7a4de7a62010-08-17 18:38:24725 static void Write(Message* m, const param_type& p);
726 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57727 static void Log(const param_type& p, std::string* l);
[email protected]526776c2009-02-07 00:39:26728};
[email protected]379e7a52010-03-09 00:38:41729#endif // defined(OS_POSIX)
[email protected]526776c2009-02-07 00:39:26730
[email protected]d2e884d2009-06-22 20:37:52731// A ChannelHandle is basically a platform-inspecific wrapper around the
732// fact that IPC endpoints are handled specially on POSIX. See above comments
733// on FileDescriptor for more background.
734template<>
735struct ParamTraits<IPC::ChannelHandle> {
736 typedef ChannelHandle param_type;
[email protected]7a4de7a62010-08-17 18:38:24737 static void Write(Message* m, const param_type& p);
738 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57739 static void Log(const param_type& p, std::string* l);
[email protected]d2e884d2009-06-22 20:37:52740};
741
[email protected]7d5c3ac2009-02-04 08:58:19742#if defined(OS_WIN)
743template <>
744struct ParamTraits<XFORM> {
745 typedef XFORM param_type;
746 static void Write(Message* m, const param_type& p) {
747 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
748 }
749 static bool Read(const Message* m, void** iter, param_type* r) {
750 const char *data;
751 int data_size = 0;
752 bool result = m->ReadData(iter, &data, &data_size);
753 if (result && data_size == sizeof(XFORM)) {
754 memcpy(r, data, sizeof(XFORM));
755 } else {
756 result = false;
757 NOTREACHED();
758 }
759
760 return result;
761 }
[email protected]252cad62010-08-18 18:33:57762 static void Log(const param_type& p, std::string* l) {
763 l->append("<XFORM>");
[email protected]7d5c3ac2009-02-04 08:58:19764 }
765};
766#endif // defined(OS_WIN)
767
[email protected]7d5c3ac2009-02-04 08:58:19768struct LogData {
[email protected]20f0487a2010-09-30 20:06:30769 LogData();
770 ~LogData();
771
[email protected]9a3a293b2009-06-04 22:28:16772 std::string channel;
[email protected]8bef70e2009-04-14 19:11:24773 int32 routing_id;
[email protected]168ae922009-12-04 18:08:45774 uint32 type; // "User-defined" message type, from ipc_message.h.
[email protected]252cad62010-08-18 18:33:57775 std::string flags;
[email protected]7d5c3ac2009-02-04 08:58:19776 int64 sent; // Time that the message was sent (i.e. at Send()).
777 int64 receive; // Time before it was dispatched (i.e. before calling
778 // OnMessageReceived).
779 int64 dispatch; // Time after it was dispatched (i.e. after calling
780 // OnMessageReceived).
[email protected]252cad62010-08-18 18:33:57781 std::string message_name;
782 std::string params;
[email protected]7d5c3ac2009-02-04 08:58:19783};
784
785template <>
786struct ParamTraits<LogData> {
787 typedef LogData param_type;
[email protected]20f0487a2010-09-30 20:06:30788 static void Write(Message* m, const param_type& p);
789 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57790 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19791 // Doesn't make sense to implement this!
792 }
793};
794
[email protected]eb47a132009-03-04 00:39:56795template <>
[email protected]503683f2009-02-26 09:13:01796struct ParamTraits<Message> {
797 static void Write(Message* m, const Message& p) {
[email protected]8a861402011-01-28 19:59:11798 DCHECK(p.size() <= INT_MAX);
799 int message_size = static_cast<int>(p.size());
800 m->WriteInt(message_size);
801 m->WriteData(reinterpret_cast<const char*>(p.data()), message_size);
[email protected]503683f2009-02-26 09:13:01802 }
803 static bool Read(const Message* m, void** iter, Message* r) {
804 int size;
805 if (!m->ReadInt(iter, &size))
806 return false;
807 const char* data;
808 if (!m->ReadData(iter, &data, &size))
809 return false;
810 *r = Message(data, size);
811 return true;
812 }
[email protected]252cad62010-08-18 18:33:57813 static void Log(const Message& p, std::string* l) {
814 l->append("<IPC::Message>");
[email protected]503683f2009-02-26 09:13:01815 }
816};
817
818template <>
[email protected]7d5c3ac2009-02-04 08:58:19819struct ParamTraits<Tuple0> {
820 typedef Tuple0 param_type;
821 static void Write(Message* m, const param_type& p) {
822 }
823 static bool Read(const Message* m, void** iter, param_type* r) {
824 return true;
825 }
[email protected]252cad62010-08-18 18:33:57826 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19827 }
828};
829
830template <class A>
831struct ParamTraits< Tuple1<A> > {
832 typedef Tuple1<A> param_type;
833 static void Write(Message* m, const param_type& p) {
834 WriteParam(m, p.a);
835 }
836 static bool Read(const Message* m, void** iter, param_type* r) {
837 return ReadParam(m, iter, &r->a);
838 }
[email protected]252cad62010-08-18 18:33:57839 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19840 LogParam(p.a, l);
841 }
842};
843
844template <class A, class B>
845struct ParamTraits< Tuple2<A, B> > {
846 typedef Tuple2<A, B> param_type;
847 static void Write(Message* m, const param_type& p) {
848 WriteParam(m, p.a);
849 WriteParam(m, p.b);
850 }
851 static bool Read(const Message* m, void** iter, param_type* r) {
852 return (ReadParam(m, iter, &r->a) &&
853 ReadParam(m, iter, &r->b));
854 }
[email protected]252cad62010-08-18 18:33:57855 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19856 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57857 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19858 LogParam(p.b, l);
859 }
860};
861
862template <class A, class B, class C>
863struct ParamTraits< Tuple3<A, B, C> > {
864 typedef Tuple3<A, B, C> param_type;
865 static void Write(Message* m, const param_type& p) {
866 WriteParam(m, p.a);
867 WriteParam(m, p.b);
868 WriteParam(m, p.c);
869 }
870 static bool Read(const Message* m, void** iter, param_type* r) {
871 return (ReadParam(m, iter, &r->a) &&
872 ReadParam(m, iter, &r->b) &&
873 ReadParam(m, iter, &r->c));
874 }
[email protected]252cad62010-08-18 18:33:57875 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19876 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57877 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19878 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57879 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19880 LogParam(p.c, l);
881 }
882};
883
884template <class A, class B, class C, class D>
885struct ParamTraits< Tuple4<A, B, C, D> > {
886 typedef Tuple4<A, B, C, D> param_type;
887 static void Write(Message* m, const param_type& p) {
888 WriteParam(m, p.a);
889 WriteParam(m, p.b);
890 WriteParam(m, p.c);
891 WriteParam(m, p.d);
892 }
893 static bool Read(const Message* m, void** iter, param_type* r) {
894 return (ReadParam(m, iter, &r->a) &&
895 ReadParam(m, iter, &r->b) &&
896 ReadParam(m, iter, &r->c) &&
897 ReadParam(m, iter, &r->d));
898 }
[email protected]252cad62010-08-18 18:33:57899 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19900 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57901 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19902 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57903 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19904 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57905 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19906 LogParam(p.d, l);
907 }
908};
909
910template <class A, class B, class C, class D, class E>
911struct ParamTraits< Tuple5<A, B, C, D, E> > {
912 typedef Tuple5<A, B, C, D, E> param_type;
913 static void Write(Message* m, const param_type& p) {
914 WriteParam(m, p.a);
915 WriteParam(m, p.b);
916 WriteParam(m, p.c);
917 WriteParam(m, p.d);
918 WriteParam(m, p.e);
919 }
920 static bool Read(const Message* m, void** iter, param_type* r) {
921 return (ReadParam(m, iter, &r->a) &&
922 ReadParam(m, iter, &r->b) &&
923 ReadParam(m, iter, &r->c) &&
924 ReadParam(m, iter, &r->d) &&
925 ReadParam(m, iter, &r->e));
926 }
[email protected]252cad62010-08-18 18:33:57927 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19928 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57929 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19930 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57931 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19932 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57933 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19934 LogParam(p.d, l);
[email protected]252cad62010-08-18 18:33:57935 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19936 LogParam(p.e, l);
937 }
938};
939
[email protected]7d5c3ac2009-02-04 08:58:19940//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:29941// Generic message subclasses
942
943// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:24944template <class ParamType>
initial.commit09911bf2008-07-26 23:55:29945class MessageWithTuple : public Message {
946 public:
[email protected]81a34412009-01-05 19:17:24947 typedef ParamType Param;
[email protected]7a4de7a62010-08-17 18:38:24948 typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
[email protected]81a34412009-01-05 19:17:24949
[email protected]7a4de7a62010-08-17 18:38:24950 // The constructor and the Read() method's templated implementations are in
951 // ipc_message_utils_impl.h. The subclass constructor and Log() methods call
952 // the templated versions of these and make sure there are instantiations in
953 // those translation units.
954 MessageWithTuple(int32 routing_id, uint32 type, const RefParam& p);
[email protected]071b4b92010-08-09 16:06:58955
[email protected]7a4de7a62010-08-17 18:38:24956 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:29957
958 // Generic dispatcher. Should cover most cases.
[email protected]65412272010-12-21 20:03:24959 template<class T, class S, class Method>
960 static bool Dispatch(const Message* msg, T* obj, S* sender, Method func) {
initial.commit09911bf2008-07-26 23:55:29961 Param p;
962 if (Read(msg, &p)) {
963 DispatchToMethod(obj, func, p);
964 return true;
965 }
966 return false;
967 }
968
969 // The following dispatchers exist for the case where the callback function
970 // needs the message as well. They assume that "Param" is a type of Tuple
971 // (except the one arg case, as there is no Tuple1).
[email protected]65412272010-12-21 20:03:24972 template<class T, class S, typename TA>
973 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29974 void (T::*func)(const Message&, TA)) {
975 Param p;
976 if (Read(msg, &p)) {
[email protected]c2fe31542009-05-20 18:24:14977 (obj->*func)(*msg, p.a);
initial.commit09911bf2008-07-26 23:55:29978 return true;
979 }
980 return false;
981 }
982
[email protected]65412272010-12-21 20:03:24983 template<class T, class S, typename TA, typename TB>
984 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29985 void (T::*func)(const Message&, TA, TB)) {
986 Param p;
987 if (Read(msg, &p)) {
988 (obj->*func)(*msg, p.a, p.b);
989 return true;
990 }
991 return false;
992 }
993
[email protected]65412272010-12-21 20:03:24994 template<class T, class S, typename TA, typename TB, typename TC>
995 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29996 void (T::*func)(const Message&, TA, TB, TC)) {
997 Param p;
998 if (Read(msg, &p)) {
999 (obj->*func)(*msg, p.a, p.b, p.c);
1000 return true;
1001 }
1002 return false;
1003 }
1004
[email protected]65412272010-12-21 20:03:241005 template<class T, class S, typename TA, typename TB, typename TC, typename TD>
1006 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:291007 void (T::*func)(const Message&, TA, TB, TC, TD)) {
1008 Param p;
1009 if (Read(msg, &p)) {
1010 (obj->*func)(*msg, p.a, p.b, p.c, p.d);
1011 return true;
1012 }
1013 return false;
1014 }
1015
[email protected]65412272010-12-21 20:03:241016 template<class T, class S, typename TA, typename TB, typename TC, typename TD,
initial.commit09911bf2008-07-26 23:55:291017 typename TE>
[email protected]65412272010-12-21 20:03:241018 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:291019 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
1020 Param p;
1021 if (Read(msg, &p)) {
1022 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
1023 return true;
1024 }
1025 return false;
1026 }
1027
[email protected]deb57402009-02-06 01:35:301028 // Functions used to do manual unpacking. Only used by the automation code,
1029 // these should go away once that code uses SyncChannel.
1030 template<typename TA, typename TB>
1031 static bool Read(const IPC::Message* msg, TA* a, TB* b) {
1032 ParamType params;
1033 if (!Read(msg, &params))
1034 return false;
1035 *a = params.a;
1036 *b = params.b;
1037 return true;
1038 }
1039
1040 template<typename TA, typename TB, typename TC>
1041 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
1042 ParamType params;
1043 if (!Read(msg, &params))
1044 return false;
1045 *a = params.a;
1046 *b = params.b;
1047 *c = params.c;
1048 return true;
1049 }
1050
1051 template<typename TA, typename TB, typename TC, typename TD>
1052 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) {
1053 ParamType params;
1054 if (!Read(msg, &params))
1055 return false;
1056 *a = params.a;
1057 *b = params.b;
1058 *c = params.c;
1059 *d = params.d;
1060 return true;
1061 }
1062
1063 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1064 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) {
1065 ParamType params;
1066 if (!Read(msg, &params))
1067 return false;
1068 *a = params.a;
1069 *b = params.b;
1070 *c = params.c;
1071 *d = params.d;
1072 *e = params.e;
1073 return true;
1074 }
initial.commit09911bf2008-07-26 23:55:291075};
1076
[email protected]7a4de7a62010-08-17 18:38:241077// defined in ipc_logging.cc
1078void GenerateLogData(const std::string& channel, const Message& message,
1079 LogData* data);
1080
1081
1082#if defined(IPC_MESSAGE_LOG_ENABLED)
[email protected]252cad62010-08-18 18:33:571083inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
1084 const std::string& output_params = msg->output_params();
[email protected]7a4de7a62010-08-17 18:38:241085 if (!l->empty() && !output_params.empty())
[email protected]252cad62010-08-18 18:33:571086 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:241087
1088 l->append(output_params);
1089}
1090
1091template <class ReplyParamType>
1092inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1093 const Message* msg) {
1094 if (msg->received_time() != 0) {
[email protected]252cad62010-08-18 18:33:571095 std::string output_params;
[email protected]7a4de7a62010-08-17 18:38:241096 LogParam(reply_params, &output_params);
1097 msg->set_output_params(output_params);
1098 }
1099}
1100
1101inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
1102 if (msg->sent_time()) {
1103 // Don't log the sync message after dispatch, as we don't have the
1104 // output parameters at that point. Instead, save its data and log it
1105 // with the outgoing reply message when it's sent.
1106 LogData* data = new LogData;
1107 GenerateLogData("", *msg, data);
1108 msg->set_dont_log();
1109 reply->set_sync_log_data(data);
1110 }
1111}
1112#else
[email protected]252cad62010-08-18 18:33:571113inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
[email protected]7a4de7a62010-08-17 18:38:241114
1115template <class ReplyParamType>
1116inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1117 const Message* msg) {}
1118
1119inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1120#endif
1121
initial.commit09911bf2008-07-26 23:55:291122// This class assumes that its template argument is a RefTuple (a Tuple with
[email protected]7a4de7a62010-08-17 18:38:241123// reference elements). This would go into ipc_message_utils_impl.h, but it is
1124// also used by chrome_frame.
initial.commit09911bf2008-07-26 23:55:291125template <class RefTuple>
1126class ParamDeserializer : public MessageReplyDeserializer {
1127 public:
[email protected]e1981f432008-08-12 15:22:131128 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:291129
1130 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1131 return ReadParam(&msg, &iter, &out_);
1132 }
1133
1134 RefTuple out_;
1135};
1136
initial.commit09911bf2008-07-26 23:55:291137// Used for synchronous messages.
[email protected]75e5a872009-04-02 23:56:111138template <class SendParamType, class ReplyParamType>
initial.commit09911bf2008-07-26 23:55:291139class MessageWithReply : public SyncMessage {
1140 public:
[email protected]75e5a872009-04-02 23:56:111141 typedef SendParamType SendParam;
[email protected]7a4de7a62010-08-17 18:38:241142 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
[email protected]75e5a872009-04-02 23:56:111143 typedef ReplyParamType ReplyParam;
1144
[email protected]168ae922009-12-04 18:08:451145 MessageWithReply(int32 routing_id, uint32 type,
[email protected]7a4de7a62010-08-17 18:38:241146 const RefSendParam& send, const ReplyParam& reply);
1147 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
1148 static bool ReadReplyParam(
1149 const Message* msg,
1150 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:291151
[email protected]65412272010-12-21 20:03:241152 template<class T, class S, class Method>
1153 static bool Dispatch(const Message* msg, T* obj, S* sender, Method func) {
initial.commit09911bf2008-07-26 23:55:291154 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291155 Message* reply = GenerateReply(msg);
1156 bool error;
[email protected]7a4de7a62010-08-17 18:38:241157 if (ReadSendParam(msg, &send_params)) {
1158 typename TupleTypes<ReplyParam>::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:291159 DispatchToMethod(obj, func, send_params, &reply_params);
1160 WriteParam(reply, reply_params);
1161 error = false;
[email protected]7a4de7a62010-08-17 18:38:241162 LogReplyParamsToMessage(reply_params, msg);
initial.commit09911bf2008-07-26 23:55:291163 } else {
1164 NOTREACHED() << "Error deserializing message " << msg->type();
1165 reply->set_reply_error();
1166 error = true;
1167 }
1168
[email protected]65412272010-12-21 20:03:241169 sender->Send(reply);
initial.commit09911bf2008-07-26 23:55:291170 return !error;
1171 }
1172
1173 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191174 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291175 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291176 Message* reply = GenerateReply(msg);
1177 bool error;
[email protected]7a4de7a62010-08-17 18:38:241178 if (ReadSendParam(msg, &send_params)) {
initial.commit09911bf2008-07-26 23:55:291179 Tuple1<Message&> t = MakeRefTuple(*reply);
[email protected]7a4de7a62010-08-17 18:38:241180 ConnectMessageAndReply(msg, reply);
initial.commit09911bf2008-07-26 23:55:291181 DispatchToMethod(obj, func, send_params, &t);
1182 error = false;
1183 } else {
1184 NOTREACHED() << "Error deserializing message " << msg->type();
1185 reply->set_reply_error();
1186 obj->Send(reply);
1187 error = true;
1188 }
1189 return !error;
1190 }
1191
1192 template<typename TA>
1193 static void WriteReplyParams(Message* reply, TA a) {
1194 ReplyParam p(a);
1195 WriteParam(reply, p);
1196 }
1197
1198 template<typename TA, typename TB>
1199 static void WriteReplyParams(Message* reply, TA a, TB b) {
1200 ReplyParam p(a, b);
1201 WriteParam(reply, p);
1202 }
1203
1204 template<typename TA, typename TB, typename TC>
1205 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1206 ReplyParam p(a, b, c);
1207 WriteParam(reply, p);
1208 }
1209
1210 template<typename TA, typename TB, typename TC, typename TD>
1211 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1212 ReplyParam p(a, b, c, d);
1213 WriteParam(reply, p);
1214 }
1215
1216 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1217 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1218 ReplyParam p(a, b, c, d, e);
1219 WriteParam(reply, p);
1220 }
1221};
1222
[email protected]7d5c3ac2009-02-04 08:58:191223//-----------------------------------------------------------------------------
1224
[email protected]3178f4e22008-08-05 21:20:411225} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291226
[email protected]946d1b22009-07-22 23:57:211227#endif // IPC_IPC_MESSAGE_UTILS_H_