disable ImageBackgroundFilter.BackgroundFilterRotated_GL cc_unittests on Dr.Memory...
[chromium-blink-merge.git] / ipc / ipc_message_utils.cc
blob3670497ae00dd7a5df66f4c153e38a2228bc68b1
1 // Copyright (c) 2012 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.
5 #include "ipc/ipc_message_utils.h"
7 #include "base/files/file_path.h"
8 #include "base/json/json_writer.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/strings/nullable_string16.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/time/time.h"
14 #include "base/values.h"
15 #include "ipc/ipc_channel_handle.h"
16 #include "ipc/ipc_message_attachment.h"
17 #include "ipc/ipc_message_attachment_set.h"
19 #if defined(OS_POSIX)
20 #include "ipc/ipc_platform_file_attachment_posix.h"
21 #endif
23 #if defined(OS_MACOSX) && !defined(OS_IOS)
24 #include "base/memory/shared_memory_handle.h"
25 #endif // defined(OS_MACOSX) && !defined(OS_IOS)
27 #if defined(OS_WIN)
28 #include <tchar.h>
29 #endif
31 namespace IPC {
33 namespace {
35 const int kMaxRecursionDepth = 100;
37 template<typename CharType>
38 void LogBytes(const std::vector<CharType>& data, std::string* out) {
39 #if defined(OS_WIN)
40 // Windows has a GUI for logging, which can handle arbitrary binary data.
41 for (size_t i = 0; i < data.size(); ++i)
42 out->push_back(data[i]);
43 #else
44 // On POSIX, we log to stdout, which we assume can display ASCII.
45 static const size_t kMaxBytesToLog = 100;
46 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
47 if (isprint(data[i]))
48 out->push_back(data[i]);
49 else
50 out->append(
51 base::StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
53 if (data.size() > kMaxBytesToLog) {
54 out->append(base::StringPrintf(
55 " and %u more bytes",
56 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
58 #endif
61 bool ReadValue(const Message* m,
62 base::PickleIterator* iter,
63 base::Value** value,
64 int recursion);
66 void WriteValue(Message* m, const base::Value* value, int recursion) {
67 bool result;
68 if (recursion > kMaxRecursionDepth) {
69 LOG(WARNING) << "Max recursion depth hit in WriteValue.";
70 return;
73 m->WriteInt(value->GetType());
75 switch (value->GetType()) {
76 case base::Value::TYPE_NULL:
77 break;
78 case base::Value::TYPE_BOOLEAN: {
79 bool val;
80 result = value->GetAsBoolean(&val);
81 DCHECK(result);
82 WriteParam(m, val);
83 break;
85 case base::Value::TYPE_INTEGER: {
86 int val;
87 result = value->GetAsInteger(&val);
88 DCHECK(result);
89 WriteParam(m, val);
90 break;
92 case base::Value::TYPE_DOUBLE: {
93 double val;
94 result = value->GetAsDouble(&val);
95 DCHECK(result);
96 WriteParam(m, val);
97 break;
99 case base::Value::TYPE_STRING: {
100 std::string val;
101 result = value->GetAsString(&val);
102 DCHECK(result);
103 WriteParam(m, val);
104 break;
106 case base::Value::TYPE_BINARY: {
107 const base::BinaryValue* binary =
108 static_cast<const base::BinaryValue*>(value);
109 m->WriteData(binary->GetBuffer(), static_cast<int>(binary->GetSize()));
110 break;
112 case base::Value::TYPE_DICTIONARY: {
113 const base::DictionaryValue* dict =
114 static_cast<const base::DictionaryValue*>(value);
116 WriteParam(m, static_cast<int>(dict->size()));
118 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd();
119 it.Advance()) {
120 WriteParam(m, it.key());
121 WriteValue(m, &it.value(), recursion + 1);
123 break;
125 case base::Value::TYPE_LIST: {
126 const base::ListValue* list = static_cast<const base::ListValue*>(value);
127 WriteParam(m, static_cast<int>(list->GetSize()));
128 for (base::ListValue::const_iterator it = list->begin();
129 it != list->end(); ++it) {
130 WriteValue(m, *it, recursion + 1);
132 break;
137 // Helper for ReadValue that reads a DictionaryValue into a pre-allocated
138 // object.
139 bool ReadDictionaryValue(const Message* m,
140 base::PickleIterator* iter,
141 base::DictionaryValue* value,
142 int recursion) {
143 int size;
144 if (!ReadParam(m, iter, &size))
145 return false;
147 for (int i = 0; i < size; ++i) {
148 std::string key;
149 base::Value* subval;
150 if (!ReadParam(m, iter, &key) ||
151 !ReadValue(m, iter, &subval, recursion + 1))
152 return false;
153 value->SetWithoutPathExpansion(key, subval);
156 return true;
159 // Helper for ReadValue that reads a ReadListValue into a pre-allocated
160 // object.
161 bool ReadListValue(const Message* m,
162 base::PickleIterator* iter,
163 base::ListValue* value,
164 int recursion) {
165 int size;
166 if (!ReadParam(m, iter, &size))
167 return false;
169 for (int i = 0; i < size; ++i) {
170 base::Value* subval;
171 if (!ReadValue(m, iter, &subval, recursion + 1))
172 return false;
173 value->Set(i, subval);
176 return true;
179 bool ReadValue(const Message* m,
180 base::PickleIterator* iter,
181 base::Value** value,
182 int recursion) {
183 if (recursion > kMaxRecursionDepth) {
184 LOG(WARNING) << "Max recursion depth hit in ReadValue.";
185 return false;
188 int type;
189 if (!ReadParam(m, iter, &type))
190 return false;
192 switch (type) {
193 case base::Value::TYPE_NULL:
194 *value = base::Value::CreateNullValue().release();
195 break;
196 case base::Value::TYPE_BOOLEAN: {
197 bool val;
198 if (!ReadParam(m, iter, &val))
199 return false;
200 *value = new base::FundamentalValue(val);
201 break;
203 case base::Value::TYPE_INTEGER: {
204 int val;
205 if (!ReadParam(m, iter, &val))
206 return false;
207 *value = new base::FundamentalValue(val);
208 break;
210 case base::Value::TYPE_DOUBLE: {
211 double val;
212 if (!ReadParam(m, iter, &val))
213 return false;
214 *value = new base::FundamentalValue(val);
215 break;
217 case base::Value::TYPE_STRING: {
218 std::string val;
219 if (!ReadParam(m, iter, &val))
220 return false;
221 *value = new base::StringValue(val);
222 break;
224 case base::Value::TYPE_BINARY: {
225 const char* data;
226 int length;
227 if (!iter->ReadData(&data, &length))
228 return false;
229 *value = base::BinaryValue::CreateWithCopiedBuffer(data, length);
230 break;
232 case base::Value::TYPE_DICTIONARY: {
233 scoped_ptr<base::DictionaryValue> val(new base::DictionaryValue());
234 if (!ReadDictionaryValue(m, iter, val.get(), recursion))
235 return false;
236 *value = val.release();
237 break;
239 case base::Value::TYPE_LIST: {
240 scoped_ptr<base::ListValue> val(new base::ListValue());
241 if (!ReadListValue(m, iter, val.get(), recursion))
242 return false;
243 *value = val.release();
244 break;
246 default:
247 return false;
250 return true;
253 } // namespace
255 // -----------------------------------------------------------------------------
257 LogData::LogData()
258 : routing_id(0),
259 type(0),
260 sent(0),
261 receive(0),
262 dispatch(0) {
265 LogData::~LogData() {
268 void ParamTraits<bool>::Log(const param_type& p, std::string* l) {
269 l->append(p ? "true" : "false");
272 void ParamTraits<unsigned char>::Write(Message* m, const param_type& p) {
273 m->WriteBytes(&p, sizeof(param_type));
276 bool ParamTraits<unsigned char>::Read(const Message* m,
277 base::PickleIterator* iter,
278 param_type* r) {
279 const char* data;
280 if (!iter->ReadBytes(&data, sizeof(param_type)))
281 return false;
282 memcpy(r, data, sizeof(param_type));
283 return true;
286 void ParamTraits<unsigned char>::Log(const param_type& p, std::string* l) {
287 l->append(base::UintToString(p));
290 void ParamTraits<unsigned short>::Write(Message* m, const param_type& p) {
291 m->WriteBytes(&p, sizeof(param_type));
294 bool ParamTraits<unsigned short>::Read(const Message* m,
295 base::PickleIterator* iter,
296 param_type* r) {
297 const char* data;
298 if (!iter->ReadBytes(&data, sizeof(param_type)))
299 return false;
300 memcpy(r, data, sizeof(param_type));
301 return true;
304 void ParamTraits<unsigned short>::Log(const param_type& p, std::string* l) {
305 l->append(base::UintToString(p));
308 void ParamTraits<int>::Log(const param_type& p, std::string* l) {
309 l->append(base::IntToString(p));
312 void ParamTraits<unsigned int>::Log(const param_type& p, std::string* l) {
313 l->append(base::UintToString(p));
316 void ParamTraits<long>::Log(const param_type& p, std::string* l) {
317 l->append(base::Int64ToString(static_cast<int64>(p)));
320 void ParamTraits<unsigned long>::Log(const param_type& p, std::string* l) {
321 l->append(base::Uint64ToString(static_cast<uint64>(p)));
324 void ParamTraits<long long>::Log(const param_type& p, std::string* l) {
325 l->append(base::Int64ToString(static_cast<int64>(p)));
328 void ParamTraits<unsigned long long>::Log(const param_type& p, std::string* l) {
329 l->append(base::Uint64ToString(p));
332 void ParamTraits<float>::Log(const param_type& p, std::string* l) {
333 l->append(base::StringPrintf("%e", p));
336 void ParamTraits<double>::Write(Message* m, const param_type& p) {
337 m->WriteBytes(reinterpret_cast<const char*>(&p), sizeof(param_type));
340 bool ParamTraits<double>::Read(const Message* m,
341 base::PickleIterator* iter,
342 param_type* r) {
343 const char *data;
344 if (!iter->ReadBytes(&data, sizeof(*r))) {
345 NOTREACHED();
346 return false;
348 memcpy(r, data, sizeof(param_type));
349 return true;
352 void ParamTraits<double>::Log(const param_type& p, std::string* l) {
353 l->append(base::StringPrintf("%e", p));
357 void ParamTraits<std::string>::Log(const param_type& p, std::string* l) {
358 l->append(p);
361 void ParamTraits<base::string16>::Log(const param_type& p, std::string* l) {
362 l->append(base::UTF16ToUTF8(p));
365 void ParamTraits<std::vector<char> >::Write(Message* m, const param_type& p) {
366 if (p.empty()) {
367 m->WriteData(NULL, 0);
368 } else {
369 m->WriteData(&p.front(), static_cast<int>(p.size()));
373 bool ParamTraits<std::vector<char>>::Read(const Message* m,
374 base::PickleIterator* iter,
375 param_type* r) {
376 const char *data;
377 int data_size = 0;
378 if (!iter->ReadData(&data, &data_size) || data_size < 0)
379 return false;
380 r->resize(data_size);
381 if (data_size)
382 memcpy(&r->front(), data, data_size);
383 return true;
386 void ParamTraits<std::vector<char> >::Log(const param_type& p, std::string* l) {
387 LogBytes(p, l);
390 void ParamTraits<std::vector<unsigned char> >::Write(Message* m,
391 const param_type& p) {
392 if (p.empty()) {
393 m->WriteData(NULL, 0);
394 } else {
395 m->WriteData(reinterpret_cast<const char*>(&p.front()),
396 static_cast<int>(p.size()));
400 bool ParamTraits<std::vector<unsigned char>>::Read(const Message* m,
401 base::PickleIterator* iter,
402 param_type* r) {
403 const char *data;
404 int data_size = 0;
405 if (!iter->ReadData(&data, &data_size) || data_size < 0)
406 return false;
407 r->resize(data_size);
408 if (data_size)
409 memcpy(&r->front(), data, data_size);
410 return true;
413 void ParamTraits<std::vector<unsigned char> >::Log(const param_type& p,
414 std::string* l) {
415 LogBytes(p, l);
418 void ParamTraits<std::vector<bool> >::Write(Message* m, const param_type& p) {
419 WriteParam(m, static_cast<int>(p.size()));
420 // Cast to bool below is required because libc++'s
421 // vector<bool>::const_reference is different from bool, and we want to avoid
422 // writing an extra specialization of ParamTraits for it.
423 for (size_t i = 0; i < p.size(); i++)
424 WriteParam(m, static_cast<bool>(p[i]));
427 bool ParamTraits<std::vector<bool>>::Read(const Message* m,
428 base::PickleIterator* iter,
429 param_type* r) {
430 int size;
431 // ReadLength() checks for < 0 itself.
432 if (!iter->ReadLength(&size))
433 return false;
434 r->resize(size);
435 for (int i = 0; i < size; i++) {
436 bool value;
437 if (!ReadParam(m, iter, &value))
438 return false;
439 (*r)[i] = value;
441 return true;
444 void ParamTraits<std::vector<bool> >::Log(const param_type& p, std::string* l) {
445 for (size_t i = 0; i < p.size(); ++i) {
446 if (i != 0)
447 l->push_back(' ');
448 LogParam(static_cast<bool>(p[i]), l);
452 void ParamTraits<BrokerableAttachment::AttachmentId>::Write(
453 Message* m,
454 const param_type& p) {
455 m->WriteBytes(p.nonce, static_cast<int>(BrokerableAttachment::kNonceSize));
458 bool ParamTraits<BrokerableAttachment::AttachmentId>::Read(
459 const Message* m,
460 base::PickleIterator* iter,
461 param_type* r) {
462 const char* data;
463 if (!iter->ReadBytes(&data,
464 static_cast<int>(BrokerableAttachment::kNonceSize))) {
465 return false;
467 memcpy(r->nonce, data, BrokerableAttachment::kNonceSize);
468 return true;
471 void ParamTraits<BrokerableAttachment::AttachmentId>::Log(const param_type& p,
472 std::string* l) {
473 l->append(base::HexEncode(p.nonce, BrokerableAttachment::kNonceSize));
476 void ParamTraits<base::DictionaryValue>::Write(Message* m,
477 const param_type& p) {
478 WriteValue(m, &p, 0);
481 bool ParamTraits<base::DictionaryValue>::Read(const Message* m,
482 base::PickleIterator* iter,
483 param_type* r) {
484 int type;
485 if (!ReadParam(m, iter, &type) || type != base::Value::TYPE_DICTIONARY)
486 return false;
488 return ReadDictionaryValue(m, iter, r, 0);
491 void ParamTraits<base::DictionaryValue>::Log(const param_type& p,
492 std::string* l) {
493 std::string json;
494 base::JSONWriter::Write(p, &json);
495 l->append(json);
498 #if defined(OS_POSIX)
499 void ParamTraits<base::FileDescriptor>::Write(Message* m, const param_type& p) {
500 const bool valid = p.fd >= 0;
501 WriteParam(m, valid);
503 if (!valid)
504 return;
506 if (p.auto_close) {
507 if (!m->WriteAttachment(
508 new internal::PlatformFileAttachment(base::ScopedFD(p.fd))))
509 NOTREACHED();
510 } else {
511 if (!m->WriteAttachment(new internal::PlatformFileAttachment(p.fd)))
512 NOTREACHED();
516 bool ParamTraits<base::FileDescriptor>::Read(const Message* m,
517 base::PickleIterator* iter,
518 param_type* r) {
519 *r = base::FileDescriptor();
521 bool valid;
522 if (!ReadParam(m, iter, &valid))
523 return false;
525 // TODO(morrita): Seems like this should return false.
526 if (!valid)
527 return true;
529 scoped_refptr<MessageAttachment> attachment;
530 if (!m->ReadAttachment(iter, &attachment))
531 return false;
533 *r = base::FileDescriptor(attachment->TakePlatformFile(), true);
534 return true;
537 void ParamTraits<base::FileDescriptor>::Log(const param_type& p,
538 std::string* l) {
539 if (p.auto_close) {
540 l->append(base::StringPrintf("FD(%d auto-close)", p.fd));
541 } else {
542 l->append(base::StringPrintf("FD(%d)", p.fd));
545 #endif // defined(OS_POSIX)
547 #if defined(OS_MACOSX) && !defined(OS_IOS)
548 void ParamTraits<base::SharedMemoryHandle>::Write(Message* m,
549 const param_type& p) {
550 m->WriteInt(p.GetType());
552 if (p.GetType() == base::SharedMemoryHandle::POSIX)
553 ParamTraits<base::FileDescriptor>::Write(m, p.GetFileDescriptor());
556 bool ParamTraits<base::SharedMemoryHandle>::Read(const Message* m,
557 base::PickleIterator* iter,
558 param_type* r) {
559 base::SharedMemoryHandle::TypeWireFormat type;
560 if (!iter->ReadInt(&type))
561 return false;
563 base::SharedMemoryHandle::Type shm_type = base::SharedMemoryHandle::POSIX;
564 switch (type) {
565 case base::SharedMemoryHandle::POSIX:
566 case base::SharedMemoryHandle::MACH: {
567 shm_type = static_cast<base::SharedMemoryHandle::Type>(type);
568 break;
570 default:
571 return false;
574 if (shm_type == base::SharedMemoryHandle::POSIX) {
575 base::FileDescriptor file_descriptor;
577 bool success =
578 ParamTraits<base::FileDescriptor>::Read(m, iter, &file_descriptor);
579 if (!success)
580 return false;
582 *r = base::SharedMemoryHandle(file_descriptor.fd,
583 file_descriptor.auto_close);
584 return true;
587 return true;
590 void ParamTraits<base::SharedMemoryHandle>::Log(const param_type& p,
591 std::string* l) {
592 if (p.GetType() == base::SharedMemoryHandle::POSIX) {
593 l->append(base::StringPrintf("Mechanism POSIX Fd"));
594 ParamTraits<base::FileDescriptor>::Log(p.GetFileDescriptor(), l);
597 #endif // defined(OS_MACOSX) && !defined(OS_IOS)
599 void ParamTraits<base::FilePath>::Write(Message* m, const param_type& p) {
600 p.WriteToPickle(m);
603 bool ParamTraits<base::FilePath>::Read(const Message* m,
604 base::PickleIterator* iter,
605 param_type* r) {
606 return r->ReadFromPickle(iter);
609 void ParamTraits<base::FilePath>::Log(const param_type& p, std::string* l) {
610 ParamTraits<base::FilePath::StringType>::Log(p.value(), l);
613 void ParamTraits<base::ListValue>::Write(Message* m, const param_type& p) {
614 WriteValue(m, &p, 0);
617 bool ParamTraits<base::ListValue>::Read(const Message* m,
618 base::PickleIterator* iter,
619 param_type* r) {
620 int type;
621 if (!ReadParam(m, iter, &type) || type != base::Value::TYPE_LIST)
622 return false;
624 return ReadListValue(m, iter, r, 0);
627 void ParamTraits<base::ListValue>::Log(const param_type& p, std::string* l) {
628 std::string json;
629 base::JSONWriter::Write(p, &json);
630 l->append(json);
633 void ParamTraits<base::NullableString16>::Write(Message* m,
634 const param_type& p) {
635 WriteParam(m, p.string());
636 WriteParam(m, p.is_null());
639 bool ParamTraits<base::NullableString16>::Read(const Message* m,
640 base::PickleIterator* iter,
641 param_type* r) {
642 base::string16 string;
643 if (!ReadParam(m, iter, &string))
644 return false;
645 bool is_null;
646 if (!ReadParam(m, iter, &is_null))
647 return false;
648 *r = base::NullableString16(string, is_null);
649 return true;
652 void ParamTraits<base::NullableString16>::Log(const param_type& p,
653 std::string* l) {
654 l->append("(");
655 LogParam(p.string(), l);
656 l->append(", ");
657 LogParam(p.is_null(), l);
658 l->append(")");
661 void ParamTraits<base::File::Info>::Write(Message* m,
662 const param_type& p) {
663 WriteParam(m, p.size);
664 WriteParam(m, p.is_directory);
665 WriteParam(m, p.last_modified.ToDoubleT());
666 WriteParam(m, p.last_accessed.ToDoubleT());
667 WriteParam(m, p.creation_time.ToDoubleT());
670 bool ParamTraits<base::File::Info>::Read(const Message* m,
671 base::PickleIterator* iter,
672 param_type* p) {
673 double last_modified, last_accessed, creation_time;
674 if (!ReadParam(m, iter, &p->size) ||
675 !ReadParam(m, iter, &p->is_directory) ||
676 !ReadParam(m, iter, &last_modified) ||
677 !ReadParam(m, iter, &last_accessed) ||
678 !ReadParam(m, iter, &creation_time))
679 return false;
680 p->last_modified = base::Time::FromDoubleT(last_modified);
681 p->last_accessed = base::Time::FromDoubleT(last_accessed);
682 p->creation_time = base::Time::FromDoubleT(creation_time);
683 return true;
686 void ParamTraits<base::File::Info>::Log(const param_type& p,
687 std::string* l) {
688 l->append("(");
689 LogParam(p.size, l);
690 l->append(",");
691 LogParam(p.is_directory, l);
692 l->append(",");
693 LogParam(p.last_modified.ToDoubleT(), l);
694 l->append(",");
695 LogParam(p.last_accessed.ToDoubleT(), l);
696 l->append(",");
697 LogParam(p.creation_time.ToDoubleT(), l);
698 l->append(")");
701 void ParamTraits<base::Time>::Write(Message* m, const param_type& p) {
702 ParamTraits<int64>::Write(m, p.ToInternalValue());
705 bool ParamTraits<base::Time>::Read(const Message* m,
706 base::PickleIterator* iter,
707 param_type* r) {
708 int64 value;
709 if (!ParamTraits<int64>::Read(m, iter, &value))
710 return false;
711 *r = base::Time::FromInternalValue(value);
712 return true;
715 void ParamTraits<base::Time>::Log(const param_type& p, std::string* l) {
716 ParamTraits<int64>::Log(p.ToInternalValue(), l);
719 void ParamTraits<base::TimeDelta>::Write(Message* m, const param_type& p) {
720 ParamTraits<int64>::Write(m, p.ToInternalValue());
723 bool ParamTraits<base::TimeDelta>::Read(const Message* m,
724 base::PickleIterator* iter,
725 param_type* r) {
726 int64 value;
727 bool ret = ParamTraits<int64>::Read(m, iter, &value);
728 if (ret)
729 *r = base::TimeDelta::FromInternalValue(value);
731 return ret;
734 void ParamTraits<base::TimeDelta>::Log(const param_type& p, std::string* l) {
735 ParamTraits<int64>::Log(p.ToInternalValue(), l);
738 void ParamTraits<base::TimeTicks>::Write(Message* m, const param_type& p) {
739 ParamTraits<int64>::Write(m, p.ToInternalValue());
742 bool ParamTraits<base::TimeTicks>::Read(const Message* m,
743 base::PickleIterator* iter,
744 param_type* r) {
745 int64 value;
746 bool ret = ParamTraits<int64>::Read(m, iter, &value);
747 if (ret)
748 *r = base::TimeTicks::FromInternalValue(value);
750 return ret;
753 void ParamTraits<base::TimeTicks>::Log(const param_type& p, std::string* l) {
754 ParamTraits<int64>::Log(p.ToInternalValue(), l);
757 void ParamTraits<base::TraceTicks>::Write(Message* m, const param_type& p) {
758 ParamTraits<int64>::Write(m, p.ToInternalValue());
761 bool ParamTraits<base::TraceTicks>::Read(const Message* m,
762 base::PickleIterator* iter,
763 param_type* r) {
764 int64 value;
765 bool ret = ParamTraits<int64>::Read(m, iter, &value);
766 if (ret)
767 *r = base::TraceTicks::FromInternalValue(value);
769 return ret;
772 void ParamTraits<base::TraceTicks>::Log(const param_type& p, std::string* l) {
773 ParamTraits<int64>::Log(p.ToInternalValue(), l);
776 void ParamTraits<IPC::ChannelHandle>::Write(Message* m, const param_type& p) {
777 #if defined(OS_WIN)
778 // On Windows marshalling pipe handle is not supported.
779 DCHECK(p.pipe.handle == NULL);
780 #endif // defined (OS_WIN)
781 WriteParam(m, p.name);
782 #if defined(OS_POSIX)
783 WriteParam(m, p.socket);
784 #endif
787 bool ParamTraits<IPC::ChannelHandle>::Read(const Message* m,
788 base::PickleIterator* iter,
789 param_type* r) {
790 return ReadParam(m, iter, &r->name)
791 #if defined(OS_POSIX)
792 && ReadParam(m, iter, &r->socket)
793 #endif
797 void ParamTraits<IPC::ChannelHandle>::Log(const param_type& p,
798 std::string* l) {
799 l->append(base::StringPrintf("ChannelHandle(%s", p.name.c_str()));
800 #if defined(OS_POSIX)
801 l->append(", ");
802 ParamTraits<base::FileDescriptor>::Log(p.socket, l);
803 #endif
804 l->append(")");
807 void ParamTraits<LogData>::Write(Message* m, const param_type& p) {
808 WriteParam(m, p.channel);
809 WriteParam(m, p.routing_id);
810 WriteParam(m, p.type);
811 WriteParam(m, p.flags);
812 WriteParam(m, p.sent);
813 WriteParam(m, p.receive);
814 WriteParam(m, p.dispatch);
815 WriteParam(m, p.message_name);
816 WriteParam(m, p.params);
819 bool ParamTraits<LogData>::Read(const Message* m,
820 base::PickleIterator* iter,
821 param_type* r) {
822 return
823 ReadParam(m, iter, &r->channel) &&
824 ReadParam(m, iter, &r->routing_id) &&
825 ReadParam(m, iter, &r->type) &&
826 ReadParam(m, iter, &r->flags) &&
827 ReadParam(m, iter, &r->sent) &&
828 ReadParam(m, iter, &r->receive) &&
829 ReadParam(m, iter, &r->dispatch) &&
830 ReadParam(m, iter, &r->message_name) &&
831 ReadParam(m, iter, &r->params);
834 void ParamTraits<LogData>::Log(const param_type& p, std::string* l) {
835 // Doesn't make sense to implement this!
838 void ParamTraits<Message>::Write(Message* m, const Message& p) {
839 #if defined(OS_POSIX)
840 // We don't serialize the file descriptors in the nested message, so there
841 // better not be any.
842 DCHECK(!p.HasAttachments());
843 #endif
845 // Don't just write out the message. This is used to send messages between
846 // NaCl (Posix environment) and the browser (could be on Windows). The message
847 // header formats differ between these systems (so does handle sharing, but
848 // we already asserted we don't have any handles). So just write out the
849 // parts of the header we use.
851 // Be careful also to use only explicitly-sized types. The NaCl environment
852 // could be 64-bit and the host browser could be 32-bits. The nested message
853 // may or may not be safe to send between 32-bit and 64-bit systems, but we
854 // leave that up to the code sending the message to ensure.
855 m->WriteUInt32(static_cast<uint32>(p.routing_id()));
856 m->WriteUInt32(p.type());
857 m->WriteUInt32(p.flags());
858 m->WriteData(p.payload(), static_cast<uint32>(p.payload_size()));
861 bool ParamTraits<Message>::Read(const Message* m,
862 base::PickleIterator* iter,
863 Message* r) {
864 uint32 routing_id, type, flags;
865 if (!iter->ReadUInt32(&routing_id) ||
866 !iter->ReadUInt32(&type) ||
867 !iter->ReadUInt32(&flags))
868 return false;
870 int payload_size;
871 const char* payload;
872 if (!iter->ReadData(&payload, &payload_size))
873 return false;
875 r->SetHeaderValues(static_cast<int32>(routing_id), type, flags);
876 return r->WriteBytes(payload, payload_size);
879 void ParamTraits<Message>::Log(const Message& p, std::string* l) {
880 l->append("<IPC::Message>");
883 #if defined(OS_WIN)
884 // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
885 // bit systems. That's why we use the Windows macros to convert to 32 bits.
886 void ParamTraits<HANDLE>::Write(Message* m, const param_type& p) {
887 m->WriteInt(HandleToLong(p));
890 bool ParamTraits<HANDLE>::Read(const Message* m,
891 base::PickleIterator* iter,
892 param_type* r) {
893 int32 temp;
894 if (!iter->ReadInt(&temp))
895 return false;
896 *r = LongToHandle(temp);
897 return true;
900 void ParamTraits<HANDLE>::Log(const param_type& p, std::string* l) {
901 l->append(base::StringPrintf("0x%X", p));
904 void ParamTraits<LOGFONT>::Write(Message* m, const param_type& p) {
905 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
908 bool ParamTraits<LOGFONT>::Read(const Message* m,
909 base::PickleIterator* iter,
910 param_type* r) {
911 const char *data;
912 int data_size = 0;
913 if (iter->ReadData(&data, &data_size) && data_size == sizeof(LOGFONT)) {
914 const LOGFONT *font = reinterpret_cast<LOGFONT*>(const_cast<char*>(data));
915 if (_tcsnlen(font->lfFaceName, LF_FACESIZE) < LF_FACESIZE) {
916 memcpy(r, data, sizeof(LOGFONT));
917 return true;
921 NOTREACHED();
922 return false;
925 void ParamTraits<LOGFONT>::Log(const param_type& p, std::string* l) {
926 l->append(base::StringPrintf("<LOGFONT>"));
929 void ParamTraits<MSG>::Write(Message* m, const param_type& p) {
930 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
933 bool ParamTraits<MSG>::Read(const Message* m,
934 base::PickleIterator* iter,
935 param_type* r) {
936 const char *data;
937 int data_size = 0;
938 bool result = iter->ReadData(&data, &data_size);
939 if (result && data_size == sizeof(MSG)) {
940 memcpy(r, data, sizeof(MSG));
941 } else {
942 result = false;
943 NOTREACHED();
946 return result;
949 void ParamTraits<MSG>::Log(const param_type& p, std::string* l) {
950 l->append("<MSG>");
953 #endif // OS_WIN
955 } // namespace IPC