Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(664)

Side by Side Diff: ipc/ipc_message_utils.h

Issue 155905: Separates ipc code from common (http://crbug.com/16829) (Closed)
Patch Set: Fixes reference to 'common_message_traits' it's actually 'common_param_traits' Created 11 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ipc/ipc_message_unittest.cc ('k') | ipc/ipc_message_utils.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef IPC_IPC_MESSAGE_UTILS_H_
6 #define IPC_IPC_MESSAGE_UTILS_H_
7
8 #include <string>
9 #include <vector>
10 #include <map>
11
12 #include "base/file_path.h"
13 #include "base/format_macros.h"
14 #include "base/string16.h"
15 #include "base/string_util.h"
16 #include "base/time.h"
17 #include "base/tuple.h"
18 #include "base/values.h"
19 #if defined(OS_POSIX)
20 #include "ipc/file_descriptor_set_posix.h"
21 #endif
22 #include "ipc/ipc_channel_handle.h"
23 #include "ipc/ipc_sync_message.h"
24
25 // Used by IPC_BEGIN_MESSAGES so that each message class starts from a unique
26 // base. Messages have unique IDs across channels in order for the IPC logging
27 // code to figure out the message class from its ID.
28 enum IPCMessageStart {
29 // By using a start value of 0 for automation messages, we keep backward
30 // compatibility with old builds.
31 AutomationMsgStart = 0,
32 ViewMsgStart,
33 ViewHostMsgStart,
34 PluginProcessMsgStart,
35 PluginProcessHostMsgStart,
36 PluginMsgStart,
37 PluginHostMsgStart,
38 NPObjectMsgStart,
39 TestMsgStart,
40 DevToolsAgentMsgStart,
41 DevToolsClientMsgStart,
42 WorkerProcessMsgStart,
43 WorkerProcessHostMsgStart,
44 WorkerMsgStart,
45 WorkerHostMsgStart,
46 // NOTE: When you add a new message class, also update
47 // IPCStatusView::IPCStatusView to ensure logging works.
48 // NOTE: this enum is used by IPC_MESSAGE_MACRO to generate a unique message
49 // id. Only 4 bits are used for the message type, so if this enum needs more
50 // than 16 entries, that code needs to be updated.
51 LastMsgIndex
52 };
53
54 COMPILE_ASSERT(LastMsgIndex <= 16, need_to_update_IPC_MESSAGE_MACRO);
55
56
57 namespace IPC {
58
59 //-----------------------------------------------------------------------------
60 // An iterator class for reading the fields contained within a Message.
61
62 class MessageIterator {
63 public:
64 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
65 }
66 int NextInt() const {
67 int val;
68 if (!msg_.ReadInt(&iter_, &val))
69 NOTREACHED();
70 return val;
71 }
72 intptr_t NextIntPtr() const {
73 intptr_t val;
74 if (!msg_.ReadIntPtr(&iter_, &val))
75 NOTREACHED();
76 return val;
77 }
78 const std::string NextString() const {
79 std::string val;
80 if (!msg_.ReadString(&iter_, &val))
81 NOTREACHED();
82 return val;
83 }
84 const std::wstring NextWString() const {
85 std::wstring val;
86 if (!msg_.ReadWString(&iter_, &val))
87 NOTREACHED();
88 return val;
89 }
90 const void NextData(const char** data, int* length) const {
91 if (!msg_.ReadData(&iter_, data, length)) {
92 NOTREACHED();
93 }
94 }
95 private:
96 const Message& msg_;
97 mutable void* iter_;
98 };
99
100 //-----------------------------------------------------------------------------
101 // ParamTraits specializations, etc.
102
103 template <class P> struct ParamTraits {};
104
105 template <class P>
106 static inline void WriteParam(Message* m, const P& p) {
107 ParamTraits<P>::Write(m, p);
108 }
109
110 template <class P>
111 static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
112 P* p) {
113 return ParamTraits<P>::Read(m, iter, p);
114 }
115
116 template <class P>
117 static inline void LogParam(const P& p, std::wstring* l) {
118 ParamTraits<P>::Log(p, l);
119 }
120
121 template <>
122 struct ParamTraits<bool> {
123 typedef bool param_type;
124 static void Write(Message* m, const param_type& p) {
125 m->WriteBool(p);
126 }
127 static bool Read(const Message* m, void** iter, param_type* r) {
128 return m->ReadBool(iter, r);
129 }
130 static void Log(const param_type& p, std::wstring* l) {
131 l->append(p ? L"true" : L"false");
132 }
133 };
134
135 template <>
136 struct ParamTraits<int> {
137 typedef int param_type;
138 static void Write(Message* m, const param_type& p) {
139 m->WriteInt(p);
140 }
141 static bool Read(const Message* m, void** iter, param_type* r) {
142 return m->ReadInt(iter, r);
143 }
144 static void Log(const param_type& p, std::wstring* l) {
145 l->append(StringPrintf(L"%d", p));
146 }
147 };
148
149 template <>
150 struct ParamTraits<long> {
151 typedef long param_type;
152 static void Write(Message* m, const param_type& p) {
153 m->WriteLong(p);
154 }
155 static bool Read(const Message* m, void** iter, param_type* r) {
156 return m->ReadLong(iter, r);
157 }
158 static void Log(const param_type& p, std::wstring* l) {
159 l->append(StringPrintf(L"%l", p));
160 }
161 };
162
163 #if defined(OS_LINUX) || defined(OS_WIN)
164 // On Linux, unsigned long is used for serializing X window ids.
165 // On Windows, it's used for serializing process ids.
166 // On Mac, it conflicts with some other definition.
167 template <>
168 struct ParamTraits<unsigned long> {
169 typedef unsigned long param_type;
170 static void Write(Message* m, const param_type& p) {
171 m->WriteLong(p);
172 }
173 static bool Read(const Message* m, void** iter, param_type* r) {
174 long read_output;
175 if (!m->ReadLong(iter, &read_output))
176 return false;
177 *r = static_cast<unsigned long>(read_output);
178 return true;
179 }
180 static void Log(const param_type& p, std::wstring* l) {
181 l->append(StringPrintf(L"%ul", p));
182 }
183 };
184 #endif
185
186 template <>
187 struct ParamTraits<size_t> {
188 typedef size_t param_type;
189 static void Write(Message* m, const param_type& p) {
190 m->WriteSize(p);
191 }
192 static bool Read(const Message* m, void** iter, param_type* r) {
193 return m->ReadSize(iter, r);
194 }
195 static void Log(const param_type& p, std::wstring* l) {
196 l->append(StringPrintf(L"%u", p));
197 }
198 };
199
200 #if defined(OS_MACOSX)
201 // On Linux size_t & uint32 can be the same type.
202 // TODO(playmobil): Fix compilation if this is not the case.
203 template <>
204 struct ParamTraits<uint32> {
205 typedef uint32 param_type;
206 static void Write(Message* m, const param_type& p) {
207 m->WriteUInt32(p);
208 }
209 static bool Read(const Message* m, void** iter, param_type* r) {
210 return m->ReadUInt32(iter, r);
211 }
212 static void Log(const param_type& p, std::wstring* l) {
213 l->append(StringPrintf(L"%u", p));
214 }
215 };
216 #endif // defined(OS_MACOSX)
217
218 template <>
219 struct ParamTraits<int64> {
220 typedef int64 param_type;
221 static void Write(Message* m, const param_type& p) {
222 m->WriteInt64(p);
223 }
224 static bool Read(const Message* m, void** iter, param_type* r) {
225 return m->ReadInt64(iter, r);
226 }
227 static void Log(const param_type& p, std::wstring* l) {
228 l->append(StringPrintf(L"%" WidePRId64, p));
229 }
230 };
231
232 template <>
233 struct ParamTraits<uint64> {
234 typedef uint64 param_type;
235 static void Write(Message* m, const param_type& p) {
236 m->WriteInt64(static_cast<int64>(p));
237 }
238 static bool Read(const Message* m, void** iter, param_type* r) {
239 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
240 }
241 static void Log(const param_type& p, std::wstring* l) {
242 l->append(StringPrintf(L"%" WidePRId64, p));
243 }
244 };
245
246 template <>
247 struct ParamTraits<double> {
248 typedef double param_type;
249 static void Write(Message* m, const param_type& p) {
250 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
251 }
252 static bool Read(const Message* m, void** iter, param_type* r) {
253 const char *data;
254 int data_size = 0;
255 bool result = m->ReadData(iter, &data, &data_size);
256 if (result && data_size == sizeof(param_type)) {
257 memcpy(r, data, sizeof(param_type));
258 } else {
259 result = false;
260 NOTREACHED();
261 }
262
263 return result;
264 }
265 static void Log(const param_type& p, std::wstring* l) {
266 l->append(StringPrintf(L"e", p));
267 }
268 };
269
270 template <>
271 struct ParamTraits<wchar_t> {
272 typedef wchar_t param_type;
273 static void Write(Message* m, const param_type& p) {
274 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
275 }
276 static bool Read(const Message* m, void** iter, param_type* r) {
277 const char *data;
278 int data_size = 0;
279 bool result = m->ReadData(iter, &data, &data_size);
280 if (result && data_size == sizeof(param_type)) {
281 memcpy(r, data, sizeof(param_type));
282 } else {
283 result = false;
284 NOTREACHED();
285 }
286
287 return result;
288 }
289 static void Log(const param_type& p, std::wstring* l) {
290 l->append(StringPrintf(L"%lc", p));
291 }
292 };
293
294 template <>
295 struct ParamTraits<base::Time> {
296 typedef base::Time param_type;
297 static void Write(Message* m, const param_type& p) {
298 ParamTraits<int64>::Write(m, p.ToInternalValue());
299 }
300 static bool Read(const Message* m, void** iter, param_type* r) {
301 int64 value;
302 if (!ParamTraits<int64>::Read(m, iter, &value))
303 return false;
304 *r = base::Time::FromInternalValue(value);
305 return true;
306 }
307 static void Log(const param_type& p, std::wstring* l) {
308 ParamTraits<int64>::Log(p.ToInternalValue(), l);
309 }
310 };
311
312 #if defined(OS_WIN)
313 template <>
314 struct ParamTraits<LOGFONT> {
315 typedef LOGFONT param_type;
316 static void Write(Message* m, const param_type& p) {
317 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
318 }
319 static bool Read(const Message* m, void** iter, param_type* r) {
320 const char *data;
321 int data_size = 0;
322 bool result = m->ReadData(iter, &data, &data_size);
323 if (result && data_size == sizeof(LOGFONT)) {
324 memcpy(r, data, sizeof(LOGFONT));
325 } else {
326 result = false;
327 NOTREACHED();
328 }
329
330 return result;
331 }
332 static void Log(const param_type& p, std::wstring* l) {
333 l->append(StringPrintf(L"<LOGFONT>"));
334 }
335 };
336
337 template <>
338 struct ParamTraits<MSG> {
339 typedef MSG param_type;
340 static void Write(Message* m, const param_type& p) {
341 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
342 }
343 static bool Read(const Message* m, void** iter, param_type* r) {
344 const char *data;
345 int data_size = 0;
346 bool result = m->ReadData(iter, &data, &data_size);
347 if (result && data_size == sizeof(MSG)) {
348 memcpy(r, data, sizeof(MSG));
349 } else {
350 result = false;
351 NOTREACHED();
352 }
353
354 return result;
355 }
356 };
357 #endif // defined(OS_WIN)
358
359 template <>
360 struct ParamTraits<DictionaryValue> {
361 typedef DictionaryValue param_type;
362 static void Write(Message* m, const param_type& p);
363 static bool Read(const Message* m, void** iter, param_type* r);
364 static void Log(const param_type& p, std::wstring* l);
365 };
366
367 template <>
368 struct ParamTraits<ListValue> {
369 typedef ListValue param_type;
370 static void Write(Message* m, const param_type& p);
371 static bool Read(const Message* m, void** iter, param_type* r);
372 static void Log(const param_type& p, std::wstring* l);
373 };
374
375 template <>
376 struct ParamTraits<std::string> {
377 typedef std::string param_type;
378 static void Write(Message* m, const param_type& p) {
379 m->WriteString(p);
380 }
381 static bool Read(const Message* m, void** iter, param_type* r) {
382 return m->ReadString(iter, r);
383 }
384 static void Log(const param_type& p, std::wstring* l) {
385 l->append(UTF8ToWide(p));
386 }
387 };
388
389 template <>
390 struct ParamTraits<std::vector<unsigned char> > {
391 typedef std::vector<unsigned char> param_type;
392 static void Write(Message* m, const param_type& p) {
393 if (p.size() == 0) {
394 m->WriteData(NULL, 0);
395 } else {
396 m->WriteData(reinterpret_cast<const char*>(&p.front()),
397 static_cast<int>(p.size()));
398 }
399 }
400 static bool Read(const Message* m, void** iter, param_type* r) {
401 const char *data;
402 int data_size = 0;
403 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
404 return false;
405 r->resize(data_size);
406 if (data_size)
407 memcpy(&r->front(), data, data_size);
408 return true;
409 }
410 static void Log(const param_type& p, std::wstring* l) {
411 for (size_t i = 0; i < p.size(); ++i)
412 l->push_back(p[i]);
413 }
414 };
415
416 template <>
417 struct ParamTraits<std::vector<char> > {
418 typedef std::vector<char> param_type;
419 static void Write(Message* m, const param_type& p) {
420 if (p.size() == 0) {
421 m->WriteData(NULL, 0);
422 } else {
423 m->WriteData(&p.front(), static_cast<int>(p.size()));
424 }
425 }
426 static bool Read(const Message* m, void** iter, param_type* r) {
427 const char *data;
428 int data_size = 0;
429 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
430 return false;
431 r->resize(data_size);
432 if (data_size)
433 memcpy(&r->front(), data, data_size);
434 return true;
435 }
436 static void Log(const param_type& p, std::wstring* l) {
437 for (size_t i = 0; i < p.size(); ++i)
438 l->push_back(p[i]);
439 }
440 };
441
442 template <class P>
443 struct ParamTraits<std::vector<P> > {
444 typedef std::vector<P> param_type;
445 static void Write(Message* m, const param_type& p) {
446 WriteParam(m, static_cast<int>(p.size()));
447 for (size_t i = 0; i < p.size(); i++)
448 WriteParam(m, p[i]);
449 }
450 static bool Read(const Message* m, void** iter, param_type* r) {
451 int size;
452 if (!m->ReadLength(iter, &size))
453 return false;
454 // Resizing beforehand is not safe, see BUG 1006367 for details.
455 if (m->IteratorHasRoomFor(*iter, size * sizeof(P))) {
456 r->resize(size);
457 for (int i = 0; i < size; i++) {
458 if (!ReadParam(m, iter, &(*r)[i]))
459 return false;
460 }
461 } else {
462 for (int i = 0; i < size; i++) {
463 P element;
464 if (!ReadParam(m, iter, &element))
465 return false;
466 r->push_back(element);
467 }
468 }
469 return true;
470 }
471 static void Log(const param_type& p, std::wstring* l) {
472 for (size_t i = 0; i < p.size(); ++i) {
473 if (i != 0)
474 l->append(L" ");
475
476 LogParam((p[i]), l);
477 }
478 }
479 };
480
481 template <class K, class V>
482 struct ParamTraits<std::map<K, V> > {
483 typedef std::map<K, V> param_type;
484 static void Write(Message* m, const param_type& p) {
485 WriteParam(m, static_cast<int>(p.size()));
486 typename param_type::const_iterator iter;
487 for (iter = p.begin(); iter != p.end(); ++iter) {
488 WriteParam(m, iter->first);
489 WriteParam(m, iter->second);
490 }
491 }
492 static bool Read(const Message* m, void** iter, param_type* r) {
493 int size;
494 if (!ReadParam(m, iter, &size) || size < 0)
495 return false;
496 for (int i = 0; i < size; ++i) {
497 K k;
498 if (!ReadParam(m, iter, &k))
499 return false;
500 V& value = (*r)[k];
501 if (!ReadParam(m, iter, &value))
502 return false;
503 }
504 return true;
505 }
506 static void Log(const param_type& p, std::wstring* l) {
507 l->append(L"<std::map>");
508 }
509 };
510
511
512 template <>
513 struct ParamTraits<std::wstring> {
514 typedef std::wstring param_type;
515 static void Write(Message* m, const param_type& p) {
516 m->WriteWString(p);
517 }
518 static bool Read(const Message* m, void** iter, param_type* r) {
519 return m->ReadWString(iter, r);
520 }
521 static void Log(const param_type& p, std::wstring* l) {
522 l->append(p);
523 }
524 };
525
526 // If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
527 // need this trait.
528 #if !defined(WCHAR_T_IS_UTF16)
529 template <>
530 struct ParamTraits<string16> {
531 typedef string16 param_type;
532 static void Write(Message* m, const param_type& p) {
533 m->WriteString16(p);
534 }
535 static bool Read(const Message* m, void** iter, param_type* r) {
536 return m->ReadString16(iter, r);
537 }
538 static void Log(const param_type& p, std::wstring* l) {
539 l->append(UTF16ToWide(p));
540 }
541 };
542 #endif
543
544 // and, a few more useful types...
545 #if defined(OS_WIN)
546 template <>
547 struct ParamTraits<HANDLE> {
548 typedef HANDLE param_type;
549 static void Write(Message* m, const param_type& p) {
550 m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
551 }
552 static bool Read(const Message* m, void** iter, param_type* r) {
553 DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
554 return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
555 }
556 static void Log(const param_type& p, std::wstring* l) {
557 l->append(StringPrintf(L"0x%X", p));
558 }
559 };
560
561 template <>
562 struct ParamTraits<HCURSOR> {
563 typedef HCURSOR param_type;
564 static void Write(Message* m, const param_type& p) {
565 m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
566 }
567 static bool Read(const Message* m, void** iter, param_type* r) {
568 DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
569 return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
570 }
571 static void Log(const param_type& p, std::wstring* l) {
572 l->append(StringPrintf(L"0x%X", p));
573 }
574 };
575
576 template <>
577 struct ParamTraits<HACCEL> {
578 typedef HACCEL param_type;
579 static void Write(Message* m, const param_type& p) {
580 m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
581 }
582 static bool Read(const Message* m, void** iter, param_type* r) {
583 DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
584 return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
585 }
586 };
587
588 template <>
589 struct ParamTraits<POINT> {
590 typedef POINT param_type;
591 static void Write(Message* m, const param_type& p) {
592 m->WriteInt(p.x);
593 m->WriteInt(p.y);
594 }
595 static bool Read(const Message* m, void** iter, param_type* r) {
596 int x, y;
597 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
598 return false;
599 r->x = x;
600 r->y = y;
601 return true;
602 }
603 static void Log(const param_type& p, std::wstring* l) {
604 l->append(StringPrintf(L"(%d, %d)", p.x, p.y));
605 }
606 };
607 #endif // defined(OS_WIN)
608
609 template <>
610 struct ParamTraits<FilePath> {
611 typedef FilePath param_type;
612 static void Write(Message* m, const param_type& p) {
613 ParamTraits<FilePath::StringType>::Write(m, p.value());
614 }
615 static bool Read(const Message* m, void** iter, param_type* r) {
616 FilePath::StringType value;
617 if (!ParamTraits<FilePath::StringType>::Read(m, iter, &value))
618 return false;
619 *r = FilePath(value);
620 return true;
621 }
622 static void Log(const param_type& p, std::wstring* l) {
623 ParamTraits<FilePath::StringType>::Log(p.value(), l);
624 }
625 };
626
627 #if defined(OS_POSIX)
628 // FileDescriptors may be serialised over IPC channels on POSIX. On the
629 // receiving side, the FileDescriptor is a valid duplicate of the file
630 // descriptor which was transmitted: *it is not just a copy of the integer like
631 // HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
632 // this case, the receiving end will see a value of -1. *Zero is a valid file
633 // descriptor*.
634 //
635 // The received file descriptor will have the |auto_close| flag set to true. The
636 // code which handles the message is responsible for taking ownership of it.
637 // File descriptors are OS resources and must be closed when no longer needed.
638 //
639 // When sending a file descriptor, the file descriptor must be valid at the time
640 // of transmission. Since transmission is not synchronous, one should consider
641 // dup()ing any file descriptors to be transmitted and setting the |auto_close|
642 // flag, which causes the file descriptor to be closed after writing.
643 template<>
644 struct ParamTraits<base::FileDescriptor> {
645 typedef base::FileDescriptor param_type;
646 static void Write(Message* m, const param_type& p) {
647 const bool valid = p.fd >= 0;
648 WriteParam(m, valid);
649
650 if (valid) {
651 if (!m->WriteFileDescriptor(p))
652 NOTREACHED();
653 }
654 }
655 static bool Read(const Message* m, void** iter, param_type* r) {
656 bool valid;
657 if (!ReadParam(m, iter, &valid))
658 return false;
659
660 if (!valid) {
661 r->fd = -1;
662 r->auto_close = false;
663 return true;
664 }
665
666 return m->ReadFileDescriptor(iter, r);
667 }
668 static void Log(const param_type& p, std::wstring* l) {
669 if (p.auto_close) {
670 l->append(StringPrintf(L"FD(%d auto-close)", p.fd));
671 } else {
672 l->append(StringPrintf(L"FD(%d)", p.fd));
673 }
674 }
675 };
676 #endif // defined(OS_POSIX)
677
678 // A ChannelHandle is basically a platform-inspecific wrapper around the
679 // fact that IPC endpoints are handled specially on POSIX. See above comments
680 // on FileDescriptor for more background.
681 template<>
682 struct ParamTraits<IPC::ChannelHandle> {
683 typedef ChannelHandle param_type;
684 static void Write(Message* m, const param_type& p) {
685 WriteParam(m, p.name);
686 #if defined(OS_POSIX)
687 WriteParam(m, p.socket);
688 #endif
689 }
690 static bool Read(const Message* m, void** iter, param_type* r) {
691 return ReadParam(m, iter, &r->name)
692 #if defined(OS_POSIX)
693 && ReadParam(m, iter, &r->socket)
694 #endif
695 ;
696 }
697 static void Log(const param_type& p, std::wstring* l) {
698 l->append(ASCIIToWide(StringPrintf("ChannelHandle(%s", p.name.c_str())));
699 #if defined(OS_POSIX)
700 ParamTraits<base::FileDescriptor>::Log(p.socket, l);
701 #endif
702 l->append(L")");
703 }
704 };
705
706 #if defined(OS_WIN)
707 template <>
708 struct ParamTraits<XFORM> {
709 typedef XFORM param_type;
710 static void Write(Message* m, const param_type& p) {
711 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
712 }
713 static bool Read(const Message* m, void** iter, param_type* r) {
714 const char *data;
715 int data_size = 0;
716 bool result = m->ReadData(iter, &data, &data_size);
717 if (result && data_size == sizeof(XFORM)) {
718 memcpy(r, data, sizeof(XFORM));
719 } else {
720 result = false;
721 NOTREACHED();
722 }
723
724 return result;
725 }
726 static void Log(const param_type& p, std::wstring* l) {
727 l->append(L"<XFORM>");
728 }
729 };
730 #endif // defined(OS_WIN)
731
732 struct LogData {
733 std::string channel;
734 int32 routing_id;
735 uint16 type;
736 std::wstring flags;
737 int64 sent; // Time that the message was sent (i.e. at Send()).
738 int64 receive; // Time before it was dispatched (i.e. before calling
739 // OnMessageReceived).
740 int64 dispatch; // Time after it was dispatched (i.e. after calling
741 // OnMessageReceived).
742 std::wstring message_name;
743 std::wstring params;
744 };
745
746 template <>
747 struct ParamTraits<LogData> {
748 typedef LogData param_type;
749 static void Write(Message* m, const param_type& p) {
750 WriteParam(m, p.channel);
751 WriteParam(m, p.routing_id);
752 WriteParam(m, static_cast<int>(p.type));
753 WriteParam(m, p.flags);
754 WriteParam(m, p.sent);
755 WriteParam(m, p.receive);
756 WriteParam(m, p.dispatch);
757 WriteParam(m, p.params);
758 }
759 static bool Read(const Message* m, void** iter, param_type* r) {
760 int type;
761 bool result =
762 ReadParam(m, iter, &r->channel) &&
763 ReadParam(m, iter, &r->routing_id);
764 ReadParam(m, iter, &type) &&
765 ReadParam(m, iter, &r->flags) &&
766 ReadParam(m, iter, &r->sent) &&
767 ReadParam(m, iter, &r->receive) &&
768 ReadParam(m, iter, &r->dispatch) &&
769 ReadParam(m, iter, &r->params);
770 r->type = static_cast<uint16>(type);
771 return result;
772 }
773 static void Log(const param_type& p, std::wstring* l) {
774 // Doesn't make sense to implement this!
775 }
776 };
777
778
779 template <>
780 struct ParamTraits<Message> {
781 static void Write(Message* m, const Message& p) {
782 m->WriteInt(p.size());
783 m->WriteData(reinterpret_cast<const char*>(p.data()), p.size());
784 }
785 static bool Read(const Message* m, void** iter, Message* r) {
786 int size;
787 if (!m->ReadInt(iter, &size))
788 return false;
789 const char* data;
790 if (!m->ReadData(iter, &data, &size))
791 return false;
792 *r = Message(data, size);
793 return true;
794 }
795 static void Log(const Message& p, std::wstring* l) {
796 l->append(L"<IPC::Message>");
797 }
798 };
799
800 template <>
801 struct ParamTraits<Tuple0> {
802 typedef Tuple0 param_type;
803 static void Write(Message* m, const param_type& p) {
804 }
805 static bool Read(const Message* m, void** iter, param_type* r) {
806 return true;
807 }
808 static void Log(const param_type& p, std::wstring* l) {
809 }
810 };
811
812 template <class A>
813 struct ParamTraits< Tuple1<A> > {
814 typedef Tuple1<A> param_type;
815 static void Write(Message* m, const param_type& p) {
816 WriteParam(m, p.a);
817 }
818 static bool Read(const Message* m, void** iter, param_type* r) {
819 return ReadParam(m, iter, &r->a);
820 }
821 static void Log(const param_type& p, std::wstring* l) {
822 LogParam(p.a, l);
823 }
824 };
825
826 template <class A, class B>
827 struct ParamTraits< Tuple2<A, B> > {
828 typedef Tuple2<A, B> param_type;
829 static void Write(Message* m, const param_type& p) {
830 WriteParam(m, p.a);
831 WriteParam(m, p.b);
832 }
833 static bool Read(const Message* m, void** iter, param_type* r) {
834 return (ReadParam(m, iter, &r->a) &&
835 ReadParam(m, iter, &r->b));
836 }
837 static void Log(const param_type& p, std::wstring* l) {
838 LogParam(p.a, l);
839 l->append(L", ");
840 LogParam(p.b, l);
841 }
842 };
843
844 template <class A, class B, class C>
845 struct ParamTraits< Tuple3<A, B, C> > {
846 typedef Tuple3<A, B, C> param_type;
847 static void Write(Message* m, const param_type& p) {
848 WriteParam(m, p.a);
849 WriteParam(m, p.b);
850 WriteParam(m, p.c);
851 }
852 static bool Read(const Message* m, void** iter, param_type* r) {
853 return (ReadParam(m, iter, &r->a) &&
854 ReadParam(m, iter, &r->b) &&
855 ReadParam(m, iter, &r->c));
856 }
857 static void Log(const param_type& p, std::wstring* l) {
858 LogParam(p.a, l);
859 l->append(L", ");
860 LogParam(p.b, l);
861 l->append(L", ");
862 LogParam(p.c, l);
863 }
864 };
865
866 template <class A, class B, class C, class D>
867 struct ParamTraits< Tuple4<A, B, C, D> > {
868 typedef Tuple4<A, B, C, D> param_type;
869 static void Write(Message* m, const param_type& p) {
870 WriteParam(m, p.a);
871 WriteParam(m, p.b);
872 WriteParam(m, p.c);
873 WriteParam(m, p.d);
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 ReadParam(m, iter, &r->d));
880 }
881 static void Log(const param_type& p, std::wstring* l) {
882 LogParam(p.a, l);
883 l->append(L", ");
884 LogParam(p.b, l);
885 l->append(L", ");
886 LogParam(p.c, l);
887 l->append(L", ");
888 LogParam(p.d, l);
889 }
890 };
891
892 template <class A, class B, class C, class D, class E>
893 struct ParamTraits< Tuple5<A, B, C, D, E> > {
894 typedef Tuple5<A, B, C, D, E> param_type;
895 static void Write(Message* m, const param_type& p) {
896 WriteParam(m, p.a);
897 WriteParam(m, p.b);
898 WriteParam(m, p.c);
899 WriteParam(m, p.d);
900 WriteParam(m, p.e);
901 }
902 static bool Read(const Message* m, void** iter, param_type* r) {
903 return (ReadParam(m, iter, &r->a) &&
904 ReadParam(m, iter, &r->b) &&
905 ReadParam(m, iter, &r->c) &&
906 ReadParam(m, iter, &r->d) &&
907 ReadParam(m, iter, &r->e));
908 }
909 static void Log(const param_type& p, std::wstring* l) {
910 LogParam(p.a, l);
911 l->append(L", ");
912 LogParam(p.b, l);
913 l->append(L", ");
914 LogParam(p.c, l);
915 l->append(L", ");
916 LogParam(p.d, l);
917 l->append(L", ");
918 LogParam(p.e, l);
919 }
920 };
921
922 //-----------------------------------------------------------------------------
923 // Generic message subclasses
924
925 // Used for asynchronous messages.
926 template <class ParamType>
927 class MessageWithTuple : public Message {
928 public:
929 typedef ParamType Param;
930 typedef typename ParamType::ParamTuple RefParam;
931
932 MessageWithTuple(int32 routing_id, uint16 type, const RefParam& p)
933 : Message(routing_id, type, PRIORITY_NORMAL) {
934 WriteParam(this, p);
935 }
936
937 static bool Read(const Message* msg, Param* p) {
938 void* iter = NULL;
939 if (ReadParam(msg, &iter, p))
940 return true;
941 NOTREACHED() << "Error deserializing message " << msg->type();
942 return false;
943 }
944
945 // Generic dispatcher. Should cover most cases.
946 template<class T, class Method>
947 static bool Dispatch(const Message* msg, T* obj, Method func) {
948 Param p;
949 if (Read(msg, &p)) {
950 DispatchToMethod(obj, func, p);
951 return true;
952 }
953 return false;
954 }
955
956 // The following dispatchers exist for the case where the callback function
957 // needs the message as well. They assume that "Param" is a type of Tuple
958 // (except the one arg case, as there is no Tuple1).
959 template<class T, typename TA>
960 static bool Dispatch(const Message* msg, T* obj,
961 void (T::*func)(const Message&, TA)) {
962 Param p;
963 if (Read(msg, &p)) {
964 (obj->*func)(*msg, p.a);
965 return true;
966 }
967 return false;
968 }
969
970 template<class T, typename TA, typename TB>
971 static bool Dispatch(const Message* msg, T* obj,
972 void (T::*func)(const Message&, TA, TB)) {
973 Param p;
974 if (Read(msg, &p)) {
975 (obj->*func)(*msg, p.a, p.b);
976 return true;
977 }
978 return false;
979 }
980
981 template<class T, typename TA, typename TB, typename TC>
982 static bool Dispatch(const Message* msg, T* obj,
983 void (T::*func)(const Message&, TA, TB, TC)) {
984 Param p;
985 if (Read(msg, &p)) {
986 (obj->*func)(*msg, p.a, p.b, p.c);
987 return true;
988 }
989 return false;
990 }
991
992 template<class T, typename TA, typename TB, typename TC, typename TD>
993 static bool Dispatch(const Message* msg, T* obj,
994 void (T::*func)(const Message&, TA, TB, TC, TD)) {
995 Param p;
996 if (Read(msg, &p)) {
997 (obj->*func)(*msg, p.a, p.b, p.c, p.d);
998 return true;
999 }
1000 return false;
1001 }
1002
1003 template<class T, typename TA, typename TB, typename TC, typename TD,
1004 typename TE>
1005 static bool Dispatch(const Message* msg, T* obj,
1006 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
1007 Param p;
1008 if (Read(msg, &p)) {
1009 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
1010 return true;
1011 }
1012 return false;
1013 }
1014
1015 static void Log(const Message* msg, std::wstring* l) {
1016 Param p;
1017 if (Read(msg, &p))
1018 LogParam(p, l);
1019 }
1020
1021 // Functions used to do manual unpacking. Only used by the automation code,
1022 // these should go away once that code uses SyncChannel.
1023 template<typename TA, typename TB>
1024 static bool Read(const IPC::Message* msg, TA* a, TB* b) {
1025 ParamType params;
1026 if (!Read(msg, &params))
1027 return false;
1028 *a = params.a;
1029 *b = params.b;
1030 return true;
1031 }
1032
1033 template<typename TA, typename TB, typename TC>
1034 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
1035 ParamType params;
1036 if (!Read(msg, &params))
1037 return false;
1038 *a = params.a;
1039 *b = params.b;
1040 *c = params.c;
1041 return true;
1042 }
1043
1044 template<typename TA, typename TB, typename TC, typename TD>
1045 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) {
1046 ParamType params;
1047 if (!Read(msg, &params))
1048 return false;
1049 *a = params.a;
1050 *b = params.b;
1051 *c = params.c;
1052 *d = params.d;
1053 return true;
1054 }
1055
1056 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1057 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) {
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 *e = params.e;
1066 return true;
1067 }
1068 };
1069
1070 // This class assumes that its template argument is a RefTuple (a Tuple with
1071 // reference elements).
1072 template <class RefTuple>
1073 class ParamDeserializer : public MessageReplyDeserializer {
1074 public:
1075 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
1076
1077 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1078 return ReadParam(&msg, &iter, &out_);
1079 }
1080
1081 RefTuple out_;
1082 };
1083
1084 // defined in ipc_logging.cc
1085 void GenerateLogData(const std::string& channel, const Message& message,
1086 LogData* data);
1087
1088 // Used for synchronous messages.
1089 template <class SendParamType, class ReplyParamType>
1090 class MessageWithReply : public SyncMessage {
1091 public:
1092 typedef SendParamType SendParam;
1093 typedef typename SendParam::ParamTuple RefSendParam;
1094 typedef ReplyParamType ReplyParam;
1095
1096 MessageWithReply(int32 routing_id, uint16 type,
1097 const RefSendParam& send, const ReplyParam& reply)
1098 : SyncMessage(routing_id, type, PRIORITY_NORMAL,
1099 new ParamDeserializer<ReplyParam>(reply)) {
1100 WriteParam(this, send);
1101 }
1102
1103 static void Log(const Message* msg, std::wstring* l) {
1104 if (msg->is_sync()) {
1105 SendParam p;
1106 void* iter = SyncMessage::GetDataIterator(msg);
1107 if (ReadParam(msg, &iter, &p))
1108 LogParam(p, l);
1109
1110 #if defined(IPC_MESSAGE_LOG_ENABLED)
1111 const std::wstring& output_params = msg->output_params();
1112 if (!l->empty() && !output_params.empty())
1113 l->append(L", ");
1114
1115 l->append(output_params);
1116 #endif
1117 } else {
1118 // This is an outgoing reply. Now that we have the output parameters, we
1119 // can finally log the message.
1120 typename ReplyParam::ValueTuple p;
1121 void* iter = SyncMessage::GetDataIterator(msg);
1122 if (ReadParam(msg, &iter, &p))
1123 LogParam(p, l);
1124 }
1125 }
1126
1127 template<class T, class Method>
1128 static bool Dispatch(const Message* msg, T* obj, Method func) {
1129 SendParam send_params;
1130 void* iter = GetDataIterator(msg);
1131 Message* reply = GenerateReply(msg);
1132 bool error;
1133 if (ReadParam(msg, &iter, &send_params)) {
1134 typename ReplyParam::ValueTuple reply_params;
1135 DispatchToMethod(obj, func, send_params, &reply_params);
1136 WriteParam(reply, reply_params);
1137 error = false;
1138 #ifdef IPC_MESSAGE_LOG_ENABLED
1139 if (msg->received_time() != 0) {
1140 std::wstring output_params;
1141 LogParam(reply_params, &output_params);
1142 msg->set_output_params(output_params);
1143 }
1144 #endif
1145 } else {
1146 NOTREACHED() << "Error deserializing message " << msg->type();
1147 reply->set_reply_error();
1148 error = true;
1149 }
1150
1151 obj->Send(reply);
1152 return !error;
1153 }
1154
1155 template<class T, class Method>
1156 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
1157 SendParam send_params;
1158 void* iter = GetDataIterator(msg);
1159 Message* reply = GenerateReply(msg);
1160 bool error;
1161 if (ReadParam(msg, &iter, &send_params)) {
1162 Tuple1<Message&> t = MakeRefTuple(*reply);
1163
1164 #ifdef IPC_MESSAGE_LOG_ENABLED
1165 if (msg->sent_time()) {
1166 // Don't log the sync message after dispatch, as we don't have the
1167 // output parameters at that point. Instead, save its data and log it
1168 // with the outgoing reply message when it's sent.
1169 LogData* data = new LogData;
1170 GenerateLogData("", *msg, data);
1171 msg->set_dont_log();
1172 reply->set_sync_log_data(data);
1173 }
1174 #endif
1175 DispatchToMethod(obj, func, send_params, &t);
1176 error = false;
1177 } else {
1178 NOTREACHED() << "Error deserializing message " << msg->type();
1179 reply->set_reply_error();
1180 obj->Send(reply);
1181 error = true;
1182 }
1183 return !error;
1184 }
1185
1186 template<typename TA>
1187 static void WriteReplyParams(Message* reply, TA a) {
1188 ReplyParam p(a);
1189 WriteParam(reply, p);
1190 }
1191
1192 template<typename TA, typename TB>
1193 static void WriteReplyParams(Message* reply, TA a, TB b) {
1194 ReplyParam p(a, b);
1195 WriteParam(reply, p);
1196 }
1197
1198 template<typename TA, typename TB, typename TC>
1199 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1200 ReplyParam p(a, b, c);
1201 WriteParam(reply, p);
1202 }
1203
1204 template<typename TA, typename TB, typename TC, typename TD>
1205 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1206 ReplyParam p(a, b, c, d);
1207 WriteParam(reply, p);
1208 }
1209
1210 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1211 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1212 ReplyParam p(a, b, c, d, e);
1213 WriteParam(reply, p);
1214 }
1215 };
1216
1217 //-----------------------------------------------------------------------------
1218
1219 } // namespace IPC
1220
1221 #endif // IPC_IPC_MESSAGE_UTILS_H_
OLDNEW
« no previous file with comments | « ipc/ipc_message_unittest.cc ('k') | ipc/ipc_message_utils.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698