Create a new-installs-only uniformity trial.
[chromium-blink-merge.git] / ipc / ipc_message_utils.cc
blob3ce9be53b3672cf1b9f1642bb39b64d326140aaa
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/file_path.h"
8 #include "base/json/json_writer.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/nullable_string16.h"
11 #include "base/string_number_conversions.h"
12 #include "base/time.h"
13 #include "base/utf_string_conversions.h"
14 #include "base/values.h"
15 #include "ipc/ipc_channel_handle.h"
17 #if defined(OS_POSIX)
18 #include "ipc/file_descriptor_set_posix.h"
19 #endif
21 namespace IPC {
23 namespace {
25 const int kMaxRecursionDepth = 100;
27 template<typename CharType>
28 void LogBytes(const std::vector<CharType>& data, std::string* out) {
29 #if defined(OS_WIN)
30 // Windows has a GUI for logging, which can handle arbitrary binary data.
31 for (size_t i = 0; i < data.size(); ++i)
32 out->push_back(data[i]);
33 #else
34 // On POSIX, we log to stdout, which we assume can display ASCII.
35 static const size_t kMaxBytesToLog = 100;
36 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
37 if (isprint(data[i]))
38 out->push_back(data[i]);
39 else
40 out->append(StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
42 if (data.size() > kMaxBytesToLog) {
43 out->append(
44 StringPrintf(" and %u more bytes",
45 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
47 #endif
50 bool ReadValue(const Message* m, PickleIterator* iter, Value** value,
51 int recursion);
53 void WriteValue(Message* m, const Value* value, int recursion) {
54 bool result;
55 if (recursion > kMaxRecursionDepth) {
56 LOG(WARNING) << "Max recursion depth hit in WriteValue.";
57 return;
60 m->WriteInt(value->GetType());
62 switch (value->GetType()) {
63 case Value::TYPE_NULL:
64 break;
65 case Value::TYPE_BOOLEAN: {
66 bool val;
67 result = value->GetAsBoolean(&val);
68 DCHECK(result);
69 WriteParam(m, val);
70 break;
72 case Value::TYPE_INTEGER: {
73 int val;
74 result = value->GetAsInteger(&val);
75 DCHECK(result);
76 WriteParam(m, val);
77 break;
79 case Value::TYPE_DOUBLE: {
80 double val;
81 result = value->GetAsDouble(&val);
82 DCHECK(result);
83 WriteParam(m, val);
84 break;
86 case Value::TYPE_STRING: {
87 std::string val;
88 result = value->GetAsString(&val);
89 DCHECK(result);
90 WriteParam(m, val);
91 break;
93 case Value::TYPE_BINARY: {
94 const base::BinaryValue* binary =
95 static_cast<const base::BinaryValue*>(value);
96 m->WriteData(binary->GetBuffer(), static_cast<int>(binary->GetSize()));
97 break;
99 case Value::TYPE_DICTIONARY: {
100 const DictionaryValue* dict = static_cast<const DictionaryValue*>(value);
102 WriteParam(m, static_cast<int>(dict->size()));
104 for (DictionaryValue::key_iterator it = dict->begin_keys();
105 it != dict->end_keys(); ++it) {
106 const Value* subval;
107 if (dict->GetWithoutPathExpansion(*it, &subval)) {
108 WriteParam(m, *it);
109 WriteValue(m, subval, recursion + 1);
110 } else {
111 NOTREACHED() << "DictionaryValue iterators are filthy liars.";
114 break;
116 case Value::TYPE_LIST: {
117 const ListValue* list = static_cast<const ListValue*>(value);
118 WriteParam(m, static_cast<int>(list->GetSize()));
119 for (size_t i = 0; i < list->GetSize(); ++i) {
120 const Value* subval;
121 if (list->Get(i, &subval)) {
122 WriteValue(m, subval, recursion + 1);
123 } else {
124 NOTREACHED() << "ListValue::GetSize is a filthy liar.";
127 break;
132 // Helper for ReadValue that reads a DictionaryValue into a pre-allocated
133 // object.
134 bool ReadDictionaryValue(const Message* m, PickleIterator* iter,
135 DictionaryValue* value, int recursion) {
136 int size;
137 if (!ReadParam(m, iter, &size))
138 return false;
140 for (int i = 0; i < size; ++i) {
141 std::string key;
142 Value* subval;
143 if (!ReadParam(m, iter, &key) ||
144 !ReadValue(m, iter, &subval, recursion + 1))
145 return false;
146 value->SetWithoutPathExpansion(key, subval);
149 return true;
152 // Helper for ReadValue that reads a ReadListValue into a pre-allocated
153 // object.
154 bool ReadListValue(const Message* m, PickleIterator* iter,
155 ListValue* value, int recursion) {
156 int size;
157 if (!ReadParam(m, iter, &size))
158 return false;
160 for (int i = 0; i < size; ++i) {
161 Value* subval;
162 if (!ReadValue(m, iter, &subval, recursion + 1))
163 return false;
164 value->Set(i, subval);
167 return true;
170 bool ReadValue(const Message* m, PickleIterator* iter, Value** value,
171 int recursion) {
172 if (recursion > kMaxRecursionDepth) {
173 LOG(WARNING) << "Max recursion depth hit in ReadValue.";
174 return false;
177 int type;
178 if (!ReadParam(m, iter, &type))
179 return false;
181 switch (type) {
182 case Value::TYPE_NULL:
183 *value = Value::CreateNullValue();
184 break;
185 case Value::TYPE_BOOLEAN: {
186 bool val;
187 if (!ReadParam(m, iter, &val))
188 return false;
189 *value = Value::CreateBooleanValue(val);
190 break;
192 case Value::TYPE_INTEGER: {
193 int val;
194 if (!ReadParam(m, iter, &val))
195 return false;
196 *value = Value::CreateIntegerValue(val);
197 break;
199 case Value::TYPE_DOUBLE: {
200 double val;
201 if (!ReadParam(m, iter, &val))
202 return false;
203 *value = Value::CreateDoubleValue(val);
204 break;
206 case Value::TYPE_STRING: {
207 std::string val;
208 if (!ReadParam(m, iter, &val))
209 return false;
210 *value = Value::CreateStringValue(val);
211 break;
213 case Value::TYPE_BINARY: {
214 const char* data;
215 int length;
216 if (!m->ReadData(iter, &data, &length))
217 return false;
218 *value = base::BinaryValue::CreateWithCopiedBuffer(data, length);
219 break;
221 case Value::TYPE_DICTIONARY: {
222 scoped_ptr<DictionaryValue> val(new DictionaryValue());
223 if (!ReadDictionaryValue(m, iter, val.get(), recursion))
224 return false;
225 *value = val.release();
226 break;
228 case Value::TYPE_LIST: {
229 scoped_ptr<ListValue> val(new ListValue());
230 if (!ReadListValue(m, iter, val.get(), recursion))
231 return false;
232 *value = val.release();
233 break;
235 default:
236 return false;
239 return true;
242 } // namespace
244 // -----------------------------------------------------------------------------
246 LogData::LogData()
247 : routing_id(0),
248 type(0),
249 sent(0),
250 receive(0),
251 dispatch(0) {
254 LogData::~LogData() {
257 MessageIterator::MessageIterator(const Message& m) : iter_(m) {
260 int MessageIterator::NextInt() const {
261 int val = -1;
262 if (!iter_.ReadInt(&val))
263 NOTREACHED();
264 return val;
267 const std::string MessageIterator::NextString() const {
268 std::string val;
269 if (!iter_.ReadString(&val))
270 NOTREACHED();
271 return val;
274 void ParamTraits<bool>::Log(const param_type& p, std::string* l) {
275 l->append(p ? "true" : "false");
278 void ParamTraits<int>::Log(const param_type& p, std::string* l) {
279 l->append(base::IntToString(p));
282 void ParamTraits<unsigned int>::Log(const param_type& p, std::string* l) {
283 l->append(base::UintToString(p));
286 void ParamTraits<long>::Log(const param_type& p, std::string* l) {
287 l->append(base::Int64ToString(static_cast<int64>(p)));
290 void ParamTraits<unsigned long>::Log(const param_type& p, std::string* l) {
291 l->append(base::Uint64ToString(static_cast<uint64>(p)));
294 void ParamTraits<long long>::Log(const param_type& p, std::string* l) {
295 l->append(base::Int64ToString(static_cast<int64>(p)));
298 void ParamTraits<unsigned long long>::Log(const param_type& p, std::string* l) {
299 l->append(base::Uint64ToString(p));
302 void ParamTraits<unsigned short>::Write(Message* m, const param_type& p) {
303 m->WriteBytes(&p, sizeof(param_type));
306 bool ParamTraits<unsigned short>::Read(const Message* m, PickleIterator* iter,
307 param_type* r) {
308 const char* data;
309 if (!m->ReadBytes(iter, &data, sizeof(param_type)))
310 return false;
311 memcpy(r, data, sizeof(param_type));
312 return true;
315 void ParamTraits<unsigned short>::Log(const param_type& p, std::string* l) {
316 l->append(base::UintToString(p));
319 void ParamTraits<float>::Write(Message* m, const param_type& p) {
320 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
323 bool ParamTraits<float>::Read(const Message* m, PickleIterator* iter,
324 param_type* r) {
325 const char *data;
326 int data_size;
327 if (!m->ReadData(iter, &data, &data_size) ||
328 data_size != sizeof(param_type)) {
329 NOTREACHED();
330 return false;
332 memcpy(r, data, sizeof(param_type));
333 return true;
336 void ParamTraits<float>::Log(const param_type& p, std::string* l) {
337 l->append(StringPrintf("%e", p));
340 void ParamTraits<double>::Write(Message* m, const param_type& p) {
341 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
344 bool ParamTraits<double>::Read(const Message* m, PickleIterator* iter,
345 param_type* r) {
346 const char *data;
347 int data_size;
348 if (!m->ReadData(iter, &data, &data_size) ||
349 data_size != sizeof(param_type)) {
350 NOTREACHED();
351 return false;
353 memcpy(r, data, sizeof(param_type));
354 return true;
357 void ParamTraits<double>::Log(const param_type& p, std::string* l) {
358 l->append(StringPrintf("%e", p));
362 void ParamTraits<std::string>::Log(const param_type& p, std::string* l) {
363 l->append(p);
366 void ParamTraits<std::wstring>::Log(const param_type& p, std::string* l) {
367 l->append(WideToUTF8(p));
370 #if !defined(WCHAR_T_IS_UTF16)
371 void ParamTraits<string16>::Log(const param_type& p, std::string* l) {
372 l->append(UTF16ToUTF8(p));
374 #endif
376 void ParamTraits<std::vector<char> >::Write(Message* m, const param_type& p) {
377 if (p.empty()) {
378 m->WriteData(NULL, 0);
379 } else {
380 m->WriteData(&p.front(), static_cast<int>(p.size()));
384 bool ParamTraits<std::vector<char> >::Read(const Message* m,
385 PickleIterator* iter,
386 param_type* r) {
387 const char *data;
388 int data_size = 0;
389 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
390 return false;
391 r->resize(data_size);
392 if (data_size)
393 memcpy(&r->front(), data, data_size);
394 return true;
397 void ParamTraits<std::vector<char> >::Log(const param_type& p, std::string* l) {
398 LogBytes(p, l);
401 void ParamTraits<std::vector<unsigned char> >::Write(Message* m,
402 const param_type& p) {
403 if (p.empty()) {
404 m->WriteData(NULL, 0);
405 } else {
406 m->WriteData(reinterpret_cast<const char*>(&p.front()),
407 static_cast<int>(p.size()));
411 bool ParamTraits<std::vector<unsigned char> >::Read(const Message* m,
412 PickleIterator* iter,
413 param_type* r) {
414 const char *data;
415 int data_size = 0;
416 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
417 return false;
418 r->resize(data_size);
419 if (data_size)
420 memcpy(&r->front(), data, data_size);
421 return true;
424 void ParamTraits<std::vector<unsigned char> >::Log(const param_type& p,
425 std::string* l) {
426 LogBytes(p, l);
429 void ParamTraits<std::vector<bool> >::Write(Message* m, const param_type& p) {
430 WriteParam(m, static_cast<int>(p.size()));
431 for (size_t i = 0; i < p.size(); i++)
432 WriteParam(m, p[i]);
435 bool ParamTraits<std::vector<bool> >::Read(const Message* m,
436 PickleIterator* iter,
437 param_type* r) {
438 int size;
439 // ReadLength() checks for < 0 itself.
440 if (!m->ReadLength(iter, &size))
441 return false;
442 r->resize(size);
443 for (int i = 0; i < size; i++) {
444 bool value;
445 if (!ReadParam(m, iter, &value))
446 return false;
447 (*r)[i] = value;
449 return true;
452 void ParamTraits<std::vector<bool> >::Log(const param_type& p, std::string* l) {
453 for (size_t i = 0; i < p.size(); ++i) {
454 if (i != 0)
455 l->push_back(' ');
456 LogParam((p[i]), l);
460 void ParamTraits<DictionaryValue>::Write(Message* m, const param_type& p) {
461 WriteValue(m, &p, 0);
464 bool ParamTraits<DictionaryValue>::Read(
465 const Message* m, PickleIterator* iter, param_type* r) {
466 int type;
467 if (!ReadParam(m, iter, &type) || type != Value::TYPE_DICTIONARY)
468 return false;
470 return ReadDictionaryValue(m, iter, r, 0);
473 void ParamTraits<DictionaryValue>::Log(const param_type& p, std::string* l) {
474 std::string json;
475 base::JSONWriter::Write(&p, &json);
476 l->append(json);
479 #if defined(OS_POSIX)
480 void ParamTraits<base::FileDescriptor>::Write(Message* m, const param_type& p) {
481 const bool valid = p.fd >= 0;
482 WriteParam(m, valid);
484 if (valid) {
485 if (!m->WriteFileDescriptor(p))
486 NOTREACHED();
490 bool ParamTraits<base::FileDescriptor>::Read(const Message* m,
491 PickleIterator* iter,
492 param_type* r) {
493 bool valid;
494 if (!ReadParam(m, iter, &valid))
495 return false;
497 if (!valid) {
498 r->fd = -1;
499 r->auto_close = false;
500 return true;
503 return m->ReadFileDescriptor(iter, r);
506 void ParamTraits<base::FileDescriptor>::Log(const param_type& p,
507 std::string* l) {
508 if (p.auto_close) {
509 l->append(StringPrintf("FD(%d auto-close)", p.fd));
510 } else {
511 l->append(StringPrintf("FD(%d)", p.fd));
514 #endif // defined(OS_POSIX)
516 void ParamTraits<FilePath>::Write(Message* m, const param_type& p) {
517 ParamTraits<FilePath::StringType>::Write(m, p.value());
520 bool ParamTraits<FilePath>::Read(const Message* m,
521 PickleIterator* iter,
522 param_type* r) {
523 FilePath::StringType value;
524 if (!ParamTraits<FilePath::StringType>::Read(m, iter, &value))
525 return false;
526 *r = FilePath(value);
527 return true;
530 void ParamTraits<FilePath>::Log(const param_type& p, std::string* l) {
531 ParamTraits<FilePath::StringType>::Log(p.value(), l);
534 void ParamTraits<ListValue>::Write(Message* m, const param_type& p) {
535 WriteValue(m, &p, 0);
538 bool ParamTraits<ListValue>::Read(
539 const Message* m, PickleIterator* iter, param_type* r) {
540 int type;
541 if (!ReadParam(m, iter, &type) || type != Value::TYPE_LIST)
542 return false;
544 return ReadListValue(m, iter, r, 0);
547 void ParamTraits<ListValue>::Log(const param_type& p, std::string* l) {
548 std::string json;
549 base::JSONWriter::Write(&p, &json);
550 l->append(json);
553 void ParamTraits<NullableString16>::Write(Message* m, const param_type& p) {
554 WriteParam(m, p.string());
555 WriteParam(m, p.is_null());
558 bool ParamTraits<NullableString16>::Read(const Message* m, PickleIterator* iter,
559 param_type* r) {
560 string16 string;
561 if (!ReadParam(m, iter, &string))
562 return false;
563 bool is_null;
564 if (!ReadParam(m, iter, &is_null))
565 return false;
566 *r = NullableString16(string, is_null);
567 return true;
570 void ParamTraits<NullableString16>::Log(const param_type& p, std::string* l) {
571 l->append("(");
572 LogParam(p.string(), l);
573 l->append(", ");
574 LogParam(p.is_null(), l);
575 l->append(")");
578 void ParamTraits<base::PlatformFileInfo>::Write(Message* m,
579 const param_type& p) {
580 WriteParam(m, p.size);
581 WriteParam(m, p.is_directory);
582 WriteParam(m, p.last_modified.ToDoubleT());
583 WriteParam(m, p.last_accessed.ToDoubleT());
584 WriteParam(m, p.creation_time.ToDoubleT());
587 bool ParamTraits<base::PlatformFileInfo>::Read(const Message* m,
588 PickleIterator* iter,
589 param_type* p) {
590 double last_modified;
591 double last_accessed;
592 double creation_time;
593 bool result =
594 ReadParam(m, iter, &p->size) &&
595 ReadParam(m, iter, &p->is_directory) &&
596 ReadParam(m, iter, &last_modified) &&
597 ReadParam(m, iter, &last_accessed) &&
598 ReadParam(m, iter, &creation_time);
599 if (result) {
600 p->last_modified = base::Time::FromDoubleT(last_modified);
601 p->last_accessed = base::Time::FromDoubleT(last_accessed);
602 p->creation_time = base::Time::FromDoubleT(creation_time);
604 return result;
607 void ParamTraits<base::PlatformFileInfo>::Log(const param_type& p,
608 std::string* l) {
609 l->append("(");
610 LogParam(p.size, l);
611 l->append(",");
612 LogParam(p.is_directory, l);
613 l->append(",");
614 LogParam(p.last_modified.ToDoubleT(), l);
615 l->append(",");
616 LogParam(p.last_accessed.ToDoubleT(), l);
617 l->append(",");
618 LogParam(p.creation_time.ToDoubleT(), l);
619 l->append(")");
622 void ParamTraits<base::Time>::Write(Message* m, const param_type& p) {
623 ParamTraits<int64>::Write(m, p.ToInternalValue());
626 bool ParamTraits<base::Time>::Read(const Message* m, PickleIterator* iter,
627 param_type* r) {
628 int64 value;
629 if (!ParamTraits<int64>::Read(m, iter, &value))
630 return false;
631 *r = base::Time::FromInternalValue(value);
632 return true;
635 void ParamTraits<base::Time>::Log(const param_type& p, std::string* l) {
636 ParamTraits<int64>::Log(p.ToInternalValue(), l);
639 void ParamTraits<base::TimeDelta>::Write(Message* m, const param_type& p) {
640 ParamTraits<int64>::Write(m, p.ToInternalValue());
643 bool ParamTraits<base::TimeDelta>::Read(const Message* m,
644 PickleIterator* iter,
645 param_type* r) {
646 int64 value;
647 bool ret = ParamTraits<int64>::Read(m, iter, &value);
648 if (ret)
649 *r = base::TimeDelta::FromInternalValue(value);
651 return ret;
654 void ParamTraits<base::TimeDelta>::Log(const param_type& p, std::string* l) {
655 ParamTraits<int64>::Log(p.ToInternalValue(), l);
658 void ParamTraits<base::TimeTicks>::Write(Message* m, const param_type& p) {
659 ParamTraits<int64>::Write(m, p.ToInternalValue());
662 bool ParamTraits<base::TimeTicks>::Read(const Message* m,
663 PickleIterator* iter,
664 param_type* r) {
665 int64 value;
666 bool ret = ParamTraits<int64>::Read(m, iter, &value);
667 if (ret)
668 *r = base::TimeTicks::FromInternalValue(value);
670 return ret;
673 void ParamTraits<base::TimeTicks>::Log(const param_type& p, std::string* l) {
674 ParamTraits<int64>::Log(p.ToInternalValue(), l);
677 void ParamTraits<IPC::ChannelHandle>::Write(Message* m, const param_type& p) {
678 #if defined(OS_WIN)
679 // On Windows marshalling pipe handle is not supported.
680 DCHECK(p.pipe.handle == NULL);
681 #endif // defined (OS_WIN)
682 WriteParam(m, p.name);
683 #if defined(OS_POSIX)
684 WriteParam(m, p.socket);
685 #endif
688 bool ParamTraits<IPC::ChannelHandle>::Read(const Message* m,
689 PickleIterator* iter,
690 param_type* r) {
691 return ReadParam(m, iter, &r->name)
692 #if defined(OS_POSIX)
693 && ReadParam(m, iter, &r->socket)
694 #endif
698 void ParamTraits<IPC::ChannelHandle>::Log(const param_type& p,
699 std::string* l) {
700 l->append(StringPrintf("ChannelHandle(%s", p.name.c_str()));
701 #if defined(OS_POSIX)
702 l->append(", ");
703 ParamTraits<base::FileDescriptor>::Log(p.socket, l);
704 #endif
705 l->append(")");
708 void ParamTraits<LogData>::Write(Message* m, const param_type& p) {
709 WriteParam(m, p.channel);
710 WriteParam(m, p.routing_id);
711 WriteParam(m, p.type);
712 WriteParam(m, p.flags);
713 WriteParam(m, p.sent);
714 WriteParam(m, p.receive);
715 WriteParam(m, p.dispatch);
716 WriteParam(m, p.params);
719 bool ParamTraits<LogData>::Read(const Message* m,
720 PickleIterator* iter,
721 param_type* r) {
722 return
723 ReadParam(m, iter, &r->channel) &&
724 ReadParam(m, iter, &r->routing_id) &&
725 ReadParam(m, iter, &r->type) &&
726 ReadParam(m, iter, &r->flags) &&
727 ReadParam(m, iter, &r->sent) &&
728 ReadParam(m, iter, &r->receive) &&
729 ReadParam(m, iter, &r->dispatch) &&
730 ReadParam(m, iter, &r->params);
733 void ParamTraits<LogData>::Log(const param_type& p, std::string* l) {
734 // Doesn't make sense to implement this!
737 void ParamTraits<Message>::Write(Message* m, const Message& p) {
738 #if defined(OS_POSIX)
739 // We don't serialize the file descriptors in the nested message, so there
740 // better not be any.
741 DCHECK(!p.HasFileDescriptors());
742 #endif
744 // Don't just write out the message. This is used to send messages between
745 // NaCl (Posix environment) and the browser (could be on Windows). The message
746 // header formats differ between these systems (so does handle sharing, but
747 // we already asserted we don't have any handles). So just write out the
748 // parts of the header we use.
750 // Be careful also to use only explicitly-sized types. The NaCl environment
751 // could be 64-bit and the host browser could be 32-bits. The nested message
752 // may or may not be safe to send between 32-bit and 64-bit systems, but we
753 // leave that up to the code sending the message to ensure.
754 m->WriteUInt32(static_cast<uint32>(p.routing_id()));
755 m->WriteUInt32(p.type());
756 m->WriteUInt32(p.flags());
757 m->WriteData(p.payload(), static_cast<uint32>(p.payload_size()));
760 bool ParamTraits<Message>::Read(const Message* m, PickleIterator* iter,
761 Message* r) {
762 uint32 routing_id, type, flags;
763 if (!m->ReadUInt32(iter, &routing_id) ||
764 !m->ReadUInt32(iter, &type) ||
765 !m->ReadUInt32(iter, &flags))
766 return false;
768 int payload_size;
769 const char* payload;
770 if (!m->ReadData(iter, &payload, &payload_size))
771 return false;
773 r->SetHeaderValues(static_cast<int32>(routing_id), type, flags);
774 return r->WriteBytes(payload, payload_size);
777 void ParamTraits<Message>::Log(const Message& p, std::string* l) {
778 l->append("<IPC::Message>");
781 #if defined(OS_WIN)
782 // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
783 // bit systems.
784 void ParamTraits<HANDLE>::Write(Message* m, const param_type& p) {
785 m->WriteUInt32(reinterpret_cast<uint32>(p));
788 bool ParamTraits<HANDLE>::Read(const Message* m, PickleIterator* iter,
789 param_type* r) {
790 uint32 temp;
791 if (!m->ReadUInt32(iter, &temp))
792 return false;
793 *r = reinterpret_cast<HANDLE>(temp);
794 return true;
797 void ParamTraits<HANDLE>::Log(const param_type& p, std::string* l) {
798 l->append(StringPrintf("0x%X", p));
801 void ParamTraits<LOGFONT>::Write(Message* m, const param_type& p) {
802 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
805 bool ParamTraits<LOGFONT>::Read(const Message* m, PickleIterator* iter,
806 param_type* r) {
807 const char *data;
808 int data_size = 0;
809 bool result = m->ReadData(iter, &data, &data_size);
810 if (result && data_size == sizeof(LOGFONT)) {
811 memcpy(r, data, sizeof(LOGFONT));
812 } else {
813 result = false;
814 NOTREACHED();
817 return result;
820 void ParamTraits<LOGFONT>::Log(const param_type& p, std::string* l) {
821 l->append(StringPrintf("<LOGFONT>"));
824 void ParamTraits<MSG>::Write(Message* m, const param_type& p) {
825 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
828 bool ParamTraits<MSG>::Read(const Message* m, PickleIterator* iter,
829 param_type* r) {
830 const char *data;
831 int data_size = 0;
832 bool result = m->ReadData(iter, &data, &data_size);
833 if (result && data_size == sizeof(MSG)) {
834 memcpy(r, data, sizeof(MSG));
835 } else {
836 result = false;
837 NOTREACHED();
840 return result;
843 void ParamTraits<MSG>::Log(const param_type& p, std::string* l) {
844 l->append("<MSG>");
847 #endif // OS_WIN
849 } // namespace IPC