blob: 800daafb8f2fee2658f9c82452a52b70cf105fc7 [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]f91cb992009-02-04 20:10:1275};
76
[email protected]7a4de7a62010-08-17 18:38:2477class DictionaryValue;
78class FilePath;
79class ListValue;
80class NullableString16;
81
82namespace base {
83class Time;
[email protected]d84e48b2010-10-21 22:04:5284class TimeDelta;
[email protected]7a4de7a62010-08-17 18:38:2485struct FileDescriptor;
86}
87
initial.commit09911bf2008-07-26 23:55:2988namespace IPC {
89
[email protected]7a4de7a62010-08-17 18:38:2490struct ChannelHandle;
91
initial.commit09911bf2008-07-26 23:55:2992//-----------------------------------------------------------------------------
93// An iterator class for reading the fields contained within a Message.
94
95class MessageIterator {
96 public:
[email protected]e1981f432008-08-12 15:22:1397 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
initial.commit09911bf2008-07-26 23:55:2998 }
99 int NextInt() const {
[email protected]9422b7dc2009-12-30 20:09:02100 int val = -1;
initial.commit09911bf2008-07-26 23:55:29101 if (!msg_.ReadInt(&iter_, &val))
102 NOTREACHED();
103 return val;
104 }
initial.commit09911bf2008-07-26 23:55:29105 const std::string NextString() const {
106 std::string val;
107 if (!msg_.ReadString(&iter_, &val))
108 NOTREACHED();
109 return val;
110 }
111 const std::wstring NextWString() const {
112 std::wstring val;
113 if (!msg_.ReadWString(&iter_, &val))
114 NOTREACHED();
115 return val;
116 }
[email protected]225c8f52010-02-05 22:23:20117 void NextData(const char** data, int* length) const {
initial.commit09911bf2008-07-26 23:55:29118 if (!msg_.ReadData(&iter_, data, length)) {
119 NOTREACHED();
120 }
121 }
122 private:
123 const Message& msg_;
124 mutable void* iter_;
125};
126
127//-----------------------------------------------------------------------------
[email protected]6476c72c2011-02-11 18:46:19128// A dummy struct to place first just to allow leading commas for all
129// members in the macro-generated constructor initializer lists.
130struct NoParams {
131};
132
133//-----------------------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19134// ParamTraits specializations, etc.
135
[email protected]7d5c3ac2009-02-04 08:58:19136template <class P>
137static inline void WriteParam(Message* m, const P& p) {
[email protected]7b291f92009-08-14 05:43:53138 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53139 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
[email protected]7d5c3ac2009-02-04 08:58:19140}
141
142template <class P>
[email protected]1e86aa62009-04-24 21:22:33143static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
144 P* p) {
[email protected]7b291f92009-08-14 05:43:53145 typedef typename SimilarTypeTraits<P>::Type Type;
146 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
[email protected]7d5c3ac2009-02-04 08:58:19147}
148
149template <class P>
[email protected]252cad62010-08-18 18:33:57150static inline void LogParam(const P& p, std::string* l) {
[email protected]7b291f92009-08-14 05:43:53151 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53152 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19153}
154
155template <>
156struct ParamTraits<bool> {
157 typedef bool param_type;
158 static void Write(Message* m, const param_type& p) {
159 m->WriteBool(p);
160 }
161 static bool Read(const Message* m, void** iter, param_type* r) {
162 return m->ReadBool(iter, r);
163 }
[email protected]252cad62010-08-18 18:33:57164 static void Log(const param_type& p, std::string* l) {
165 l->append(p ? "true" : "false");
[email protected]7d5c3ac2009-02-04 08:58:19166 }
167};
168
169template <>
170struct ParamTraits<int> {
171 typedef int param_type;
172 static void Write(Message* m, const param_type& p) {
173 m->WriteInt(p);
174 }
175 static bool Read(const Message* m, void** iter, param_type* r) {
176 return m->ReadInt(iter, r);
177 }
[email protected]252cad62010-08-18 18:33:57178 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19179};
180
181template <>
[email protected]63263f92009-07-28 19:35:08182struct ParamTraits<unsigned int> {
183 typedef unsigned int param_type;
184 static void Write(Message* m, const param_type& p) {
185 m->WriteInt(p);
186 }
187 static bool Read(const Message* m, void** iter, param_type* r) {
188 return m->ReadInt(iter, reinterpret_cast<int*>(r));
189 }
[email protected]252cad62010-08-18 18:33:57190 static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08191};
192
193template <>
[email protected]7d5c3ac2009-02-04 08:58:19194struct ParamTraits<long> {
195 typedef long param_type;
196 static void Write(Message* m, const param_type& p) {
197 m->WriteLong(p);
198 }
199 static bool Read(const Message* m, void** iter, param_type* r) {
200 return m->ReadLong(iter, r);
201 }
[email protected]252cad62010-08-18 18:33:57202 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19203};
204
[email protected]140c3032009-06-26 18:22:54205template <>
206struct ParamTraits<unsigned long> {
207 typedef unsigned long param_type;
208 static void Write(Message* m, const param_type& p) {
209 m->WriteLong(p);
210 }
211 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]63263f92009-07-28 19:35:08212 return m->ReadLong(iter, reinterpret_cast<long*>(r));
[email protected]140c3032009-06-26 18:22:54213 }
[email protected]252cad62010-08-18 18:33:57214 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19215};
216
217template <>
[email protected]63263f92009-07-28 19:35:08218struct ParamTraits<long long> {
219 typedef long long param_type;
[email protected]7d5c3ac2009-02-04 08:58:19220 static void Write(Message* m, const param_type& p) {
221 m->WriteInt64(static_cast<int64>(p));
222 }
223 static bool Read(const Message* m, void** iter, param_type* r) {
224 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
225 }
[email protected]252cad62010-08-18 18:33:57226 static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08227};
228
229template <>
230struct ParamTraits<unsigned long long> {
231 typedef unsigned long long param_type;
232 static void Write(Message* m, const param_type& p) {
233 m->WriteInt64(p);
234 }
235 static bool Read(const Message* m, void** iter, param_type* r) {
236 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
237 }
[email protected]252cad62010-08-18 18:33:57238 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19239};
240
[email protected]43a40202010-11-12 16:25:01241template <>
242struct ParamTraits<unsigned short> {
243 typedef unsigned short param_type;
244 static void Write(Message* m, const param_type& p);
245 static bool Read(const Message* m, void** iter, param_type* r);
246 static void Log(const param_type& p, std::string* l);
247};
248
[email protected]20199662010-06-17 03:29:26249// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
250// should be sure to check the sanity of these values after receiving them over
251// IPC.
252template <>
253struct ParamTraits<float> {
254 typedef float param_type;
255 static void Write(Message* m, const param_type& p) {
256 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
257 }
258 static bool Read(const Message* m, void** iter, param_type* r) {
259 const char *data;
260 int data_size;
261 if (!m->ReadData(iter, &data, &data_size) ||
262 data_size != sizeof(param_type)) {
263 NOTREACHED();
264 return false;
265 }
266 memcpy(r, data, sizeof(param_type));
267 return true;
268 }
[email protected]252cad62010-08-18 18:33:57269 static void Log(const param_type& p, std::string* l) {
270 l->append(StringPrintf("%e", p));
[email protected]20199662010-06-17 03:29:26271 }
272};
273
[email protected]7d5c3ac2009-02-04 08:58:19274template <>
275struct ParamTraits<double> {
276 typedef double param_type;
277 static void Write(Message* m, const param_type& p) {
278 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
279 }
280 static bool Read(const Message* m, void** iter, param_type* r) {
281 const char *data;
[email protected]20199662010-06-17 03:29:26282 int data_size;
283 if (!m->ReadData(iter, &data, &data_size) ||
284 data_size != sizeof(param_type)) {
[email protected]7d5c3ac2009-02-04 08:58:19285 NOTREACHED();
[email protected]20199662010-06-17 03:29:26286 return false;
[email protected]7d5c3ac2009-02-04 08:58:19287 }
[email protected]20199662010-06-17 03:29:26288 memcpy(r, data, sizeof(param_type));
289 return true;
[email protected]7d5c3ac2009-02-04 08:58:19290 }
[email protected]252cad62010-08-18 18:33:57291 static void Log(const param_type& p, std::string* l) {
292 l->append(StringPrintf("%e", p));
[email protected]7d5c3ac2009-02-04 08:58:19293 }
294};
295
296template <>
[email protected]7d5c3ac2009-02-04 08:58:19297struct ParamTraits<base::Time> {
298 typedef base::Time param_type;
[email protected]7a4de7a62010-08-17 18:38:24299 static void Write(Message* m, const param_type& p);
300 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57301 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19302};
303
[email protected]d84e48b2010-10-21 22:04:52304template <>
305struct ParamTraits<base::TimeDelta> {
306 typedef base::TimeDelta param_type;
307 static void Write(Message* m, const param_type& p);
308 static bool Read(const Message* m, void** iter, param_type* r);
309 static void Log(const param_type& p, std::string* l);
310};
311
[email protected]7d5c3ac2009-02-04 08:58:19312#if defined(OS_WIN)
313template <>
314struct ParamTraits<LOGFONT> {
315 typedef LOGFONT param_type;
316 static void Write(Message* m, const param_type& p) {
317 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
318 }
319 static bool Read(const Message* m, void** iter, param_type* r) {
320 const char *data;
321 int data_size = 0;
322 bool result = m->ReadData(iter, &data, &data_size);
323 if (result && data_size == sizeof(LOGFONT)) {
324 memcpy(r, data, sizeof(LOGFONT));
325 } else {
326 result = false;
327 NOTREACHED();
328 }
329
330 return result;
331 }
[email protected]252cad62010-08-18 18:33:57332 static void Log(const param_type& p, std::string* l) {
333 l->append(StringPrintf("<LOGFONT>"));
[email protected]7d5c3ac2009-02-04 08:58:19334 }
335};
336
337template <>
338struct ParamTraits<MSG> {
339 typedef MSG param_type;
340 static void Write(Message* m, const param_type& p) {
341 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
342 }
343 static bool Read(const Message* m, void** iter, param_type* r) {
344 const char *data;
345 int data_size = 0;
346 bool result = m->ReadData(iter, &data, &data_size);
347 if (result && data_size == sizeof(MSG)) {
348 memcpy(r, data, sizeof(MSG));
349 } else {
350 result = false;
351 NOTREACHED();
352 }
353
354 return result;
355 }
[email protected]252cad62010-08-18 18:33:57356 static void Log(const param_type& p, std::string* l) {
357 l->append("<MSG>");
[email protected]7a4de7a62010-08-17 18:38:24358 }
[email protected]7d5c3ac2009-02-04 08:58:19359};
360#endif // defined(OS_WIN)
361
362template <>
[email protected]584f2b22009-05-21 01:01:59363struct ParamTraits<DictionaryValue> {
364 typedef DictionaryValue param_type;
365 static void Write(Message* m, const param_type& p);
366 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57367 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59368};
369
370template <>
371struct ParamTraits<ListValue> {
372 typedef ListValue param_type;
373 static void Write(Message* m, const param_type& p);
374 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57375 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59376};
377
378template <>
[email protected]7d5c3ac2009-02-04 08:58:19379struct ParamTraits<std::string> {
380 typedef std::string param_type;
381 static void Write(Message* m, const param_type& p) {
382 m->WriteString(p);
383 }
384 static bool Read(const Message* m, void** iter, param_type* r) {
385 return m->ReadString(iter, r);
386 }
[email protected]252cad62010-08-18 18:33:57387 static void Log(const param_type& p, std::string* l) {
388 l->append(p);
[email protected]7d5c3ac2009-02-04 08:58:19389 }
390};
391
[email protected]3dd7a7a2009-07-27 21:09:07392template<typename CharType>
[email protected]252cad62010-08-18 18:33:57393static void LogBytes(const std::vector<CharType>& data, std::string* out) {
[email protected]3dd7a7a2009-07-27 21:09:07394#if defined(OS_WIN)
395 // Windows has a GUI for logging, which can handle arbitrary binary data.
396 for (size_t i = 0; i < data.size(); ++i)
397 out->push_back(data[i]);
398#else
399 // On POSIX, we log to stdout, which we assume can display ASCII.
400 static const size_t kMaxBytesToLog = 100;
401 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
402 if (isprint(data[i]))
403 out->push_back(data[i]);
404 else
[email protected]252cad62010-08-18 18:33:57405 out->append(StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
[email protected]3dd7a7a2009-07-27 21:09:07406 }
407 if (data.size() > kMaxBytesToLog) {
408 out->append(
[email protected]252cad62010-08-18 18:33:57409 StringPrintf(" and %u more bytes",
[email protected]3dd7a7a2009-07-27 21:09:07410 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
411 }
412#endif
413}
414
[email protected]7d5c3ac2009-02-04 08:58:19415template <>
416struct ParamTraits<std::vector<unsigned char> > {
417 typedef std::vector<unsigned char> param_type;
418 static void Write(Message* m, const param_type& p) {
[email protected]f6b8ce32011-03-02 00:03:18419 if (p.empty()) {
[email protected]7d5c3ac2009-02-04 08:58:19420 m->WriteData(NULL, 0);
421 } else {
422 m->WriteData(reinterpret_cast<const char*>(&p.front()),
423 static_cast<int>(p.size()));
424 }
425 }
426 static bool Read(const Message* m, void** iter, param_type* r) {
427 const char *data;
428 int data_size = 0;
429 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
430 return false;
431 r->resize(data_size);
432 if (data_size)
433 memcpy(&r->front(), data, data_size);
434 return true;
435 }
[email protected]252cad62010-08-18 18:33:57436 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07437 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19438 }
439};
440
441template <>
442struct ParamTraits<std::vector<char> > {
443 typedef std::vector<char> param_type;
444 static void Write(Message* m, const param_type& p) {
[email protected]f6b8ce32011-03-02 00:03:18445 if (p.empty()) {
[email protected]7d5c3ac2009-02-04 08:58:19446 m->WriteData(NULL, 0);
447 } else {
448 m->WriteData(&p.front(), static_cast<int>(p.size()));
449 }
450 }
451 static bool Read(const Message* m, void** iter, param_type* r) {
452 const char *data;
453 int data_size = 0;
454 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
455 return false;
456 r->resize(data_size);
457 if (data_size)
458 memcpy(&r->front(), data, data_size);
459 return true;
460 }
[email protected]252cad62010-08-18 18:33:57461 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07462 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19463 }
464};
465
466template <class P>
467struct ParamTraits<std::vector<P> > {
468 typedef std::vector<P> param_type;
469 static void Write(Message* m, const param_type& p) {
470 WriteParam(m, static_cast<int>(p.size()));
471 for (size_t i = 0; i < p.size(); i++)
472 WriteParam(m, p[i]);
473 }
474 static bool Read(const Message* m, void** iter, param_type* r) {
475 int size;
[email protected]86440f52009-12-31 05:17:23476 // ReadLength() checks for < 0 itself.
[email protected]7d5c3ac2009-02-04 08:58:19477 if (!m->ReadLength(iter, &size))
478 return false;
479 // Resizing beforehand is not safe, see BUG 1006367 for details.
[email protected]86440f52009-12-31 05:17:23480 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
481 return false;
482 r->resize(size);
483 for (int i = 0; i < size; i++) {
484 if (!ReadParam(m, iter, &(*r)[i]))
485 return false;
[email protected]7d5c3ac2009-02-04 08:58:19486 }
487 return true;
488 }
[email protected]252cad62010-08-18 18:33:57489 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19490 for (size_t i = 0; i < p.size(); ++i) {
491 if (i != 0)
[email protected]252cad62010-08-18 18:33:57492 l->append(" ");
[email protected]7d5c3ac2009-02-04 08:58:19493 LogParam((p[i]), l);
494 }
495 }
496};
497
[email protected]96da6962010-05-13 19:10:34498template <class P>
499struct ParamTraits<std::set<P> > {
500 typedef std::set<P> param_type;
501 static void Write(Message* m, const param_type& p) {
502 WriteParam(m, static_cast<int>(p.size()));
503 typename param_type::const_iterator iter;
504 for (iter = p.begin(); iter != p.end(); ++iter)
505 WriteParam(m, *iter);
506 }
507 static bool Read(const Message* m, void** iter, param_type* r) {
508 int size;
509 if (!m->ReadLength(iter, &size))
510 return false;
511 for (int i = 0; i < size; ++i) {
512 P item;
513 if (!ReadParam(m, iter, &item))
514 return false;
515 r->insert(item);
516 }
517 return true;
518 }
[email protected]252cad62010-08-18 18:33:57519 static void Log(const param_type& p, std::string* l) {
520 l->append("<std::set>");
[email protected]96da6962010-05-13 19:10:34521 }
522};
523
524
[email protected]7d5c3ac2009-02-04 08:58:19525template <class K, class V>
526struct ParamTraits<std::map<K, V> > {
527 typedef std::map<K, V> param_type;
528 static void Write(Message* m, const param_type& p) {
529 WriteParam(m, static_cast<int>(p.size()));
530 typename param_type::const_iterator iter;
531 for (iter = p.begin(); iter != p.end(); ++iter) {
532 WriteParam(m, iter->first);
533 WriteParam(m, iter->second);
534 }
535 }
536 static bool Read(const Message* m, void** iter, param_type* r) {
537 int size;
538 if (!ReadParam(m, iter, &size) || size < 0)
539 return false;
540 for (int i = 0; i < size; ++i) {
541 K k;
542 if (!ReadParam(m, iter, &k))
543 return false;
544 V& value = (*r)[k];
545 if (!ReadParam(m, iter, &value))
546 return false;
547 }
548 return true;
549 }
[email protected]252cad62010-08-18 18:33:57550 static void Log(const param_type& p, std::string* l) {
551 l->append("<std::map>");
[email protected]7d5c3ac2009-02-04 08:58:19552 }
553};
554
[email protected]eb47a132009-03-04 00:39:56555
[email protected]7d5c3ac2009-02-04 08:58:19556template <>
557struct ParamTraits<std::wstring> {
558 typedef std::wstring param_type;
559 static void Write(Message* m, const param_type& p) {
560 m->WriteWString(p);
561 }
562 static bool Read(const Message* m, void** iter, param_type* r) {
563 return m->ReadWString(iter, r);
564 }
[email protected]252cad62010-08-18 18:33:57565 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19566};
567
[email protected]a5da6d612009-08-04 02:00:56568template <class A, class B>
569struct ParamTraits<std::pair<A, B> > {
570 typedef std::pair<A, B> param_type;
571 static void Write(Message* m, const param_type& p) {
572 WriteParam(m, p.first);
573 WriteParam(m, p.second);
574 }
575 static bool Read(const Message* m, void** iter, param_type* r) {
576 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
577 }
[email protected]252cad62010-08-18 18:33:57578 static void Log(const param_type& p, std::string* l) {
579 l->append("(");
[email protected]a5da6d612009-08-04 02:00:56580 LogParam(p.first, l);
[email protected]252cad62010-08-18 18:33:57581 l->append(", ");
[email protected]a5da6d612009-08-04 02:00:56582 LogParam(p.second, l);
[email protected]252cad62010-08-18 18:33:57583 l->append(")");
[email protected]a5da6d612009-08-04 02:00:56584 }
585};
586
[email protected]15bf8712009-08-27 00:55:02587template <>
588struct ParamTraits<NullableString16> {
589 typedef NullableString16 param_type;
[email protected]7a4de7a62010-08-17 18:38:24590 static void Write(Message* m, const param_type& p);
591 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57592 static void Log(const param_type& p, std::string* l);
[email protected]15bf8712009-08-27 00:55:02593};
594
[email protected]eb47a132009-03-04 00:39:56595// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
596// need this trait.
597#if !defined(WCHAR_T_IS_UTF16)
[email protected]eb47a132009-03-04 00:39:56598template <>
599struct ParamTraits<string16> {
600 typedef string16 param_type;
601 static void Write(Message* m, const param_type& p) {
[email protected]3a2a5d22009-03-04 03:36:36602 m->WriteString16(p);
[email protected]eb47a132009-03-04 00:39:56603 }
604 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]3a2a5d22009-03-04 03:36:36605 return m->ReadString16(iter, r);
[email protected]eb47a132009-03-04 00:39:56606 }
[email protected]252cad62010-08-18 18:33:57607 static void Log(const param_type& p, std::string* l);
[email protected]eb47a132009-03-04 00:39:56608};
[email protected]eb47a132009-03-04 00:39:56609#endif
610
[email protected]7d5c3ac2009-02-04 08:58:19611// and, a few more useful types...
612#if defined(OS_WIN)
613template <>
614struct ParamTraits<HANDLE> {
615 typedef HANDLE param_type;
616 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35617 // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
618 // bit systems.
619 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19620 }
621 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35622 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
623 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19624 }
[email protected]252cad62010-08-18 18:33:57625 static void Log(const param_type& p, std::string* l) {
626 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19627 }
628};
629
630template <>
631struct ParamTraits<HCURSOR> {
632 typedef HCURSOR param_type;
633 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35634 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19635 }
636 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35637 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
638 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19639 }
[email protected]252cad62010-08-18 18:33:57640 static void Log(const param_type& p, std::string* l) {
641 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19642 }
643};
644
645template <>
[email protected]7d5c3ac2009-02-04 08:58:19646struct ParamTraits<HACCEL> {
647 typedef HACCEL param_type;
648 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35649 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19650 }
651 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35652 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
653 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19654 }
655};
656
657template <>
658struct ParamTraits<POINT> {
659 typedef POINT param_type;
660 static void Write(Message* m, const param_type& p) {
661 m->WriteInt(p.x);
662 m->WriteInt(p.y);
663 }
664 static bool Read(const Message* m, void** iter, param_type* r) {
665 int x, y;
666 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
667 return false;
668 r->x = x;
669 r->y = y;
670 return true;
671 }
[email protected]252cad62010-08-18 18:33:57672 static void Log(const param_type& p, std::string* l) {
673 l->append(StringPrintf("(%d, %d)", p.x, p.y));
[email protected]7d5c3ac2009-02-04 08:58:19674 }
675};
676#endif // defined(OS_WIN)
677
678template <>
679struct ParamTraits<FilePath> {
680 typedef FilePath param_type;
[email protected]7a4de7a62010-08-17 18:38:24681 static void Write(Message* m, const param_type& p);
682 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57683 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19684};
685
[email protected]526776c2009-02-07 00:39:26686#if defined(OS_POSIX)
[email protected]2749885f2009-03-05 21:40:11687// FileDescriptors may be serialised over IPC channels on POSIX. On the
688// receiving side, the FileDescriptor is a valid duplicate of the file
689// descriptor which was transmitted: *it is not just a copy of the integer like
690// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
691// this case, the receiving end will see a value of -1. *Zero is a valid file
692// descriptor*.
693//
694// The received file descriptor will have the |auto_close| flag set to true. The
695// code which handles the message is responsible for taking ownership of it.
696// File descriptors are OS resources and must be closed when no longer needed.
697//
698// When sending a file descriptor, the file descriptor must be valid at the time
699// of transmission. Since transmission is not synchronous, one should consider
700// dup()ing any file descriptors to be transmitted and setting the |auto_close|
701// flag, which causes the file descriptor to be closed after writing.
[email protected]526776c2009-02-07 00:39:26702template<>
[email protected]5fe733de2009-02-11 18:59:20703struct ParamTraits<base::FileDescriptor> {
704 typedef base::FileDescriptor param_type;
[email protected]7a4de7a62010-08-17 18:38:24705 static void Write(Message* m, const param_type& p);
706 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57707 static void Log(const param_type& p, std::string* l);
[email protected]526776c2009-02-07 00:39:26708};
[email protected]379e7a52010-03-09 00:38:41709#endif // defined(OS_POSIX)
[email protected]526776c2009-02-07 00:39:26710
[email protected]d2e884d2009-06-22 20:37:52711// A ChannelHandle is basically a platform-inspecific wrapper around the
712// fact that IPC endpoints are handled specially on POSIX. See above comments
713// on FileDescriptor for more background.
714template<>
715struct ParamTraits<IPC::ChannelHandle> {
716 typedef ChannelHandle param_type;
[email protected]7a4de7a62010-08-17 18:38:24717 static void Write(Message* m, const param_type& p);
718 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57719 static void Log(const param_type& p, std::string* l);
[email protected]d2e884d2009-06-22 20:37:52720};
721
[email protected]7d5c3ac2009-02-04 08:58:19722#if defined(OS_WIN)
723template <>
724struct ParamTraits<XFORM> {
725 typedef XFORM param_type;
726 static void Write(Message* m, const param_type& p) {
727 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
728 }
729 static bool Read(const Message* m, void** iter, param_type* r) {
730 const char *data;
731 int data_size = 0;
732 bool result = m->ReadData(iter, &data, &data_size);
733 if (result && data_size == sizeof(XFORM)) {
734 memcpy(r, data, sizeof(XFORM));
735 } else {
736 result = false;
737 NOTREACHED();
738 }
739
740 return result;
741 }
[email protected]252cad62010-08-18 18:33:57742 static void Log(const param_type& p, std::string* l) {
743 l->append("<XFORM>");
[email protected]7d5c3ac2009-02-04 08:58:19744 }
745};
746#endif // defined(OS_WIN)
747
[email protected]7d5c3ac2009-02-04 08:58:19748struct LogData {
[email protected]20f0487a2010-09-30 20:06:30749 LogData();
750 ~LogData();
751
[email protected]9a3a293b2009-06-04 22:28:16752 std::string channel;
[email protected]8bef70e2009-04-14 19:11:24753 int32 routing_id;
[email protected]168ae922009-12-04 18:08:45754 uint32 type; // "User-defined" message type, from ipc_message.h.
[email protected]252cad62010-08-18 18:33:57755 std::string flags;
[email protected]7d5c3ac2009-02-04 08:58:19756 int64 sent; // Time that the message was sent (i.e. at Send()).
757 int64 receive; // Time before it was dispatched (i.e. before calling
758 // OnMessageReceived).
759 int64 dispatch; // Time after it was dispatched (i.e. after calling
760 // OnMessageReceived).
[email protected]252cad62010-08-18 18:33:57761 std::string message_name;
762 std::string params;
[email protected]7d5c3ac2009-02-04 08:58:19763};
764
765template <>
766struct ParamTraits<LogData> {
767 typedef LogData param_type;
[email protected]20f0487a2010-09-30 20:06:30768 static void Write(Message* m, const param_type& p);
769 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57770 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19771 // Doesn't make sense to implement this!
772 }
773};
774
[email protected]eb47a132009-03-04 00:39:56775template <>
[email protected]503683f2009-02-26 09:13:01776struct ParamTraits<Message> {
777 static void Write(Message* m, const Message& p) {
[email protected]8a861402011-01-28 19:59:11778 DCHECK(p.size() <= INT_MAX);
779 int message_size = static_cast<int>(p.size());
780 m->WriteInt(message_size);
781 m->WriteData(reinterpret_cast<const char*>(p.data()), message_size);
[email protected]503683f2009-02-26 09:13:01782 }
783 static bool Read(const Message* m, void** iter, Message* r) {
784 int size;
785 if (!m->ReadInt(iter, &size))
786 return false;
787 const char* data;
788 if (!m->ReadData(iter, &data, &size))
789 return false;
790 *r = Message(data, size);
791 return true;
792 }
[email protected]252cad62010-08-18 18:33:57793 static void Log(const Message& p, std::string* l) {
794 l->append("<IPC::Message>");
[email protected]503683f2009-02-26 09:13:01795 }
796};
797
798template <>
[email protected]7d5c3ac2009-02-04 08:58:19799struct ParamTraits<Tuple0> {
800 typedef Tuple0 param_type;
801 static void Write(Message* m, const param_type& p) {
802 }
803 static bool Read(const Message* m, void** iter, param_type* r) {
804 return true;
805 }
[email protected]252cad62010-08-18 18:33:57806 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19807 }
808};
809
810template <class A>
811struct ParamTraits< Tuple1<A> > {
812 typedef Tuple1<A> param_type;
813 static void Write(Message* m, const param_type& p) {
814 WriteParam(m, p.a);
815 }
816 static bool Read(const Message* m, void** iter, param_type* r) {
817 return ReadParam(m, iter, &r->a);
818 }
[email protected]252cad62010-08-18 18:33:57819 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19820 LogParam(p.a, l);
821 }
822};
823
824template <class A, class B>
825struct ParamTraits< Tuple2<A, B> > {
826 typedef Tuple2<A, B> param_type;
827 static void Write(Message* m, const param_type& p) {
828 WriteParam(m, p.a);
829 WriteParam(m, p.b);
830 }
831 static bool Read(const Message* m, void** iter, param_type* r) {
832 return (ReadParam(m, iter, &r->a) &&
833 ReadParam(m, iter, &r->b));
834 }
[email protected]252cad62010-08-18 18:33:57835 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19836 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57837 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19838 LogParam(p.b, l);
839 }
840};
841
842template <class A, class B, class C>
843struct ParamTraits< Tuple3<A, B, C> > {
844 typedef Tuple3<A, B, C> param_type;
845 static void Write(Message* m, const param_type& p) {
846 WriteParam(m, p.a);
847 WriteParam(m, p.b);
848 WriteParam(m, p.c);
849 }
850 static bool Read(const Message* m, void** iter, param_type* r) {
851 return (ReadParam(m, iter, &r->a) &&
852 ReadParam(m, iter, &r->b) &&
853 ReadParam(m, iter, &r->c));
854 }
[email protected]252cad62010-08-18 18:33:57855 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19856 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57857 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19858 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57859 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19860 LogParam(p.c, l);
861 }
862};
863
864template <class A, class B, class C, class D>
865struct ParamTraits< Tuple4<A, B, C, D> > {
866 typedef Tuple4<A, B, C, D> param_type;
867 static void Write(Message* m, const param_type& p) {
868 WriteParam(m, p.a);
869 WriteParam(m, p.b);
870 WriteParam(m, p.c);
871 WriteParam(m, p.d);
872 }
873 static bool Read(const Message* m, void** iter, param_type* r) {
874 return (ReadParam(m, iter, &r->a) &&
875 ReadParam(m, iter, &r->b) &&
876 ReadParam(m, iter, &r->c) &&
877 ReadParam(m, iter, &r->d));
878 }
[email protected]252cad62010-08-18 18:33:57879 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19880 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57881 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19882 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57883 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19884 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57885 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19886 LogParam(p.d, l);
887 }
888};
889
890template <class A, class B, class C, class D, class E>
891struct ParamTraits< Tuple5<A, B, C, D, E> > {
892 typedef Tuple5<A, B, C, D, E> param_type;
893 static void Write(Message* m, const param_type& p) {
894 WriteParam(m, p.a);
895 WriteParam(m, p.b);
896 WriteParam(m, p.c);
897 WriteParam(m, p.d);
898 WriteParam(m, p.e);
899 }
900 static bool Read(const Message* m, void** iter, param_type* r) {
901 return (ReadParam(m, iter, &r->a) &&
902 ReadParam(m, iter, &r->b) &&
903 ReadParam(m, iter, &r->c) &&
904 ReadParam(m, iter, &r->d) &&
905 ReadParam(m, iter, &r->e));
906 }
[email protected]252cad62010-08-18 18:33:57907 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19908 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57909 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19910 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57911 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19912 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57913 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19914 LogParam(p.d, l);
[email protected]252cad62010-08-18 18:33:57915 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19916 LogParam(p.e, l);
917 }
918};
919
[email protected]7d5c3ac2009-02-04 08:58:19920//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:29921// Generic message subclasses
922
923// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:24924template <class ParamType>
initial.commit09911bf2008-07-26 23:55:29925class MessageWithTuple : public Message {
926 public:
[email protected]81a34412009-01-05 19:17:24927 typedef ParamType Param;
[email protected]7a4de7a62010-08-17 18:38:24928 typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
[email protected]81a34412009-01-05 19:17:24929
[email protected]7a4de7a62010-08-17 18:38:24930 // The constructor and the Read() method's templated implementations are in
931 // ipc_message_utils_impl.h. The subclass constructor and Log() methods call
932 // the templated versions of these and make sure there are instantiations in
933 // those translation units.
934 MessageWithTuple(int32 routing_id, uint32 type, const RefParam& p);
[email protected]071b4b92010-08-09 16:06:58935
[email protected]7a4de7a62010-08-17 18:38:24936 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:29937
938 // Generic dispatcher. Should cover most cases.
[email protected]65412272010-12-21 20:03:24939 template<class T, class S, class Method>
940 static bool Dispatch(const Message* msg, T* obj, S* sender, Method func) {
initial.commit09911bf2008-07-26 23:55:29941 Param p;
942 if (Read(msg, &p)) {
943 DispatchToMethod(obj, func, p);
944 return true;
945 }
946 return false;
947 }
948
949 // The following dispatchers exist for the case where the callback function
950 // needs the message as well. They assume that "Param" is a type of Tuple
951 // (except the one arg case, as there is no Tuple1).
[email protected]65412272010-12-21 20:03:24952 template<class T, class S, typename TA>
953 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29954 void (T::*func)(const Message&, TA)) {
955 Param p;
956 if (Read(msg, &p)) {
[email protected]c2fe31542009-05-20 18:24:14957 (obj->*func)(*msg, p.a);
initial.commit09911bf2008-07-26 23:55:29958 return true;
959 }
960 return false;
961 }
962
[email protected]65412272010-12-21 20:03:24963 template<class T, class S, typename TA, typename TB>
964 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29965 void (T::*func)(const Message&, TA, TB)) {
966 Param p;
967 if (Read(msg, &p)) {
968 (obj->*func)(*msg, p.a, p.b);
969 return true;
970 }
971 return false;
972 }
973
[email protected]65412272010-12-21 20:03:24974 template<class T, class S, typename TA, typename TB, typename TC>
975 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29976 void (T::*func)(const Message&, TA, TB, TC)) {
977 Param p;
978 if (Read(msg, &p)) {
979 (obj->*func)(*msg, p.a, p.b, p.c);
980 return true;
981 }
982 return false;
983 }
984
[email protected]65412272010-12-21 20:03:24985 template<class T, class S, typename TA, typename TB, typename TC, typename TD>
986 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29987 void (T::*func)(const Message&, TA, TB, TC, TD)) {
988 Param p;
989 if (Read(msg, &p)) {
990 (obj->*func)(*msg, p.a, p.b, p.c, p.d);
991 return true;
992 }
993 return false;
994 }
995
[email protected]65412272010-12-21 20:03:24996 template<class T, class S, typename TA, typename TB, typename TC, typename TD,
initial.commit09911bf2008-07-26 23:55:29997 typename TE>
[email protected]65412272010-12-21 20:03:24998 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29999 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
1000 Param p;
1001 if (Read(msg, &p)) {
1002 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
1003 return true;
1004 }
1005 return false;
1006 }
1007
[email protected]deb57402009-02-06 01:35:301008 // Functions used to do manual unpacking. Only used by the automation code,
1009 // these should go away once that code uses SyncChannel.
1010 template<typename TA, typename TB>
1011 static bool Read(const IPC::Message* msg, TA* a, TB* b) {
1012 ParamType params;
1013 if (!Read(msg, &params))
1014 return false;
1015 *a = params.a;
1016 *b = params.b;
1017 return true;
1018 }
1019
1020 template<typename TA, typename TB, typename TC>
1021 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
1022 ParamType params;
1023 if (!Read(msg, &params))
1024 return false;
1025 *a = params.a;
1026 *b = params.b;
1027 *c = params.c;
1028 return true;
1029 }
1030
1031 template<typename TA, typename TB, typename TC, typename TD>
1032 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) {
1033 ParamType params;
1034 if (!Read(msg, &params))
1035 return false;
1036 *a = params.a;
1037 *b = params.b;
1038 *c = params.c;
1039 *d = params.d;
1040 return true;
1041 }
1042
1043 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1044 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) {
1045 ParamType params;
1046 if (!Read(msg, &params))
1047 return false;
1048 *a = params.a;
1049 *b = params.b;
1050 *c = params.c;
1051 *d = params.d;
1052 *e = params.e;
1053 return true;
1054 }
initial.commit09911bf2008-07-26 23:55:291055};
1056
[email protected]7a4de7a62010-08-17 18:38:241057// defined in ipc_logging.cc
1058void GenerateLogData(const std::string& channel, const Message& message,
1059 LogData* data);
1060
1061
1062#if defined(IPC_MESSAGE_LOG_ENABLED)
[email protected]252cad62010-08-18 18:33:571063inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
1064 const std::string& output_params = msg->output_params();
[email protected]7a4de7a62010-08-17 18:38:241065 if (!l->empty() && !output_params.empty())
[email protected]252cad62010-08-18 18:33:571066 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:241067
1068 l->append(output_params);
1069}
1070
1071template <class ReplyParamType>
1072inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1073 const Message* msg) {
1074 if (msg->received_time() != 0) {
[email protected]252cad62010-08-18 18:33:571075 std::string output_params;
[email protected]7a4de7a62010-08-17 18:38:241076 LogParam(reply_params, &output_params);
1077 msg->set_output_params(output_params);
1078 }
1079}
1080
1081inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
1082 if (msg->sent_time()) {
1083 // Don't log the sync message after dispatch, as we don't have the
1084 // output parameters at that point. Instead, save its data and log it
1085 // with the outgoing reply message when it's sent.
1086 LogData* data = new LogData;
1087 GenerateLogData("", *msg, data);
1088 msg->set_dont_log();
1089 reply->set_sync_log_data(data);
1090 }
1091}
1092#else
[email protected]252cad62010-08-18 18:33:571093inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
[email protected]7a4de7a62010-08-17 18:38:241094
1095template <class ReplyParamType>
1096inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1097 const Message* msg) {}
1098
1099inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1100#endif
1101
initial.commit09911bf2008-07-26 23:55:291102// This class assumes that its template argument is a RefTuple (a Tuple with
[email protected]7a4de7a62010-08-17 18:38:241103// reference elements). This would go into ipc_message_utils_impl.h, but it is
1104// also used by chrome_frame.
initial.commit09911bf2008-07-26 23:55:291105template <class RefTuple>
1106class ParamDeserializer : public MessageReplyDeserializer {
1107 public:
[email protected]e1981f432008-08-12 15:22:131108 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:291109
1110 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1111 return ReadParam(&msg, &iter, &out_);
1112 }
1113
1114 RefTuple out_;
1115};
1116
initial.commit09911bf2008-07-26 23:55:291117// Used for synchronous messages.
[email protected]75e5a872009-04-02 23:56:111118template <class SendParamType, class ReplyParamType>
initial.commit09911bf2008-07-26 23:55:291119class MessageWithReply : public SyncMessage {
1120 public:
[email protected]75e5a872009-04-02 23:56:111121 typedef SendParamType SendParam;
[email protected]7a4de7a62010-08-17 18:38:241122 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
[email protected]75e5a872009-04-02 23:56:111123 typedef ReplyParamType ReplyParam;
1124
[email protected]168ae922009-12-04 18:08:451125 MessageWithReply(int32 routing_id, uint32 type,
[email protected]7a4de7a62010-08-17 18:38:241126 const RefSendParam& send, const ReplyParam& reply);
1127 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
1128 static bool ReadReplyParam(
1129 const Message* msg,
1130 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:291131
[email protected]65412272010-12-21 20:03:241132 template<class T, class S, class Method>
1133 static bool Dispatch(const Message* msg, T* obj, S* sender, Method func) {
initial.commit09911bf2008-07-26 23:55:291134 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291135 Message* reply = GenerateReply(msg);
1136 bool error;
[email protected]7a4de7a62010-08-17 18:38:241137 if (ReadSendParam(msg, &send_params)) {
1138 typename TupleTypes<ReplyParam>::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:291139 DispatchToMethod(obj, func, send_params, &reply_params);
1140 WriteParam(reply, reply_params);
1141 error = false;
[email protected]7a4de7a62010-08-17 18:38:241142 LogReplyParamsToMessage(reply_params, msg);
initial.commit09911bf2008-07-26 23:55:291143 } else {
1144 NOTREACHED() << "Error deserializing message " << msg->type();
1145 reply->set_reply_error();
1146 error = true;
1147 }
1148
[email protected]65412272010-12-21 20:03:241149 sender->Send(reply);
initial.commit09911bf2008-07-26 23:55:291150 return !error;
1151 }
1152
1153 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191154 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291155 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291156 Message* reply = GenerateReply(msg);
1157 bool error;
[email protected]7a4de7a62010-08-17 18:38:241158 if (ReadSendParam(msg, &send_params)) {
initial.commit09911bf2008-07-26 23:55:291159 Tuple1<Message&> t = MakeRefTuple(*reply);
[email protected]7a4de7a62010-08-17 18:38:241160 ConnectMessageAndReply(msg, reply);
initial.commit09911bf2008-07-26 23:55:291161 DispatchToMethod(obj, func, send_params, &t);
1162 error = false;
1163 } else {
1164 NOTREACHED() << "Error deserializing message " << msg->type();
1165 reply->set_reply_error();
1166 obj->Send(reply);
1167 error = true;
1168 }
1169 return !error;
1170 }
1171
1172 template<typename TA>
1173 static void WriteReplyParams(Message* reply, TA a) {
1174 ReplyParam p(a);
1175 WriteParam(reply, p);
1176 }
1177
1178 template<typename TA, typename TB>
1179 static void WriteReplyParams(Message* reply, TA a, TB b) {
1180 ReplyParam p(a, b);
1181 WriteParam(reply, p);
1182 }
1183
1184 template<typename TA, typename TB, typename TC>
1185 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1186 ReplyParam p(a, b, c);
1187 WriteParam(reply, p);
1188 }
1189
1190 template<typename TA, typename TB, typename TC, typename TD>
1191 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1192 ReplyParam p(a, b, c, d);
1193 WriteParam(reply, p);
1194 }
1195
1196 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1197 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1198 ReplyParam p(a, b, c, d, e);
1199 WriteParam(reply, p);
1200 }
1201};
1202
[email protected]7d5c3ac2009-02-04 08:58:191203//-----------------------------------------------------------------------------
1204
[email protected]3178f4e22008-08-05 21:20:411205} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291206
[email protected]946d1b22009-07-22 23:57:211207#endif // IPC_IPC_MESSAGE_UTILS_H_