blob: 34e257a504323000005d5dfaa2ae4e1ad413f4b4 [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 {
49 // By using a start value of 0 for automation messages, we keep backward
50 // compatibility with old builds.
51 AutomationMsgStart = 0,
52 ViewMsgStart,
53 ViewHostMsgStart,
54 PluginProcessMsgStart,
55 PluginProcessHostMsgStart,
56 PluginMsgStart,
57 PluginHostMsgStart,
[email protected]96da6962010-05-13 19:10:3458 ProfileImportProcessMsgStart,
59 ProfileImportProcessHostMsgStart,
[email protected]f91cb992009-02-04 20:10:1260 NPObjectMsgStart,
61 TestMsgStart,
[email protected]503683f2009-02-26 09:13:0162 DevToolsAgentMsgStart,
63 DevToolsClientMsgStart,
[email protected]eb47a132009-03-04 00:39:5664 WorkerProcessMsgStart,
65 WorkerProcessHostMsgStart,
66 WorkerMsgStart,
67 WorkerHostMsgStart,
[email protected]d032f492009-09-29 00:33:4668 NaClProcessMsgStart,
[email protected]246a70452010-03-05 21:53:5069 GpuCommandBufferMsgStart,
[email protected]60f14392009-12-15 20:46:3270 UtilityMsgStart,
71 UtilityHostMsgStart,
[email protected]c0fc0942010-01-13 00:55:3772 GpuMsgStart,
73 GpuHostMsgStart,
[email protected]246a70452010-03-05 21:53:5074 GpuChannelMsgStart,
[email protected]ee68378a2010-08-10 01:05:4175 GpuVideoDecoderHostMsgStart,
76 GpuVideoDecoderMsgStart,
[email protected]38fe1962010-07-31 07:57:0077 ServiceMsgStart,
78 ServiceHostMsgStart,
[email protected]f91cb992009-02-04 20:10:1279 // NOTE: When you add a new message class, also update
80 // IPCStatusView::IPCStatusView to ensure logging works.
[email protected]f91cb992009-02-04 20:10:1281 LastMsgIndex
82};
83
[email protected]7a4de7a62010-08-17 18:38:2484class DictionaryValue;
85class FilePath;
86class ListValue;
87class NullableString16;
88
89namespace base {
90class Time;
91struct FileDescriptor;
92}
93
initial.commit09911bf2008-07-26 23:55:2994namespace IPC {
95
[email protected]7a4de7a62010-08-17 18:38:2496struct ChannelHandle;
97
initial.commit09911bf2008-07-26 23:55:2998//-----------------------------------------------------------------------------
99// An iterator class for reading the fields contained within a Message.
100
101class MessageIterator {
102 public:
[email protected]e1981f432008-08-12 15:22:13103 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
initial.commit09911bf2008-07-26 23:55:29104 }
105 int NextInt() const {
[email protected]9422b7dc2009-12-30 20:09:02106 int val = -1;
initial.commit09911bf2008-07-26 23:55:29107 if (!msg_.ReadInt(&iter_, &val))
108 NOTREACHED();
109 return val;
110 }
initial.commit09911bf2008-07-26 23:55:29111 const std::string NextString() const {
112 std::string val;
113 if (!msg_.ReadString(&iter_, &val))
114 NOTREACHED();
115 return val;
116 }
117 const std::wstring NextWString() const {
118 std::wstring val;
119 if (!msg_.ReadWString(&iter_, &val))
120 NOTREACHED();
121 return val;
122 }
[email protected]225c8f52010-02-05 22:23:20123 void NextData(const char** data, int* length) const {
initial.commit09911bf2008-07-26 23:55:29124 if (!msg_.ReadData(&iter_, data, length)) {
125 NOTREACHED();
126 }
127 }
128 private:
129 const Message& msg_;
130 mutable void* iter_;
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]20199662010-06-17 03:29:26241// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
242// should be sure to check the sanity of these values after receiving them over
243// IPC.
244template <>
245struct ParamTraits<float> {
246 typedef float param_type;
247 static void Write(Message* m, const param_type& p) {
248 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
249 }
250 static bool Read(const Message* m, void** iter, param_type* r) {
251 const char *data;
252 int data_size;
253 if (!m->ReadData(iter, &data, &data_size) ||
254 data_size != sizeof(param_type)) {
255 NOTREACHED();
256 return false;
257 }
258 memcpy(r, data, sizeof(param_type));
259 return true;
260 }
[email protected]252cad62010-08-18 18:33:57261 static void Log(const param_type& p, std::string* l) {
262 l->append(StringPrintf("%e", p));
[email protected]20199662010-06-17 03:29:26263 }
264};
265
[email protected]7d5c3ac2009-02-04 08:58:19266template <>
267struct ParamTraits<double> {
268 typedef double param_type;
269 static void Write(Message* m, const param_type& p) {
270 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
271 }
272 static bool Read(const Message* m, void** iter, param_type* r) {
273 const char *data;
[email protected]20199662010-06-17 03:29:26274 int data_size;
275 if (!m->ReadData(iter, &data, &data_size) ||
276 data_size != sizeof(param_type)) {
[email protected]7d5c3ac2009-02-04 08:58:19277 NOTREACHED();
[email protected]20199662010-06-17 03:29:26278 return false;
[email protected]7d5c3ac2009-02-04 08:58:19279 }
[email protected]20199662010-06-17 03:29:26280 memcpy(r, data, sizeof(param_type));
281 return true;
[email protected]7d5c3ac2009-02-04 08:58:19282 }
[email protected]252cad62010-08-18 18:33:57283 static void Log(const param_type& p, std::string* l) {
284 l->append(StringPrintf("%e", p));
[email protected]7d5c3ac2009-02-04 08:58:19285 }
286};
287
288template <>
289struct ParamTraits<wchar_t> {
290 typedef wchar_t param_type;
291 static void Write(Message* m, const param_type& p) {
292 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
293 }
294 static bool Read(const Message* m, void** iter, param_type* r) {
295 const char *data;
296 int data_size = 0;
297 bool result = m->ReadData(iter, &data, &data_size);
298 if (result && data_size == sizeof(param_type)) {
299 memcpy(r, data, sizeof(param_type));
300 } else {
301 result = false;
302 NOTREACHED();
303 }
304
305 return result;
306 }
[email protected]252cad62010-08-18 18:33:57307 static void Log(const param_type& p, std::string* l) {
308 l->append(StringPrintf("%lc", p));
[email protected]7d5c3ac2009-02-04 08:58:19309 }
310};
311
312template <>
313struct ParamTraits<base::Time> {
314 typedef base::Time param_type;
[email protected]7a4de7a62010-08-17 18:38:24315 static void Write(Message* m, const param_type& p);
316 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57317 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19318};
319
320#if defined(OS_WIN)
321template <>
322struct ParamTraits<LOGFONT> {
323 typedef LOGFONT param_type;
324 static void Write(Message* m, const param_type& p) {
325 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
326 }
327 static bool Read(const Message* m, void** iter, param_type* r) {
328 const char *data;
329 int data_size = 0;
330 bool result = m->ReadData(iter, &data, &data_size);
331 if (result && data_size == sizeof(LOGFONT)) {
332 memcpy(r, data, sizeof(LOGFONT));
333 } else {
334 result = false;
335 NOTREACHED();
336 }
337
338 return result;
339 }
[email protected]252cad62010-08-18 18:33:57340 static void Log(const param_type& p, std::string* l) {
341 l->append(StringPrintf("<LOGFONT>"));
[email protected]7d5c3ac2009-02-04 08:58:19342 }
343};
344
345template <>
346struct ParamTraits<MSG> {
347 typedef MSG param_type;
348 static void Write(Message* m, const param_type& p) {
349 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
350 }
351 static bool Read(const Message* m, void** iter, param_type* r) {
352 const char *data;
353 int data_size = 0;
354 bool result = m->ReadData(iter, &data, &data_size);
355 if (result && data_size == sizeof(MSG)) {
356 memcpy(r, data, sizeof(MSG));
357 } else {
358 result = false;
359 NOTREACHED();
360 }
361
362 return result;
363 }
[email protected]252cad62010-08-18 18:33:57364 static void Log(const param_type& p, std::string* l) {
365 l->append("<MSG>");
[email protected]7a4de7a62010-08-17 18:38:24366 }
[email protected]7d5c3ac2009-02-04 08:58:19367};
368#endif // defined(OS_WIN)
369
370template <>
[email protected]584f2b22009-05-21 01:01:59371struct ParamTraits<DictionaryValue> {
372 typedef DictionaryValue 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 <>
379struct ParamTraits<ListValue> {
380 typedef ListValue param_type;
381 static void Write(Message* m, const param_type& p);
382 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57383 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59384};
385
386template <>
[email protected]7d5c3ac2009-02-04 08:58:19387struct ParamTraits<std::string> {
388 typedef std::string param_type;
389 static void Write(Message* m, const param_type& p) {
390 m->WriteString(p);
391 }
392 static bool Read(const Message* m, void** iter, param_type* r) {
393 return m->ReadString(iter, r);
394 }
[email protected]252cad62010-08-18 18:33:57395 static void Log(const param_type& p, std::string* l) {
396 l->append(p);
[email protected]7d5c3ac2009-02-04 08:58:19397 }
398};
399
[email protected]3dd7a7a2009-07-27 21:09:07400template<typename CharType>
[email protected]252cad62010-08-18 18:33:57401static void LogBytes(const std::vector<CharType>& data, std::string* out) {
[email protected]3dd7a7a2009-07-27 21:09:07402#if defined(OS_WIN)
403 // Windows has a GUI for logging, which can handle arbitrary binary data.
404 for (size_t i = 0; i < data.size(); ++i)
405 out->push_back(data[i]);
406#else
407 // On POSIX, we log to stdout, which we assume can display ASCII.
408 static const size_t kMaxBytesToLog = 100;
409 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
410 if (isprint(data[i]))
411 out->push_back(data[i]);
412 else
[email protected]252cad62010-08-18 18:33:57413 out->append(StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
[email protected]3dd7a7a2009-07-27 21:09:07414 }
415 if (data.size() > kMaxBytesToLog) {
416 out->append(
[email protected]252cad62010-08-18 18:33:57417 StringPrintf(" and %u more bytes",
[email protected]3dd7a7a2009-07-27 21:09:07418 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
419 }
420#endif
421}
422
[email protected]7d5c3ac2009-02-04 08:58:19423template <>
424struct ParamTraits<std::vector<unsigned char> > {
425 typedef std::vector<unsigned char> param_type;
426 static void Write(Message* m, const param_type& p) {
427 if (p.size() == 0) {
428 m->WriteData(NULL, 0);
429 } else {
430 m->WriteData(reinterpret_cast<const char*>(&p.front()),
431 static_cast<int>(p.size()));
432 }
433 }
434 static bool Read(const Message* m, void** iter, param_type* r) {
435 const char *data;
436 int data_size = 0;
437 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
438 return false;
439 r->resize(data_size);
440 if (data_size)
441 memcpy(&r->front(), data, data_size);
442 return true;
443 }
[email protected]252cad62010-08-18 18:33:57444 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07445 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19446 }
447};
448
449template <>
450struct ParamTraits<std::vector<char> > {
451 typedef std::vector<char> param_type;
452 static void Write(Message* m, const param_type& p) {
453 if (p.size() == 0) {
454 m->WriteData(NULL, 0);
455 } else {
456 m->WriteData(&p.front(), static_cast<int>(p.size()));
457 }
458 }
459 static bool Read(const Message* m, void** iter, param_type* r) {
460 const char *data;
461 int data_size = 0;
462 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
463 return false;
464 r->resize(data_size);
465 if (data_size)
466 memcpy(&r->front(), data, data_size);
467 return true;
468 }
[email protected]252cad62010-08-18 18:33:57469 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07470 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19471 }
472};
473
474template <class P>
475struct ParamTraits<std::vector<P> > {
476 typedef std::vector<P> param_type;
477 static void Write(Message* m, const param_type& p) {
478 WriteParam(m, static_cast<int>(p.size()));
479 for (size_t i = 0; i < p.size(); i++)
480 WriteParam(m, p[i]);
481 }
482 static bool Read(const Message* m, void** iter, param_type* r) {
483 int size;
[email protected]86440f52009-12-31 05:17:23484 // ReadLength() checks for < 0 itself.
[email protected]7d5c3ac2009-02-04 08:58:19485 if (!m->ReadLength(iter, &size))
486 return false;
487 // Resizing beforehand is not safe, see BUG 1006367 for details.
[email protected]86440f52009-12-31 05:17:23488 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
489 return false;
490 r->resize(size);
491 for (int i = 0; i < size; i++) {
492 if (!ReadParam(m, iter, &(*r)[i]))
493 return false;
[email protected]7d5c3ac2009-02-04 08:58:19494 }
495 return true;
496 }
[email protected]252cad62010-08-18 18:33:57497 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19498 for (size_t i = 0; i < p.size(); ++i) {
499 if (i != 0)
[email protected]252cad62010-08-18 18:33:57500 l->append(" ");
[email protected]7d5c3ac2009-02-04 08:58:19501 LogParam((p[i]), l);
502 }
503 }
504};
505
[email protected]96da6962010-05-13 19:10:34506template <class P>
507struct ParamTraits<std::set<P> > {
508 typedef std::set<P> param_type;
509 static void Write(Message* m, const param_type& p) {
510 WriteParam(m, static_cast<int>(p.size()));
511 typename param_type::const_iterator iter;
512 for (iter = p.begin(); iter != p.end(); ++iter)
513 WriteParam(m, *iter);
514 }
515 static bool Read(const Message* m, void** iter, param_type* r) {
516 int size;
517 if (!m->ReadLength(iter, &size))
518 return false;
519 for (int i = 0; i < size; ++i) {
520 P item;
521 if (!ReadParam(m, iter, &item))
522 return false;
523 r->insert(item);
524 }
525 return true;
526 }
[email protected]252cad62010-08-18 18:33:57527 static void Log(const param_type& p, std::string* l) {
528 l->append("<std::set>");
[email protected]96da6962010-05-13 19:10:34529 }
530};
531
532
[email protected]7d5c3ac2009-02-04 08:58:19533template <class K, class V>
534struct ParamTraits<std::map<K, V> > {
535 typedef std::map<K, V> param_type;
536 static void Write(Message* m, const param_type& p) {
537 WriteParam(m, static_cast<int>(p.size()));
538 typename param_type::const_iterator iter;
539 for (iter = p.begin(); iter != p.end(); ++iter) {
540 WriteParam(m, iter->first);
541 WriteParam(m, iter->second);
542 }
543 }
544 static bool Read(const Message* m, void** iter, param_type* r) {
545 int size;
546 if (!ReadParam(m, iter, &size) || size < 0)
547 return false;
548 for (int i = 0; i < size; ++i) {
549 K k;
550 if (!ReadParam(m, iter, &k))
551 return false;
552 V& value = (*r)[k];
553 if (!ReadParam(m, iter, &value))
554 return false;
555 }
556 return true;
557 }
[email protected]252cad62010-08-18 18:33:57558 static void Log(const param_type& p, std::string* l) {
559 l->append("<std::map>");
[email protected]7d5c3ac2009-02-04 08:58:19560 }
561};
562
[email protected]eb47a132009-03-04 00:39:56563
[email protected]7d5c3ac2009-02-04 08:58:19564template <>
565struct ParamTraits<std::wstring> {
566 typedef std::wstring param_type;
567 static void Write(Message* m, const param_type& p) {
568 m->WriteWString(p);
569 }
570 static bool Read(const Message* m, void** iter, param_type* r) {
571 return m->ReadWString(iter, r);
572 }
[email protected]252cad62010-08-18 18:33:57573 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19574};
575
[email protected]a5da6d612009-08-04 02:00:56576template <class A, class B>
577struct ParamTraits<std::pair<A, B> > {
578 typedef std::pair<A, B> param_type;
579 static void Write(Message* m, const param_type& p) {
580 WriteParam(m, p.first);
581 WriteParam(m, p.second);
582 }
583 static bool Read(const Message* m, void** iter, param_type* r) {
584 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
585 }
[email protected]252cad62010-08-18 18:33:57586 static void Log(const param_type& p, std::string* l) {
587 l->append("(");
[email protected]a5da6d612009-08-04 02:00:56588 LogParam(p.first, l);
[email protected]252cad62010-08-18 18:33:57589 l->append(", ");
[email protected]a5da6d612009-08-04 02:00:56590 LogParam(p.second, l);
[email protected]252cad62010-08-18 18:33:57591 l->append(")");
[email protected]a5da6d612009-08-04 02:00:56592 }
593};
594
[email protected]15bf8712009-08-27 00:55:02595template <>
596struct ParamTraits<NullableString16> {
597 typedef NullableString16 param_type;
[email protected]7a4de7a62010-08-17 18:38:24598 static void Write(Message* m, const param_type& p);
599 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57600 static void Log(const param_type& p, std::string* l);
[email protected]15bf8712009-08-27 00:55:02601};
602
[email protected]eb47a132009-03-04 00:39:56603// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
604// need this trait.
605#if !defined(WCHAR_T_IS_UTF16)
[email protected]eb47a132009-03-04 00:39:56606template <>
607struct ParamTraits<string16> {
608 typedef string16 param_type;
609 static void Write(Message* m, const param_type& p) {
[email protected]3a2a5d22009-03-04 03:36:36610 m->WriteString16(p);
[email protected]eb47a132009-03-04 00:39:56611 }
612 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]3a2a5d22009-03-04 03:36:36613 return m->ReadString16(iter, r);
[email protected]eb47a132009-03-04 00:39:56614 }
[email protected]252cad62010-08-18 18:33:57615 static void Log(const param_type& p, std::string* l);
[email protected]eb47a132009-03-04 00:39:56616};
[email protected]eb47a132009-03-04 00:39:56617#endif
618
[email protected]7d5c3ac2009-02-04 08:58:19619// and, a few more useful types...
620#if defined(OS_WIN)
621template <>
622struct ParamTraits<HANDLE> {
623 typedef HANDLE param_type;
624 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35625 // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
626 // bit systems.
627 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19628 }
629 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35630 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
631 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19632 }
[email protected]252cad62010-08-18 18:33:57633 static void Log(const param_type& p, std::string* l) {
634 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19635 }
636};
637
638template <>
639struct ParamTraits<HCURSOR> {
640 typedef HCURSOR param_type;
641 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35642 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19643 }
644 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35645 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
646 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19647 }
[email protected]252cad62010-08-18 18:33:57648 static void Log(const param_type& p, std::string* l) {
649 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19650 }
651};
652
653template <>
[email protected]7d5c3ac2009-02-04 08:58:19654struct ParamTraits<HACCEL> {
655 typedef HACCEL param_type;
656 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35657 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19658 }
659 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35660 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
661 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19662 }
663};
664
665template <>
666struct ParamTraits<POINT> {
667 typedef POINT param_type;
668 static void Write(Message* m, const param_type& p) {
669 m->WriteInt(p.x);
670 m->WriteInt(p.y);
671 }
672 static bool Read(const Message* m, void** iter, param_type* r) {
673 int x, y;
674 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
675 return false;
676 r->x = x;
677 r->y = y;
678 return true;
679 }
[email protected]252cad62010-08-18 18:33:57680 static void Log(const param_type& p, std::string* l) {
681 l->append(StringPrintf("(%d, %d)", p.x, p.y));
[email protected]7d5c3ac2009-02-04 08:58:19682 }
683};
684#endif // defined(OS_WIN)
685
686template <>
687struct ParamTraits<FilePath> {
688 typedef FilePath param_type;
[email protected]7a4de7a62010-08-17 18:38:24689 static void Write(Message* m, const param_type& p);
690 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57691 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19692};
693
[email protected]526776c2009-02-07 00:39:26694#if defined(OS_POSIX)
[email protected]2749885f2009-03-05 21:40:11695// FileDescriptors may be serialised over IPC channels on POSIX. On the
696// receiving side, the FileDescriptor is a valid duplicate of the file
697// descriptor which was transmitted: *it is not just a copy of the integer like
698// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
699// this case, the receiving end will see a value of -1. *Zero is a valid file
700// descriptor*.
701//
702// The received file descriptor will have the |auto_close| flag set to true. The
703// code which handles the message is responsible for taking ownership of it.
704// File descriptors are OS resources and must be closed when no longer needed.
705//
706// When sending a file descriptor, the file descriptor must be valid at the time
707// of transmission. Since transmission is not synchronous, one should consider
708// dup()ing any file descriptors to be transmitted and setting the |auto_close|
709// flag, which causes the file descriptor to be closed after writing.
[email protected]526776c2009-02-07 00:39:26710template<>
[email protected]5fe733de2009-02-11 18:59:20711struct ParamTraits<base::FileDescriptor> {
712 typedef base::FileDescriptor param_type;
[email protected]7a4de7a62010-08-17 18:38:24713 static void Write(Message* m, const param_type& p);
714 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57715 static void Log(const param_type& p, std::string* l);
[email protected]526776c2009-02-07 00:39:26716};
[email protected]379e7a52010-03-09 00:38:41717#endif // defined(OS_POSIX)
[email protected]526776c2009-02-07 00:39:26718
[email protected]d2e884d2009-06-22 20:37:52719// A ChannelHandle is basically a platform-inspecific wrapper around the
720// fact that IPC endpoints are handled specially on POSIX. See above comments
721// on FileDescriptor for more background.
722template<>
723struct ParamTraits<IPC::ChannelHandle> {
724 typedef ChannelHandle param_type;
[email protected]7a4de7a62010-08-17 18:38:24725 static void Write(Message* m, const param_type& p);
726 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57727 static void Log(const param_type& p, std::string* l);
[email protected]d2e884d2009-06-22 20:37:52728};
729
[email protected]7d5c3ac2009-02-04 08:58:19730#if defined(OS_WIN)
731template <>
732struct ParamTraits<XFORM> {
733 typedef XFORM param_type;
734 static void Write(Message* m, const param_type& p) {
735 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
736 }
737 static bool Read(const Message* m, void** iter, param_type* r) {
738 const char *data;
739 int data_size = 0;
740 bool result = m->ReadData(iter, &data, &data_size);
741 if (result && data_size == sizeof(XFORM)) {
742 memcpy(r, data, sizeof(XFORM));
743 } else {
744 result = false;
745 NOTREACHED();
746 }
747
748 return result;
749 }
[email protected]252cad62010-08-18 18:33:57750 static void Log(const param_type& p, std::string* l) {
751 l->append("<XFORM>");
[email protected]7d5c3ac2009-02-04 08:58:19752 }
753};
754#endif // defined(OS_WIN)
755
[email protected]7d5c3ac2009-02-04 08:58:19756struct LogData {
[email protected]9a3a293b2009-06-04 22:28:16757 std::string channel;
[email protected]8bef70e2009-04-14 19:11:24758 int32 routing_id;
[email protected]168ae922009-12-04 18:08:45759 uint32 type; // "User-defined" message type, from ipc_message.h.
[email protected]252cad62010-08-18 18:33:57760 std::string flags;
[email protected]7d5c3ac2009-02-04 08:58:19761 int64 sent; // Time that the message was sent (i.e. at Send()).
762 int64 receive; // Time before it was dispatched (i.e. before calling
763 // OnMessageReceived).
764 int64 dispatch; // Time after it was dispatched (i.e. after calling
765 // OnMessageReceived).
[email protected]252cad62010-08-18 18:33:57766 std::string message_name;
767 std::string params;
[email protected]7d5c3ac2009-02-04 08:58:19768};
769
770template <>
771struct ParamTraits<LogData> {
772 typedef LogData param_type;
773 static void Write(Message* m, const param_type& p) {
774 WriteParam(m, p.channel);
[email protected]8bef70e2009-04-14 19:11:24775 WriteParam(m, p.routing_id);
[email protected]7d5c3ac2009-02-04 08:58:19776 WriteParam(m, static_cast<int>(p.type));
777 WriteParam(m, p.flags);
778 WriteParam(m, p.sent);
779 WriteParam(m, p.receive);
780 WriteParam(m, p.dispatch);
781 WriteParam(m, p.params);
782 }
783 static bool Read(const Message* m, void** iter, param_type* r) {
784 int type;
785 bool result =
786 ReadParam(m, iter, &r->channel) &&
[email protected]25af92052010-03-26 22:21:17787 ReadParam(m, iter, &r->routing_id) &&
[email protected]7d5c3ac2009-02-04 08:58:19788 ReadParam(m, iter, &type) &&
789 ReadParam(m, iter, &r->flags) &&
790 ReadParam(m, iter, &r->sent) &&
791 ReadParam(m, iter, &r->receive) &&
792 ReadParam(m, iter, &r->dispatch) &&
793 ReadParam(m, iter, &r->params);
794 r->type = static_cast<uint16>(type);
795 return result;
796 }
[email protected]252cad62010-08-18 18:33:57797 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19798 // Doesn't make sense to implement this!
799 }
800};
801
[email protected]eb47a132009-03-04 00:39:56802template <>
[email protected]503683f2009-02-26 09:13:01803struct ParamTraits<Message> {
804 static void Write(Message* m, const Message& p) {
805 m->WriteInt(p.size());
806 m->WriteData(reinterpret_cast<const char*>(p.data()), p.size());
807 }
808 static bool Read(const Message* m, void** iter, Message* r) {
809 int size;
810 if (!m->ReadInt(iter, &size))
811 return false;
812 const char* data;
813 if (!m->ReadData(iter, &data, &size))
814 return false;
815 *r = Message(data, size);
816 return true;
817 }
[email protected]252cad62010-08-18 18:33:57818 static void Log(const Message& p, std::string* l) {
819 l->append("<IPC::Message>");
[email protected]503683f2009-02-26 09:13:01820 }
821};
822
823template <>
[email protected]7d5c3ac2009-02-04 08:58:19824struct ParamTraits<Tuple0> {
825 typedef Tuple0 param_type;
826 static void Write(Message* m, const param_type& p) {
827 }
828 static bool Read(const Message* m, void** iter, param_type* r) {
829 return true;
830 }
[email protected]252cad62010-08-18 18:33:57831 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19832 }
833};
834
835template <class A>
836struct ParamTraits< Tuple1<A> > {
837 typedef Tuple1<A> param_type;
838 static void Write(Message* m, const param_type& p) {
839 WriteParam(m, p.a);
840 }
841 static bool Read(const Message* m, void** iter, param_type* r) {
842 return ReadParam(m, iter, &r->a);
843 }
[email protected]252cad62010-08-18 18:33:57844 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19845 LogParam(p.a, l);
846 }
847};
848
849template <class A, class B>
850struct ParamTraits< Tuple2<A, B> > {
851 typedef Tuple2<A, B> param_type;
852 static void Write(Message* m, const param_type& p) {
853 WriteParam(m, p.a);
854 WriteParam(m, p.b);
855 }
856 static bool Read(const Message* m, void** iter, param_type* r) {
857 return (ReadParam(m, iter, &r->a) &&
858 ReadParam(m, iter, &r->b));
859 }
[email protected]252cad62010-08-18 18:33:57860 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19861 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57862 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19863 LogParam(p.b, l);
864 }
865};
866
867template <class A, class B, class C>
868struct ParamTraits< Tuple3<A, B, C> > {
869 typedef Tuple3<A, B, C> param_type;
870 static void Write(Message* m, const param_type& p) {
871 WriteParam(m, p.a);
872 WriteParam(m, p.b);
873 WriteParam(m, p.c);
874 }
875 static bool Read(const Message* m, void** iter, param_type* r) {
876 return (ReadParam(m, iter, &r->a) &&
877 ReadParam(m, iter, &r->b) &&
878 ReadParam(m, iter, &r->c));
879 }
[email protected]252cad62010-08-18 18:33:57880 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19881 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57882 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19883 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57884 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19885 LogParam(p.c, l);
886 }
887};
888
889template <class A, class B, class C, class D>
890struct ParamTraits< Tuple4<A, B, C, D> > {
891 typedef Tuple4<A, B, C, D> 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 }
898 static bool Read(const Message* m, void** iter, param_type* r) {
899 return (ReadParam(m, iter, &r->a) &&
900 ReadParam(m, iter, &r->b) &&
901 ReadParam(m, iter, &r->c) &&
902 ReadParam(m, iter, &r->d));
903 }
[email protected]252cad62010-08-18 18:33:57904 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19905 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57906 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19907 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57908 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19909 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57910 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19911 LogParam(p.d, l);
912 }
913};
914
915template <class A, class B, class C, class D, class E>
916struct ParamTraits< Tuple5<A, B, C, D, E> > {
917 typedef Tuple5<A, B, C, D, E> param_type;
918 static void Write(Message* m, const param_type& p) {
919 WriteParam(m, p.a);
920 WriteParam(m, p.b);
921 WriteParam(m, p.c);
922 WriteParam(m, p.d);
923 WriteParam(m, p.e);
924 }
925 static bool Read(const Message* m, void** iter, param_type* r) {
926 return (ReadParam(m, iter, &r->a) &&
927 ReadParam(m, iter, &r->b) &&
928 ReadParam(m, iter, &r->c) &&
929 ReadParam(m, iter, &r->d) &&
930 ReadParam(m, iter, &r->e));
931 }
[email protected]252cad62010-08-18 18:33:57932 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19933 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57934 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19935 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57936 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19937 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57938 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19939 LogParam(p.d, l);
[email protected]252cad62010-08-18 18:33:57940 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19941 LogParam(p.e, l);
942 }
943};
944
[email protected]7d5c3ac2009-02-04 08:58:19945//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:29946// Generic message subclasses
947
948// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:24949template <class ParamType>
initial.commit09911bf2008-07-26 23:55:29950class MessageWithTuple : public Message {
951 public:
[email protected]81a34412009-01-05 19:17:24952 typedef ParamType Param;
[email protected]7a4de7a62010-08-17 18:38:24953 typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
[email protected]81a34412009-01-05 19:17:24954
[email protected]7a4de7a62010-08-17 18:38:24955 // The constructor and the Read() method's templated implementations are in
956 // ipc_message_utils_impl.h. The subclass constructor and Log() methods call
957 // the templated versions of these and make sure there are instantiations in
958 // those translation units.
959 MessageWithTuple(int32 routing_id, uint32 type, const RefParam& p);
[email protected]071b4b92010-08-09 16:06:58960
[email protected]7a4de7a62010-08-17 18:38:24961 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:29962
963 // Generic dispatcher. Should cover most cases.
964 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:19965 static bool Dispatch(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:29966 Param p;
967 if (Read(msg, &p)) {
968 DispatchToMethod(obj, func, p);
969 return true;
970 }
971 return false;
972 }
973
974 // The following dispatchers exist for the case where the callback function
975 // needs the message as well. They assume that "Param" is a type of Tuple
976 // (except the one arg case, as there is no Tuple1).
977 template<class T, typename TA>
[email protected]7d5c3ac2009-02-04 08:58:19978 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:29979 void (T::*func)(const Message&, TA)) {
980 Param p;
981 if (Read(msg, &p)) {
[email protected]c2fe31542009-05-20 18:24:14982 (obj->*func)(*msg, p.a);
initial.commit09911bf2008-07-26 23:55:29983 return true;
984 }
985 return false;
986 }
987
988 template<class T, typename TA, typename TB>
[email protected]7d5c3ac2009-02-04 08:58:19989 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:29990 void (T::*func)(const Message&, TA, TB)) {
991 Param p;
992 if (Read(msg, &p)) {
993 (obj->*func)(*msg, p.a, p.b);
994 return true;
995 }
996 return false;
997 }
998
999 template<class T, typename TA, typename TB, typename TC>
[email protected]7d5c3ac2009-02-04 08:58:191000 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291001 void (T::*func)(const Message&, TA, TB, TC)) {
1002 Param p;
1003 if (Read(msg, &p)) {
1004 (obj->*func)(*msg, p.a, p.b, p.c);
1005 return true;
1006 }
1007 return false;
1008 }
1009
1010 template<class T, typename TA, typename TB, typename TC, typename TD>
[email protected]7d5c3ac2009-02-04 08:58:191011 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291012 void (T::*func)(const Message&, TA, TB, TC, TD)) {
1013 Param p;
1014 if (Read(msg, &p)) {
1015 (obj->*func)(*msg, p.a, p.b, p.c, p.d);
1016 return true;
1017 }
1018 return false;
1019 }
1020
1021 template<class T, typename TA, typename TB, typename TC, typename TD,
1022 typename TE>
[email protected]7d5c3ac2009-02-04 08:58:191023 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291024 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
1025 Param p;
1026 if (Read(msg, &p)) {
1027 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
1028 return true;
1029 }
1030 return false;
1031 }
1032
[email protected]deb57402009-02-06 01:35:301033 // Functions used to do manual unpacking. Only used by the automation code,
1034 // these should go away once that code uses SyncChannel.
1035 template<typename TA, typename TB>
1036 static bool Read(const IPC::Message* msg, TA* a, TB* b) {
1037 ParamType params;
1038 if (!Read(msg, &params))
1039 return false;
1040 *a = params.a;
1041 *b = params.b;
1042 return true;
1043 }
1044
1045 template<typename TA, typename TB, typename TC>
1046 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
1047 ParamType params;
1048 if (!Read(msg, &params))
1049 return false;
1050 *a = params.a;
1051 *b = params.b;
1052 *c = params.c;
1053 return true;
1054 }
1055
1056 template<typename TA, typename TB, typename TC, typename TD>
1057 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) {
1058 ParamType params;
1059 if (!Read(msg, &params))
1060 return false;
1061 *a = params.a;
1062 *b = params.b;
1063 *c = params.c;
1064 *d = params.d;
1065 return true;
1066 }
1067
1068 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1069 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) {
1070 ParamType params;
1071 if (!Read(msg, &params))
1072 return false;
1073 *a = params.a;
1074 *b = params.b;
1075 *c = params.c;
1076 *d = params.d;
1077 *e = params.e;
1078 return true;
1079 }
initial.commit09911bf2008-07-26 23:55:291080};
1081
[email protected]7a4de7a62010-08-17 18:38:241082// defined in ipc_logging.cc
1083void GenerateLogData(const std::string& channel, const Message& message,
1084 LogData* data);
1085
1086
1087#if defined(IPC_MESSAGE_LOG_ENABLED)
[email protected]252cad62010-08-18 18:33:571088inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
1089 const std::string& output_params = msg->output_params();
[email protected]7a4de7a62010-08-17 18:38:241090 if (!l->empty() && !output_params.empty())
[email protected]252cad62010-08-18 18:33:571091 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:241092
1093 l->append(output_params);
1094}
1095
1096template <class ReplyParamType>
1097inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1098 const Message* msg) {
1099 if (msg->received_time() != 0) {
[email protected]252cad62010-08-18 18:33:571100 std::string output_params;
[email protected]7a4de7a62010-08-17 18:38:241101 LogParam(reply_params, &output_params);
1102 msg->set_output_params(output_params);
1103 }
1104}
1105
1106inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
1107 if (msg->sent_time()) {
1108 // Don't log the sync message after dispatch, as we don't have the
1109 // output parameters at that point. Instead, save its data and log it
1110 // with the outgoing reply message when it's sent.
1111 LogData* data = new LogData;
1112 GenerateLogData("", *msg, data);
1113 msg->set_dont_log();
1114 reply->set_sync_log_data(data);
1115 }
1116}
1117#else
[email protected]252cad62010-08-18 18:33:571118inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
[email protected]7a4de7a62010-08-17 18:38:241119
1120template <class ReplyParamType>
1121inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1122 const Message* msg) {}
1123
1124inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1125#endif
1126
initial.commit09911bf2008-07-26 23:55:291127// This class assumes that its template argument is a RefTuple (a Tuple with
[email protected]7a4de7a62010-08-17 18:38:241128// reference elements). This would go into ipc_message_utils_impl.h, but it is
1129// also used by chrome_frame.
initial.commit09911bf2008-07-26 23:55:291130template <class RefTuple>
1131class ParamDeserializer : public MessageReplyDeserializer {
1132 public:
[email protected]e1981f432008-08-12 15:22:131133 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:291134
1135 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1136 return ReadParam(&msg, &iter, &out_);
1137 }
1138
1139 RefTuple out_;
1140};
1141
initial.commit09911bf2008-07-26 23:55:291142// Used for synchronous messages.
[email protected]75e5a872009-04-02 23:56:111143template <class SendParamType, class ReplyParamType>
initial.commit09911bf2008-07-26 23:55:291144class MessageWithReply : public SyncMessage {
1145 public:
[email protected]75e5a872009-04-02 23:56:111146 typedef SendParamType SendParam;
[email protected]7a4de7a62010-08-17 18:38:241147 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
[email protected]75e5a872009-04-02 23:56:111148 typedef ReplyParamType ReplyParam;
1149
[email protected]168ae922009-12-04 18:08:451150 MessageWithReply(int32 routing_id, uint32 type,
[email protected]7a4de7a62010-08-17 18:38:241151 const RefSendParam& send, const ReplyParam& reply);
1152 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
1153 static bool ReadReplyParam(
1154 const Message* msg,
1155 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:291156
1157 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191158 static bool Dispatch(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291159 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291160 Message* reply = GenerateReply(msg);
1161 bool error;
[email protected]7a4de7a62010-08-17 18:38:241162 if (ReadSendParam(msg, &send_params)) {
1163 typename TupleTypes<ReplyParam>::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:291164 DispatchToMethod(obj, func, send_params, &reply_params);
1165 WriteParam(reply, reply_params);
1166 error = false;
[email protected]7a4de7a62010-08-17 18:38:241167 LogReplyParamsToMessage(reply_params, msg);
initial.commit09911bf2008-07-26 23:55:291168 } else {
1169 NOTREACHED() << "Error deserializing message " << msg->type();
1170 reply->set_reply_error();
1171 error = true;
1172 }
1173
1174 obj->Send(reply);
1175 return !error;
1176 }
1177
1178 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191179 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291180 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291181 Message* reply = GenerateReply(msg);
1182 bool error;
[email protected]7a4de7a62010-08-17 18:38:241183 if (ReadSendParam(msg, &send_params)) {
initial.commit09911bf2008-07-26 23:55:291184 Tuple1<Message&> t = MakeRefTuple(*reply);
[email protected]7a4de7a62010-08-17 18:38:241185 ConnectMessageAndReply(msg, reply);
initial.commit09911bf2008-07-26 23:55:291186 DispatchToMethod(obj, func, send_params, &t);
1187 error = false;
1188 } else {
1189 NOTREACHED() << "Error deserializing message " << msg->type();
1190 reply->set_reply_error();
1191 obj->Send(reply);
1192 error = true;
1193 }
1194 return !error;
1195 }
1196
1197 template<typename TA>
1198 static void WriteReplyParams(Message* reply, TA a) {
1199 ReplyParam p(a);
1200 WriteParam(reply, p);
1201 }
1202
1203 template<typename TA, typename TB>
1204 static void WriteReplyParams(Message* reply, TA a, TB b) {
1205 ReplyParam p(a, b);
1206 WriteParam(reply, p);
1207 }
1208
1209 template<typename TA, typename TB, typename TC>
1210 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1211 ReplyParam p(a, b, c);
1212 WriteParam(reply, p);
1213 }
1214
1215 template<typename TA, typename TB, typename TC, typename TD>
1216 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1217 ReplyParam p(a, b, c, d);
1218 WriteParam(reply, p);
1219 }
1220
1221 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1222 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1223 ReplyParam p(a, b, c, d, e);
1224 WriteParam(reply, p);
1225 }
1226};
1227
[email protected]7d5c3ac2009-02-04 08:58:191228//-----------------------------------------------------------------------------
1229
[email protected]3178f4e22008-08-05 21:20:411230} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291231
[email protected]946d1b22009-07-22 23:57:211232#endif // IPC_IPC_MESSAGE_UTILS_H_