blob: 72723027781a04cdebd7194750e527aea4abd8a2 [file] [log] [blame]
[email protected]225c8f52010-02-05 22:23:201// Copyright (c) 2010 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 <string>
11#include <vector>
12#include <map>
[email protected]96da6962010-05-13 19:10:3413#include <set>
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]19d6e1e82011-01-26 05:08:5870 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]f91cb992009-02-04 20:10:1278};
79
[email protected]7a4de7a62010-08-17 18:38:2480class DictionaryValue;
81class FilePath;
82class ListValue;
83class NullableString16;
84
85namespace base {
86class Time;
[email protected]d84e48b2010-10-21 22:04:5287class TimeDelta;
[email protected]7a4de7a62010-08-17 18:38:2488struct FileDescriptor;
89}
90
initial.commit09911bf2008-07-26 23:55:2991namespace IPC {
92
[email protected]7a4de7a62010-08-17 18:38:2493struct ChannelHandle;
94
initial.commit09911bf2008-07-26 23:55:2995//-----------------------------------------------------------------------------
96// An iterator class for reading the fields contained within a Message.
97
98class MessageIterator {
99 public:
[email protected]e1981f432008-08-12 15:22:13100 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
initial.commit09911bf2008-07-26 23:55:29101 }
102 int NextInt() const {
[email protected]9422b7dc2009-12-30 20:09:02103 int val = -1;
initial.commit09911bf2008-07-26 23:55:29104 if (!msg_.ReadInt(&iter_, &val))
105 NOTREACHED();
106 return val;
107 }
initial.commit09911bf2008-07-26 23:55:29108 const std::string NextString() const {
109 std::string val;
110 if (!msg_.ReadString(&iter_, &val))
111 NOTREACHED();
112 return val;
113 }
114 const std::wstring NextWString() const {
115 std::wstring val;
116 if (!msg_.ReadWString(&iter_, &val))
117 NOTREACHED();
118 return val;
119 }
[email protected]225c8f52010-02-05 22:23:20120 void NextData(const char** data, int* length) const {
initial.commit09911bf2008-07-26 23:55:29121 if (!msg_.ReadData(&iter_, data, length)) {
122 NOTREACHED();
123 }
124 }
125 private:
126 const Message& msg_;
127 mutable void* iter_;
128};
129
130//-----------------------------------------------------------------------------
[email protected]6476c72c2011-02-11 18:46:19131// A dummy struct to place first just to allow leading commas for all
132// members in the macro-generated constructor initializer lists.
133struct NoParams {
134};
135
136//-----------------------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19137// ParamTraits specializations, etc.
138
[email protected]7d5c3ac2009-02-04 08:58:19139template <class P>
140static inline void WriteParam(Message* m, const P& p) {
[email protected]7b291f92009-08-14 05:43:53141 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53142 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
[email protected]7d5c3ac2009-02-04 08:58:19143}
144
145template <class P>
[email protected]1e86aa62009-04-24 21:22:33146static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
147 P* p) {
[email protected]7b291f92009-08-14 05:43:53148 typedef typename SimilarTypeTraits<P>::Type Type;
149 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
[email protected]7d5c3ac2009-02-04 08:58:19150}
151
152template <class P>
[email protected]252cad62010-08-18 18:33:57153static inline void LogParam(const P& p, std::string* l) {
[email protected]7b291f92009-08-14 05:43:53154 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53155 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19156}
157
158template <>
159struct ParamTraits<bool> {
160 typedef bool param_type;
161 static void Write(Message* m, const param_type& p) {
162 m->WriteBool(p);
163 }
164 static bool Read(const Message* m, void** iter, param_type* r) {
165 return m->ReadBool(iter, r);
166 }
[email protected]252cad62010-08-18 18:33:57167 static void Log(const param_type& p, std::string* l) {
168 l->append(p ? "true" : "false");
[email protected]7d5c3ac2009-02-04 08:58:19169 }
170};
171
172template <>
173struct ParamTraits<int> {
174 typedef int param_type;
175 static void Write(Message* m, const param_type& p) {
176 m->WriteInt(p);
177 }
178 static bool Read(const Message* m, void** iter, param_type* r) {
179 return m->ReadInt(iter, r);
180 }
[email protected]252cad62010-08-18 18:33:57181 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19182};
183
184template <>
[email protected]63263f92009-07-28 19:35:08185struct ParamTraits<unsigned int> {
186 typedef unsigned int param_type;
187 static void Write(Message* m, const param_type& p) {
188 m->WriteInt(p);
189 }
190 static bool Read(const Message* m, void** iter, param_type* r) {
191 return m->ReadInt(iter, reinterpret_cast<int*>(r));
192 }
[email protected]252cad62010-08-18 18:33:57193 static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08194};
195
196template <>
[email protected]7d5c3ac2009-02-04 08:58:19197struct ParamTraits<long> {
198 typedef long param_type;
199 static void Write(Message* m, const param_type& p) {
200 m->WriteLong(p);
201 }
202 static bool Read(const Message* m, void** iter, param_type* r) {
203 return m->ReadLong(iter, r);
204 }
[email protected]252cad62010-08-18 18:33:57205 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19206};
207
[email protected]140c3032009-06-26 18:22:54208template <>
209struct ParamTraits<unsigned long> {
210 typedef unsigned long param_type;
211 static void Write(Message* m, const param_type& p) {
212 m->WriteLong(p);
213 }
214 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]63263f92009-07-28 19:35:08215 return m->ReadLong(iter, reinterpret_cast<long*>(r));
[email protected]140c3032009-06-26 18:22:54216 }
[email protected]252cad62010-08-18 18:33:57217 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19218};
219
220template <>
[email protected]63263f92009-07-28 19:35:08221struct ParamTraits<long long> {
222 typedef long long param_type;
[email protected]7d5c3ac2009-02-04 08:58:19223 static void Write(Message* m, const param_type& p) {
224 m->WriteInt64(static_cast<int64>(p));
225 }
226 static bool Read(const Message* m, void** iter, param_type* r) {
227 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
228 }
[email protected]252cad62010-08-18 18:33:57229 static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08230};
231
232template <>
233struct ParamTraits<unsigned long long> {
234 typedef unsigned long long param_type;
235 static void Write(Message* m, const param_type& p) {
236 m->WriteInt64(p);
237 }
238 static bool Read(const Message* m, void** iter, param_type* r) {
239 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
240 }
[email protected]252cad62010-08-18 18:33:57241 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19242};
243
[email protected]43a40202010-11-12 16:25:01244template <>
245struct ParamTraits<unsigned short> {
246 typedef unsigned short param_type;
247 static void Write(Message* m, const param_type& p);
248 static bool Read(const Message* m, void** iter, param_type* r);
249 static void Log(const param_type& p, std::string* l);
250};
251
[email protected]20199662010-06-17 03:29:26252// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
253// should be sure to check the sanity of these values after receiving them over
254// IPC.
255template <>
256struct ParamTraits<float> {
257 typedef float param_type;
258 static void Write(Message* m, const param_type& p) {
259 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
260 }
261 static bool Read(const Message* m, void** iter, param_type* r) {
262 const char *data;
263 int data_size;
264 if (!m->ReadData(iter, &data, &data_size) ||
265 data_size != sizeof(param_type)) {
266 NOTREACHED();
267 return false;
268 }
269 memcpy(r, data, sizeof(param_type));
270 return true;
271 }
[email protected]252cad62010-08-18 18:33:57272 static void Log(const param_type& p, std::string* l) {
273 l->append(StringPrintf("%e", p));
[email protected]20199662010-06-17 03:29:26274 }
275};
276
[email protected]7d5c3ac2009-02-04 08:58:19277template <>
278struct ParamTraits<double> {
279 typedef double param_type;
280 static void Write(Message* m, const param_type& p) {
281 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
282 }
283 static bool Read(const Message* m, void** iter, param_type* r) {
284 const char *data;
[email protected]20199662010-06-17 03:29:26285 int data_size;
286 if (!m->ReadData(iter, &data, &data_size) ||
287 data_size != sizeof(param_type)) {
[email protected]7d5c3ac2009-02-04 08:58:19288 NOTREACHED();
[email protected]20199662010-06-17 03:29:26289 return false;
[email protected]7d5c3ac2009-02-04 08:58:19290 }
[email protected]20199662010-06-17 03:29:26291 memcpy(r, data, sizeof(param_type));
292 return true;
[email protected]7d5c3ac2009-02-04 08:58:19293 }
[email protected]252cad62010-08-18 18:33:57294 static void Log(const param_type& p, std::string* l) {
295 l->append(StringPrintf("%e", p));
[email protected]7d5c3ac2009-02-04 08:58:19296 }
297};
298
299template <>
[email protected]7d5c3ac2009-02-04 08:58:19300struct ParamTraits<base::Time> {
301 typedef base::Time param_type;
[email protected]7a4de7a62010-08-17 18:38:24302 static void Write(Message* m, const param_type& p);
303 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57304 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19305};
306
[email protected]d84e48b2010-10-21 22:04:52307template <>
308struct ParamTraits<base::TimeDelta> {
309 typedef base::TimeDelta param_type;
310 static void Write(Message* m, const param_type& p);
311 static bool Read(const Message* m, void** iter, param_type* r);
312 static void Log(const param_type& p, std::string* l);
313};
314
[email protected]7d5c3ac2009-02-04 08:58:19315#if defined(OS_WIN)
316template <>
317struct ParamTraits<LOGFONT> {
318 typedef LOGFONT param_type;
319 static void Write(Message* m, const param_type& p) {
320 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
321 }
322 static bool Read(const Message* m, void** iter, param_type* r) {
323 const char *data;
324 int data_size = 0;
325 bool result = m->ReadData(iter, &data, &data_size);
326 if (result && data_size == sizeof(LOGFONT)) {
327 memcpy(r, data, sizeof(LOGFONT));
328 } else {
329 result = false;
330 NOTREACHED();
331 }
332
333 return result;
334 }
[email protected]252cad62010-08-18 18:33:57335 static void Log(const param_type& p, std::string* l) {
336 l->append(StringPrintf("<LOGFONT>"));
[email protected]7d5c3ac2009-02-04 08:58:19337 }
338};
339
340template <>
341struct ParamTraits<MSG> {
342 typedef MSG param_type;
343 static void Write(Message* m, const param_type& p) {
344 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
345 }
346 static bool Read(const Message* m, void** iter, param_type* r) {
347 const char *data;
348 int data_size = 0;
349 bool result = m->ReadData(iter, &data, &data_size);
350 if (result && data_size == sizeof(MSG)) {
351 memcpy(r, data, sizeof(MSG));
352 } else {
353 result = false;
354 NOTREACHED();
355 }
356
357 return result;
358 }
[email protected]252cad62010-08-18 18:33:57359 static void Log(const param_type& p, std::string* l) {
360 l->append("<MSG>");
[email protected]7a4de7a62010-08-17 18:38:24361 }
[email protected]7d5c3ac2009-02-04 08:58:19362};
363#endif // defined(OS_WIN)
364
365template <>
[email protected]584f2b22009-05-21 01:01:59366struct ParamTraits<DictionaryValue> {
367 typedef DictionaryValue param_type;
368 static void Write(Message* m, const param_type& p);
369 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57370 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59371};
372
373template <>
374struct ParamTraits<ListValue> {
375 typedef ListValue param_type;
376 static void Write(Message* m, const param_type& p);
377 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57378 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59379};
380
381template <>
[email protected]7d5c3ac2009-02-04 08:58:19382struct ParamTraits<std::string> {
383 typedef std::string param_type;
384 static void Write(Message* m, const param_type& p) {
385 m->WriteString(p);
386 }
387 static bool Read(const Message* m, void** iter, param_type* r) {
388 return m->ReadString(iter, r);
389 }
[email protected]252cad62010-08-18 18:33:57390 static void Log(const param_type& p, std::string* l) {
391 l->append(p);
[email protected]7d5c3ac2009-02-04 08:58:19392 }
393};
394
[email protected]3dd7a7a2009-07-27 21:09:07395template<typename CharType>
[email protected]252cad62010-08-18 18:33:57396static void LogBytes(const std::vector<CharType>& data, std::string* out) {
[email protected]3dd7a7a2009-07-27 21:09:07397#if defined(OS_WIN)
398 // Windows has a GUI for logging, which can handle arbitrary binary data.
399 for (size_t i = 0; i < data.size(); ++i)
400 out->push_back(data[i]);
401#else
402 // On POSIX, we log to stdout, which we assume can display ASCII.
403 static const size_t kMaxBytesToLog = 100;
404 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
405 if (isprint(data[i]))
406 out->push_back(data[i]);
407 else
[email protected]252cad62010-08-18 18:33:57408 out->append(StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
[email protected]3dd7a7a2009-07-27 21:09:07409 }
410 if (data.size() > kMaxBytesToLog) {
411 out->append(
[email protected]252cad62010-08-18 18:33:57412 StringPrintf(" and %u more bytes",
[email protected]3dd7a7a2009-07-27 21:09:07413 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
414 }
415#endif
416}
417
[email protected]7d5c3ac2009-02-04 08:58:19418template <>
419struct ParamTraits<std::vector<unsigned char> > {
420 typedef std::vector<unsigned char> param_type;
421 static void Write(Message* m, const param_type& p) {
[email protected]f6b8ce32011-03-02 00:03:18422 if (p.empty()) {
[email protected]7d5c3ac2009-02-04 08:58:19423 m->WriteData(NULL, 0);
424 } else {
425 m->WriteData(reinterpret_cast<const char*>(&p.front()),
426 static_cast<int>(p.size()));
427 }
428 }
429 static bool Read(const Message* m, void** iter, param_type* r) {
430 const char *data;
431 int data_size = 0;
432 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
433 return false;
434 r->resize(data_size);
435 if (data_size)
436 memcpy(&r->front(), data, data_size);
437 return true;
438 }
[email protected]252cad62010-08-18 18:33:57439 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07440 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19441 }
442};
443
444template <>
445struct ParamTraits<std::vector<char> > {
446 typedef std::vector<char> param_type;
447 static void Write(Message* m, const param_type& p) {
[email protected]f6b8ce32011-03-02 00:03:18448 if (p.empty()) {
[email protected]7d5c3ac2009-02-04 08:58:19449 m->WriteData(NULL, 0);
450 } else {
451 m->WriteData(&p.front(), static_cast<int>(p.size()));
452 }
453 }
454 static bool Read(const Message* m, void** iter, param_type* r) {
455 const char *data;
456 int data_size = 0;
457 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
458 return false;
459 r->resize(data_size);
460 if (data_size)
461 memcpy(&r->front(), data, data_size);
462 return true;
463 }
[email protected]252cad62010-08-18 18:33:57464 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07465 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19466 }
467};
468
469template <class P>
470struct ParamTraits<std::vector<P> > {
471 typedef std::vector<P> param_type;
472 static void Write(Message* m, const param_type& p) {
473 WriteParam(m, static_cast<int>(p.size()));
474 for (size_t i = 0; i < p.size(); i++)
475 WriteParam(m, p[i]);
476 }
477 static bool Read(const Message* m, void** iter, param_type* r) {
478 int size;
[email protected]86440f52009-12-31 05:17:23479 // ReadLength() checks for < 0 itself.
[email protected]7d5c3ac2009-02-04 08:58:19480 if (!m->ReadLength(iter, &size))
481 return false;
482 // Resizing beforehand is not safe, see BUG 1006367 for details.
[email protected]86440f52009-12-31 05:17:23483 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
484 return false;
485 r->resize(size);
486 for (int i = 0; i < size; i++) {
487 if (!ReadParam(m, iter, &(*r)[i]))
488 return false;
[email protected]7d5c3ac2009-02-04 08:58:19489 }
490 return true;
491 }
[email protected]252cad62010-08-18 18:33:57492 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19493 for (size_t i = 0; i < p.size(); ++i) {
494 if (i != 0)
[email protected]252cad62010-08-18 18:33:57495 l->append(" ");
[email protected]7d5c3ac2009-02-04 08:58:19496 LogParam((p[i]), l);
497 }
498 }
499};
500
[email protected]96da6962010-05-13 19:10:34501template <class P>
502struct ParamTraits<std::set<P> > {
503 typedef std::set<P> param_type;
504 static void Write(Message* m, const param_type& p) {
505 WriteParam(m, static_cast<int>(p.size()));
506 typename param_type::const_iterator iter;
507 for (iter = p.begin(); iter != p.end(); ++iter)
508 WriteParam(m, *iter);
509 }
510 static bool Read(const Message* m, void** iter, param_type* r) {
511 int size;
512 if (!m->ReadLength(iter, &size))
513 return false;
514 for (int i = 0; i < size; ++i) {
515 P item;
516 if (!ReadParam(m, iter, &item))
517 return false;
518 r->insert(item);
519 }
520 return true;
521 }
[email protected]252cad62010-08-18 18:33:57522 static void Log(const param_type& p, std::string* l) {
523 l->append("<std::set>");
[email protected]96da6962010-05-13 19:10:34524 }
525};
526
527
[email protected]7d5c3ac2009-02-04 08:58:19528template <class K, class V>
529struct ParamTraits<std::map<K, V> > {
530 typedef std::map<K, V> param_type;
531 static void Write(Message* m, const param_type& p) {
532 WriteParam(m, static_cast<int>(p.size()));
533 typename param_type::const_iterator iter;
534 for (iter = p.begin(); iter != p.end(); ++iter) {
535 WriteParam(m, iter->first);
536 WriteParam(m, iter->second);
537 }
538 }
539 static bool Read(const Message* m, void** iter, param_type* r) {
540 int size;
541 if (!ReadParam(m, iter, &size) || size < 0)
542 return false;
543 for (int i = 0; i < size; ++i) {
544 K k;
545 if (!ReadParam(m, iter, &k))
546 return false;
547 V& value = (*r)[k];
548 if (!ReadParam(m, iter, &value))
549 return false;
550 }
551 return true;
552 }
[email protected]252cad62010-08-18 18:33:57553 static void Log(const param_type& p, std::string* l) {
554 l->append("<std::map>");
[email protected]7d5c3ac2009-02-04 08:58:19555 }
556};
557
[email protected]eb47a132009-03-04 00:39:56558
[email protected]7d5c3ac2009-02-04 08:58:19559template <>
560struct ParamTraits<std::wstring> {
561 typedef std::wstring param_type;
562 static void Write(Message* m, const param_type& p) {
563 m->WriteWString(p);
564 }
565 static bool Read(const Message* m, void** iter, param_type* r) {
566 return m->ReadWString(iter, r);
567 }
[email protected]252cad62010-08-18 18:33:57568 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19569};
570
[email protected]a5da6d612009-08-04 02:00:56571template <class A, class B>
572struct ParamTraits<std::pair<A, B> > {
573 typedef std::pair<A, B> param_type;
574 static void Write(Message* m, const param_type& p) {
575 WriteParam(m, p.first);
576 WriteParam(m, p.second);
577 }
578 static bool Read(const Message* m, void** iter, param_type* r) {
579 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
580 }
[email protected]252cad62010-08-18 18:33:57581 static void Log(const param_type& p, std::string* l) {
582 l->append("(");
[email protected]a5da6d612009-08-04 02:00:56583 LogParam(p.first, l);
[email protected]252cad62010-08-18 18:33:57584 l->append(", ");
[email protected]a5da6d612009-08-04 02:00:56585 LogParam(p.second, l);
[email protected]252cad62010-08-18 18:33:57586 l->append(")");
[email protected]a5da6d612009-08-04 02:00:56587 }
588};
589
[email protected]15bf8712009-08-27 00:55:02590template <>
591struct ParamTraits<NullableString16> {
592 typedef NullableString16 param_type;
[email protected]7a4de7a62010-08-17 18:38:24593 static void Write(Message* m, const param_type& p);
594 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57595 static void Log(const param_type& p, std::string* l);
[email protected]15bf8712009-08-27 00:55:02596};
597
[email protected]eb47a132009-03-04 00:39:56598// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
599// need this trait.
600#if !defined(WCHAR_T_IS_UTF16)
[email protected]eb47a132009-03-04 00:39:56601template <>
602struct ParamTraits<string16> {
603 typedef string16 param_type;
604 static void Write(Message* m, const param_type& p) {
[email protected]3a2a5d22009-03-04 03:36:36605 m->WriteString16(p);
[email protected]eb47a132009-03-04 00:39:56606 }
607 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]3a2a5d22009-03-04 03:36:36608 return m->ReadString16(iter, r);
[email protected]eb47a132009-03-04 00:39:56609 }
[email protected]252cad62010-08-18 18:33:57610 static void Log(const param_type& p, std::string* l);
[email protected]eb47a132009-03-04 00:39:56611};
[email protected]eb47a132009-03-04 00:39:56612#endif
613
[email protected]7d5c3ac2009-02-04 08:58:19614// and, a few more useful types...
615#if defined(OS_WIN)
616template <>
617struct ParamTraits<HANDLE> {
618 typedef HANDLE param_type;
619 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35620 // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
621 // bit systems.
622 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19623 }
624 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35625 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
626 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19627 }
[email protected]252cad62010-08-18 18:33:57628 static void Log(const param_type& p, std::string* l) {
629 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19630 }
631};
632
633template <>
634struct ParamTraits<HCURSOR> {
635 typedef HCURSOR param_type;
636 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35637 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19638 }
639 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35640 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
641 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19642 }
[email protected]252cad62010-08-18 18:33:57643 static void Log(const param_type& p, std::string* l) {
644 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19645 }
646};
647
648template <>
[email protected]7d5c3ac2009-02-04 08:58:19649struct ParamTraits<HACCEL> {
650 typedef HACCEL param_type;
651 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35652 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19653 }
654 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35655 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
656 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19657 }
658};
659
660template <>
661struct ParamTraits<POINT> {
662 typedef POINT param_type;
663 static void Write(Message* m, const param_type& p) {
664 m->WriteInt(p.x);
665 m->WriteInt(p.y);
666 }
667 static bool Read(const Message* m, void** iter, param_type* r) {
668 int x, y;
669 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
670 return false;
671 r->x = x;
672 r->y = y;
673 return true;
674 }
[email protected]252cad62010-08-18 18:33:57675 static void Log(const param_type& p, std::string* l) {
676 l->append(StringPrintf("(%d, %d)", p.x, p.y));
[email protected]7d5c3ac2009-02-04 08:58:19677 }
678};
679#endif // defined(OS_WIN)
680
681template <>
682struct ParamTraits<FilePath> {
683 typedef FilePath param_type;
[email protected]7a4de7a62010-08-17 18:38:24684 static void Write(Message* m, const param_type& p);
685 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57686 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19687};
688
[email protected]526776c2009-02-07 00:39:26689#if defined(OS_POSIX)
[email protected]2749885f2009-03-05 21:40:11690// FileDescriptors may be serialised over IPC channels on POSIX. On the
691// receiving side, the FileDescriptor is a valid duplicate of the file
692// descriptor which was transmitted: *it is not just a copy of the integer like
693// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
694// this case, the receiving end will see a value of -1. *Zero is a valid file
695// descriptor*.
696//
697// The received file descriptor will have the |auto_close| flag set to true. The
698// code which handles the message is responsible for taking ownership of it.
699// File descriptors are OS resources and must be closed when no longer needed.
700//
701// When sending a file descriptor, the file descriptor must be valid at the time
702// of transmission. Since transmission is not synchronous, one should consider
703// dup()ing any file descriptors to be transmitted and setting the |auto_close|
704// flag, which causes the file descriptor to be closed after writing.
[email protected]526776c2009-02-07 00:39:26705template<>
[email protected]5fe733de2009-02-11 18:59:20706struct ParamTraits<base::FileDescriptor> {
707 typedef base::FileDescriptor param_type;
[email protected]7a4de7a62010-08-17 18:38:24708 static void Write(Message* m, const param_type& p);
709 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57710 static void Log(const param_type& p, std::string* l);
[email protected]526776c2009-02-07 00:39:26711};
[email protected]379e7a52010-03-09 00:38:41712#endif // defined(OS_POSIX)
[email protected]526776c2009-02-07 00:39:26713
[email protected]d2e884d2009-06-22 20:37:52714// A ChannelHandle is basically a platform-inspecific wrapper around the
715// fact that IPC endpoints are handled specially on POSIX. See above comments
716// on FileDescriptor for more background.
717template<>
718struct ParamTraits<IPC::ChannelHandle> {
719 typedef ChannelHandle param_type;
[email protected]7a4de7a62010-08-17 18:38:24720 static void Write(Message* m, const param_type& p);
721 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57722 static void Log(const param_type& p, std::string* l);
[email protected]d2e884d2009-06-22 20:37:52723};
724
[email protected]7d5c3ac2009-02-04 08:58:19725#if defined(OS_WIN)
726template <>
727struct ParamTraits<XFORM> {
728 typedef XFORM param_type;
729 static void Write(Message* m, const param_type& p) {
730 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
731 }
732 static bool Read(const Message* m, void** iter, param_type* r) {
733 const char *data;
734 int data_size = 0;
735 bool result = m->ReadData(iter, &data, &data_size);
736 if (result && data_size == sizeof(XFORM)) {
737 memcpy(r, data, sizeof(XFORM));
738 } else {
739 result = false;
740 NOTREACHED();
741 }
742
743 return result;
744 }
[email protected]252cad62010-08-18 18:33:57745 static void Log(const param_type& p, std::string* l) {
746 l->append("<XFORM>");
[email protected]7d5c3ac2009-02-04 08:58:19747 }
748};
749#endif // defined(OS_WIN)
750
[email protected]7d5c3ac2009-02-04 08:58:19751struct LogData {
[email protected]20f0487a2010-09-30 20:06:30752 LogData();
753 ~LogData();
754
[email protected]9a3a293b2009-06-04 22:28:16755 std::string channel;
[email protected]8bef70e2009-04-14 19:11:24756 int32 routing_id;
[email protected]168ae922009-12-04 18:08:45757 uint32 type; // "User-defined" message type, from ipc_message.h.
[email protected]252cad62010-08-18 18:33:57758 std::string flags;
[email protected]7d5c3ac2009-02-04 08:58:19759 int64 sent; // Time that the message was sent (i.e. at Send()).
760 int64 receive; // Time before it was dispatched (i.e. before calling
761 // OnMessageReceived).
762 int64 dispatch; // Time after it was dispatched (i.e. after calling
763 // OnMessageReceived).
[email protected]252cad62010-08-18 18:33:57764 std::string message_name;
765 std::string params;
[email protected]7d5c3ac2009-02-04 08:58:19766};
767
768template <>
769struct ParamTraits<LogData> {
770 typedef LogData param_type;
[email protected]20f0487a2010-09-30 20:06:30771 static void Write(Message* m, const param_type& p);
772 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57773 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19774 // Doesn't make sense to implement this!
775 }
776};
777
[email protected]eb47a132009-03-04 00:39:56778template <>
[email protected]503683f2009-02-26 09:13:01779struct ParamTraits<Message> {
780 static void Write(Message* m, const Message& p) {
[email protected]8a861402011-01-28 19:59:11781 DCHECK(p.size() <= INT_MAX);
782 int message_size = static_cast<int>(p.size());
783 m->WriteInt(message_size);
784 m->WriteData(reinterpret_cast<const char*>(p.data()), message_size);
[email protected]503683f2009-02-26 09:13:01785 }
786 static bool Read(const Message* m, void** iter, Message* r) {
787 int size;
788 if (!m->ReadInt(iter, &size))
789 return false;
790 const char* data;
791 if (!m->ReadData(iter, &data, &size))
792 return false;
793 *r = Message(data, size);
794 return true;
795 }
[email protected]252cad62010-08-18 18:33:57796 static void Log(const Message& p, std::string* l) {
797 l->append("<IPC::Message>");
[email protected]503683f2009-02-26 09:13:01798 }
799};
800
801template <>
[email protected]7d5c3ac2009-02-04 08:58:19802struct ParamTraits<Tuple0> {
803 typedef Tuple0 param_type;
804 static void Write(Message* m, const param_type& p) {
805 }
806 static bool Read(const Message* m, void** iter, param_type* r) {
807 return true;
808 }
[email protected]252cad62010-08-18 18:33:57809 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19810 }
811};
812
813template <class A>
814struct ParamTraits< Tuple1<A> > {
815 typedef Tuple1<A> param_type;
816 static void Write(Message* m, const param_type& p) {
817 WriteParam(m, p.a);
818 }
819 static bool Read(const Message* m, void** iter, param_type* r) {
820 return ReadParam(m, iter, &r->a);
821 }
[email protected]252cad62010-08-18 18:33:57822 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19823 LogParam(p.a, l);
824 }
825};
826
827template <class A, class B>
828struct ParamTraits< Tuple2<A, B> > {
829 typedef Tuple2<A, B> param_type;
830 static void Write(Message* m, const param_type& p) {
831 WriteParam(m, p.a);
832 WriteParam(m, p.b);
833 }
834 static bool Read(const Message* m, void** iter, param_type* r) {
835 return (ReadParam(m, iter, &r->a) &&
836 ReadParam(m, iter, &r->b));
837 }
[email protected]252cad62010-08-18 18:33:57838 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19839 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57840 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19841 LogParam(p.b, l);
842 }
843};
844
845template <class A, class B, class C>
846struct ParamTraits< Tuple3<A, B, C> > {
847 typedef Tuple3<A, B, C> param_type;
848 static void Write(Message* m, const param_type& p) {
849 WriteParam(m, p.a);
850 WriteParam(m, p.b);
851 WriteParam(m, p.c);
852 }
853 static bool Read(const Message* m, void** iter, param_type* r) {
854 return (ReadParam(m, iter, &r->a) &&
855 ReadParam(m, iter, &r->b) &&
856 ReadParam(m, iter, &r->c));
857 }
[email protected]252cad62010-08-18 18:33:57858 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19859 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57860 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19861 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57862 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19863 LogParam(p.c, l);
864 }
865};
866
867template <class A, class B, class C, class D>
868struct ParamTraits< Tuple4<A, B, C, D> > {
869 typedef Tuple4<A, B, C, D> param_type;
870 static void Write(Message* m, const param_type& p) {
871 WriteParam(m, p.a);
872 WriteParam(m, p.b);
873 WriteParam(m, p.c);
874 WriteParam(m, p.d);
875 }
876 static bool Read(const Message* m, void** iter, param_type* r) {
877 return (ReadParam(m, iter, &r->a) &&
878 ReadParam(m, iter, &r->b) &&
879 ReadParam(m, iter, &r->c) &&
880 ReadParam(m, iter, &r->d));
881 }
[email protected]252cad62010-08-18 18:33:57882 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19883 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57884 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19885 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57886 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19887 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57888 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19889 LogParam(p.d, l);
890 }
891};
892
893template <class A, class B, class C, class D, class E>
894struct ParamTraits< Tuple5<A, B, C, D, E> > {
895 typedef Tuple5<A, B, C, D, E> param_type;
896 static void Write(Message* m, const param_type& p) {
897 WriteParam(m, p.a);
898 WriteParam(m, p.b);
899 WriteParam(m, p.c);
900 WriteParam(m, p.d);
901 WriteParam(m, p.e);
902 }
903 static bool Read(const Message* m, void** iter, param_type* r) {
904 return (ReadParam(m, iter, &r->a) &&
905 ReadParam(m, iter, &r->b) &&
906 ReadParam(m, iter, &r->c) &&
907 ReadParam(m, iter, &r->d) &&
908 ReadParam(m, iter, &r->e));
909 }
[email protected]252cad62010-08-18 18:33:57910 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19911 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57912 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19913 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57914 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19915 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57916 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19917 LogParam(p.d, l);
[email protected]252cad62010-08-18 18:33:57918 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19919 LogParam(p.e, l);
920 }
921};
922
[email protected]7d5c3ac2009-02-04 08:58:19923//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:29924// Generic message subclasses
925
926// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:24927template <class ParamType>
initial.commit09911bf2008-07-26 23:55:29928class MessageWithTuple : public Message {
929 public:
[email protected]81a34412009-01-05 19:17:24930 typedef ParamType Param;
[email protected]7a4de7a62010-08-17 18:38:24931 typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
[email protected]81a34412009-01-05 19:17:24932
[email protected]7a4de7a62010-08-17 18:38:24933 // The constructor and the Read() method's templated implementations are in
934 // ipc_message_utils_impl.h. The subclass constructor and Log() methods call
935 // the templated versions of these and make sure there are instantiations in
936 // those translation units.
937 MessageWithTuple(int32 routing_id, uint32 type, const RefParam& p);
[email protected]071b4b92010-08-09 16:06:58938
[email protected]7a4de7a62010-08-17 18:38:24939 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:29940
941 // Generic dispatcher. Should cover most cases.
[email protected]65412272010-12-21 20:03:24942 template<class T, class S, class Method>
943 static bool Dispatch(const Message* msg, T* obj, S* sender, Method func) {
initial.commit09911bf2008-07-26 23:55:29944 Param p;
945 if (Read(msg, &p)) {
946 DispatchToMethod(obj, func, p);
947 return true;
948 }
949 return false;
950 }
951
952 // The following dispatchers exist for the case where the callback function
953 // needs the message as well. They assume that "Param" is a type of Tuple
954 // (except the one arg case, as there is no Tuple1).
[email protected]65412272010-12-21 20:03:24955 template<class T, class S, typename TA>
956 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29957 void (T::*func)(const Message&, TA)) {
958 Param p;
959 if (Read(msg, &p)) {
[email protected]c2fe31542009-05-20 18:24:14960 (obj->*func)(*msg, p.a);
initial.commit09911bf2008-07-26 23:55:29961 return true;
962 }
963 return false;
964 }
965
[email protected]65412272010-12-21 20:03:24966 template<class T, class S, typename TA, typename TB>
967 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29968 void (T::*func)(const Message&, TA, TB)) {
969 Param p;
970 if (Read(msg, &p)) {
971 (obj->*func)(*msg, p.a, p.b);
972 return true;
973 }
974 return false;
975 }
976
[email protected]65412272010-12-21 20:03:24977 template<class T, class S, typename TA, typename TB, typename TC>
978 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29979 void (T::*func)(const Message&, TA, TB, TC)) {
980 Param p;
981 if (Read(msg, &p)) {
982 (obj->*func)(*msg, p.a, p.b, p.c);
983 return true;
984 }
985 return false;
986 }
987
[email protected]65412272010-12-21 20:03:24988 template<class T, class S, typename TA, typename TB, typename TC, typename TD>
989 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29990 void (T::*func)(const Message&, TA, TB, TC, TD)) {
991 Param p;
992 if (Read(msg, &p)) {
993 (obj->*func)(*msg, p.a, p.b, p.c, p.d);
994 return true;
995 }
996 return false;
997 }
998
[email protected]65412272010-12-21 20:03:24999 template<class T, class S, typename TA, typename TB, typename TC, typename TD,
initial.commit09911bf2008-07-26 23:55:291000 typename TE>
[email protected]65412272010-12-21 20:03:241001 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:291002 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
1003 Param p;
1004 if (Read(msg, &p)) {
1005 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
1006 return true;
1007 }
1008 return false;
1009 }
1010
[email protected]deb57402009-02-06 01:35:301011 // Functions used to do manual unpacking. Only used by the automation code,
1012 // these should go away once that code uses SyncChannel.
1013 template<typename TA, typename TB>
1014 static bool Read(const IPC::Message* msg, TA* a, TB* b) {
1015 ParamType params;
1016 if (!Read(msg, &params))
1017 return false;
1018 *a = params.a;
1019 *b = params.b;
1020 return true;
1021 }
1022
1023 template<typename TA, typename TB, typename TC>
1024 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
1025 ParamType params;
1026 if (!Read(msg, &params))
1027 return false;
1028 *a = params.a;
1029 *b = params.b;
1030 *c = params.c;
1031 return true;
1032 }
1033
1034 template<typename TA, typename TB, typename TC, typename TD>
1035 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) {
1036 ParamType params;
1037 if (!Read(msg, &params))
1038 return false;
1039 *a = params.a;
1040 *b = params.b;
1041 *c = params.c;
1042 *d = params.d;
1043 return true;
1044 }
1045
1046 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1047 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) {
1048 ParamType params;
1049 if (!Read(msg, &params))
1050 return false;
1051 *a = params.a;
1052 *b = params.b;
1053 *c = params.c;
1054 *d = params.d;
1055 *e = params.e;
1056 return true;
1057 }
initial.commit09911bf2008-07-26 23:55:291058};
1059
[email protected]7a4de7a62010-08-17 18:38:241060// defined in ipc_logging.cc
1061void GenerateLogData(const std::string& channel, const Message& message,
1062 LogData* data);
1063
1064
1065#if defined(IPC_MESSAGE_LOG_ENABLED)
[email protected]252cad62010-08-18 18:33:571066inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
1067 const std::string& output_params = msg->output_params();
[email protected]7a4de7a62010-08-17 18:38:241068 if (!l->empty() && !output_params.empty())
[email protected]252cad62010-08-18 18:33:571069 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:241070
1071 l->append(output_params);
1072}
1073
1074template <class ReplyParamType>
1075inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1076 const Message* msg) {
1077 if (msg->received_time() != 0) {
[email protected]252cad62010-08-18 18:33:571078 std::string output_params;
[email protected]7a4de7a62010-08-17 18:38:241079 LogParam(reply_params, &output_params);
1080 msg->set_output_params(output_params);
1081 }
1082}
1083
1084inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
1085 if (msg->sent_time()) {
1086 // Don't log the sync message after dispatch, as we don't have the
1087 // output parameters at that point. Instead, save its data and log it
1088 // with the outgoing reply message when it's sent.
1089 LogData* data = new LogData;
1090 GenerateLogData("", *msg, data);
1091 msg->set_dont_log();
1092 reply->set_sync_log_data(data);
1093 }
1094}
1095#else
[email protected]252cad62010-08-18 18:33:571096inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
[email protected]7a4de7a62010-08-17 18:38:241097
1098template <class ReplyParamType>
1099inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1100 const Message* msg) {}
1101
1102inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1103#endif
1104
initial.commit09911bf2008-07-26 23:55:291105// This class assumes that its template argument is a RefTuple (a Tuple with
[email protected]7a4de7a62010-08-17 18:38:241106// reference elements). This would go into ipc_message_utils_impl.h, but it is
1107// also used by chrome_frame.
initial.commit09911bf2008-07-26 23:55:291108template <class RefTuple>
1109class ParamDeserializer : public MessageReplyDeserializer {
1110 public:
[email protected]e1981f432008-08-12 15:22:131111 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:291112
1113 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1114 return ReadParam(&msg, &iter, &out_);
1115 }
1116
1117 RefTuple out_;
1118};
1119
initial.commit09911bf2008-07-26 23:55:291120// Used for synchronous messages.
[email protected]75e5a872009-04-02 23:56:111121template <class SendParamType, class ReplyParamType>
initial.commit09911bf2008-07-26 23:55:291122class MessageWithReply : public SyncMessage {
1123 public:
[email protected]75e5a872009-04-02 23:56:111124 typedef SendParamType SendParam;
[email protected]7a4de7a62010-08-17 18:38:241125 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
[email protected]75e5a872009-04-02 23:56:111126 typedef ReplyParamType ReplyParam;
1127
[email protected]168ae922009-12-04 18:08:451128 MessageWithReply(int32 routing_id, uint32 type,
[email protected]7a4de7a62010-08-17 18:38:241129 const RefSendParam& send, const ReplyParam& reply);
1130 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
1131 static bool ReadReplyParam(
1132 const Message* msg,
1133 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:291134
[email protected]65412272010-12-21 20:03:241135 template<class T, class S, class Method>
1136 static bool Dispatch(const Message* msg, T* obj, S* sender, Method func) {
initial.commit09911bf2008-07-26 23:55:291137 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291138 Message* reply = GenerateReply(msg);
1139 bool error;
[email protected]7a4de7a62010-08-17 18:38:241140 if (ReadSendParam(msg, &send_params)) {
1141 typename TupleTypes<ReplyParam>::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:291142 DispatchToMethod(obj, func, send_params, &reply_params);
1143 WriteParam(reply, reply_params);
1144 error = false;
[email protected]7a4de7a62010-08-17 18:38:241145 LogReplyParamsToMessage(reply_params, msg);
initial.commit09911bf2008-07-26 23:55:291146 } else {
1147 NOTREACHED() << "Error deserializing message " << msg->type();
1148 reply->set_reply_error();
1149 error = true;
1150 }
1151
[email protected]65412272010-12-21 20:03:241152 sender->Send(reply);
initial.commit09911bf2008-07-26 23:55:291153 return !error;
1154 }
1155
1156 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191157 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291158 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291159 Message* reply = GenerateReply(msg);
1160 bool error;
[email protected]7a4de7a62010-08-17 18:38:241161 if (ReadSendParam(msg, &send_params)) {
initial.commit09911bf2008-07-26 23:55:291162 Tuple1<Message&> t = MakeRefTuple(*reply);
[email protected]7a4de7a62010-08-17 18:38:241163 ConnectMessageAndReply(msg, reply);
initial.commit09911bf2008-07-26 23:55:291164 DispatchToMethod(obj, func, send_params, &t);
1165 error = false;
1166 } else {
1167 NOTREACHED() << "Error deserializing message " << msg->type();
1168 reply->set_reply_error();
1169 obj->Send(reply);
1170 error = true;
1171 }
1172 return !error;
1173 }
1174
1175 template<typename TA>
1176 static void WriteReplyParams(Message* reply, TA a) {
1177 ReplyParam p(a);
1178 WriteParam(reply, p);
1179 }
1180
1181 template<typename TA, typename TB>
1182 static void WriteReplyParams(Message* reply, TA a, TB b) {
1183 ReplyParam p(a, b);
1184 WriteParam(reply, p);
1185 }
1186
1187 template<typename TA, typename TB, typename TC>
1188 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1189 ReplyParam p(a, b, c);
1190 WriteParam(reply, p);
1191 }
1192
1193 template<typename TA, typename TB, typename TC, typename TD>
1194 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1195 ReplyParam p(a, b, c, d);
1196 WriteParam(reply, p);
1197 }
1198
1199 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1200 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1201 ReplyParam p(a, b, c, d, e);
1202 WriteParam(reply, p);
1203 }
1204};
1205
[email protected]7d5c3ac2009-02-04 08:58:191206//-----------------------------------------------------------------------------
1207
[email protected]3178f4e22008-08-05 21:20:411208} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291209
[email protected]946d1b22009-07-22 23:57:211210#endif // IPC_IPC_MESSAGE_UTILS_H_