blob: f7bf49a005d72ae7aae858169b95882235cd5a0d [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]f91cb992009-02-04 20:10:1274};
75
[email protected]7a4de7a62010-08-17 18:38:2476class DictionaryValue;
77class FilePath;
78class ListValue;
79class NullableString16;
80
81namespace base {
82class Time;
[email protected]d84e48b2010-10-21 22:04:5283class TimeDelta;
[email protected]7a4de7a62010-08-17 18:38:2484struct FileDescriptor;
85}
86
initial.commit09911bf2008-07-26 23:55:2987namespace IPC {
88
[email protected]7a4de7a62010-08-17 18:38:2489struct ChannelHandle;
90
initial.commit09911bf2008-07-26 23:55:2991//-----------------------------------------------------------------------------
92// An iterator class for reading the fields contained within a Message.
93
94class MessageIterator {
95 public:
[email protected]e1981f432008-08-12 15:22:1396 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
initial.commit09911bf2008-07-26 23:55:2997 }
98 int NextInt() const {
[email protected]9422b7dc2009-12-30 20:09:0299 int val = -1;
initial.commit09911bf2008-07-26 23:55:29100 if (!msg_.ReadInt(&iter_, &val))
101 NOTREACHED();
102 return val;
103 }
initial.commit09911bf2008-07-26 23:55:29104 const std::string NextString() const {
105 std::string val;
106 if (!msg_.ReadString(&iter_, &val))
107 NOTREACHED();
108 return val;
109 }
110 const std::wstring NextWString() const {
111 std::wstring val;
112 if (!msg_.ReadWString(&iter_, &val))
113 NOTREACHED();
114 return val;
115 }
[email protected]225c8f52010-02-05 22:23:20116 void NextData(const char** data, int* length) const {
initial.commit09911bf2008-07-26 23:55:29117 if (!msg_.ReadData(&iter_, data, length)) {
118 NOTREACHED();
119 }
120 }
121 private:
122 const Message& msg_;
123 mutable void* iter_;
124};
125
126//-----------------------------------------------------------------------------
[email protected]6476c72c2011-02-11 18:46:19127// A dummy struct to place first just to allow leading commas for all
128// members in the macro-generated constructor initializer lists.
129struct NoParams {
130};
131
132//-----------------------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19133// ParamTraits specializations, etc.
134
[email protected]7d5c3ac2009-02-04 08:58:19135template <class P>
136static inline void WriteParam(Message* m, const P& p) {
[email protected]7b291f92009-08-14 05:43:53137 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53138 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
[email protected]7d5c3ac2009-02-04 08:58:19139}
140
141template <class P>
[email protected]1e86aa62009-04-24 21:22:33142static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
143 P* p) {
[email protected]7b291f92009-08-14 05:43:53144 typedef typename SimilarTypeTraits<P>::Type Type;
145 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
[email protected]7d5c3ac2009-02-04 08:58:19146}
147
148template <class P>
[email protected]252cad62010-08-18 18:33:57149static inline void LogParam(const P& p, std::string* l) {
[email protected]7b291f92009-08-14 05:43:53150 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53151 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19152}
153
154template <>
155struct ParamTraits<bool> {
156 typedef bool param_type;
157 static void Write(Message* m, const param_type& p) {
158 m->WriteBool(p);
159 }
160 static bool Read(const Message* m, void** iter, param_type* r) {
161 return m->ReadBool(iter, r);
162 }
[email protected]252cad62010-08-18 18:33:57163 static void Log(const param_type& p, std::string* l) {
164 l->append(p ? "true" : "false");
[email protected]7d5c3ac2009-02-04 08:58:19165 }
166};
167
168template <>
169struct ParamTraits<int> {
170 typedef int param_type;
171 static void Write(Message* m, const param_type& p) {
172 m->WriteInt(p);
173 }
174 static bool Read(const Message* m, void** iter, param_type* r) {
175 return m->ReadInt(iter, r);
176 }
[email protected]252cad62010-08-18 18:33:57177 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19178};
179
180template <>
[email protected]63263f92009-07-28 19:35:08181struct ParamTraits<unsigned int> {
182 typedef unsigned int param_type;
183 static void Write(Message* m, const param_type& p) {
184 m->WriteInt(p);
185 }
186 static bool Read(const Message* m, void** iter, param_type* r) {
187 return m->ReadInt(iter, reinterpret_cast<int*>(r));
188 }
[email protected]252cad62010-08-18 18:33:57189 static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08190};
191
192template <>
[email protected]7d5c3ac2009-02-04 08:58:19193struct ParamTraits<long> {
194 typedef long param_type;
195 static void Write(Message* m, const param_type& p) {
196 m->WriteLong(p);
197 }
198 static bool Read(const Message* m, void** iter, param_type* r) {
199 return m->ReadLong(iter, r);
200 }
[email protected]252cad62010-08-18 18:33:57201 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19202};
203
[email protected]140c3032009-06-26 18:22:54204template <>
205struct ParamTraits<unsigned long> {
206 typedef unsigned long param_type;
207 static void Write(Message* m, const param_type& p) {
208 m->WriteLong(p);
209 }
210 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]63263f92009-07-28 19:35:08211 return m->ReadLong(iter, reinterpret_cast<long*>(r));
[email protected]140c3032009-06-26 18:22:54212 }
[email protected]252cad62010-08-18 18:33:57213 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19214};
215
216template <>
[email protected]63263f92009-07-28 19:35:08217struct ParamTraits<long long> {
218 typedef long long param_type;
[email protected]7d5c3ac2009-02-04 08:58:19219 static void Write(Message* m, const param_type& p) {
220 m->WriteInt64(static_cast<int64>(p));
221 }
222 static bool Read(const Message* m, void** iter, param_type* r) {
223 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
224 }
[email protected]252cad62010-08-18 18:33:57225 static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08226};
227
228template <>
229struct ParamTraits<unsigned long long> {
230 typedef unsigned long long param_type;
231 static void Write(Message* m, const param_type& p) {
232 m->WriteInt64(p);
233 }
234 static bool Read(const Message* m, void** iter, param_type* r) {
235 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
236 }
[email protected]252cad62010-08-18 18:33:57237 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19238};
239
[email protected]43a40202010-11-12 16:25:01240template <>
241struct ParamTraits<unsigned short> {
242 typedef unsigned short param_type;
243 static void Write(Message* m, const param_type& p);
244 static bool Read(const Message* m, void** iter, param_type* r);
245 static void Log(const param_type& p, std::string* l);
246};
247
[email protected]20199662010-06-17 03:29:26248// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
249// should be sure to check the sanity of these values after receiving them over
250// IPC.
251template <>
252struct ParamTraits<float> {
253 typedef float param_type;
254 static void Write(Message* m, const param_type& p) {
255 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
256 }
257 static bool Read(const Message* m, void** iter, param_type* r) {
258 const char *data;
259 int data_size;
260 if (!m->ReadData(iter, &data, &data_size) ||
261 data_size != sizeof(param_type)) {
262 NOTREACHED();
263 return false;
264 }
265 memcpy(r, data, sizeof(param_type));
266 return true;
267 }
[email protected]252cad62010-08-18 18:33:57268 static void Log(const param_type& p, std::string* l) {
269 l->append(StringPrintf("%e", p));
[email protected]20199662010-06-17 03:29:26270 }
271};
272
[email protected]7d5c3ac2009-02-04 08:58:19273template <>
274struct ParamTraits<double> {
275 typedef double param_type;
276 static void Write(Message* m, const param_type& p) {
277 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
278 }
279 static bool Read(const Message* m, void** iter, param_type* r) {
280 const char *data;
[email protected]20199662010-06-17 03:29:26281 int data_size;
282 if (!m->ReadData(iter, &data, &data_size) ||
283 data_size != sizeof(param_type)) {
[email protected]7d5c3ac2009-02-04 08:58:19284 NOTREACHED();
[email protected]20199662010-06-17 03:29:26285 return false;
[email protected]7d5c3ac2009-02-04 08:58:19286 }
[email protected]20199662010-06-17 03:29:26287 memcpy(r, data, sizeof(param_type));
288 return true;
[email protected]7d5c3ac2009-02-04 08:58:19289 }
[email protected]252cad62010-08-18 18:33:57290 static void Log(const param_type& p, std::string* l) {
291 l->append(StringPrintf("%e", p));
[email protected]7d5c3ac2009-02-04 08:58:19292 }
293};
294
295template <>
[email protected]7d5c3ac2009-02-04 08:58:19296struct ParamTraits<base::Time> {
297 typedef base::Time param_type;
[email protected]7a4de7a62010-08-17 18:38:24298 static void Write(Message* m, const param_type& p);
299 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57300 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19301};
302
[email protected]d84e48b2010-10-21 22:04:52303template <>
304struct ParamTraits<base::TimeDelta> {
305 typedef base::TimeDelta param_type;
306 static void Write(Message* m, const param_type& p);
307 static bool Read(const Message* m, void** iter, param_type* r);
308 static void Log(const param_type& p, std::string* l);
309};
310
[email protected]7d5c3ac2009-02-04 08:58:19311#if defined(OS_WIN)
312template <>
313struct ParamTraits<LOGFONT> {
314 typedef LOGFONT param_type;
315 static void Write(Message* m, const param_type& p) {
316 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
317 }
318 static bool Read(const Message* m, void** iter, param_type* r) {
319 const char *data;
320 int data_size = 0;
321 bool result = m->ReadData(iter, &data, &data_size);
322 if (result && data_size == sizeof(LOGFONT)) {
323 memcpy(r, data, sizeof(LOGFONT));
324 } else {
325 result = false;
326 NOTREACHED();
327 }
328
329 return result;
330 }
[email protected]252cad62010-08-18 18:33:57331 static void Log(const param_type& p, std::string* l) {
332 l->append(StringPrintf("<LOGFONT>"));
[email protected]7d5c3ac2009-02-04 08:58:19333 }
334};
335
336template <>
337struct ParamTraits<MSG> {
338 typedef MSG param_type;
339 static void Write(Message* m, const param_type& p) {
340 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
341 }
342 static bool Read(const Message* m, void** iter, param_type* r) {
343 const char *data;
344 int data_size = 0;
345 bool result = m->ReadData(iter, &data, &data_size);
346 if (result && data_size == sizeof(MSG)) {
347 memcpy(r, data, sizeof(MSG));
348 } else {
349 result = false;
350 NOTREACHED();
351 }
352
353 return result;
354 }
[email protected]252cad62010-08-18 18:33:57355 static void Log(const param_type& p, std::string* l) {
356 l->append("<MSG>");
[email protected]7a4de7a62010-08-17 18:38:24357 }
[email protected]7d5c3ac2009-02-04 08:58:19358};
359#endif // defined(OS_WIN)
360
361template <>
[email protected]584f2b22009-05-21 01:01:59362struct ParamTraits<DictionaryValue> {
363 typedef DictionaryValue param_type;
364 static void Write(Message* m, const param_type& p);
365 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57366 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59367};
368
369template <>
370struct ParamTraits<ListValue> {
371 typedef ListValue param_type;
372 static void Write(Message* m, const param_type& p);
373 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57374 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59375};
376
377template <>
[email protected]7d5c3ac2009-02-04 08:58:19378struct ParamTraits<std::string> {
379 typedef std::string param_type;
380 static void Write(Message* m, const param_type& p) {
381 m->WriteString(p);
382 }
383 static bool Read(const Message* m, void** iter, param_type* r) {
384 return m->ReadString(iter, r);
385 }
[email protected]252cad62010-08-18 18:33:57386 static void Log(const param_type& p, std::string* l) {
387 l->append(p);
[email protected]7d5c3ac2009-02-04 08:58:19388 }
389};
390
[email protected]3dd7a7a2009-07-27 21:09:07391template<typename CharType>
[email protected]252cad62010-08-18 18:33:57392static void LogBytes(const std::vector<CharType>& data, std::string* out) {
[email protected]3dd7a7a2009-07-27 21:09:07393#if defined(OS_WIN)
394 // Windows has a GUI for logging, which can handle arbitrary binary data.
395 for (size_t i = 0; i < data.size(); ++i)
396 out->push_back(data[i]);
397#else
398 // On POSIX, we log to stdout, which we assume can display ASCII.
399 static const size_t kMaxBytesToLog = 100;
400 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
401 if (isprint(data[i]))
402 out->push_back(data[i]);
403 else
[email protected]252cad62010-08-18 18:33:57404 out->append(StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
[email protected]3dd7a7a2009-07-27 21:09:07405 }
406 if (data.size() > kMaxBytesToLog) {
407 out->append(
[email protected]252cad62010-08-18 18:33:57408 StringPrintf(" and %u more bytes",
[email protected]3dd7a7a2009-07-27 21:09:07409 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
410 }
411#endif
412}
413
[email protected]7d5c3ac2009-02-04 08:58:19414template <>
415struct ParamTraits<std::vector<unsigned char> > {
416 typedef std::vector<unsigned char> param_type;
417 static void Write(Message* m, const param_type& p) {
[email protected]f6b8ce32011-03-02 00:03:18418 if (p.empty()) {
[email protected]7d5c3ac2009-02-04 08:58:19419 m->WriteData(NULL, 0);
420 } else {
421 m->WriteData(reinterpret_cast<const char*>(&p.front()),
422 static_cast<int>(p.size()));
423 }
424 }
425 static bool Read(const Message* m, void** iter, param_type* r) {
426 const char *data;
427 int data_size = 0;
428 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
429 return false;
430 r->resize(data_size);
431 if (data_size)
432 memcpy(&r->front(), data, data_size);
433 return true;
434 }
[email protected]252cad62010-08-18 18:33:57435 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07436 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19437 }
438};
439
440template <>
441struct ParamTraits<std::vector<char> > {
442 typedef std::vector<char> param_type;
443 static void Write(Message* m, const param_type& p) {
[email protected]f6b8ce32011-03-02 00:03:18444 if (p.empty()) {
[email protected]7d5c3ac2009-02-04 08:58:19445 m->WriteData(NULL, 0);
446 } else {
447 m->WriteData(&p.front(), static_cast<int>(p.size()));
448 }
449 }
450 static bool Read(const Message* m, void** iter, param_type* r) {
451 const char *data;
452 int data_size = 0;
453 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
454 return false;
455 r->resize(data_size);
456 if (data_size)
457 memcpy(&r->front(), data, data_size);
458 return true;
459 }
[email protected]252cad62010-08-18 18:33:57460 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07461 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19462 }
463};
464
465template <class P>
466struct ParamTraits<std::vector<P> > {
467 typedef std::vector<P> param_type;
468 static void Write(Message* m, const param_type& p) {
469 WriteParam(m, static_cast<int>(p.size()));
470 for (size_t i = 0; i < p.size(); i++)
471 WriteParam(m, p[i]);
472 }
473 static bool Read(const Message* m, void** iter, param_type* r) {
474 int size;
[email protected]86440f52009-12-31 05:17:23475 // ReadLength() checks for < 0 itself.
[email protected]7d5c3ac2009-02-04 08:58:19476 if (!m->ReadLength(iter, &size))
477 return false;
478 // Resizing beforehand is not safe, see BUG 1006367 for details.
[email protected]86440f52009-12-31 05:17:23479 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
480 return false;
481 r->resize(size);
482 for (int i = 0; i < size; i++) {
483 if (!ReadParam(m, iter, &(*r)[i]))
484 return false;
[email protected]7d5c3ac2009-02-04 08:58:19485 }
486 return true;
487 }
[email protected]252cad62010-08-18 18:33:57488 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19489 for (size_t i = 0; i < p.size(); ++i) {
490 if (i != 0)
[email protected]252cad62010-08-18 18:33:57491 l->append(" ");
[email protected]7d5c3ac2009-02-04 08:58:19492 LogParam((p[i]), l);
493 }
494 }
495};
496
[email protected]96da6962010-05-13 19:10:34497template <class P>
498struct ParamTraits<std::set<P> > {
499 typedef std::set<P> param_type;
500 static void Write(Message* m, const param_type& p) {
501 WriteParam(m, static_cast<int>(p.size()));
502 typename param_type::const_iterator iter;
503 for (iter = p.begin(); iter != p.end(); ++iter)
504 WriteParam(m, *iter);
505 }
506 static bool Read(const Message* m, void** iter, param_type* r) {
507 int size;
508 if (!m->ReadLength(iter, &size))
509 return false;
510 for (int i = 0; i < size; ++i) {
511 P item;
512 if (!ReadParam(m, iter, &item))
513 return false;
514 r->insert(item);
515 }
516 return true;
517 }
[email protected]252cad62010-08-18 18:33:57518 static void Log(const param_type& p, std::string* l) {
519 l->append("<std::set>");
[email protected]96da6962010-05-13 19:10:34520 }
521};
522
523
[email protected]7d5c3ac2009-02-04 08:58:19524template <class K, class V>
525struct ParamTraits<std::map<K, V> > {
526 typedef std::map<K, V> param_type;
527 static void Write(Message* m, const param_type& p) {
528 WriteParam(m, static_cast<int>(p.size()));
529 typename param_type::const_iterator iter;
530 for (iter = p.begin(); iter != p.end(); ++iter) {
531 WriteParam(m, iter->first);
532 WriteParam(m, iter->second);
533 }
534 }
535 static bool Read(const Message* m, void** iter, param_type* r) {
536 int size;
537 if (!ReadParam(m, iter, &size) || size < 0)
538 return false;
539 for (int i = 0; i < size; ++i) {
540 K k;
541 if (!ReadParam(m, iter, &k))
542 return false;
543 V& value = (*r)[k];
544 if (!ReadParam(m, iter, &value))
545 return false;
546 }
547 return true;
548 }
[email protected]252cad62010-08-18 18:33:57549 static void Log(const param_type& p, std::string* l) {
550 l->append("<std::map>");
[email protected]7d5c3ac2009-02-04 08:58:19551 }
552};
553
[email protected]eb47a132009-03-04 00:39:56554
[email protected]7d5c3ac2009-02-04 08:58:19555template <>
556struct ParamTraits<std::wstring> {
557 typedef std::wstring param_type;
558 static void Write(Message* m, const param_type& p) {
559 m->WriteWString(p);
560 }
561 static bool Read(const Message* m, void** iter, param_type* r) {
562 return m->ReadWString(iter, r);
563 }
[email protected]252cad62010-08-18 18:33:57564 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19565};
566
[email protected]a5da6d612009-08-04 02:00:56567template <class A, class B>
568struct ParamTraits<std::pair<A, B> > {
569 typedef std::pair<A, B> param_type;
570 static void Write(Message* m, const param_type& p) {
571 WriteParam(m, p.first);
572 WriteParam(m, p.second);
573 }
574 static bool Read(const Message* m, void** iter, param_type* r) {
575 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
576 }
[email protected]252cad62010-08-18 18:33:57577 static void Log(const param_type& p, std::string* l) {
578 l->append("(");
[email protected]a5da6d612009-08-04 02:00:56579 LogParam(p.first, l);
[email protected]252cad62010-08-18 18:33:57580 l->append(", ");
[email protected]a5da6d612009-08-04 02:00:56581 LogParam(p.second, l);
[email protected]252cad62010-08-18 18:33:57582 l->append(")");
[email protected]a5da6d612009-08-04 02:00:56583 }
584};
585
[email protected]15bf8712009-08-27 00:55:02586template <>
587struct ParamTraits<NullableString16> {
588 typedef NullableString16 param_type;
[email protected]7a4de7a62010-08-17 18:38:24589 static void Write(Message* m, const param_type& p);
590 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57591 static void Log(const param_type& p, std::string* l);
[email protected]15bf8712009-08-27 00:55:02592};
593
[email protected]eb47a132009-03-04 00:39:56594// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
595// need this trait.
596#if !defined(WCHAR_T_IS_UTF16)
[email protected]eb47a132009-03-04 00:39:56597template <>
598struct ParamTraits<string16> {
599 typedef string16 param_type;
600 static void Write(Message* m, const param_type& p) {
[email protected]3a2a5d22009-03-04 03:36:36601 m->WriteString16(p);
[email protected]eb47a132009-03-04 00:39:56602 }
603 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]3a2a5d22009-03-04 03:36:36604 return m->ReadString16(iter, r);
[email protected]eb47a132009-03-04 00:39:56605 }
[email protected]252cad62010-08-18 18:33:57606 static void Log(const param_type& p, std::string* l);
[email protected]eb47a132009-03-04 00:39:56607};
[email protected]eb47a132009-03-04 00:39:56608#endif
609
[email protected]7d5c3ac2009-02-04 08:58:19610// and, a few more useful types...
611#if defined(OS_WIN)
612template <>
613struct ParamTraits<HANDLE> {
614 typedef HANDLE param_type;
615 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35616 // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
617 // bit systems.
618 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19619 }
620 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35621 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
622 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19623 }
[email protected]252cad62010-08-18 18:33:57624 static void Log(const param_type& p, std::string* l) {
625 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19626 }
627};
628
629template <>
630struct ParamTraits<HCURSOR> {
631 typedef HCURSOR param_type;
632 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35633 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19634 }
635 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35636 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
637 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19638 }
[email protected]252cad62010-08-18 18:33:57639 static void Log(const param_type& p, std::string* l) {
640 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19641 }
642};
643
644template <>
[email protected]7d5c3ac2009-02-04 08:58:19645struct ParamTraits<HACCEL> {
646 typedef HACCEL param_type;
647 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35648 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19649 }
650 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35651 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
652 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19653 }
654};
655
656template <>
657struct ParamTraits<POINT> {
658 typedef POINT param_type;
659 static void Write(Message* m, const param_type& p) {
660 m->WriteInt(p.x);
661 m->WriteInt(p.y);
662 }
663 static bool Read(const Message* m, void** iter, param_type* r) {
664 int x, y;
665 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
666 return false;
667 r->x = x;
668 r->y = y;
669 return true;
670 }
[email protected]252cad62010-08-18 18:33:57671 static void Log(const param_type& p, std::string* l) {
672 l->append(StringPrintf("(%d, %d)", p.x, p.y));
[email protected]7d5c3ac2009-02-04 08:58:19673 }
674};
675#endif // defined(OS_WIN)
676
677template <>
678struct ParamTraits<FilePath> {
679 typedef FilePath param_type;
[email protected]7a4de7a62010-08-17 18:38:24680 static void Write(Message* m, const param_type& p);
681 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57682 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19683};
684
[email protected]526776c2009-02-07 00:39:26685#if defined(OS_POSIX)
[email protected]2749885f2009-03-05 21:40:11686// FileDescriptors may be serialised over IPC channels on POSIX. On the
687// receiving side, the FileDescriptor is a valid duplicate of the file
688// descriptor which was transmitted: *it is not just a copy of the integer like
689// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
690// this case, the receiving end will see a value of -1. *Zero is a valid file
691// descriptor*.
692//
693// The received file descriptor will have the |auto_close| flag set to true. The
694// code which handles the message is responsible for taking ownership of it.
695// File descriptors are OS resources and must be closed when no longer needed.
696//
697// When sending a file descriptor, the file descriptor must be valid at the time
698// of transmission. Since transmission is not synchronous, one should consider
699// dup()ing any file descriptors to be transmitted and setting the |auto_close|
700// flag, which causes the file descriptor to be closed after writing.
[email protected]526776c2009-02-07 00:39:26701template<>
[email protected]5fe733de2009-02-11 18:59:20702struct ParamTraits<base::FileDescriptor> {
703 typedef base::FileDescriptor param_type;
[email protected]7a4de7a62010-08-17 18:38:24704 static void Write(Message* m, const param_type& p);
705 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57706 static void Log(const param_type& p, std::string* l);
[email protected]526776c2009-02-07 00:39:26707};
[email protected]379e7a52010-03-09 00:38:41708#endif // defined(OS_POSIX)
[email protected]526776c2009-02-07 00:39:26709
[email protected]d2e884d2009-06-22 20:37:52710// A ChannelHandle is basically a platform-inspecific wrapper around the
711// fact that IPC endpoints are handled specially on POSIX. See above comments
712// on FileDescriptor for more background.
713template<>
714struct ParamTraits<IPC::ChannelHandle> {
715 typedef ChannelHandle param_type;
[email protected]7a4de7a62010-08-17 18:38:24716 static void Write(Message* m, const param_type& p);
717 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57718 static void Log(const param_type& p, std::string* l);
[email protected]d2e884d2009-06-22 20:37:52719};
720
[email protected]7d5c3ac2009-02-04 08:58:19721#if defined(OS_WIN)
722template <>
723struct ParamTraits<XFORM> {
724 typedef XFORM param_type;
725 static void Write(Message* m, const param_type& p) {
726 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
727 }
728 static bool Read(const Message* m, void** iter, param_type* r) {
729 const char *data;
730 int data_size = 0;
731 bool result = m->ReadData(iter, &data, &data_size);
732 if (result && data_size == sizeof(XFORM)) {
733 memcpy(r, data, sizeof(XFORM));
734 } else {
735 result = false;
736 NOTREACHED();
737 }
738
739 return result;
740 }
[email protected]252cad62010-08-18 18:33:57741 static void Log(const param_type& p, std::string* l) {
742 l->append("<XFORM>");
[email protected]7d5c3ac2009-02-04 08:58:19743 }
744};
745#endif // defined(OS_WIN)
746
[email protected]7d5c3ac2009-02-04 08:58:19747struct LogData {
[email protected]20f0487a2010-09-30 20:06:30748 LogData();
749 ~LogData();
750
[email protected]9a3a293b2009-06-04 22:28:16751 std::string channel;
[email protected]8bef70e2009-04-14 19:11:24752 int32 routing_id;
[email protected]168ae922009-12-04 18:08:45753 uint32 type; // "User-defined" message type, from ipc_message.h.
[email protected]252cad62010-08-18 18:33:57754 std::string flags;
[email protected]7d5c3ac2009-02-04 08:58:19755 int64 sent; // Time that the message was sent (i.e. at Send()).
756 int64 receive; // Time before it was dispatched (i.e. before calling
757 // OnMessageReceived).
758 int64 dispatch; // Time after it was dispatched (i.e. after calling
759 // OnMessageReceived).
[email protected]252cad62010-08-18 18:33:57760 std::string message_name;
761 std::string params;
[email protected]7d5c3ac2009-02-04 08:58:19762};
763
764template <>
765struct ParamTraits<LogData> {
766 typedef LogData param_type;
[email protected]20f0487a2010-09-30 20:06:30767 static void Write(Message* m, const param_type& p);
768 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57769 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19770 // Doesn't make sense to implement this!
771 }
772};
773
[email protected]eb47a132009-03-04 00:39:56774template <>
[email protected]503683f2009-02-26 09:13:01775struct ParamTraits<Message> {
776 static void Write(Message* m, const Message& p) {
[email protected]8a861402011-01-28 19:59:11777 DCHECK(p.size() <= INT_MAX);
778 int message_size = static_cast<int>(p.size());
779 m->WriteInt(message_size);
780 m->WriteData(reinterpret_cast<const char*>(p.data()), message_size);
[email protected]503683f2009-02-26 09:13:01781 }
782 static bool Read(const Message* m, void** iter, Message* r) {
783 int size;
784 if (!m->ReadInt(iter, &size))
785 return false;
786 const char* data;
787 if (!m->ReadData(iter, &data, &size))
788 return false;
789 *r = Message(data, size);
790 return true;
791 }
[email protected]252cad62010-08-18 18:33:57792 static void Log(const Message& p, std::string* l) {
793 l->append("<IPC::Message>");
[email protected]503683f2009-02-26 09:13:01794 }
795};
796
797template <>
[email protected]7d5c3ac2009-02-04 08:58:19798struct ParamTraits<Tuple0> {
799 typedef Tuple0 param_type;
800 static void Write(Message* m, const param_type& p) {
801 }
802 static bool Read(const Message* m, void** iter, param_type* r) {
803 return true;
804 }
[email protected]252cad62010-08-18 18:33:57805 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19806 }
807};
808
809template <class A>
810struct ParamTraits< Tuple1<A> > {
811 typedef Tuple1<A> param_type;
812 static void Write(Message* m, const param_type& p) {
813 WriteParam(m, p.a);
814 }
815 static bool Read(const Message* m, void** iter, param_type* r) {
816 return ReadParam(m, iter, &r->a);
817 }
[email protected]252cad62010-08-18 18:33:57818 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19819 LogParam(p.a, l);
820 }
821};
822
823template <class A, class B>
824struct ParamTraits< Tuple2<A, B> > {
825 typedef Tuple2<A, B> param_type;
826 static void Write(Message* m, const param_type& p) {
827 WriteParam(m, p.a);
828 WriteParam(m, p.b);
829 }
830 static bool Read(const Message* m, void** iter, param_type* r) {
831 return (ReadParam(m, iter, &r->a) &&
832 ReadParam(m, iter, &r->b));
833 }
[email protected]252cad62010-08-18 18:33:57834 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19835 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57836 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19837 LogParam(p.b, l);
838 }
839};
840
841template <class A, class B, class C>
842struct ParamTraits< Tuple3<A, B, C> > {
843 typedef Tuple3<A, B, C> param_type;
844 static void Write(Message* m, const param_type& p) {
845 WriteParam(m, p.a);
846 WriteParam(m, p.b);
847 WriteParam(m, p.c);
848 }
849 static bool Read(const Message* m, void** iter, param_type* r) {
850 return (ReadParam(m, iter, &r->a) &&
851 ReadParam(m, iter, &r->b) &&
852 ReadParam(m, iter, &r->c));
853 }
[email protected]252cad62010-08-18 18:33:57854 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19855 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57856 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19857 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57858 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19859 LogParam(p.c, l);
860 }
861};
862
863template <class A, class B, class C, class D>
864struct ParamTraits< Tuple4<A, B, C, D> > {
865 typedef Tuple4<A, B, C, D> param_type;
866 static void Write(Message* m, const param_type& p) {
867 WriteParam(m, p.a);
868 WriteParam(m, p.b);
869 WriteParam(m, p.c);
870 WriteParam(m, p.d);
871 }
872 static bool Read(const Message* m, void** iter, param_type* r) {
873 return (ReadParam(m, iter, &r->a) &&
874 ReadParam(m, iter, &r->b) &&
875 ReadParam(m, iter, &r->c) &&
876 ReadParam(m, iter, &r->d));
877 }
[email protected]252cad62010-08-18 18:33:57878 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19879 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57880 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19881 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57882 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19883 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57884 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19885 LogParam(p.d, l);
886 }
887};
888
889template <class A, class B, class C, class D, class E>
890struct ParamTraits< Tuple5<A, B, C, D, E> > {
891 typedef Tuple5<A, B, C, D, E> param_type;
892 static void Write(Message* m, const param_type& p) {
893 WriteParam(m, p.a);
894 WriteParam(m, p.b);
895 WriteParam(m, p.c);
896 WriteParam(m, p.d);
897 WriteParam(m, p.e);
898 }
899 static bool Read(const Message* m, void** iter, param_type* r) {
900 return (ReadParam(m, iter, &r->a) &&
901 ReadParam(m, iter, &r->b) &&
902 ReadParam(m, iter, &r->c) &&
903 ReadParam(m, iter, &r->d) &&
904 ReadParam(m, iter, &r->e));
905 }
[email protected]252cad62010-08-18 18:33:57906 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19907 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57908 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19909 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57910 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19911 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57912 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19913 LogParam(p.d, l);
[email protected]252cad62010-08-18 18:33:57914 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19915 LogParam(p.e, l);
916 }
917};
918
[email protected]7d5c3ac2009-02-04 08:58:19919//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:29920// Generic message subclasses
921
922// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:24923template <class ParamType>
initial.commit09911bf2008-07-26 23:55:29924class MessageWithTuple : public Message {
925 public:
[email protected]81a34412009-01-05 19:17:24926 typedef ParamType Param;
[email protected]7a4de7a62010-08-17 18:38:24927 typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
[email protected]81a34412009-01-05 19:17:24928
[email protected]7a4de7a62010-08-17 18:38:24929 // The constructor and the Read() method's templated implementations are in
930 // ipc_message_utils_impl.h. The subclass constructor and Log() methods call
931 // the templated versions of these and make sure there are instantiations in
932 // those translation units.
933 MessageWithTuple(int32 routing_id, uint32 type, const RefParam& p);
[email protected]071b4b92010-08-09 16:06:58934
[email protected]7a4de7a62010-08-17 18:38:24935 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:29936
937 // Generic dispatcher. Should cover most cases.
[email protected]65412272010-12-21 20:03:24938 template<class T, class S, class Method>
939 static bool Dispatch(const Message* msg, T* obj, S* sender, Method func) {
initial.commit09911bf2008-07-26 23:55:29940 Param p;
941 if (Read(msg, &p)) {
942 DispatchToMethod(obj, func, p);
943 return true;
944 }
945 return false;
946 }
947
948 // The following dispatchers exist for the case where the callback function
949 // needs the message as well. They assume that "Param" is a type of Tuple
950 // (except the one arg case, as there is no Tuple1).
[email protected]65412272010-12-21 20:03:24951 template<class T, class S, typename TA>
952 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29953 void (T::*func)(const Message&, TA)) {
954 Param p;
955 if (Read(msg, &p)) {
[email protected]c2fe31542009-05-20 18:24:14956 (obj->*func)(*msg, p.a);
initial.commit09911bf2008-07-26 23:55:29957 return true;
958 }
959 return false;
960 }
961
[email protected]65412272010-12-21 20:03:24962 template<class T, class S, typename TA, typename TB>
963 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29964 void (T::*func)(const Message&, TA, TB)) {
965 Param p;
966 if (Read(msg, &p)) {
967 (obj->*func)(*msg, p.a, p.b);
968 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, typename TC>
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, TC)) {
976 Param p;
977 if (Read(msg, &p)) {
978 (obj->*func)(*msg, p.a, p.b, p.c);
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, typename TD>
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, TD)) {
987 Param p;
988 if (Read(msg, &p)) {
989 (obj->*func)(*msg, p.a, p.b, p.c, p.d);
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,
initial.commit09911bf2008-07-26 23:55:29996 typename TE>
[email protected]65412272010-12-21 20:03:24997 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29998 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
999 Param p;
1000 if (Read(msg, &p)) {
1001 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
1002 return true;
1003 }
1004 return false;
1005 }
1006
[email protected]deb57402009-02-06 01:35:301007 // Functions used to do manual unpacking. Only used by the automation code,
1008 // these should go away once that code uses SyncChannel.
1009 template<typename TA, typename TB>
1010 static bool Read(const IPC::Message* msg, TA* a, TB* b) {
1011 ParamType params;
1012 if (!Read(msg, &params))
1013 return false;
1014 *a = params.a;
1015 *b = params.b;
1016 return true;
1017 }
1018
1019 template<typename TA, typename TB, typename TC>
1020 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
1021 ParamType params;
1022 if (!Read(msg, &params))
1023 return false;
1024 *a = params.a;
1025 *b = params.b;
1026 *c = params.c;
1027 return true;
1028 }
1029
1030 template<typename TA, typename TB, typename TC, typename TD>
1031 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) {
1032 ParamType params;
1033 if (!Read(msg, &params))
1034 return false;
1035 *a = params.a;
1036 *b = params.b;
1037 *c = params.c;
1038 *d = params.d;
1039 return true;
1040 }
1041
1042 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1043 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) {
1044 ParamType params;
1045 if (!Read(msg, &params))
1046 return false;
1047 *a = params.a;
1048 *b = params.b;
1049 *c = params.c;
1050 *d = params.d;
1051 *e = params.e;
1052 return true;
1053 }
initial.commit09911bf2008-07-26 23:55:291054};
1055
[email protected]7a4de7a62010-08-17 18:38:241056// defined in ipc_logging.cc
1057void GenerateLogData(const std::string& channel, const Message& message,
1058 LogData* data);
1059
1060
1061#if defined(IPC_MESSAGE_LOG_ENABLED)
[email protected]252cad62010-08-18 18:33:571062inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
1063 const std::string& output_params = msg->output_params();
[email protected]7a4de7a62010-08-17 18:38:241064 if (!l->empty() && !output_params.empty())
[email protected]252cad62010-08-18 18:33:571065 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:241066
1067 l->append(output_params);
1068}
1069
1070template <class ReplyParamType>
1071inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1072 const Message* msg) {
1073 if (msg->received_time() != 0) {
[email protected]252cad62010-08-18 18:33:571074 std::string output_params;
[email protected]7a4de7a62010-08-17 18:38:241075 LogParam(reply_params, &output_params);
1076 msg->set_output_params(output_params);
1077 }
1078}
1079
1080inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
1081 if (msg->sent_time()) {
1082 // Don't log the sync message after dispatch, as we don't have the
1083 // output parameters at that point. Instead, save its data and log it
1084 // with the outgoing reply message when it's sent.
1085 LogData* data = new LogData;
1086 GenerateLogData("", *msg, data);
1087 msg->set_dont_log();
1088 reply->set_sync_log_data(data);
1089 }
1090}
1091#else
[email protected]252cad62010-08-18 18:33:571092inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
[email protected]7a4de7a62010-08-17 18:38:241093
1094template <class ReplyParamType>
1095inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1096 const Message* msg) {}
1097
1098inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1099#endif
1100
initial.commit09911bf2008-07-26 23:55:291101// This class assumes that its template argument is a RefTuple (a Tuple with
[email protected]7a4de7a62010-08-17 18:38:241102// reference elements). This would go into ipc_message_utils_impl.h, but it is
1103// also used by chrome_frame.
initial.commit09911bf2008-07-26 23:55:291104template <class RefTuple>
1105class ParamDeserializer : public MessageReplyDeserializer {
1106 public:
[email protected]e1981f432008-08-12 15:22:131107 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:291108
1109 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1110 return ReadParam(&msg, &iter, &out_);
1111 }
1112
1113 RefTuple out_;
1114};
1115
initial.commit09911bf2008-07-26 23:55:291116// Used for synchronous messages.
[email protected]75e5a872009-04-02 23:56:111117template <class SendParamType, class ReplyParamType>
initial.commit09911bf2008-07-26 23:55:291118class MessageWithReply : public SyncMessage {
1119 public:
[email protected]75e5a872009-04-02 23:56:111120 typedef SendParamType SendParam;
[email protected]7a4de7a62010-08-17 18:38:241121 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
[email protected]75e5a872009-04-02 23:56:111122 typedef ReplyParamType ReplyParam;
1123
[email protected]168ae922009-12-04 18:08:451124 MessageWithReply(int32 routing_id, uint32 type,
[email protected]7a4de7a62010-08-17 18:38:241125 const RefSendParam& send, const ReplyParam& reply);
1126 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
1127 static bool ReadReplyParam(
1128 const Message* msg,
1129 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:291130
[email protected]65412272010-12-21 20:03:241131 template<class T, class S, class Method>
1132 static bool Dispatch(const Message* msg, T* obj, S* sender, Method func) {
initial.commit09911bf2008-07-26 23:55:291133 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291134 Message* reply = GenerateReply(msg);
1135 bool error;
[email protected]7a4de7a62010-08-17 18:38:241136 if (ReadSendParam(msg, &send_params)) {
1137 typename TupleTypes<ReplyParam>::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:291138 DispatchToMethod(obj, func, send_params, &reply_params);
1139 WriteParam(reply, reply_params);
1140 error = false;
[email protected]7a4de7a62010-08-17 18:38:241141 LogReplyParamsToMessage(reply_params, msg);
initial.commit09911bf2008-07-26 23:55:291142 } else {
1143 NOTREACHED() << "Error deserializing message " << msg->type();
1144 reply->set_reply_error();
1145 error = true;
1146 }
1147
[email protected]65412272010-12-21 20:03:241148 sender->Send(reply);
initial.commit09911bf2008-07-26 23:55:291149 return !error;
1150 }
1151
1152 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191153 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291154 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291155 Message* reply = GenerateReply(msg);
1156 bool error;
[email protected]7a4de7a62010-08-17 18:38:241157 if (ReadSendParam(msg, &send_params)) {
initial.commit09911bf2008-07-26 23:55:291158 Tuple1<Message&> t = MakeRefTuple(*reply);
[email protected]7a4de7a62010-08-17 18:38:241159 ConnectMessageAndReply(msg, reply);
initial.commit09911bf2008-07-26 23:55:291160 DispatchToMethod(obj, func, send_params, &t);
1161 error = false;
1162 } else {
1163 NOTREACHED() << "Error deserializing message " << msg->type();
1164 reply->set_reply_error();
1165 obj->Send(reply);
1166 error = true;
1167 }
1168 return !error;
1169 }
1170
1171 template<typename TA>
1172 static void WriteReplyParams(Message* reply, TA a) {
1173 ReplyParam p(a);
1174 WriteParam(reply, p);
1175 }
1176
1177 template<typename TA, typename TB>
1178 static void WriteReplyParams(Message* reply, TA a, TB b) {
1179 ReplyParam p(a, b);
1180 WriteParam(reply, p);
1181 }
1182
1183 template<typename TA, typename TB, typename TC>
1184 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1185 ReplyParam p(a, b, c);
1186 WriteParam(reply, p);
1187 }
1188
1189 template<typename TA, typename TB, typename TC, typename TD>
1190 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1191 ReplyParam p(a, b, c, d);
1192 WriteParam(reply, p);
1193 }
1194
1195 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1196 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1197 ReplyParam p(a, b, c, d, e);
1198 WriteParam(reply, p);
1199 }
1200};
1201
[email protected]7d5c3ac2009-02-04 08:58:191202//-----------------------------------------------------------------------------
1203
[email protected]3178f4e22008-08-05 21:20:411204} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291205
[email protected]946d1b22009-07-22 23:57:211206#endif // IPC_IPC_MESSAGE_UTILS_H_