blob: 6aaa3f3b99bfde022a5ef3fdefbfc2d4b0595e5a [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]e503a122011-03-17 18:20:5284 LastIPCMsgStart // Must come last.
[email protected]f91cb992009-02-04 20:10:1285};
86
[email protected]7a4de7a62010-08-17 18:38:2487class DictionaryValue;
88class FilePath;
89class ListValue;
90class NullableString16;
91
92namespace base {
93class Time;
[email protected]d84e48b2010-10-21 22:04:5294class TimeDelta;
[email protected]7a4de7a62010-08-17 18:38:2495struct FileDescriptor;
96}
97
initial.commit09911bf2008-07-26 23:55:2998namespace IPC {
99
[email protected]7a4de7a62010-08-17 18:38:24100struct ChannelHandle;
101
initial.commit09911bf2008-07-26 23:55:29102//-----------------------------------------------------------------------------
103// An iterator class for reading the fields contained within a Message.
104
105class MessageIterator {
106 public:
[email protected]e1981f432008-08-12 15:22:13107 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
initial.commit09911bf2008-07-26 23:55:29108 }
109 int NextInt() const {
[email protected]9422b7dc2009-12-30 20:09:02110 int val = -1;
initial.commit09911bf2008-07-26 23:55:29111 if (!msg_.ReadInt(&iter_, &val))
112 NOTREACHED();
113 return val;
114 }
initial.commit09911bf2008-07-26 23:55:29115 const std::string NextString() const {
116 std::string val;
117 if (!msg_.ReadString(&iter_, &val))
118 NOTREACHED();
119 return val;
120 }
121 const std::wstring NextWString() const {
122 std::wstring val;
123 if (!msg_.ReadWString(&iter_, &val))
124 NOTREACHED();
125 return val;
126 }
[email protected]225c8f52010-02-05 22:23:20127 void NextData(const char** data, int* length) const {
initial.commit09911bf2008-07-26 23:55:29128 if (!msg_.ReadData(&iter_, data, length)) {
129 NOTREACHED();
130 }
131 }
132 private:
133 const Message& msg_;
134 mutable void* iter_;
135};
136
137//-----------------------------------------------------------------------------
[email protected]6476c72c2011-02-11 18:46:19138// A dummy struct to place first just to allow leading commas for all
139// members in the macro-generated constructor initializer lists.
140struct NoParams {
141};
142
143//-----------------------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19144// ParamTraits specializations, etc.
145
[email protected]7d5c3ac2009-02-04 08:58:19146template <class P>
147static inline void WriteParam(Message* m, const P& p) {
[email protected]7b291f92009-08-14 05:43:53148 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53149 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
[email protected]7d5c3ac2009-02-04 08:58:19150}
151
152template <class P>
[email protected]1e86aa62009-04-24 21:22:33153static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
154 P* p) {
[email protected]7b291f92009-08-14 05:43:53155 typedef typename SimilarTypeTraits<P>::Type Type;
156 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
[email protected]7d5c3ac2009-02-04 08:58:19157}
158
159template <class P>
[email protected]252cad62010-08-18 18:33:57160static inline void LogParam(const P& p, std::string* l) {
[email protected]7b291f92009-08-14 05:43:53161 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53162 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19163}
164
165template <>
166struct ParamTraits<bool> {
167 typedef bool param_type;
168 static void Write(Message* m, const param_type& p) {
169 m->WriteBool(p);
170 }
171 static bool Read(const Message* m, void** iter, param_type* r) {
172 return m->ReadBool(iter, r);
173 }
[email protected]252cad62010-08-18 18:33:57174 static void Log(const param_type& p, std::string* l) {
175 l->append(p ? "true" : "false");
[email protected]7d5c3ac2009-02-04 08:58:19176 }
177};
178
179template <>
180struct ParamTraits<int> {
181 typedef int param_type;
182 static void Write(Message* m, const param_type& p) {
183 m->WriteInt(p);
184 }
185 static bool Read(const Message* m, void** iter, param_type* r) {
186 return m->ReadInt(iter, r);
187 }
[email protected]252cad62010-08-18 18:33:57188 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19189};
190
191template <>
[email protected]63263f92009-07-28 19:35:08192struct ParamTraits<unsigned int> {
193 typedef unsigned int param_type;
194 static void Write(Message* m, const param_type& p) {
195 m->WriteInt(p);
196 }
197 static bool Read(const Message* m, void** iter, param_type* r) {
198 return m->ReadInt(iter, reinterpret_cast<int*>(r));
199 }
[email protected]252cad62010-08-18 18:33:57200 static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08201};
202
203template <>
[email protected]7d5c3ac2009-02-04 08:58:19204struct ParamTraits<long> {
205 typedef long param_type;
206 static void Write(Message* m, const param_type& p) {
207 m->WriteLong(p);
208 }
209 static bool Read(const Message* m, void** iter, param_type* r) {
210 return m->ReadLong(iter, r);
211 }
[email protected]252cad62010-08-18 18:33:57212 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19213};
214
[email protected]140c3032009-06-26 18:22:54215template <>
216struct ParamTraits<unsigned long> {
217 typedef unsigned long param_type;
218 static void Write(Message* m, const param_type& p) {
219 m->WriteLong(p);
220 }
221 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]63263f92009-07-28 19:35:08222 return m->ReadLong(iter, reinterpret_cast<long*>(r));
[email protected]140c3032009-06-26 18:22:54223 }
[email protected]252cad62010-08-18 18:33:57224 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19225};
226
227template <>
[email protected]63263f92009-07-28 19:35:08228struct ParamTraits<long long> {
229 typedef long long param_type;
[email protected]7d5c3ac2009-02-04 08:58:19230 static void Write(Message* m, const param_type& p) {
231 m->WriteInt64(static_cast<int64>(p));
232 }
233 static bool Read(const Message* m, void** iter, param_type* r) {
234 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
235 }
[email protected]252cad62010-08-18 18:33:57236 static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08237};
238
239template <>
240struct ParamTraits<unsigned long long> {
241 typedef unsigned long long param_type;
242 static void Write(Message* m, const param_type& p) {
243 m->WriteInt64(p);
244 }
245 static bool Read(const Message* m, void** iter, param_type* r) {
246 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
247 }
[email protected]252cad62010-08-18 18:33:57248 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19249};
250
[email protected]43a40202010-11-12 16:25:01251template <>
252struct ParamTraits<unsigned short> {
253 typedef unsigned short param_type;
254 static void Write(Message* m, const param_type& p);
255 static bool Read(const Message* m, void** iter, param_type* r);
256 static void Log(const param_type& p, std::string* l);
257};
258
[email protected]20199662010-06-17 03:29:26259// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
260// should be sure to check the sanity of these values after receiving them over
261// IPC.
262template <>
263struct ParamTraits<float> {
264 typedef float param_type;
265 static void Write(Message* m, const param_type& p) {
266 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
267 }
268 static bool Read(const Message* m, void** iter, param_type* r) {
269 const char *data;
270 int data_size;
271 if (!m->ReadData(iter, &data, &data_size) ||
272 data_size != sizeof(param_type)) {
273 NOTREACHED();
274 return false;
275 }
276 memcpy(r, data, sizeof(param_type));
277 return true;
278 }
[email protected]252cad62010-08-18 18:33:57279 static void Log(const param_type& p, std::string* l) {
280 l->append(StringPrintf("%e", p));
[email protected]20199662010-06-17 03:29:26281 }
282};
283
[email protected]7d5c3ac2009-02-04 08:58:19284template <>
285struct ParamTraits<double> {
286 typedef double param_type;
287 static void Write(Message* m, const param_type& p) {
288 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
289 }
290 static bool Read(const Message* m, void** iter, param_type* r) {
291 const char *data;
[email protected]20199662010-06-17 03:29:26292 int data_size;
293 if (!m->ReadData(iter, &data, &data_size) ||
294 data_size != sizeof(param_type)) {
[email protected]7d5c3ac2009-02-04 08:58:19295 NOTREACHED();
[email protected]20199662010-06-17 03:29:26296 return false;
[email protected]7d5c3ac2009-02-04 08:58:19297 }
[email protected]20199662010-06-17 03:29:26298 memcpy(r, data, sizeof(param_type));
299 return true;
[email protected]7d5c3ac2009-02-04 08:58:19300 }
[email protected]252cad62010-08-18 18:33:57301 static void Log(const param_type& p, std::string* l) {
302 l->append(StringPrintf("%e", p));
[email protected]7d5c3ac2009-02-04 08:58:19303 }
304};
305
306template <>
[email protected]7d5c3ac2009-02-04 08:58:19307struct ParamTraits<base::Time> {
308 typedef base::Time param_type;
[email protected]7a4de7a62010-08-17 18:38:24309 static void Write(Message* m, const param_type& p);
310 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57311 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19312};
313
[email protected]d84e48b2010-10-21 22:04:52314template <>
315struct ParamTraits<base::TimeDelta> {
316 typedef base::TimeDelta param_type;
317 static void Write(Message* m, const param_type& p);
318 static bool Read(const Message* m, void** iter, param_type* r);
319 static void Log(const param_type& p, std::string* l);
320};
321
[email protected]7d5c3ac2009-02-04 08:58:19322#if defined(OS_WIN)
323template <>
324struct ParamTraits<LOGFONT> {
325 typedef LOGFONT param_type;
326 static void Write(Message* m, const param_type& p) {
327 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
328 }
329 static bool Read(const Message* m, void** iter, param_type* r) {
330 const char *data;
331 int data_size = 0;
332 bool result = m->ReadData(iter, &data, &data_size);
333 if (result && data_size == sizeof(LOGFONT)) {
334 memcpy(r, data, sizeof(LOGFONT));
335 } else {
336 result = false;
337 NOTREACHED();
338 }
339
340 return result;
341 }
[email protected]252cad62010-08-18 18:33:57342 static void Log(const param_type& p, std::string* l) {
343 l->append(StringPrintf("<LOGFONT>"));
[email protected]7d5c3ac2009-02-04 08:58:19344 }
345};
346
347template <>
348struct ParamTraits<MSG> {
349 typedef MSG param_type;
350 static void Write(Message* m, const param_type& p) {
351 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
352 }
353 static bool Read(const Message* m, void** iter, param_type* r) {
354 const char *data;
355 int data_size = 0;
356 bool result = m->ReadData(iter, &data, &data_size);
357 if (result && data_size == sizeof(MSG)) {
358 memcpy(r, data, sizeof(MSG));
359 } else {
360 result = false;
361 NOTREACHED();
362 }
363
364 return result;
365 }
[email protected]252cad62010-08-18 18:33:57366 static void Log(const param_type& p, std::string* l) {
367 l->append("<MSG>");
[email protected]7a4de7a62010-08-17 18:38:24368 }
[email protected]7d5c3ac2009-02-04 08:58:19369};
370#endif // defined(OS_WIN)
371
372template <>
[email protected]584f2b22009-05-21 01:01:59373struct ParamTraits<DictionaryValue> {
374 typedef DictionaryValue param_type;
375 static void Write(Message* m, const param_type& p);
376 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57377 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59378};
379
380template <>
381struct ParamTraits<ListValue> {
382 typedef ListValue param_type;
383 static void Write(Message* m, const param_type& p);
384 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57385 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59386};
387
388template <>
[email protected]7d5c3ac2009-02-04 08:58:19389struct ParamTraits<std::string> {
390 typedef std::string param_type;
391 static void Write(Message* m, const param_type& p) {
392 m->WriteString(p);
393 }
394 static bool Read(const Message* m, void** iter, param_type* r) {
395 return m->ReadString(iter, r);
396 }
[email protected]252cad62010-08-18 18:33:57397 static void Log(const param_type& p, std::string* l) {
398 l->append(p);
[email protected]7d5c3ac2009-02-04 08:58:19399 }
400};
401
[email protected]3dd7a7a2009-07-27 21:09:07402template<typename CharType>
[email protected]252cad62010-08-18 18:33:57403static void LogBytes(const std::vector<CharType>& data, std::string* out) {
[email protected]3dd7a7a2009-07-27 21:09:07404#if defined(OS_WIN)
405 // Windows has a GUI for logging, which can handle arbitrary binary data.
406 for (size_t i = 0; i < data.size(); ++i)
407 out->push_back(data[i]);
408#else
409 // On POSIX, we log to stdout, which we assume can display ASCII.
410 static const size_t kMaxBytesToLog = 100;
411 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
412 if (isprint(data[i]))
413 out->push_back(data[i]);
414 else
[email protected]252cad62010-08-18 18:33:57415 out->append(StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
[email protected]3dd7a7a2009-07-27 21:09:07416 }
417 if (data.size() > kMaxBytesToLog) {
418 out->append(
[email protected]252cad62010-08-18 18:33:57419 StringPrintf(" and %u more bytes",
[email protected]3dd7a7a2009-07-27 21:09:07420 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
421 }
422#endif
423}
424
[email protected]7d5c3ac2009-02-04 08:58:19425template <>
426struct ParamTraits<std::vector<unsigned char> > {
427 typedef std::vector<unsigned char> param_type;
428 static void Write(Message* m, const param_type& p) {
[email protected]f6b8ce32011-03-02 00:03:18429 if (p.empty()) {
[email protected]7d5c3ac2009-02-04 08:58:19430 m->WriteData(NULL, 0);
431 } else {
432 m->WriteData(reinterpret_cast<const char*>(&p.front()),
433 static_cast<int>(p.size()));
434 }
435 }
436 static bool Read(const Message* m, void** iter, param_type* r) {
437 const char *data;
438 int data_size = 0;
439 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
440 return false;
441 r->resize(data_size);
442 if (data_size)
443 memcpy(&r->front(), data, data_size);
444 return true;
445 }
[email protected]252cad62010-08-18 18:33:57446 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07447 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19448 }
449};
450
451template <>
452struct ParamTraits<std::vector<char> > {
453 typedef std::vector<char> param_type;
454 static void Write(Message* m, const param_type& p) {
[email protected]f6b8ce32011-03-02 00:03:18455 if (p.empty()) {
[email protected]7d5c3ac2009-02-04 08:58:19456 m->WriteData(NULL, 0);
457 } else {
458 m->WriteData(&p.front(), static_cast<int>(p.size()));
459 }
460 }
461 static bool Read(const Message* m, void** iter, param_type* r) {
462 const char *data;
463 int data_size = 0;
464 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
465 return false;
466 r->resize(data_size);
467 if (data_size)
468 memcpy(&r->front(), data, data_size);
469 return true;
470 }
[email protected]252cad62010-08-18 18:33:57471 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07472 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19473 }
474};
475
476template <class P>
477struct ParamTraits<std::vector<P> > {
478 typedef std::vector<P> param_type;
479 static void Write(Message* m, const param_type& p) {
480 WriteParam(m, static_cast<int>(p.size()));
481 for (size_t i = 0; i < p.size(); i++)
482 WriteParam(m, p[i]);
483 }
484 static bool Read(const Message* m, void** iter, param_type* r) {
485 int size;
[email protected]86440f52009-12-31 05:17:23486 // ReadLength() checks for < 0 itself.
[email protected]7d5c3ac2009-02-04 08:58:19487 if (!m->ReadLength(iter, &size))
488 return false;
489 // Resizing beforehand is not safe, see BUG 1006367 for details.
[email protected]86440f52009-12-31 05:17:23490 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
491 return false;
492 r->resize(size);
493 for (int i = 0; i < size; i++) {
494 if (!ReadParam(m, iter, &(*r)[i]))
495 return false;
[email protected]7d5c3ac2009-02-04 08:58:19496 }
497 return true;
498 }
[email protected]252cad62010-08-18 18:33:57499 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19500 for (size_t i = 0; i < p.size(); ++i) {
501 if (i != 0)
[email protected]252cad62010-08-18 18:33:57502 l->append(" ");
[email protected]7d5c3ac2009-02-04 08:58:19503 LogParam((p[i]), l);
504 }
505 }
506};
507
[email protected]96da6962010-05-13 19:10:34508template <class P>
509struct ParamTraits<std::set<P> > {
510 typedef std::set<P> param_type;
511 static void Write(Message* m, const param_type& p) {
512 WriteParam(m, static_cast<int>(p.size()));
513 typename param_type::const_iterator iter;
514 for (iter = p.begin(); iter != p.end(); ++iter)
515 WriteParam(m, *iter);
516 }
517 static bool Read(const Message* m, void** iter, param_type* r) {
518 int size;
519 if (!m->ReadLength(iter, &size))
520 return false;
521 for (int i = 0; i < size; ++i) {
522 P item;
523 if (!ReadParam(m, iter, &item))
524 return false;
525 r->insert(item);
526 }
527 return true;
528 }
[email protected]252cad62010-08-18 18:33:57529 static void Log(const param_type& p, std::string* l) {
530 l->append("<std::set>");
[email protected]96da6962010-05-13 19:10:34531 }
532};
533
534
[email protected]7d5c3ac2009-02-04 08:58:19535template <class K, class V>
536struct ParamTraits<std::map<K, V> > {
537 typedef std::map<K, V> param_type;
538 static void Write(Message* m, const param_type& p) {
539 WriteParam(m, static_cast<int>(p.size()));
540 typename param_type::const_iterator iter;
541 for (iter = p.begin(); iter != p.end(); ++iter) {
542 WriteParam(m, iter->first);
543 WriteParam(m, iter->second);
544 }
545 }
546 static bool Read(const Message* m, void** iter, param_type* r) {
547 int size;
548 if (!ReadParam(m, iter, &size) || size < 0)
549 return false;
550 for (int i = 0; i < size; ++i) {
551 K k;
552 if (!ReadParam(m, iter, &k))
553 return false;
554 V& value = (*r)[k];
555 if (!ReadParam(m, iter, &value))
556 return false;
557 }
558 return true;
559 }
[email protected]252cad62010-08-18 18:33:57560 static void Log(const param_type& p, std::string* l) {
561 l->append("<std::map>");
[email protected]7d5c3ac2009-02-04 08:58:19562 }
563};
564
[email protected]eb47a132009-03-04 00:39:56565
[email protected]7d5c3ac2009-02-04 08:58:19566template <>
567struct ParamTraits<std::wstring> {
568 typedef std::wstring param_type;
569 static void Write(Message* m, const param_type& p) {
570 m->WriteWString(p);
571 }
572 static bool Read(const Message* m, void** iter, param_type* r) {
573 return m->ReadWString(iter, r);
574 }
[email protected]252cad62010-08-18 18:33:57575 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19576};
577
[email protected]a5da6d612009-08-04 02:00:56578template <class A, class B>
579struct ParamTraits<std::pair<A, B> > {
580 typedef std::pair<A, B> param_type;
581 static void Write(Message* m, const param_type& p) {
582 WriteParam(m, p.first);
583 WriteParam(m, p.second);
584 }
585 static bool Read(const Message* m, void** iter, param_type* r) {
586 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
587 }
[email protected]252cad62010-08-18 18:33:57588 static void Log(const param_type& p, std::string* l) {
589 l->append("(");
[email protected]a5da6d612009-08-04 02:00:56590 LogParam(p.first, l);
[email protected]252cad62010-08-18 18:33:57591 l->append(", ");
[email protected]a5da6d612009-08-04 02:00:56592 LogParam(p.second, l);
[email protected]252cad62010-08-18 18:33:57593 l->append(")");
[email protected]a5da6d612009-08-04 02:00:56594 }
595};
596
[email protected]15bf8712009-08-27 00:55:02597template <>
598struct ParamTraits<NullableString16> {
599 typedef NullableString16 param_type;
[email protected]7a4de7a62010-08-17 18:38:24600 static void Write(Message* m, const param_type& p);
601 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57602 static void Log(const param_type& p, std::string* l);
[email protected]15bf8712009-08-27 00:55:02603};
604
[email protected]eb47a132009-03-04 00:39:56605// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
606// need this trait.
607#if !defined(WCHAR_T_IS_UTF16)
[email protected]eb47a132009-03-04 00:39:56608template <>
609struct ParamTraits<string16> {
610 typedef string16 param_type;
611 static void Write(Message* m, const param_type& p) {
[email protected]3a2a5d22009-03-04 03:36:36612 m->WriteString16(p);
[email protected]eb47a132009-03-04 00:39:56613 }
614 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]3a2a5d22009-03-04 03:36:36615 return m->ReadString16(iter, r);
[email protected]eb47a132009-03-04 00:39:56616 }
[email protected]252cad62010-08-18 18:33:57617 static void Log(const param_type& p, std::string* l);
[email protected]eb47a132009-03-04 00:39:56618};
[email protected]eb47a132009-03-04 00:39:56619#endif
620
[email protected]7d5c3ac2009-02-04 08:58:19621// and, a few more useful types...
622#if defined(OS_WIN)
623template <>
624struct ParamTraits<HANDLE> {
625 typedef HANDLE param_type;
626 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35627 // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
628 // bit systems.
629 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19630 }
631 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35632 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
633 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19634 }
[email protected]252cad62010-08-18 18:33:57635 static void Log(const param_type& p, std::string* l) {
636 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19637 }
638};
639
640template <>
641struct ParamTraits<HCURSOR> {
642 typedef HCURSOR param_type;
643 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35644 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19645 }
646 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35647 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
648 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19649 }
[email protected]252cad62010-08-18 18:33:57650 static void Log(const param_type& p, std::string* l) {
651 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19652 }
653};
654
655template <>
[email protected]7d5c3ac2009-02-04 08:58:19656struct ParamTraits<HACCEL> {
657 typedef HACCEL param_type;
658 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35659 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19660 }
661 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35662 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
663 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19664 }
665};
666
667template <>
668struct ParamTraits<POINT> {
669 typedef POINT param_type;
670 static void Write(Message* m, const param_type& p) {
671 m->WriteInt(p.x);
672 m->WriteInt(p.y);
673 }
674 static bool Read(const Message* m, void** iter, param_type* r) {
675 int x, y;
676 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
677 return false;
678 r->x = x;
679 r->y = y;
680 return true;
681 }
[email protected]252cad62010-08-18 18:33:57682 static void Log(const param_type& p, std::string* l) {
683 l->append(StringPrintf("(%d, %d)", p.x, p.y));
[email protected]7d5c3ac2009-02-04 08:58:19684 }
685};
686#endif // defined(OS_WIN)
687
688template <>
689struct ParamTraits<FilePath> {
690 typedef FilePath param_type;
[email protected]7a4de7a62010-08-17 18:38:24691 static void Write(Message* m, const param_type& p);
692 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57693 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19694};
695
[email protected]526776c2009-02-07 00:39:26696#if defined(OS_POSIX)
[email protected]2749885f2009-03-05 21:40:11697// FileDescriptors may be serialised over IPC channels on POSIX. On the
698// receiving side, the FileDescriptor is a valid duplicate of the file
699// descriptor which was transmitted: *it is not just a copy of the integer like
700// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
701// this case, the receiving end will see a value of -1. *Zero is a valid file
702// descriptor*.
703//
704// The received file descriptor will have the |auto_close| flag set to true. The
705// code which handles the message is responsible for taking ownership of it.
706// File descriptors are OS resources and must be closed when no longer needed.
707//
708// When sending a file descriptor, the file descriptor must be valid at the time
709// of transmission. Since transmission is not synchronous, one should consider
710// dup()ing any file descriptors to be transmitted and setting the |auto_close|
711// flag, which causes the file descriptor to be closed after writing.
[email protected]526776c2009-02-07 00:39:26712template<>
[email protected]5fe733de2009-02-11 18:59:20713struct ParamTraits<base::FileDescriptor> {
714 typedef base::FileDescriptor param_type;
[email protected]7a4de7a62010-08-17 18:38:24715 static void Write(Message* m, const param_type& p);
716 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57717 static void Log(const param_type& p, std::string* l);
[email protected]526776c2009-02-07 00:39:26718};
[email protected]379e7a52010-03-09 00:38:41719#endif // defined(OS_POSIX)
[email protected]526776c2009-02-07 00:39:26720
[email protected]d2e884d2009-06-22 20:37:52721// A ChannelHandle is basically a platform-inspecific wrapper around the
722// fact that IPC endpoints are handled specially on POSIX. See above comments
723// on FileDescriptor for more background.
724template<>
725struct ParamTraits<IPC::ChannelHandle> {
726 typedef ChannelHandle param_type;
[email protected]7a4de7a62010-08-17 18:38:24727 static void Write(Message* m, const param_type& p);
728 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57729 static void Log(const param_type& p, std::string* l);
[email protected]d2e884d2009-06-22 20:37:52730};
731
[email protected]7d5c3ac2009-02-04 08:58:19732#if defined(OS_WIN)
733template <>
734struct ParamTraits<XFORM> {
735 typedef XFORM param_type;
736 static void Write(Message* m, const param_type& p) {
737 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
738 }
739 static bool Read(const Message* m, void** iter, param_type* r) {
740 const char *data;
741 int data_size = 0;
742 bool result = m->ReadData(iter, &data, &data_size);
743 if (result && data_size == sizeof(XFORM)) {
744 memcpy(r, data, sizeof(XFORM));
745 } else {
746 result = false;
747 NOTREACHED();
748 }
749
750 return result;
751 }
[email protected]252cad62010-08-18 18:33:57752 static void Log(const param_type& p, std::string* l) {
753 l->append("<XFORM>");
[email protected]7d5c3ac2009-02-04 08:58:19754 }
755};
756#endif // defined(OS_WIN)
757
[email protected]7d5c3ac2009-02-04 08:58:19758struct LogData {
[email protected]20f0487a2010-09-30 20:06:30759 LogData();
760 ~LogData();
761
[email protected]9a3a293b2009-06-04 22:28:16762 std::string channel;
[email protected]8bef70e2009-04-14 19:11:24763 int32 routing_id;
[email protected]168ae922009-12-04 18:08:45764 uint32 type; // "User-defined" message type, from ipc_message.h.
[email protected]252cad62010-08-18 18:33:57765 std::string flags;
[email protected]7d5c3ac2009-02-04 08:58:19766 int64 sent; // Time that the message was sent (i.e. at Send()).
767 int64 receive; // Time before it was dispatched (i.e. before calling
768 // OnMessageReceived).
769 int64 dispatch; // Time after it was dispatched (i.e. after calling
770 // OnMessageReceived).
[email protected]252cad62010-08-18 18:33:57771 std::string message_name;
772 std::string params;
[email protected]7d5c3ac2009-02-04 08:58:19773};
774
775template <>
776struct ParamTraits<LogData> {
777 typedef LogData param_type;
[email protected]20f0487a2010-09-30 20:06:30778 static void Write(Message* m, const param_type& p);
779 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57780 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19781 // Doesn't make sense to implement this!
782 }
783};
784
[email protected]eb47a132009-03-04 00:39:56785template <>
[email protected]503683f2009-02-26 09:13:01786struct ParamTraits<Message> {
787 static void Write(Message* m, const Message& p) {
[email protected]8a861402011-01-28 19:59:11788 DCHECK(p.size() <= INT_MAX);
789 int message_size = static_cast<int>(p.size());
790 m->WriteInt(message_size);
791 m->WriteData(reinterpret_cast<const char*>(p.data()), message_size);
[email protected]503683f2009-02-26 09:13:01792 }
793 static bool Read(const Message* m, void** iter, Message* r) {
794 int size;
795 if (!m->ReadInt(iter, &size))
796 return false;
797 const char* data;
798 if (!m->ReadData(iter, &data, &size))
799 return false;
800 *r = Message(data, size);
801 return true;
802 }
[email protected]252cad62010-08-18 18:33:57803 static void Log(const Message& p, std::string* l) {
804 l->append("<IPC::Message>");
[email protected]503683f2009-02-26 09:13:01805 }
806};
807
808template <>
[email protected]7d5c3ac2009-02-04 08:58:19809struct ParamTraits<Tuple0> {
810 typedef Tuple0 param_type;
811 static void Write(Message* m, const param_type& p) {
812 }
813 static bool Read(const Message* m, void** iter, param_type* r) {
814 return true;
815 }
[email protected]252cad62010-08-18 18:33:57816 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19817 }
818};
819
820template <class A>
821struct ParamTraits< Tuple1<A> > {
822 typedef Tuple1<A> param_type;
823 static void Write(Message* m, const param_type& p) {
824 WriteParam(m, p.a);
825 }
826 static bool Read(const Message* m, void** iter, param_type* r) {
827 return ReadParam(m, iter, &r->a);
828 }
[email protected]252cad62010-08-18 18:33:57829 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19830 LogParam(p.a, l);
831 }
832};
833
834template <class A, class B>
835struct ParamTraits< Tuple2<A, B> > {
836 typedef Tuple2<A, B> param_type;
837 static void Write(Message* m, const param_type& p) {
838 WriteParam(m, p.a);
839 WriteParam(m, p.b);
840 }
841 static bool Read(const Message* m, void** iter, param_type* r) {
842 return (ReadParam(m, iter, &r->a) &&
843 ReadParam(m, iter, &r->b));
844 }
[email protected]252cad62010-08-18 18:33:57845 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19846 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57847 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19848 LogParam(p.b, l);
849 }
850};
851
852template <class A, class B, class C>
853struct ParamTraits< Tuple3<A, B, C> > {
854 typedef Tuple3<A, B, C> param_type;
855 static void Write(Message* m, const param_type& p) {
856 WriteParam(m, p.a);
857 WriteParam(m, p.b);
858 WriteParam(m, p.c);
859 }
860 static bool Read(const Message* m, void** iter, param_type* r) {
861 return (ReadParam(m, iter, &r->a) &&
862 ReadParam(m, iter, &r->b) &&
863 ReadParam(m, iter, &r->c));
864 }
[email protected]252cad62010-08-18 18:33:57865 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19866 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57867 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19868 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57869 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19870 LogParam(p.c, l);
871 }
872};
873
874template <class A, class B, class C, class D>
875struct ParamTraits< Tuple4<A, B, C, D> > {
876 typedef Tuple4<A, B, C, D> param_type;
877 static void Write(Message* m, const param_type& p) {
878 WriteParam(m, p.a);
879 WriteParam(m, p.b);
880 WriteParam(m, p.c);
881 WriteParam(m, p.d);
882 }
883 static bool Read(const Message* m, void** iter, param_type* r) {
884 return (ReadParam(m, iter, &r->a) &&
885 ReadParam(m, iter, &r->b) &&
886 ReadParam(m, iter, &r->c) &&
887 ReadParam(m, iter, &r->d));
888 }
[email protected]252cad62010-08-18 18:33:57889 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19890 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57891 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19892 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57893 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19894 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57895 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19896 LogParam(p.d, l);
897 }
898};
899
900template <class A, class B, class C, class D, class E>
901struct ParamTraits< Tuple5<A, B, C, D, E> > {
902 typedef Tuple5<A, B, C, D, E> param_type;
903 static void Write(Message* m, const param_type& p) {
904 WriteParam(m, p.a);
905 WriteParam(m, p.b);
906 WriteParam(m, p.c);
907 WriteParam(m, p.d);
908 WriteParam(m, p.e);
909 }
910 static bool Read(const Message* m, void** iter, param_type* r) {
911 return (ReadParam(m, iter, &r->a) &&
912 ReadParam(m, iter, &r->b) &&
913 ReadParam(m, iter, &r->c) &&
914 ReadParam(m, iter, &r->d) &&
915 ReadParam(m, iter, &r->e));
916 }
[email protected]252cad62010-08-18 18:33:57917 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19918 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57919 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19920 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57921 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19922 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57923 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19924 LogParam(p.d, l);
[email protected]252cad62010-08-18 18:33:57925 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19926 LogParam(p.e, l);
927 }
928};
929
[email protected]7d5c3ac2009-02-04 08:58:19930//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:29931// Generic message subclasses
932
933// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:24934template <class ParamType>
initial.commit09911bf2008-07-26 23:55:29935class MessageWithTuple : public Message {
936 public:
[email protected]81a34412009-01-05 19:17:24937 typedef ParamType Param;
[email protected]7a4de7a62010-08-17 18:38:24938 typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
[email protected]81a34412009-01-05 19:17:24939
[email protected]7a4de7a62010-08-17 18:38:24940 // The constructor and the Read() method's templated implementations are in
941 // ipc_message_utils_impl.h. The subclass constructor and Log() methods call
942 // the templated versions of these and make sure there are instantiations in
943 // those translation units.
944 MessageWithTuple(int32 routing_id, uint32 type, const RefParam& p);
[email protected]071b4b92010-08-09 16:06:58945
[email protected]7a4de7a62010-08-17 18:38:24946 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:29947
948 // Generic dispatcher. Should cover most cases.
[email protected]65412272010-12-21 20:03:24949 template<class T, class S, class Method>
950 static bool Dispatch(const Message* msg, T* obj, S* sender, Method func) {
initial.commit09911bf2008-07-26 23:55:29951 Param p;
952 if (Read(msg, &p)) {
953 DispatchToMethod(obj, func, p);
954 return true;
955 }
956 return false;
957 }
958
959 // The following dispatchers exist for the case where the callback function
960 // needs the message as well. They assume that "Param" is a type of Tuple
961 // (except the one arg case, as there is no Tuple1).
[email protected]65412272010-12-21 20:03:24962 template<class T, class S, typename TA>
963 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29964 void (T::*func)(const Message&, TA)) {
965 Param p;
966 if (Read(msg, &p)) {
[email protected]c2fe31542009-05-20 18:24:14967 (obj->*func)(*msg, p.a);
initial.commit09911bf2008-07-26 23:55:29968 return true;
969 }
970 return false;
971 }
972
[email protected]65412272010-12-21 20:03:24973 template<class T, class S, typename TA, typename TB>
974 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29975 void (T::*func)(const Message&, TA, TB)) {
976 Param p;
977 if (Read(msg, &p)) {
978 (obj->*func)(*msg, p.a, p.b);
979 return true;
980 }
981 return false;
982 }
983
[email protected]65412272010-12-21 20:03:24984 template<class T, class S, typename TA, typename TB, typename TC>
985 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29986 void (T::*func)(const Message&, TA, TB, TC)) {
987 Param p;
988 if (Read(msg, &p)) {
989 (obj->*func)(*msg, p.a, p.b, p.c);
990 return true;
991 }
992 return false;
993 }
994
[email protected]65412272010-12-21 20:03:24995 template<class T, class S, typename TA, typename TB, typename TC, typename TD>
996 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29997 void (T::*func)(const Message&, TA, TB, TC, TD)) {
998 Param p;
999 if (Read(msg, &p)) {
1000 (obj->*func)(*msg, p.a, p.b, p.c, p.d);
1001 return true;
1002 }
1003 return false;
1004 }
1005
[email protected]65412272010-12-21 20:03:241006 template<class T, class S, typename TA, typename TB, typename TC, typename TD,
initial.commit09911bf2008-07-26 23:55:291007 typename TE>
[email protected]65412272010-12-21 20:03:241008 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:291009 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
1010 Param p;
1011 if (Read(msg, &p)) {
1012 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
1013 return true;
1014 }
1015 return false;
1016 }
1017
[email protected]deb57402009-02-06 01:35:301018 // Functions used to do manual unpacking. Only used by the automation code,
1019 // these should go away once that code uses SyncChannel.
1020 template<typename TA, typename TB>
1021 static bool Read(const IPC::Message* msg, TA* a, TB* b) {
1022 ParamType params;
1023 if (!Read(msg, &params))
1024 return false;
1025 *a = params.a;
1026 *b = params.b;
1027 return true;
1028 }
1029
1030 template<typename TA, typename TB, typename TC>
1031 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
1032 ParamType params;
1033 if (!Read(msg, &params))
1034 return false;
1035 *a = params.a;
1036 *b = params.b;
1037 *c = params.c;
1038 return true;
1039 }
1040
1041 template<typename TA, typename TB, typename TC, typename TD>
1042 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) {
1043 ParamType params;
1044 if (!Read(msg, &params))
1045 return false;
1046 *a = params.a;
1047 *b = params.b;
1048 *c = params.c;
1049 *d = params.d;
1050 return true;
1051 }
1052
1053 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1054 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) {
1055 ParamType params;
1056 if (!Read(msg, &params))
1057 return false;
1058 *a = params.a;
1059 *b = params.b;
1060 *c = params.c;
1061 *d = params.d;
1062 *e = params.e;
1063 return true;
1064 }
initial.commit09911bf2008-07-26 23:55:291065};
1066
[email protected]7a4de7a62010-08-17 18:38:241067// defined in ipc_logging.cc
1068void GenerateLogData(const std::string& channel, const Message& message,
1069 LogData* data);
1070
1071
1072#if defined(IPC_MESSAGE_LOG_ENABLED)
[email protected]252cad62010-08-18 18:33:571073inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
1074 const std::string& output_params = msg->output_params();
[email protected]7a4de7a62010-08-17 18:38:241075 if (!l->empty() && !output_params.empty())
[email protected]252cad62010-08-18 18:33:571076 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:241077
1078 l->append(output_params);
1079}
1080
1081template <class ReplyParamType>
1082inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1083 const Message* msg) {
1084 if (msg->received_time() != 0) {
[email protected]252cad62010-08-18 18:33:571085 std::string output_params;
[email protected]7a4de7a62010-08-17 18:38:241086 LogParam(reply_params, &output_params);
1087 msg->set_output_params(output_params);
1088 }
1089}
1090
1091inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
1092 if (msg->sent_time()) {
1093 // Don't log the sync message after dispatch, as we don't have the
1094 // output parameters at that point. Instead, save its data and log it
1095 // with the outgoing reply message when it's sent.
1096 LogData* data = new LogData;
1097 GenerateLogData("", *msg, data);
1098 msg->set_dont_log();
1099 reply->set_sync_log_data(data);
1100 }
1101}
1102#else
[email protected]252cad62010-08-18 18:33:571103inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
[email protected]7a4de7a62010-08-17 18:38:241104
1105template <class ReplyParamType>
1106inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1107 const Message* msg) {}
1108
1109inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1110#endif
1111
initial.commit09911bf2008-07-26 23:55:291112// This class assumes that its template argument is a RefTuple (a Tuple with
[email protected]7a4de7a62010-08-17 18:38:241113// reference elements). This would go into ipc_message_utils_impl.h, but it is
1114// also used by chrome_frame.
initial.commit09911bf2008-07-26 23:55:291115template <class RefTuple>
1116class ParamDeserializer : public MessageReplyDeserializer {
1117 public:
[email protected]e1981f432008-08-12 15:22:131118 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:291119
1120 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1121 return ReadParam(&msg, &iter, &out_);
1122 }
1123
1124 RefTuple out_;
1125};
1126
initial.commit09911bf2008-07-26 23:55:291127// Used for synchronous messages.
[email protected]75e5a872009-04-02 23:56:111128template <class SendParamType, class ReplyParamType>
initial.commit09911bf2008-07-26 23:55:291129class MessageWithReply : public SyncMessage {
1130 public:
[email protected]75e5a872009-04-02 23:56:111131 typedef SendParamType SendParam;
[email protected]7a4de7a62010-08-17 18:38:241132 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
[email protected]75e5a872009-04-02 23:56:111133 typedef ReplyParamType ReplyParam;
1134
[email protected]168ae922009-12-04 18:08:451135 MessageWithReply(int32 routing_id, uint32 type,
[email protected]7a4de7a62010-08-17 18:38:241136 const RefSendParam& send, const ReplyParam& reply);
1137 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
1138 static bool ReadReplyParam(
1139 const Message* msg,
1140 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:291141
[email protected]65412272010-12-21 20:03:241142 template<class T, class S, class Method>
1143 static bool Dispatch(const Message* msg, T* obj, S* sender, Method func) {
initial.commit09911bf2008-07-26 23:55:291144 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291145 Message* reply = GenerateReply(msg);
1146 bool error;
[email protected]7a4de7a62010-08-17 18:38:241147 if (ReadSendParam(msg, &send_params)) {
1148 typename TupleTypes<ReplyParam>::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:291149 DispatchToMethod(obj, func, send_params, &reply_params);
1150 WriteParam(reply, reply_params);
1151 error = false;
[email protected]7a4de7a62010-08-17 18:38:241152 LogReplyParamsToMessage(reply_params, msg);
initial.commit09911bf2008-07-26 23:55:291153 } else {
1154 NOTREACHED() << "Error deserializing message " << msg->type();
1155 reply->set_reply_error();
1156 error = true;
1157 }
1158
[email protected]65412272010-12-21 20:03:241159 sender->Send(reply);
initial.commit09911bf2008-07-26 23:55:291160 return !error;
1161 }
1162
1163 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191164 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291165 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291166 Message* reply = GenerateReply(msg);
1167 bool error;
[email protected]7a4de7a62010-08-17 18:38:241168 if (ReadSendParam(msg, &send_params)) {
initial.commit09911bf2008-07-26 23:55:291169 Tuple1<Message&> t = MakeRefTuple(*reply);
[email protected]7a4de7a62010-08-17 18:38:241170 ConnectMessageAndReply(msg, reply);
initial.commit09911bf2008-07-26 23:55:291171 DispatchToMethod(obj, func, send_params, &t);
1172 error = false;
1173 } else {
1174 NOTREACHED() << "Error deserializing message " << msg->type();
1175 reply->set_reply_error();
1176 obj->Send(reply);
1177 error = true;
1178 }
1179 return !error;
1180 }
1181
1182 template<typename TA>
1183 static void WriteReplyParams(Message* reply, TA a) {
1184 ReplyParam p(a);
1185 WriteParam(reply, p);
1186 }
1187
1188 template<typename TA, typename TB>
1189 static void WriteReplyParams(Message* reply, TA a, TB b) {
1190 ReplyParam p(a, b);
1191 WriteParam(reply, p);
1192 }
1193
1194 template<typename TA, typename TB, typename TC>
1195 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1196 ReplyParam p(a, b, c);
1197 WriteParam(reply, p);
1198 }
1199
1200 template<typename TA, typename TB, typename TC, typename TD>
1201 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1202 ReplyParam p(a, b, c, d);
1203 WriteParam(reply, p);
1204 }
1205
1206 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1207 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1208 ReplyParam p(a, b, c, d, e);
1209 WriteParam(reply, p);
1210 }
1211};
1212
[email protected]7d5c3ac2009-02-04 08:58:191213//-----------------------------------------------------------------------------
1214
[email protected]3178f4e22008-08-05 21:20:411215} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291216
[email protected]946d1b22009-07-22 23:57:211217#endif // IPC_IPC_MESSAGE_UTILS_H_