blob: 05d39165f248fc0aebd4ed6a7af0fd005cee353e [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]528c56d2010-07-30 19:28:4417#include "base/string_number_conversions.h"
[email protected]dce5df52009-06-29 17:58:2518#include "base/string_util.h"
initial.commit09911bf2008-07-26 23:55:2919#include "base/tuple.h"
[email protected]be1ce6a72010-08-03 14:35:2220#include "base/utf_string_conversions.h"
[email protected]0cfe5dae2010-08-17 00:24:5421#include "ipc/ipc_sync_message.h"
[email protected]55b4e212010-08-13 20:43:5822
[email protected]7a4de7a62010-08-17 18:38:2423#if defined(COMPILER_GCC)
24// GCC "helpfully" tries to inline template methods in release mode. Except we
25// want the majority of the template junk being expanded once in the
26// implementation file (and only provide the definitions in
27// ipc_message_utils_impl.h in those files) and exported, instead of expanded
28// at every call site. Special note: GCC happily accepts the attribute before
29// the method declaration, but only acts on it if it is after.
30#define IPC_MSG_NOINLINE __attribute__((noinline));
31#elif defined(COMPILER_MSVC)
32// MSVC++ doesn't do this.
33#define IPC_MSG_NOINLINE
34#else
35#error "Please add the noinline property for your new compiler here."
36#endif
37
[email protected]f91cb992009-02-04 20:10:1238// Used by IPC_BEGIN_MESSAGES so that each message class starts from a unique
39// base. Messages have unique IDs across channels in order for the IPC logging
40// code to figure out the message class from its ID.
41enum IPCMessageStart {
42 // By using a start value of 0 for automation messages, we keep backward
43 // compatibility with old builds.
44 AutomationMsgStart = 0,
45 ViewMsgStart,
46 ViewHostMsgStart,
47 PluginProcessMsgStart,
48 PluginProcessHostMsgStart,
49 PluginMsgStart,
50 PluginHostMsgStart,
[email protected]96da6962010-05-13 19:10:3451 ProfileImportProcessMsgStart,
52 ProfileImportProcessHostMsgStart,
[email protected]f91cb992009-02-04 20:10:1253 NPObjectMsgStart,
54 TestMsgStart,
[email protected]503683f2009-02-26 09:13:0155 DevToolsAgentMsgStart,
56 DevToolsClientMsgStart,
[email protected]eb47a132009-03-04 00:39:5657 WorkerProcessMsgStart,
58 WorkerProcessHostMsgStart,
59 WorkerMsgStart,
60 WorkerHostMsgStart,
[email protected]d032f492009-09-29 00:33:4661 NaClProcessMsgStart,
[email protected]246a70452010-03-05 21:53:5062 GpuCommandBufferMsgStart,
[email protected]60f14392009-12-15 20:46:3263 UtilityMsgStart,
64 UtilityHostMsgStart,
[email protected]c0fc0942010-01-13 00:55:3765 GpuMsgStart,
66 GpuHostMsgStart,
[email protected]246a70452010-03-05 21:53:5067 GpuChannelMsgStart,
[email protected]ee68378a2010-08-10 01:05:4168 GpuVideoDecoderHostMsgStart,
69 GpuVideoDecoderMsgStart,
[email protected]38fe1962010-07-31 07:57:0070 ServiceMsgStart,
71 ServiceHostMsgStart,
[email protected]f91cb992009-02-04 20:10:1272 // NOTE: When you add a new message class, also update
73 // IPCStatusView::IPCStatusView to ensure logging works.
[email protected]f91cb992009-02-04 20:10:1274 LastMsgIndex
75};
76
[email protected]7a4de7a62010-08-17 18:38:2477class DictionaryValue;
78class FilePath;
79class ListValue;
80class NullableString16;
81
82namespace base {
83class Time;
84struct FileDescriptor;
85}
86
initial.commit09911bf2008-07-26 23:55:2987namespace IPC {
88
[email protected]7a4de7a62010-08-17 18:38:2489struct ChannelHandle;
90
initial.commit09911bf2008-07-26 23:55:2991//-----------------------------------------------------------------------------
92// An iterator class for reading the fields contained within a Message.
93
94class MessageIterator {
95 public:
[email protected]e1981f432008-08-12 15:22:1396 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
initial.commit09911bf2008-07-26 23:55:2997 }
98 int NextInt() const {
[email protected]9422b7dc2009-12-30 20:09:0299 int val = -1;
initial.commit09911bf2008-07-26 23:55:29100 if (!msg_.ReadInt(&iter_, &val))
101 NOTREACHED();
102 return val;
103 }
initial.commit09911bf2008-07-26 23:55:29104 const std::string NextString() const {
105 std::string val;
106 if (!msg_.ReadString(&iter_, &val))
107 NOTREACHED();
108 return val;
109 }
110 const std::wstring NextWString() const {
111 std::wstring val;
112 if (!msg_.ReadWString(&iter_, &val))
113 NOTREACHED();
114 return val;
115 }
[email protected]225c8f52010-02-05 22:23:20116 void NextData(const char** data, int* length) const {
initial.commit09911bf2008-07-26 23:55:29117 if (!msg_.ReadData(&iter_, data, length)) {
118 NOTREACHED();
119 }
120 }
121 private:
122 const Message& msg_;
123 mutable void* iter_;
124};
125
126//-----------------------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19127// ParamTraits specializations, etc.
128
[email protected]7b291f92009-08-14 05:43:53129template <class P> struct ParamTraits {
130};
131
132template <class P>
133struct SimilarTypeTraits {
134 typedef P Type;
135};
[email protected]7d5c3ac2009-02-04 08:58:19136
137template <class P>
138static inline void WriteParam(Message* m, const P& p) {
[email protected]7b291f92009-08-14 05:43:53139 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53140 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
[email protected]7d5c3ac2009-02-04 08:58:19141}
142
143template <class P>
[email protected]1e86aa62009-04-24 21:22:33144static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
145 P* p) {
[email protected]7b291f92009-08-14 05:43:53146 typedef typename SimilarTypeTraits<P>::Type Type;
147 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
[email protected]7d5c3ac2009-02-04 08:58:19148}
149
150template <class P>
151static inline void LogParam(const P& p, std::wstring* l) {
[email protected]7b291f92009-08-14 05:43:53152 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53153 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19154}
155
156template <>
157struct ParamTraits<bool> {
158 typedef bool param_type;
159 static void Write(Message* m, const param_type& p) {
160 m->WriteBool(p);
161 }
162 static bool Read(const Message* m, void** iter, param_type* r) {
163 return m->ReadBool(iter, r);
164 }
165 static void Log(const param_type& p, std::wstring* l) {
166 l->append(p ? L"true" : L"false");
167 }
168};
169
170template <>
171struct ParamTraits<int> {
172 typedef int param_type;
173 static void Write(Message* m, const param_type& p) {
174 m->WriteInt(p);
175 }
176 static bool Read(const Message* m, void** iter, param_type* r) {
177 return m->ReadInt(iter, r);
178 }
179 static void Log(const param_type& p, std::wstring* l) {
180 l->append(StringPrintf(L"%d", p));
181 }
182};
183
184template <>
[email protected]63263f92009-07-28 19:35:08185struct ParamTraits<unsigned int> {
186 typedef unsigned int param_type;
187 static void Write(Message* m, const param_type& p) {
188 m->WriteInt(p);
189 }
190 static bool Read(const Message* m, void** iter, param_type* r) {
191 return m->ReadInt(iter, reinterpret_cast<int*>(r));
192 }
193 static void Log(const param_type& p, std::wstring* l) {
194 l->append(StringPrintf(L"%d", p));
195 }
196};
197
198template <>
[email protected]7d5c3ac2009-02-04 08:58:19199struct ParamTraits<long> {
200 typedef long param_type;
201 static void Write(Message* m, const param_type& p) {
202 m->WriteLong(p);
203 }
204 static bool Read(const Message* m, void** iter, param_type* r) {
205 return m->ReadLong(iter, r);
206 }
207 static void Log(const param_type& p, std::wstring* l) {
[email protected]63263f92009-07-28 19:35:08208 l->append(StringPrintf(L"%ld", p));
[email protected]7d5c3ac2009-02-04 08:58:19209 }
210};
211
[email protected]140c3032009-06-26 18:22:54212template <>
213struct ParamTraits<unsigned long> {
214 typedef unsigned long param_type;
215 static void Write(Message* m, const param_type& p) {
216 m->WriteLong(p);
217 }
218 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]63263f92009-07-28 19:35:08219 return m->ReadLong(iter, reinterpret_cast<long*>(r));
[email protected]140c3032009-06-26 18:22:54220 }
221 static void Log(const param_type& p, std::wstring* l) {
[email protected]63263f92009-07-28 19:35:08222 l->append(StringPrintf(L"%lu", p));
[email protected]7d5c3ac2009-02-04 08:58:19223 }
224};
225
226template <>
[email protected]63263f92009-07-28 19:35:08227struct ParamTraits<long long> {
228 typedef long long param_type;
[email protected]7d5c3ac2009-02-04 08:58:19229 static void Write(Message* m, const param_type& p) {
230 m->WriteInt64(static_cast<int64>(p));
231 }
232 static bool Read(const Message* m, void** iter, param_type* r) {
233 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
234 }
235 static void Log(const param_type& p, std::wstring* l) {
[email protected]528c56d2010-07-30 19:28:44236 l->append(UTF8ToWide(base::Int64ToString(static_cast<int64>(p))));
[email protected]63263f92009-07-28 19:35:08237 }
238};
239
240template <>
241struct ParamTraits<unsigned long long> {
242 typedef unsigned long long param_type;
243 static void Write(Message* m, const param_type& p) {
244 m->WriteInt64(p);
245 }
246 static bool Read(const Message* m, void** iter, param_type* r) {
247 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
248 }
249 static void Log(const param_type& p, std::wstring* l) {
[email protected]528c56d2010-07-30 19:28:44250 l->append(UTF8ToWide(base::Uint64ToString(p)));
[email protected]7d5c3ac2009-02-04 08:58:19251 }
252};
253
[email protected]20199662010-06-17 03:29:26254// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
255// should be sure to check the sanity of these values after receiving them over
256// IPC.
257template <>
258struct ParamTraits<float> {
259 typedef float param_type;
260 static void Write(Message* m, const param_type& p) {
261 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
262 }
263 static bool Read(const Message* m, void** iter, param_type* r) {
264 const char *data;
265 int data_size;
266 if (!m->ReadData(iter, &data, &data_size) ||
267 data_size != sizeof(param_type)) {
268 NOTREACHED();
269 return false;
270 }
271 memcpy(r, data, sizeof(param_type));
272 return true;
273 }
274 static void Log(const param_type& p, std::wstring* l) {
275 l->append(StringPrintf(L"e", p));
276 }
277};
278
[email protected]7d5c3ac2009-02-04 08:58:19279template <>
280struct ParamTraits<double> {
281 typedef double param_type;
282 static void Write(Message* m, const param_type& p) {
283 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
284 }
285 static bool Read(const Message* m, void** iter, param_type* r) {
286 const char *data;
[email protected]20199662010-06-17 03:29:26287 int data_size;
288 if (!m->ReadData(iter, &data, &data_size) ||
289 data_size != sizeof(param_type)) {
[email protected]7d5c3ac2009-02-04 08:58:19290 NOTREACHED();
[email protected]20199662010-06-17 03:29:26291 return false;
[email protected]7d5c3ac2009-02-04 08:58:19292 }
[email protected]20199662010-06-17 03:29:26293 memcpy(r, data, sizeof(param_type));
294 return true;
[email protected]7d5c3ac2009-02-04 08:58:19295 }
296 static void Log(const param_type& p, std::wstring* l) {
297 l->append(StringPrintf(L"e", p));
298 }
299};
300
301template <>
302struct ParamTraits<wchar_t> {
303 typedef wchar_t param_type;
304 static void Write(Message* m, const param_type& p) {
305 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
306 }
307 static bool Read(const Message* m, void** iter, param_type* r) {
308 const char *data;
309 int data_size = 0;
310 bool result = m->ReadData(iter, &data, &data_size);
311 if (result && data_size == sizeof(param_type)) {
312 memcpy(r, data, sizeof(param_type));
313 } else {
314 result = false;
315 NOTREACHED();
316 }
317
318 return result;
319 }
320 static void Log(const param_type& p, std::wstring* l) {
321 l->append(StringPrintf(L"%lc", p));
322 }
323};
324
325template <>
326struct ParamTraits<base::Time> {
327 typedef base::Time param_type;
[email protected]7a4de7a62010-08-17 18:38:24328 static void Write(Message* m, const param_type& p);
329 static bool Read(const Message* m, void** iter, param_type* r);
330 static void Log(const param_type& p, std::wstring* l);
[email protected]7d5c3ac2009-02-04 08:58:19331};
332
333#if defined(OS_WIN)
334template <>
335struct ParamTraits<LOGFONT> {
336 typedef LOGFONT param_type;
337 static void Write(Message* m, const param_type& p) {
338 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
339 }
340 static bool Read(const Message* m, void** iter, param_type* r) {
341 const char *data;
342 int data_size = 0;
343 bool result = m->ReadData(iter, &data, &data_size);
344 if (result && data_size == sizeof(LOGFONT)) {
345 memcpy(r, data, sizeof(LOGFONT));
346 } else {
347 result = false;
348 NOTREACHED();
349 }
350
351 return result;
352 }
353 static void Log(const param_type& p, std::wstring* l) {
354 l->append(StringPrintf(L"<LOGFONT>"));
355 }
356};
357
358template <>
359struct ParamTraits<MSG> {
360 typedef MSG param_type;
361 static void Write(Message* m, const param_type& p) {
362 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
363 }
364 static bool Read(const Message* m, void** iter, param_type* r) {
365 const char *data;
366 int data_size = 0;
367 bool result = m->ReadData(iter, &data, &data_size);
368 if (result && data_size == sizeof(MSG)) {
369 memcpy(r, data, sizeof(MSG));
370 } else {
371 result = false;
372 NOTREACHED();
373 }
374
375 return result;
376 }
[email protected]7a4de7a62010-08-17 18:38:24377 static void Log(const param_type& p, std::wstring* l) {
378 l->append(L"<MSG>");
379 }
[email protected]7d5c3ac2009-02-04 08:58:19380};
381#endif // defined(OS_WIN)
382
383template <>
[email protected]584f2b22009-05-21 01:01:59384struct ParamTraits<DictionaryValue> {
385 typedef DictionaryValue param_type;
386 static void Write(Message* m, const param_type& p);
387 static bool Read(const Message* m, void** iter, param_type* r);
388 static void Log(const param_type& p, std::wstring* l);
389};
390
391template <>
392struct ParamTraits<ListValue> {
393 typedef ListValue param_type;
394 static void Write(Message* m, const param_type& p);
395 static bool Read(const Message* m, void** iter, param_type* r);
396 static void Log(const param_type& p, std::wstring* l);
397};
398
399template <>
[email protected]7d5c3ac2009-02-04 08:58:19400struct ParamTraits<std::string> {
401 typedef std::string param_type;
402 static void Write(Message* m, const param_type& p) {
403 m->WriteString(p);
404 }
405 static bool Read(const Message* m, void** iter, param_type* r) {
406 return m->ReadString(iter, r);
407 }
408 static void Log(const param_type& p, std::wstring* l) {
409 l->append(UTF8ToWide(p));
410 }
411};
412
[email protected]3dd7a7a2009-07-27 21:09:07413template<typename CharType>
414static void LogBytes(const std::vector<CharType>& data, std::wstring* out) {
415#if defined(OS_WIN)
416 // Windows has a GUI for logging, which can handle arbitrary binary data.
417 for (size_t i = 0; i < data.size(); ++i)
418 out->push_back(data[i]);
419#else
420 // On POSIX, we log to stdout, which we assume can display ASCII.
421 static const size_t kMaxBytesToLog = 100;
422 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
423 if (isprint(data[i]))
424 out->push_back(data[i]);
425 else
426 out->append(StringPrintf(L"[%02X]", static_cast<unsigned char>(data[i])));
427 }
428 if (data.size() > kMaxBytesToLog) {
429 out->append(
430 StringPrintf(L" and %u more bytes",
431 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
432 }
433#endif
434}
435
[email protected]7d5c3ac2009-02-04 08:58:19436template <>
437struct ParamTraits<std::vector<unsigned char> > {
438 typedef std::vector<unsigned char> param_type;
439 static void Write(Message* m, const param_type& p) {
440 if (p.size() == 0) {
441 m->WriteData(NULL, 0);
442 } else {
443 m->WriteData(reinterpret_cast<const char*>(&p.front()),
444 static_cast<int>(p.size()));
445 }
446 }
447 static bool Read(const Message* m, void** iter, param_type* r) {
448 const char *data;
449 int data_size = 0;
450 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
451 return false;
452 r->resize(data_size);
453 if (data_size)
454 memcpy(&r->front(), data, data_size);
455 return true;
456 }
457 static void Log(const param_type& p, std::wstring* l) {
[email protected]3dd7a7a2009-07-27 21:09:07458 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19459 }
460};
461
462template <>
463struct ParamTraits<std::vector<char> > {
464 typedef std::vector<char> param_type;
465 static void Write(Message* m, const param_type& p) {
466 if (p.size() == 0) {
467 m->WriteData(NULL, 0);
468 } else {
469 m->WriteData(&p.front(), static_cast<int>(p.size()));
470 }
471 }
472 static bool Read(const Message* m, void** iter, param_type* r) {
473 const char *data;
474 int data_size = 0;
475 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
476 return false;
477 r->resize(data_size);
478 if (data_size)
479 memcpy(&r->front(), data, data_size);
480 return true;
481 }
482 static void Log(const param_type& p, std::wstring* l) {
[email protected]3dd7a7a2009-07-27 21:09:07483 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19484 }
485};
486
487template <class P>
488struct ParamTraits<std::vector<P> > {
489 typedef std::vector<P> param_type;
490 static void Write(Message* m, const param_type& p) {
491 WriteParam(m, static_cast<int>(p.size()));
492 for (size_t i = 0; i < p.size(); i++)
493 WriteParam(m, p[i]);
494 }
495 static bool Read(const Message* m, void** iter, param_type* r) {
496 int size;
[email protected]86440f52009-12-31 05:17:23497 // ReadLength() checks for < 0 itself.
[email protected]7d5c3ac2009-02-04 08:58:19498 if (!m->ReadLength(iter, &size))
499 return false;
500 // Resizing beforehand is not safe, see BUG 1006367 for details.
[email protected]86440f52009-12-31 05:17:23501 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
502 return false;
503 r->resize(size);
504 for (int i = 0; i < size; i++) {
505 if (!ReadParam(m, iter, &(*r)[i]))
506 return false;
[email protected]7d5c3ac2009-02-04 08:58:19507 }
508 return true;
509 }
510 static void Log(const param_type& p, std::wstring* l) {
511 for (size_t i = 0; i < p.size(); ++i) {
512 if (i != 0)
513 l->append(L" ");
[email protected]7d5c3ac2009-02-04 08:58:19514 LogParam((p[i]), l);
515 }
516 }
517};
518
[email protected]96da6962010-05-13 19:10:34519template <class P>
520struct ParamTraits<std::set<P> > {
521 typedef std::set<P> param_type;
522 static void Write(Message* m, const param_type& p) {
523 WriteParam(m, static_cast<int>(p.size()));
524 typename param_type::const_iterator iter;
525 for (iter = p.begin(); iter != p.end(); ++iter)
526 WriteParam(m, *iter);
527 }
528 static bool Read(const Message* m, void** iter, param_type* r) {
529 int size;
530 if (!m->ReadLength(iter, &size))
531 return false;
532 for (int i = 0; i < size; ++i) {
533 P item;
534 if (!ReadParam(m, iter, &item))
535 return false;
536 r->insert(item);
537 }
538 return true;
539 }
540 static void Log(const param_type& p, std::wstring* l) {
541 l->append(L"<std::set>");
542 }
543};
544
545
[email protected]7d5c3ac2009-02-04 08:58:19546template <class K, class V>
547struct ParamTraits<std::map<K, V> > {
548 typedef std::map<K, V> param_type;
549 static void Write(Message* m, const param_type& p) {
550 WriteParam(m, static_cast<int>(p.size()));
551 typename param_type::const_iterator iter;
552 for (iter = p.begin(); iter != p.end(); ++iter) {
553 WriteParam(m, iter->first);
554 WriteParam(m, iter->second);
555 }
556 }
557 static bool Read(const Message* m, void** iter, param_type* r) {
558 int size;
559 if (!ReadParam(m, iter, &size) || size < 0)
560 return false;
561 for (int i = 0; i < size; ++i) {
562 K k;
563 if (!ReadParam(m, iter, &k))
564 return false;
565 V& value = (*r)[k];
566 if (!ReadParam(m, iter, &value))
567 return false;
568 }
569 return true;
570 }
571 static void Log(const param_type& p, std::wstring* l) {
572 l->append(L"<std::map>");
573 }
574};
575
[email protected]eb47a132009-03-04 00:39:56576
[email protected]7d5c3ac2009-02-04 08:58:19577template <>
578struct ParamTraits<std::wstring> {
579 typedef std::wstring param_type;
580 static void Write(Message* m, const param_type& p) {
581 m->WriteWString(p);
582 }
583 static bool Read(const Message* m, void** iter, param_type* r) {
584 return m->ReadWString(iter, r);
585 }
586 static void Log(const param_type& p, std::wstring* l) {
587 l->append(p);
588 }
589};
590
[email protected]a5da6d612009-08-04 02:00:56591template <class A, class B>
592struct ParamTraits<std::pair<A, B> > {
593 typedef std::pair<A, B> param_type;
594 static void Write(Message* m, const param_type& p) {
595 WriteParam(m, p.first);
596 WriteParam(m, p.second);
597 }
598 static bool Read(const Message* m, void** iter, param_type* r) {
599 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
600 }
601 static void Log(const param_type& p, std::wstring* l) {
602 l->append(L"(");
603 LogParam(p.first, l);
604 l->append(L", ");
605 LogParam(p.second, l);
606 l->append(L")");
607 }
608};
609
[email protected]15bf8712009-08-27 00:55:02610template <>
611struct ParamTraits<NullableString16> {
612 typedef NullableString16 param_type;
[email protected]7a4de7a62010-08-17 18:38:24613 static void Write(Message* m, const param_type& p);
614 static bool Read(const Message* m, void** iter, param_type* r);
615 static void Log(const param_type& p, std::wstring* l);
[email protected]15bf8712009-08-27 00:55:02616};
617
[email protected]eb47a132009-03-04 00:39:56618// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
619// need this trait.
620#if !defined(WCHAR_T_IS_UTF16)
[email protected]eb47a132009-03-04 00:39:56621template <>
622struct ParamTraits<string16> {
623 typedef string16 param_type;
624 static void Write(Message* m, const param_type& p) {
[email protected]3a2a5d22009-03-04 03:36:36625 m->WriteString16(p);
[email protected]eb47a132009-03-04 00:39:56626 }
627 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]3a2a5d22009-03-04 03:36:36628 return m->ReadString16(iter, r);
[email protected]eb47a132009-03-04 00:39:56629 }
630 static void Log(const param_type& p, std::wstring* l) {
631 l->append(UTF16ToWide(p));
632 }
633};
[email protected]eb47a132009-03-04 00:39:56634#endif
635
[email protected]7d5c3ac2009-02-04 08:58:19636// and, a few more useful types...
637#if defined(OS_WIN)
638template <>
639struct ParamTraits<HANDLE> {
640 typedef HANDLE param_type;
641 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35642 // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
643 // bit systems.
644 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19645 }
646 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35647 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
648 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19649 }
650 static void Log(const param_type& p, std::wstring* l) {
651 l->append(StringPrintf(L"0x%X", p));
652 }
653};
654
655template <>
656struct ParamTraits<HCURSOR> {
657 typedef HCURSOR param_type;
658 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35659 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19660 }
661 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35662 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
663 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19664 }
665 static void Log(const param_type& p, std::wstring* l) {
666 l->append(StringPrintf(L"0x%X", p));
667 }
668};
669
670template <>
[email protected]7d5c3ac2009-02-04 08:58:19671struct ParamTraits<HACCEL> {
672 typedef HACCEL param_type;
673 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35674 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19675 }
676 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35677 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
678 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19679 }
680};
681
682template <>
683struct ParamTraits<POINT> {
684 typedef POINT param_type;
685 static void Write(Message* m, const param_type& p) {
686 m->WriteInt(p.x);
687 m->WriteInt(p.y);
688 }
689 static bool Read(const Message* m, void** iter, param_type* r) {
690 int x, y;
691 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
692 return false;
693 r->x = x;
694 r->y = y;
695 return true;
696 }
697 static void Log(const param_type& p, std::wstring* l) {
698 l->append(StringPrintf(L"(%d, %d)", p.x, p.y));
699 }
700};
701#endif // defined(OS_WIN)
702
703template <>
704struct ParamTraits<FilePath> {
705 typedef FilePath param_type;
[email protected]7a4de7a62010-08-17 18:38:24706 static void Write(Message* m, const param_type& p);
707 static bool Read(const Message* m, void** iter, param_type* r);
708 static void Log(const param_type& p, std::wstring* l);
[email protected]7d5c3ac2009-02-04 08:58:19709};
710
[email protected]526776c2009-02-07 00:39:26711#if defined(OS_POSIX)
[email protected]2749885f2009-03-05 21:40:11712// FileDescriptors may be serialised over IPC channels on POSIX. On the
713// receiving side, the FileDescriptor is a valid duplicate of the file
714// descriptor which was transmitted: *it is not just a copy of the integer like
715// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
716// this case, the receiving end will see a value of -1. *Zero is a valid file
717// descriptor*.
718//
719// The received file descriptor will have the |auto_close| flag set to true. The
720// code which handles the message is responsible for taking ownership of it.
721// File descriptors are OS resources and must be closed when no longer needed.
722//
723// When sending a file descriptor, the file descriptor must be valid at the time
724// of transmission. Since transmission is not synchronous, one should consider
725// dup()ing any file descriptors to be transmitted and setting the |auto_close|
726// flag, which causes the file descriptor to be closed after writing.
[email protected]526776c2009-02-07 00:39:26727template<>
[email protected]5fe733de2009-02-11 18:59:20728struct ParamTraits<base::FileDescriptor> {
729 typedef base::FileDescriptor param_type;
[email protected]7a4de7a62010-08-17 18:38:24730 static void Write(Message* m, const param_type& p);
731 static bool Read(const Message* m, void** iter, param_type* r);
732 static void Log(const param_type& p, std::wstring* l);
[email protected]526776c2009-02-07 00:39:26733};
[email protected]379e7a52010-03-09 00:38:41734#endif // defined(OS_POSIX)
[email protected]526776c2009-02-07 00:39:26735
[email protected]d2e884d2009-06-22 20:37:52736// A ChannelHandle is basically a platform-inspecific wrapper around the
737// fact that IPC endpoints are handled specially on POSIX. See above comments
738// on FileDescriptor for more background.
739template<>
740struct ParamTraits<IPC::ChannelHandle> {
741 typedef ChannelHandle param_type;
[email protected]7a4de7a62010-08-17 18:38:24742 static void Write(Message* m, const param_type& p);
743 static bool Read(const Message* m, void** iter, param_type* r);
744 static void Log(const param_type& p, std::wstring* l);
[email protected]d2e884d2009-06-22 20:37:52745};
746
[email protected]7d5c3ac2009-02-04 08:58:19747#if defined(OS_WIN)
748template <>
749struct ParamTraits<XFORM> {
750 typedef XFORM param_type;
751 static void Write(Message* m, const param_type& p) {
752 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
753 }
754 static bool Read(const Message* m, void** iter, param_type* r) {
755 const char *data;
756 int data_size = 0;
757 bool result = m->ReadData(iter, &data, &data_size);
758 if (result && data_size == sizeof(XFORM)) {
759 memcpy(r, data, sizeof(XFORM));
760 } else {
761 result = false;
762 NOTREACHED();
763 }
764
765 return result;
766 }
767 static void Log(const param_type& p, std::wstring* l) {
768 l->append(L"<XFORM>");
769 }
770};
771#endif // defined(OS_WIN)
772
[email protected]7d5c3ac2009-02-04 08:58:19773struct LogData {
[email protected]9a3a293b2009-06-04 22:28:16774 std::string channel;
[email protected]8bef70e2009-04-14 19:11:24775 int32 routing_id;
[email protected]168ae922009-12-04 18:08:45776 uint32 type; // "User-defined" message type, from ipc_message.h.
[email protected]7d5c3ac2009-02-04 08:58:19777 std::wstring flags;
778 int64 sent; // Time that the message was sent (i.e. at Send()).
779 int64 receive; // Time before it was dispatched (i.e. before calling
780 // OnMessageReceived).
781 int64 dispatch; // Time after it was dispatched (i.e. after calling
782 // OnMessageReceived).
[email protected]e707d5e62009-02-12 04:00:08783 std::wstring message_name;
[email protected]7d5c3ac2009-02-04 08:58:19784 std::wstring params;
785};
786
787template <>
788struct ParamTraits<LogData> {
789 typedef LogData param_type;
790 static void Write(Message* m, const param_type& p) {
791 WriteParam(m, p.channel);
[email protected]8bef70e2009-04-14 19:11:24792 WriteParam(m, p.routing_id);
[email protected]7d5c3ac2009-02-04 08:58:19793 WriteParam(m, static_cast<int>(p.type));
794 WriteParam(m, p.flags);
795 WriteParam(m, p.sent);
796 WriteParam(m, p.receive);
797 WriteParam(m, p.dispatch);
798 WriteParam(m, p.params);
799 }
800 static bool Read(const Message* m, void** iter, param_type* r) {
801 int type;
802 bool result =
803 ReadParam(m, iter, &r->channel) &&
[email protected]25af92052010-03-26 22:21:17804 ReadParam(m, iter, &r->routing_id) &&
[email protected]7d5c3ac2009-02-04 08:58:19805 ReadParam(m, iter, &type) &&
806 ReadParam(m, iter, &r->flags) &&
807 ReadParam(m, iter, &r->sent) &&
808 ReadParam(m, iter, &r->receive) &&
809 ReadParam(m, iter, &r->dispatch) &&
810 ReadParam(m, iter, &r->params);
811 r->type = static_cast<uint16>(type);
812 return result;
813 }
814 static void Log(const param_type& p, std::wstring* l) {
815 // Doesn't make sense to implement this!
816 }
817};
818
[email protected]eb47a132009-03-04 00:39:56819template <>
[email protected]503683f2009-02-26 09:13:01820struct ParamTraits<Message> {
821 static void Write(Message* m, const Message& p) {
822 m->WriteInt(p.size());
823 m->WriteData(reinterpret_cast<const char*>(p.data()), p.size());
824 }
825 static bool Read(const Message* m, void** iter, Message* r) {
826 int size;
827 if (!m->ReadInt(iter, &size))
828 return false;
829 const char* data;
830 if (!m->ReadData(iter, &data, &size))
831 return false;
832 *r = Message(data, size);
833 return true;
834 }
835 static void Log(const Message& p, std::wstring* l) {
836 l->append(L"<IPC::Message>");
837 }
838};
839
840template <>
[email protected]7d5c3ac2009-02-04 08:58:19841struct ParamTraits<Tuple0> {
842 typedef Tuple0 param_type;
843 static void Write(Message* m, const param_type& p) {
844 }
845 static bool Read(const Message* m, void** iter, param_type* r) {
846 return true;
847 }
848 static void Log(const param_type& p, std::wstring* l) {
849 }
850};
851
852template <class A>
853struct ParamTraits< Tuple1<A> > {
854 typedef Tuple1<A> param_type;
855 static void Write(Message* m, const param_type& p) {
856 WriteParam(m, p.a);
857 }
858 static bool Read(const Message* m, void** iter, param_type* r) {
859 return ReadParam(m, iter, &r->a);
860 }
861 static void Log(const param_type& p, std::wstring* l) {
862 LogParam(p.a, l);
863 }
864};
865
866template <class A, class B>
867struct ParamTraits< Tuple2<A, B> > {
868 typedef Tuple2<A, B> param_type;
869 static void Write(Message* m, const param_type& p) {
870 WriteParam(m, p.a);
871 WriteParam(m, p.b);
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 }
877 static void Log(const param_type& p, std::wstring* l) {
878 LogParam(p.a, l);
879 l->append(L", ");
880 LogParam(p.b, l);
881 }
882};
883
884template <class A, class B, class C>
885struct ParamTraits< Tuple3<A, B, C> > {
886 typedef Tuple3<A, B, C> param_type;
887 static void Write(Message* m, const param_type& p) {
888 WriteParam(m, p.a);
889 WriteParam(m, p.b);
890 WriteParam(m, p.c);
891 }
892 static bool Read(const Message* m, void** iter, param_type* r) {
893 return (ReadParam(m, iter, &r->a) &&
894 ReadParam(m, iter, &r->b) &&
895 ReadParam(m, iter, &r->c));
896 }
897 static void Log(const param_type& p, std::wstring* l) {
898 LogParam(p.a, l);
899 l->append(L", ");
900 LogParam(p.b, l);
901 l->append(L", ");
902 LogParam(p.c, l);
903 }
904};
905
906template <class A, class B, class C, class D>
907struct ParamTraits< Tuple4<A, B, C, D> > {
908 typedef Tuple4<A, B, C, D> param_type;
909 static void Write(Message* m, const param_type& p) {
910 WriteParam(m, p.a);
911 WriteParam(m, p.b);
912 WriteParam(m, p.c);
913 WriteParam(m, p.d);
914 }
915 static bool Read(const Message* m, void** iter, param_type* r) {
916 return (ReadParam(m, iter, &r->a) &&
917 ReadParam(m, iter, &r->b) &&
918 ReadParam(m, iter, &r->c) &&
919 ReadParam(m, iter, &r->d));
920 }
921 static void Log(const param_type& p, std::wstring* l) {
922 LogParam(p.a, l);
923 l->append(L", ");
924 LogParam(p.b, l);
925 l->append(L", ");
926 LogParam(p.c, l);
927 l->append(L", ");
928 LogParam(p.d, l);
929 }
930};
931
932template <class A, class B, class C, class D, class E>
933struct ParamTraits< Tuple5<A, B, C, D, E> > {
934 typedef Tuple5<A, B, C, D, E> param_type;
935 static void Write(Message* m, const param_type& p) {
936 WriteParam(m, p.a);
937 WriteParam(m, p.b);
938 WriteParam(m, p.c);
939 WriteParam(m, p.d);
940 WriteParam(m, p.e);
941 }
942 static bool Read(const Message* m, void** iter, param_type* r) {
943 return (ReadParam(m, iter, &r->a) &&
944 ReadParam(m, iter, &r->b) &&
945 ReadParam(m, iter, &r->c) &&
946 ReadParam(m, iter, &r->d) &&
947 ReadParam(m, iter, &r->e));
948 }
949 static void Log(const param_type& p, std::wstring* l) {
950 LogParam(p.a, l);
951 l->append(L", ");
952 LogParam(p.b, l);
953 l->append(L", ");
954 LogParam(p.c, l);
955 l->append(L", ");
956 LogParam(p.d, l);
957 l->append(L", ");
958 LogParam(p.e, l);
959 }
960};
961
[email protected]7d5c3ac2009-02-04 08:58:19962//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:29963// Generic message subclasses
964
965// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:24966template <class ParamType>
initial.commit09911bf2008-07-26 23:55:29967class MessageWithTuple : public Message {
968 public:
[email protected]81a34412009-01-05 19:17:24969 typedef ParamType Param;
[email protected]7a4de7a62010-08-17 18:38:24970 typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
[email protected]81a34412009-01-05 19:17:24971
[email protected]7a4de7a62010-08-17 18:38:24972 // The constructor and the Read() method's templated implementations are in
973 // ipc_message_utils_impl.h. The subclass constructor and Log() methods call
974 // the templated versions of these and make sure there are instantiations in
975 // those translation units.
976 MessageWithTuple(int32 routing_id, uint32 type, const RefParam& p);
[email protected]071b4b92010-08-09 16:06:58977
[email protected]7a4de7a62010-08-17 18:38:24978 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:29979
980 // Generic dispatcher. Should cover most cases.
981 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:19982 static bool Dispatch(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:29983 Param p;
984 if (Read(msg, &p)) {
985 DispatchToMethod(obj, func, p);
986 return true;
987 }
988 return false;
989 }
990
991 // The following dispatchers exist for the case where the callback function
992 // needs the message as well. They assume that "Param" is a type of Tuple
993 // (except the one arg case, as there is no Tuple1).
994 template<class T, typename TA>
[email protected]7d5c3ac2009-02-04 08:58:19995 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:29996 void (T::*func)(const Message&, TA)) {
997 Param p;
998 if (Read(msg, &p)) {
[email protected]c2fe31542009-05-20 18:24:14999 (obj->*func)(*msg, p.a);
initial.commit09911bf2008-07-26 23:55:291000 return true;
1001 }
1002 return false;
1003 }
1004
1005 template<class T, typename TA, typename TB>
[email protected]7d5c3ac2009-02-04 08:58:191006 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291007 void (T::*func)(const Message&, TA, TB)) {
1008 Param p;
1009 if (Read(msg, &p)) {
1010 (obj->*func)(*msg, p.a, p.b);
1011 return true;
1012 }
1013 return false;
1014 }
1015
1016 template<class T, typename TA, typename TB, typename TC>
[email protected]7d5c3ac2009-02-04 08:58:191017 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291018 void (T::*func)(const Message&, TA, TB, TC)) {
1019 Param p;
1020 if (Read(msg, &p)) {
1021 (obj->*func)(*msg, p.a, p.b, p.c);
1022 return true;
1023 }
1024 return false;
1025 }
1026
1027 template<class T, typename TA, typename TB, typename TC, typename TD>
[email protected]7d5c3ac2009-02-04 08:58:191028 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291029 void (T::*func)(const Message&, TA, TB, TC, TD)) {
1030 Param p;
1031 if (Read(msg, &p)) {
1032 (obj->*func)(*msg, p.a, p.b, p.c, p.d);
1033 return true;
1034 }
1035 return false;
1036 }
1037
1038 template<class T, typename TA, typename TB, typename TC, typename TD,
1039 typename TE>
[email protected]7d5c3ac2009-02-04 08:58:191040 static bool Dispatch(const Message* msg, T* obj,
initial.commit09911bf2008-07-26 23:55:291041 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
1042 Param p;
1043 if (Read(msg, &p)) {
1044 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
1045 return true;
1046 }
1047 return false;
1048 }
1049
[email protected]deb57402009-02-06 01:35:301050 // Functions used to do manual unpacking. Only used by the automation code,
1051 // these should go away once that code uses SyncChannel.
1052 template<typename TA, typename TB>
1053 static bool Read(const IPC::Message* msg, TA* a, TB* b) {
1054 ParamType params;
1055 if (!Read(msg, &params))
1056 return false;
1057 *a = params.a;
1058 *b = params.b;
1059 return true;
1060 }
1061
1062 template<typename TA, typename TB, typename TC>
1063 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
1064 ParamType params;
1065 if (!Read(msg, &params))
1066 return false;
1067 *a = params.a;
1068 *b = params.b;
1069 *c = params.c;
1070 return true;
1071 }
1072
1073 template<typename TA, typename TB, typename TC, typename TD>
1074 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) {
1075 ParamType params;
1076 if (!Read(msg, &params))
1077 return false;
1078 *a = params.a;
1079 *b = params.b;
1080 *c = params.c;
1081 *d = params.d;
1082 return true;
1083 }
1084
1085 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1086 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) {
1087 ParamType params;
1088 if (!Read(msg, &params))
1089 return false;
1090 *a = params.a;
1091 *b = params.b;
1092 *c = params.c;
1093 *d = params.d;
1094 *e = params.e;
1095 return true;
1096 }
initial.commit09911bf2008-07-26 23:55:291097};
1098
[email protected]7a4de7a62010-08-17 18:38:241099// defined in ipc_logging.cc
1100void GenerateLogData(const std::string& channel, const Message& message,
1101 LogData* data);
1102
1103
1104#if defined(IPC_MESSAGE_LOG_ENABLED)
1105inline void AddOutputParamsToLog(const Message* msg, std::wstring* l) {
1106 const std::wstring& output_params = msg->output_params();
1107 if (!l->empty() && !output_params.empty())
1108 l->append(L", ");
1109
1110 l->append(output_params);
1111}
1112
1113template <class ReplyParamType>
1114inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1115 const Message* msg) {
1116 if (msg->received_time() != 0) {
1117 std::wstring output_params;
1118 LogParam(reply_params, &output_params);
1119 msg->set_output_params(output_params);
1120 }
1121}
1122
1123inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
1124 if (msg->sent_time()) {
1125 // Don't log the sync message after dispatch, as we don't have the
1126 // output parameters at that point. Instead, save its data and log it
1127 // with the outgoing reply message when it's sent.
1128 LogData* data = new LogData;
1129 GenerateLogData("", *msg, data);
1130 msg->set_dont_log();
1131 reply->set_sync_log_data(data);
1132 }
1133}
1134#else
1135inline void AddOutputParamsToLog(const Message* msg, std::wstring* l) {}
1136
1137template <class ReplyParamType>
1138inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1139 const Message* msg) {}
1140
1141inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1142#endif
1143
initial.commit09911bf2008-07-26 23:55:291144// This class assumes that its template argument is a RefTuple (a Tuple with
[email protected]7a4de7a62010-08-17 18:38:241145// reference elements). This would go into ipc_message_utils_impl.h, but it is
1146// also used by chrome_frame.
initial.commit09911bf2008-07-26 23:55:291147template <class RefTuple>
1148class ParamDeserializer : public MessageReplyDeserializer {
1149 public:
[email protected]e1981f432008-08-12 15:22:131150 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:291151
1152 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1153 return ReadParam(&msg, &iter, &out_);
1154 }
1155
1156 RefTuple out_;
1157};
1158
initial.commit09911bf2008-07-26 23:55:291159// Used for synchronous messages.
[email protected]75e5a872009-04-02 23:56:111160template <class SendParamType, class ReplyParamType>
initial.commit09911bf2008-07-26 23:55:291161class MessageWithReply : public SyncMessage {
1162 public:
[email protected]75e5a872009-04-02 23:56:111163 typedef SendParamType SendParam;
[email protected]7a4de7a62010-08-17 18:38:241164 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
[email protected]75e5a872009-04-02 23:56:111165 typedef ReplyParamType ReplyParam;
1166
[email protected]168ae922009-12-04 18:08:451167 MessageWithReply(int32 routing_id, uint32 type,
[email protected]7a4de7a62010-08-17 18:38:241168 const RefSendParam& send, const ReplyParam& reply);
1169 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
1170 static bool ReadReplyParam(
1171 const Message* msg,
1172 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:291173
1174 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191175 static bool Dispatch(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291176 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291177 Message* reply = GenerateReply(msg);
1178 bool error;
[email protected]7a4de7a62010-08-17 18:38:241179 if (ReadSendParam(msg, &send_params)) {
1180 typename TupleTypes<ReplyParam>::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:291181 DispatchToMethod(obj, func, send_params, &reply_params);
1182 WriteParam(reply, reply_params);
1183 error = false;
[email protected]7a4de7a62010-08-17 18:38:241184 LogReplyParamsToMessage(reply_params, msg);
initial.commit09911bf2008-07-26 23:55:291185 } else {
1186 NOTREACHED() << "Error deserializing message " << msg->type();
1187 reply->set_reply_error();
1188 error = true;
1189 }
1190
1191 obj->Send(reply);
1192 return !error;
1193 }
1194
1195 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191196 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291197 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291198 Message* reply = GenerateReply(msg);
1199 bool error;
[email protected]7a4de7a62010-08-17 18:38:241200 if (ReadSendParam(msg, &send_params)) {
initial.commit09911bf2008-07-26 23:55:291201 Tuple1<Message&> t = MakeRefTuple(*reply);
[email protected]7a4de7a62010-08-17 18:38:241202 ConnectMessageAndReply(msg, reply);
initial.commit09911bf2008-07-26 23:55:291203 DispatchToMethod(obj, func, send_params, &t);
1204 error = false;
1205 } else {
1206 NOTREACHED() << "Error deserializing message " << msg->type();
1207 reply->set_reply_error();
1208 obj->Send(reply);
1209 error = true;
1210 }
1211 return !error;
1212 }
1213
1214 template<typename TA>
1215 static void WriteReplyParams(Message* reply, TA a) {
1216 ReplyParam p(a);
1217 WriteParam(reply, p);
1218 }
1219
1220 template<typename TA, typename TB>
1221 static void WriteReplyParams(Message* reply, TA a, TB b) {
1222 ReplyParam p(a, b);
1223 WriteParam(reply, p);
1224 }
1225
1226 template<typename TA, typename TB, typename TC>
1227 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1228 ReplyParam p(a, b, c);
1229 WriteParam(reply, p);
1230 }
1231
1232 template<typename TA, typename TB, typename TC, typename TD>
1233 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1234 ReplyParam p(a, b, c, d);
1235 WriteParam(reply, p);
1236 }
1237
1238 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1239 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1240 ReplyParam p(a, b, c, d, e);
1241 WriteParam(reply, p);
1242 }
1243};
1244
[email protected]7d5c3ac2009-02-04 08:58:191245//-----------------------------------------------------------------------------
1246
[email protected]3178f4e22008-08-05 21:20:411247} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291248
[email protected]946d1b22009-07-22 23:57:211249#endif // IPC_IPC_MESSAGE_UTILS_H_