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