• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "ipc/ipc_message_utils.h"
6 
7 #include <stddef.h>
8 #include <stdint.h>
9 
10 #include "base/files/file_path.h"
11 #include "base/json/json_writer.h"
12 #include "base/strings/nullable_string16.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "base/time/time.h"
16 #include "base/values.h"
17 #include "build/build_config.h"
18 #include "ipc/ipc_channel_handle.h"
19 #include "ipc/ipc_message_attachment.h"
20 #include "ipc/ipc_message_attachment_set.h"
21 #include "ipc/ipc_mojo_param_traits.h"
22 
23 #if defined(OS_POSIX)
24 #include "ipc/ipc_platform_file_attachment_posix.h"
25 #endif
26 
27 #if (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
28 #include "base/memory/shared_memory_handle.h"
29 #endif  // (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
30 
31 #if defined(OS_MACOSX) && !defined(OS_IOS)
32 #include "ipc/mach_port_mac.h"
33 #endif
34 
35 #if defined(OS_WIN)
36 #include <tchar.h>
37 #include "ipc/handle_win.h"
38 #endif
39 
40 namespace IPC {
41 
42 namespace {
43 
44 const int kMaxRecursionDepth = 100;
45 
46 template<typename CharType>
LogBytes(const std::vector<CharType> & data,std::string * out)47 void LogBytes(const std::vector<CharType>& data, std::string* out) {
48 #if defined(OS_WIN)
49   // Windows has a GUI for logging, which can handle arbitrary binary data.
50   for (size_t i = 0; i < data.size(); ++i)
51     out->push_back(data[i]);
52 #else
53   // On POSIX, we log to stdout, which we assume can display ASCII.
54   static const size_t kMaxBytesToLog = 100;
55   for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
56     if (isprint(data[i]))
57       out->push_back(data[i]);
58     else
59       out->append(
60           base::StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
61   }
62   if (data.size() > kMaxBytesToLog) {
63     out->append(base::StringPrintf(
64         " and %u more bytes",
65         static_cast<unsigned>(data.size() - kMaxBytesToLog)));
66   }
67 #endif
68 }
69 
70 bool ReadValue(const base::Pickle* m,
71                base::PickleIterator* iter,
72                base::Value** value,
73                int recursion);
74 
GetValueSize(base::PickleSizer * sizer,const base::Value * value,int recursion)75 void GetValueSize(base::PickleSizer* sizer,
76                   const base::Value* value,
77                   int recursion) {
78   if (recursion > kMaxRecursionDepth) {
79     LOG(WARNING) << "Max recursion depth hit in GetValueSize.";
80     return;
81   }
82 
83   sizer->AddInt();
84   switch (value->GetType()) {
85     case base::Value::TYPE_NULL:
86       break;
87     case base::Value::TYPE_BOOLEAN:
88       sizer->AddBool();
89       break;
90     case base::Value::TYPE_INTEGER:
91       sizer->AddInt();
92       break;
93     case base::Value::TYPE_DOUBLE:
94       sizer->AddDouble();
95       break;
96     case base::Value::TYPE_STRING: {
97       const base::StringValue* result;
98       value->GetAsString(&result);
99       if (value->GetAsString(&result)) {
100         DCHECK(result);
101         GetParamSize(sizer, result->GetString());
102       } else {
103         std::string str;
104         bool as_string_result = value->GetAsString(&str);
105         DCHECK(as_string_result);
106         GetParamSize(sizer, str);
107       }
108       break;
109     }
110     case base::Value::TYPE_BINARY: {
111       const base::BinaryValue* binary =
112           static_cast<const base::BinaryValue*>(value);
113       sizer->AddData(static_cast<int>(binary->GetSize()));
114       break;
115     }
116     case base::Value::TYPE_DICTIONARY: {
117       sizer->AddInt();
118       const base::DictionaryValue* dict =
119           static_cast<const base::DictionaryValue*>(value);
120       for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd();
121            it.Advance()) {
122         GetParamSize(sizer, it.key());
123         GetValueSize(sizer, &it.value(), recursion + 1);
124       }
125       break;
126     }
127     case base::Value::TYPE_LIST: {
128       sizer->AddInt();
129       const base::ListValue* list = static_cast<const base::ListValue*>(value);
130       for (const auto& entry : *list) {
131         GetValueSize(sizer, entry.get(), recursion + 1);
132       }
133       break;
134     }
135     default:
136       NOTREACHED() << "Invalid base::Value type.";
137   }
138 }
139 
WriteValue(base::Pickle * m,const base::Value * value,int recursion)140 void WriteValue(base::Pickle* m, const base::Value* value, int recursion) {
141   bool result;
142   if (recursion > kMaxRecursionDepth) {
143     LOG(WARNING) << "Max recursion depth hit in WriteValue.";
144     return;
145   }
146 
147   m->WriteInt(value->GetType());
148 
149   switch (value->GetType()) {
150     case base::Value::TYPE_NULL:
151     break;
152     case base::Value::TYPE_BOOLEAN: {
153       bool val;
154       result = value->GetAsBoolean(&val);
155       DCHECK(result);
156       WriteParam(m, val);
157       break;
158     }
159     case base::Value::TYPE_INTEGER: {
160       int val;
161       result = value->GetAsInteger(&val);
162       DCHECK(result);
163       WriteParam(m, val);
164       break;
165     }
166     case base::Value::TYPE_DOUBLE: {
167       double val;
168       result = value->GetAsDouble(&val);
169       DCHECK(result);
170       WriteParam(m, val);
171       break;
172     }
173     case base::Value::TYPE_STRING: {
174       std::string val;
175       result = value->GetAsString(&val);
176       DCHECK(result);
177       WriteParam(m, val);
178       break;
179     }
180     case base::Value::TYPE_BINARY: {
181       const base::BinaryValue* binary =
182           static_cast<const base::BinaryValue*>(value);
183       m->WriteData(binary->GetBuffer(), static_cast<int>(binary->GetSize()));
184       break;
185     }
186     case base::Value::TYPE_DICTIONARY: {
187       const base::DictionaryValue* dict =
188           static_cast<const base::DictionaryValue*>(value);
189 
190       WriteParam(m, static_cast<int>(dict->size()));
191 
192       for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd();
193            it.Advance()) {
194         WriteParam(m, it.key());
195         WriteValue(m, &it.value(), recursion + 1);
196       }
197       break;
198     }
199     case base::Value::TYPE_LIST: {
200       const base::ListValue* list = static_cast<const base::ListValue*>(value);
201       WriteParam(m, static_cast<int>(list->GetSize()));
202       for (const auto& entry : *list) {
203         WriteValue(m, entry.get(), recursion + 1);
204       }
205       break;
206     }
207   }
208 }
209 
210 // Helper for ReadValue that reads a DictionaryValue into a pre-allocated
211 // object.
ReadDictionaryValue(const base::Pickle * m,base::PickleIterator * iter,base::DictionaryValue * value,int recursion)212 bool ReadDictionaryValue(const base::Pickle* m,
213                          base::PickleIterator* iter,
214                          base::DictionaryValue* value,
215                          int recursion) {
216   int size;
217   if (!ReadParam(m, iter, &size))
218     return false;
219 
220   for (int i = 0; i < size; ++i) {
221     std::string key;
222     base::Value* subval;
223     if (!ReadParam(m, iter, &key) ||
224         !ReadValue(m, iter, &subval, recursion + 1))
225       return false;
226     value->SetWithoutPathExpansion(key, subval);
227   }
228 
229   return true;
230 }
231 
232 // Helper for ReadValue that reads a ReadListValue into a pre-allocated
233 // object.
ReadListValue(const base::Pickle * m,base::PickleIterator * iter,base::ListValue * value,int recursion)234 bool ReadListValue(const base::Pickle* m,
235                    base::PickleIterator* iter,
236                    base::ListValue* value,
237                    int recursion) {
238   int size;
239   if (!ReadParam(m, iter, &size))
240     return false;
241 
242   for (int i = 0; i < size; ++i) {
243     base::Value* subval;
244     if (!ReadValue(m, iter, &subval, recursion + 1))
245       return false;
246     value->Set(i, subval);
247   }
248 
249   return true;
250 }
251 
ReadValue(const base::Pickle * m,base::PickleIterator * iter,base::Value ** value,int recursion)252 bool ReadValue(const base::Pickle* m,
253                base::PickleIterator* iter,
254                base::Value** value,
255                int recursion) {
256   if (recursion > kMaxRecursionDepth) {
257     LOG(WARNING) << "Max recursion depth hit in ReadValue.";
258     return false;
259   }
260 
261   int type;
262   if (!ReadParam(m, iter, &type))
263     return false;
264 
265   switch (type) {
266     case base::Value::TYPE_NULL:
267       *value = base::Value::CreateNullValue().release();
268     break;
269     case base::Value::TYPE_BOOLEAN: {
270       bool val;
271       if (!ReadParam(m, iter, &val))
272         return false;
273       *value = new base::FundamentalValue(val);
274       break;
275     }
276     case base::Value::TYPE_INTEGER: {
277       int val;
278       if (!ReadParam(m, iter, &val))
279         return false;
280       *value = new base::FundamentalValue(val);
281       break;
282     }
283     case base::Value::TYPE_DOUBLE: {
284       double val;
285       if (!ReadParam(m, iter, &val))
286         return false;
287       *value = new base::FundamentalValue(val);
288       break;
289     }
290     case base::Value::TYPE_STRING: {
291       std::string val;
292       if (!ReadParam(m, iter, &val))
293         return false;
294       *value = new base::StringValue(val);
295       break;
296     }
297     case base::Value::TYPE_BINARY: {
298       const char* data;
299       int length;
300       if (!iter->ReadData(&data, &length))
301         return false;
302       std::unique_ptr<base::BinaryValue> val =
303           base::BinaryValue::CreateWithCopiedBuffer(data, length);
304       *value = val.release();
305       break;
306     }
307     case base::Value::TYPE_DICTIONARY: {
308       std::unique_ptr<base::DictionaryValue> val(new base::DictionaryValue());
309       if (!ReadDictionaryValue(m, iter, val.get(), recursion))
310         return false;
311       *value = val.release();
312       break;
313     }
314     case base::Value::TYPE_LIST: {
315       std::unique_ptr<base::ListValue> val(new base::ListValue());
316       if (!ReadListValue(m, iter, val.get(), recursion))
317         return false;
318       *value = val.release();
319       break;
320     }
321     default:
322     return false;
323   }
324 
325   return true;
326 }
327 
328 }  // namespace
329 
330 // -----------------------------------------------------------------------------
331 
LogData()332 LogData::LogData()
333     : routing_id(0),
334       type(0),
335       sent(0),
336       receive(0),
337       dispatch(0) {
338 }
339 
340 LogData::LogData(const LogData& other) = default;
341 
~LogData()342 LogData::~LogData() {
343 }
344 
Log(const param_type & p,std::string * l)345 void ParamTraits<bool>::Log(const param_type& p, std::string* l) {
346   l->append(p ? "true" : "false");
347 }
348 
GetSize(base::PickleSizer * sizer,const param_type & p)349 void ParamTraits<signed char>::GetSize(base::PickleSizer* sizer,
350                                        const param_type& p) {
351   sizer->AddBytes(sizeof(param_type));
352 }
353 
Write(base::Pickle * m,const param_type & p)354 void ParamTraits<signed char>::Write(base::Pickle* m, const param_type& p) {
355   m->WriteBytes(&p, sizeof(param_type));
356 }
357 
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)358 bool ParamTraits<signed char>::Read(const base::Pickle* m,
359                                     base::PickleIterator* iter,
360                                     param_type* r) {
361   const char* data;
362   if (!iter->ReadBytes(&data, sizeof(param_type)))
363     return false;
364   memcpy(r, data, sizeof(param_type));
365   return true;
366 }
367 
Log(const param_type & p,std::string * l)368 void ParamTraits<signed char>::Log(const param_type& p, std::string* l) {
369   l->append(base::IntToString(p));
370 }
371 
GetSize(base::PickleSizer * sizer,const param_type & p)372 void ParamTraits<unsigned char>::GetSize(base::PickleSizer* sizer,
373                                        const param_type& p) {
374   sizer->AddBytes(sizeof(param_type));
375 }
376 
Write(base::Pickle * m,const param_type & p)377 void ParamTraits<unsigned char>::Write(base::Pickle* m, const param_type& p) {
378   m->WriteBytes(&p, sizeof(param_type));
379 }
380 
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)381 bool ParamTraits<unsigned char>::Read(const base::Pickle* m,
382                                       base::PickleIterator* iter,
383                                       param_type* r) {
384   const char* data;
385   if (!iter->ReadBytes(&data, sizeof(param_type)))
386     return false;
387   memcpy(r, data, sizeof(param_type));
388   return true;
389 }
390 
Log(const param_type & p,std::string * l)391 void ParamTraits<unsigned char>::Log(const param_type& p, std::string* l) {
392   l->append(base::UintToString(p));
393 }
394 
GetSize(base::PickleSizer * sizer,const param_type & p)395 void ParamTraits<unsigned short>::GetSize(base::PickleSizer* sizer,
396                                           const param_type& p) {
397   sizer->AddBytes(sizeof(param_type));
398 }
399 
Write(base::Pickle * m,const param_type & p)400 void ParamTraits<unsigned short>::Write(base::Pickle* m, const param_type& p) {
401   m->WriteBytes(&p, sizeof(param_type));
402 }
403 
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)404 bool ParamTraits<unsigned short>::Read(const base::Pickle* m,
405                                        base::PickleIterator* iter,
406                                        param_type* r) {
407   const char* data;
408   if (!iter->ReadBytes(&data, sizeof(param_type)))
409     return false;
410   memcpy(r, data, sizeof(param_type));
411   return true;
412 }
413 
Log(const param_type & p,std::string * l)414 void ParamTraits<unsigned short>::Log(const param_type& p, std::string* l) {
415   l->append(base::UintToString(p));
416 }
417 
Log(const param_type & p,std::string * l)418 void ParamTraits<int>::Log(const param_type& p, std::string* l) {
419   l->append(base::IntToString(p));
420 }
421 
Log(const param_type & p,std::string * l)422 void ParamTraits<unsigned int>::Log(const param_type& p, std::string* l) {
423   l->append(base::UintToString(p));
424 }
425 
426 #if defined(OS_WIN) || defined(OS_LINUX) || \
427     (defined(OS_ANDROID) && defined(ARCH_CPU_64_BITS))
Log(const param_type & p,std::string * l)428 void ParamTraits<long>::Log(const param_type& p, std::string* l) {
429   l->append(base::Int64ToString(static_cast<int64_t>(p)));
430 }
431 
Log(const param_type & p,std::string * l)432 void ParamTraits<unsigned long>::Log(const param_type& p, std::string* l) {
433   l->append(base::Uint64ToString(static_cast<uint64_t>(p)));
434 }
435 #endif
436 
Log(const param_type & p,std::string * l)437 void ParamTraits<long long>::Log(const param_type& p, std::string* l) {
438   l->append(base::Int64ToString(static_cast<int64_t>(p)));
439 }
440 
Log(const param_type & p,std::string * l)441 void ParamTraits<unsigned long long>::Log(const param_type& p, std::string* l) {
442   l->append(base::Uint64ToString(p));
443 }
444 
Log(const param_type & p,std::string * l)445 void ParamTraits<float>::Log(const param_type& p, std::string* l) {
446   l->append(base::StringPrintf("%e", p));
447 }
448 
GetSize(base::PickleSizer * sizer,const param_type & p)449 void ParamTraits<double>::GetSize(base::PickleSizer* sizer,
450                                   const param_type& p) {
451   sizer->AddBytes(sizeof(param_type));
452 }
453 
Write(base::Pickle * m,const param_type & p)454 void ParamTraits<double>::Write(base::Pickle* m, const param_type& p) {
455   m->WriteBytes(reinterpret_cast<const char*>(&p), sizeof(param_type));
456 }
457 
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)458 bool ParamTraits<double>::Read(const base::Pickle* m,
459                                base::PickleIterator* iter,
460                                param_type* r) {
461   const char *data;
462   if (!iter->ReadBytes(&data, sizeof(*r))) {
463     NOTREACHED();
464     return false;
465   }
466   memcpy(r, data, sizeof(param_type));
467   return true;
468 }
469 
Log(const param_type & p,std::string * l)470 void ParamTraits<double>::Log(const param_type& p, std::string* l) {
471   l->append(base::StringPrintf("%e", p));
472 }
473 
474 
Log(const param_type & p,std::string * l)475 void ParamTraits<std::string>::Log(const param_type& p, std::string* l) {
476   l->append(p);
477 }
478 
Log(const param_type & p,std::string * l)479 void ParamTraits<base::string16>::Log(const param_type& p, std::string* l) {
480   l->append(base::UTF16ToUTF8(p));
481 }
482 
GetSize(base::PickleSizer * sizer,const param_type & p)483 void ParamTraits<std::vector<char>>::GetSize(base::PickleSizer* sizer,
484                                              const param_type& p) {
485   sizer->AddData(static_cast<int>(p.size()));
486 }
487 
Write(base::Pickle * m,const param_type & p)488 void ParamTraits<std::vector<char>>::Write(base::Pickle* m,
489                                            const param_type& p) {
490   if (p.empty()) {
491     m->WriteData(NULL, 0);
492   } else {
493     m->WriteData(&p.front(), static_cast<int>(p.size()));
494   }
495 }
496 
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)497 bool ParamTraits<std::vector<char>>::Read(const base::Pickle* m,
498                                           base::PickleIterator* iter,
499                                           param_type* r) {
500   const char *data;
501   int data_size = 0;
502   if (!iter->ReadData(&data, &data_size) || data_size < 0)
503     return false;
504   r->resize(data_size);
505   if (data_size)
506     memcpy(&r->front(), data, data_size);
507   return true;
508 }
509 
Log(const param_type & p,std::string * l)510 void ParamTraits<std::vector<char> >::Log(const param_type& p, std::string* l) {
511   LogBytes(p, l);
512 }
513 
GetSize(base::PickleSizer * sizer,const param_type & p)514 void ParamTraits<std::vector<unsigned char>>::GetSize(base::PickleSizer* sizer,
515                                                       const param_type& p) {
516   sizer->AddData(static_cast<int>(p.size()));
517 }
518 
Write(base::Pickle * m,const param_type & p)519 void ParamTraits<std::vector<unsigned char>>::Write(base::Pickle* m,
520                                                     const param_type& p) {
521   if (p.empty()) {
522     m->WriteData(NULL, 0);
523   } else {
524     m->WriteData(reinterpret_cast<const char*>(&p.front()),
525                  static_cast<int>(p.size()));
526   }
527 }
528 
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)529 bool ParamTraits<std::vector<unsigned char>>::Read(const base::Pickle* m,
530                                                    base::PickleIterator* iter,
531                                                    param_type* r) {
532   const char *data;
533   int data_size = 0;
534   if (!iter->ReadData(&data, &data_size) || data_size < 0)
535     return false;
536   r->resize(data_size);
537   if (data_size)
538     memcpy(&r->front(), data, data_size);
539   return true;
540 }
541 
Log(const param_type & p,std::string * l)542 void ParamTraits<std::vector<unsigned char> >::Log(const param_type& p,
543                                                    std::string* l) {
544   LogBytes(p, l);
545 }
546 
GetSize(base::PickleSizer * sizer,const param_type & p)547 void ParamTraits<std::vector<bool>>::GetSize(base::PickleSizer* sizer,
548                                              const param_type& p) {
549   GetParamSize(sizer, static_cast<int>(p.size()));
550   for (size_t i = 0; i < p.size(); ++i)
551     GetParamSize(sizer, static_cast<bool>(p[i]));
552 }
553 
Write(base::Pickle * m,const param_type & p)554 void ParamTraits<std::vector<bool>>::Write(base::Pickle* m,
555                                            const param_type& p) {
556   WriteParam(m, static_cast<int>(p.size()));
557   // Cast to bool below is required because libc++'s
558   // vector<bool>::const_reference is different from bool, and we want to avoid
559   // writing an extra specialization of ParamTraits for it.
560   for (size_t i = 0; i < p.size(); i++)
561     WriteParam(m, static_cast<bool>(p[i]));
562 }
563 
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)564 bool ParamTraits<std::vector<bool>>::Read(const base::Pickle* m,
565                                           base::PickleIterator* iter,
566                                           param_type* r) {
567   int size;
568   // ReadLength() checks for < 0 itself.
569   if (!iter->ReadLength(&size))
570     return false;
571   r->resize(size);
572   for (int i = 0; i < size; i++) {
573     bool value;
574     if (!ReadParam(m, iter, &value))
575       return false;
576     (*r)[i] = value;
577   }
578   return true;
579 }
580 
Log(const param_type & p,std::string * l)581 void ParamTraits<std::vector<bool> >::Log(const param_type& p, std::string* l) {
582   for (size_t i = 0; i < p.size(); ++i) {
583     if (i != 0)
584       l->push_back(' ');
585     LogParam(static_cast<bool>(p[i]), l);
586   }
587 }
588 
Write(base::Pickle * m,const param_type & p)589 void ParamTraits<BrokerableAttachment::AttachmentId>::Write(
590     base::Pickle* m,
591     const param_type& p) {
592   m->WriteBytes(p.nonce, BrokerableAttachment::kNonceSize);
593 }
594 
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)595 bool ParamTraits<BrokerableAttachment::AttachmentId>::Read(
596     const base::Pickle* m,
597     base::PickleIterator* iter,
598     param_type* r) {
599   const char* data;
600   if (!iter->ReadBytes(&data, BrokerableAttachment::kNonceSize))
601     return false;
602   memcpy(r->nonce, data, BrokerableAttachment::kNonceSize);
603   return true;
604 }
605 
Log(const param_type & p,std::string * l)606 void ParamTraits<BrokerableAttachment::AttachmentId>::Log(const param_type& p,
607                                                           std::string* l) {
608   l->append(base::HexEncode(p.nonce, BrokerableAttachment::kNonceSize));
609 }
610 
GetSize(base::PickleSizer * sizer,const param_type & p)611 void ParamTraits<base::DictionaryValue>::GetSize(base::PickleSizer* sizer,
612                                                  const param_type& p) {
613   GetValueSize(sizer, &p, 0);
614 }
615 
Write(base::Pickle * m,const param_type & p)616 void ParamTraits<base::DictionaryValue>::Write(base::Pickle* m,
617                                                const param_type& p) {
618   WriteValue(m, &p, 0);
619 }
620 
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)621 bool ParamTraits<base::DictionaryValue>::Read(const base::Pickle* m,
622                                               base::PickleIterator* iter,
623                                               param_type* r) {
624   int type;
625   if (!ReadParam(m, iter, &type) || type != base::Value::TYPE_DICTIONARY)
626     return false;
627 
628   return ReadDictionaryValue(m, iter, r, 0);
629 }
630 
Log(const param_type & p,std::string * l)631 void ParamTraits<base::DictionaryValue>::Log(const param_type& p,
632                                              std::string* l) {
633   std::string json;
634   base::JSONWriter::Write(p, &json);
635   l->append(json);
636 }
637 
638 #if defined(OS_POSIX)
GetSize(base::PickleSizer * sizer,const param_type & p)639 void ParamTraits<base::FileDescriptor>::GetSize(base::PickleSizer* sizer,
640                                                 const param_type& p) {
641   GetParamSize(sizer, p.fd >= 0);
642   if (p.fd >= 0)
643     sizer->AddAttachment();
644 }
645 
Write(base::Pickle * m,const param_type & p)646 void ParamTraits<base::FileDescriptor>::Write(base::Pickle* m,
647                                               const param_type& p) {
648   const bool valid = p.fd >= 0;
649   WriteParam(m, valid);
650 
651   if (!valid)
652     return;
653 
654   if (p.auto_close) {
655     if (!m->WriteAttachment(
656             new internal::PlatformFileAttachment(base::ScopedFD(p.fd))))
657       NOTREACHED();
658   } else {
659     if (!m->WriteAttachment(new internal::PlatformFileAttachment(p.fd)))
660       NOTREACHED();
661   }
662 }
663 
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)664 bool ParamTraits<base::FileDescriptor>::Read(const base::Pickle* m,
665                                              base::PickleIterator* iter,
666                                              param_type* r) {
667   *r = base::FileDescriptor();
668 
669   bool valid;
670   if (!ReadParam(m, iter, &valid))
671     return false;
672 
673   // TODO(morrita): Seems like this should return false.
674   if (!valid)
675     return true;
676 
677   scoped_refptr<base::Pickle::Attachment> attachment;
678   if (!m->ReadAttachment(iter, &attachment))
679     return false;
680 
681   *r = base::FileDescriptor(
682       static_cast<MessageAttachment*>(attachment.get())->TakePlatformFile(),
683       true);
684   return true;
685 }
686 
Log(const param_type & p,std::string * l)687 void ParamTraits<base::FileDescriptor>::Log(const param_type& p,
688                                             std::string* l) {
689   if (p.auto_close) {
690     l->append(base::StringPrintf("FD(%d auto-close)", p.fd));
691   } else {
692     l->append(base::StringPrintf("FD(%d)", p.fd));
693   }
694 }
695 #endif  // defined(OS_POSIX)
696 
697 #if defined(OS_MACOSX) && !defined(OS_IOS)
GetSize(base::PickleSizer * sizer,const param_type & p)698 void ParamTraits<base::SharedMemoryHandle>::GetSize(base::PickleSizer* sizer,
699                                                     const param_type& p) {
700   GetParamSize(sizer, p.GetMemoryObject());
701   uint32_t dummy = 0;
702   GetParamSize(sizer, dummy);
703 }
704 
Write(base::Pickle * m,const param_type & p)705 void ParamTraits<base::SharedMemoryHandle>::Write(base::Pickle* m,
706                                                   const param_type& p) {
707   MachPortMac mach_port_mac(p.GetMemoryObject());
708   ParamTraits<MachPortMac>::Write(m, mach_port_mac);
709   size_t size = 0;
710   bool result = p.GetSize(&size);
711   DCHECK(result);
712   ParamTraits<uint32_t>::Write(m, static_cast<uint32_t>(size));
713 
714   // If the caller intended to pass ownership to the IPC stack, release a
715   // reference.
716   if (p.OwnershipPassesToIPC())
717     p.Close();
718 }
719 
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)720 bool ParamTraits<base::SharedMemoryHandle>::Read(const base::Pickle* m,
721                                                  base::PickleIterator* iter,
722                                                  param_type* r) {
723   MachPortMac mach_port_mac;
724   if (!ParamTraits<MachPortMac>::Read(m, iter, &mach_port_mac))
725     return false;
726 
727   uint32_t size;
728   if (!ParamTraits<uint32_t>::Read(m, iter, &size))
729     return false;
730 
731   *r = base::SharedMemoryHandle(mach_port_mac.get_mach_port(),
732                                 static_cast<size_t>(size),
733                                 base::GetCurrentProcId());
734   return true;
735 }
736 
Log(const param_type & p,std::string * l)737 void ParamTraits<base::SharedMemoryHandle>::Log(const param_type& p,
738                                                 std::string* l) {
739   l->append("Mach port: ");
740   LogParam(p.GetMemoryObject(), l);
741 }
742 
743 #elif defined(OS_WIN)
GetSize(base::PickleSizer * s,const param_type & p)744 void ParamTraits<base::SharedMemoryHandle>::GetSize(base::PickleSizer* s,
745                                                     const param_type& p) {
746   GetParamSize(s, p.NeedsBrokering());
747   if (p.NeedsBrokering()) {
748     GetParamSize(s, p.GetHandle());
749   } else {
750     GetParamSize(s, HandleToLong(p.GetHandle()));
751   }
752 }
753 
Write(base::Pickle * m,const param_type & p)754 void ParamTraits<base::SharedMemoryHandle>::Write(base::Pickle* m,
755                                                   const param_type& p) {
756   m->WriteBool(p.NeedsBrokering());
757 
758   if (p.NeedsBrokering()) {
759     HandleWin handle_win(p.GetHandle(), HandleWin::DUPLICATE);
760     ParamTraits<HandleWin>::Write(m, handle_win);
761 
762     // If the caller intended to pass ownership to the IPC stack, release a
763     // reference.
764     if (p.OwnershipPassesToIPC() && p.BelongsToCurrentProcess())
765       p.Close();
766   } else {
767     m->WriteInt(HandleToLong(p.GetHandle()));
768   }
769 }
770 
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)771 bool ParamTraits<base::SharedMemoryHandle>::Read(const base::Pickle* m,
772                                                  base::PickleIterator* iter,
773                                                  param_type* r) {
774   bool needs_brokering;
775   if (!iter->ReadBool(&needs_brokering))
776     return false;
777 
778   if (needs_brokering) {
779     HandleWin handle_win;
780     if (!ParamTraits<HandleWin>::Read(m, iter, &handle_win))
781       return false;
782     *r = base::SharedMemoryHandle(handle_win.get_handle(),
783                                   base::GetCurrentProcId());
784     return true;
785   }
786 
787   int handle_int;
788   if (!iter->ReadInt(&handle_int))
789     return false;
790   HANDLE handle = LongToHandle(handle_int);
791   *r = base::SharedMemoryHandle(handle, base::GetCurrentProcId());
792   return true;
793 }
794 
Log(const param_type & p,std::string * l)795 void ParamTraits<base::SharedMemoryHandle>::Log(const param_type& p,
796                                                 std::string* l) {
797   LogParam(p.GetHandle(), l);
798   l->append(" needs brokering: ");
799   LogParam(p.NeedsBrokering(), l);
800 }
801 #endif  // defined(OS_MACOSX) && !defined(OS_IOS)
802 
GetSize(base::PickleSizer * sizer,const param_type & p)803 void ParamTraits<base::FilePath>::GetSize(base::PickleSizer* sizer,
804                                           const param_type& p) {
805   p.GetSizeForPickle(sizer);
806 }
807 
Write(base::Pickle * m,const param_type & p)808 void ParamTraits<base::FilePath>::Write(base::Pickle* m, const param_type& p) {
809   p.WriteToPickle(m);
810 }
811 
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)812 bool ParamTraits<base::FilePath>::Read(const base::Pickle* m,
813                                        base::PickleIterator* iter,
814                                        param_type* r) {
815   return r->ReadFromPickle(iter);
816 }
817 
Log(const param_type & p,std::string * l)818 void ParamTraits<base::FilePath>::Log(const param_type& p, std::string* l) {
819   ParamTraits<base::FilePath::StringType>::Log(p.value(), l);
820 }
821 
GetSize(base::PickleSizer * sizer,const param_type & p)822 void ParamTraits<base::ListValue>::GetSize(base::PickleSizer* sizer,
823                                            const param_type& p) {
824   GetValueSize(sizer, &p, 0);
825 }
826 
Write(base::Pickle * m,const param_type & p)827 void ParamTraits<base::ListValue>::Write(base::Pickle* m, const param_type& p) {
828   WriteValue(m, &p, 0);
829 }
830 
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)831 bool ParamTraits<base::ListValue>::Read(const base::Pickle* m,
832                                         base::PickleIterator* iter,
833                                         param_type* r) {
834   int type;
835   if (!ReadParam(m, iter, &type) || type != base::Value::TYPE_LIST)
836     return false;
837 
838   return ReadListValue(m, iter, r, 0);
839 }
840 
Log(const param_type & p,std::string * l)841 void ParamTraits<base::ListValue>::Log(const param_type& p, std::string* l) {
842   std::string json;
843   base::JSONWriter::Write(p, &json);
844   l->append(json);
845 }
846 
GetSize(base::PickleSizer * sizer,const param_type & p)847 void ParamTraits<base::NullableString16>::GetSize(base::PickleSizer* sizer,
848                                                   const param_type& p) {
849   GetParamSize(sizer, p.string());
850   GetParamSize(sizer, p.is_null());
851 }
852 
Write(base::Pickle * m,const param_type & p)853 void ParamTraits<base::NullableString16>::Write(base::Pickle* m,
854                                                 const param_type& p) {
855   WriteParam(m, p.string());
856   WriteParam(m, p.is_null());
857 }
858 
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)859 bool ParamTraits<base::NullableString16>::Read(const base::Pickle* m,
860                                                base::PickleIterator* iter,
861                                                param_type* r) {
862   base::string16 string;
863   if (!ReadParam(m, iter, &string))
864     return false;
865   bool is_null;
866   if (!ReadParam(m, iter, &is_null))
867     return false;
868   *r = base::NullableString16(string, is_null);
869   return true;
870 }
871 
Log(const param_type & p,std::string * l)872 void ParamTraits<base::NullableString16>::Log(const param_type& p,
873                                               std::string* l) {
874   l->append("(");
875   LogParam(p.string(), l);
876   l->append(", ");
877   LogParam(p.is_null(), l);
878   l->append(")");
879 }
880 
GetSize(base::PickleSizer * sizer,const param_type & p)881 void ParamTraits<base::File::Info>::GetSize(base::PickleSizer* sizer,
882                                             const param_type& p) {
883   GetParamSize(sizer, p.size);
884   GetParamSize(sizer, p.is_directory);
885   GetParamSize(sizer, p.last_modified.ToDoubleT());
886   GetParamSize(sizer, p.last_accessed.ToDoubleT());
887   GetParamSize(sizer, p.creation_time.ToDoubleT());
888 }
889 
Write(base::Pickle * m,const param_type & p)890 void ParamTraits<base::File::Info>::Write(base::Pickle* m,
891                                           const param_type& p) {
892   WriteParam(m, p.size);
893   WriteParam(m, p.is_directory);
894   WriteParam(m, p.last_modified.ToDoubleT());
895   WriteParam(m, p.last_accessed.ToDoubleT());
896   WriteParam(m, p.creation_time.ToDoubleT());
897 }
898 
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * p)899 bool ParamTraits<base::File::Info>::Read(const base::Pickle* m,
900                                          base::PickleIterator* iter,
901                                          param_type* p) {
902   double last_modified, last_accessed, creation_time;
903   if (!ReadParam(m, iter, &p->size) ||
904       !ReadParam(m, iter, &p->is_directory) ||
905       !ReadParam(m, iter, &last_modified) ||
906       !ReadParam(m, iter, &last_accessed) ||
907       !ReadParam(m, iter, &creation_time))
908     return false;
909   p->last_modified = base::Time::FromDoubleT(last_modified);
910   p->last_accessed = base::Time::FromDoubleT(last_accessed);
911   p->creation_time = base::Time::FromDoubleT(creation_time);
912   return true;
913 }
914 
Log(const param_type & p,std::string * l)915 void ParamTraits<base::File::Info>::Log(const param_type& p,
916                                         std::string* l) {
917   l->append("(");
918   LogParam(p.size, l);
919   l->append(",");
920   LogParam(p.is_directory, l);
921   l->append(",");
922   LogParam(p.last_modified.ToDoubleT(), l);
923   l->append(",");
924   LogParam(p.last_accessed.ToDoubleT(), l);
925   l->append(",");
926   LogParam(p.creation_time.ToDoubleT(), l);
927   l->append(")");
928 }
929 
GetSize(base::PickleSizer * sizer,const param_type & p)930 void ParamTraits<base::Time>::GetSize(base::PickleSizer* sizer,
931                                       const param_type& p) {
932   sizer->AddInt64();
933 }
934 
Write(base::Pickle * m,const param_type & p)935 void ParamTraits<base::Time>::Write(base::Pickle* m, const param_type& p) {
936   ParamTraits<int64_t>::Write(m, p.ToInternalValue());
937 }
938 
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)939 bool ParamTraits<base::Time>::Read(const base::Pickle* m,
940                                    base::PickleIterator* iter,
941                                    param_type* r) {
942   int64_t value;
943   if (!ParamTraits<int64_t>::Read(m, iter, &value))
944     return false;
945   *r = base::Time::FromInternalValue(value);
946   return true;
947 }
948 
Log(const param_type & p,std::string * l)949 void ParamTraits<base::Time>::Log(const param_type& p, std::string* l) {
950   ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
951 }
952 
GetSize(base::PickleSizer * sizer,const param_type & p)953 void ParamTraits<base::TimeDelta>::GetSize(base::PickleSizer* sizer,
954                                            const param_type& p) {
955   sizer->AddInt64();
956 }
957 
Write(base::Pickle * m,const param_type & p)958 void ParamTraits<base::TimeDelta>::Write(base::Pickle* m, const param_type& p) {
959   ParamTraits<int64_t>::Write(m, p.ToInternalValue());
960 }
961 
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)962 bool ParamTraits<base::TimeDelta>::Read(const base::Pickle* m,
963                                         base::PickleIterator* iter,
964                                         param_type* r) {
965   int64_t value;
966   bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
967   if (ret)
968     *r = base::TimeDelta::FromInternalValue(value);
969 
970   return ret;
971 }
972 
Log(const param_type & p,std::string * l)973 void ParamTraits<base::TimeDelta>::Log(const param_type& p, std::string* l) {
974   ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
975 }
976 
GetSize(base::PickleSizer * sizer,const param_type & p)977 void ParamTraits<base::TimeTicks>::GetSize(base::PickleSizer* sizer,
978                                            const param_type& p) {
979   sizer->AddInt64();
980 }
981 
Write(base::Pickle * m,const param_type & p)982 void ParamTraits<base::TimeTicks>::Write(base::Pickle* m, const param_type& p) {
983   ParamTraits<int64_t>::Write(m, p.ToInternalValue());
984 }
985 
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)986 bool ParamTraits<base::TimeTicks>::Read(const base::Pickle* m,
987                                         base::PickleIterator* iter,
988                                         param_type* r) {
989   int64_t value;
990   bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
991   if (ret)
992     *r = base::TimeTicks::FromInternalValue(value);
993 
994   return ret;
995 }
996 
Log(const param_type & p,std::string * l)997 void ParamTraits<base::TimeTicks>::Log(const param_type& p, std::string* l) {
998   ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
999 }
1000 
GetSize(base::PickleSizer * sizer,const param_type & p)1001 void ParamTraits<IPC::ChannelHandle>::GetSize(base::PickleSizer* sizer,
1002                                               const param_type& p) {
1003   GetParamSize(sizer, p.name);
1004 #if defined(OS_POSIX)
1005   GetParamSize(sizer, p.socket);
1006 #endif
1007   GetParamSize(sizer, p.mojo_handle);
1008 }
1009 
Write(base::Pickle * m,const param_type & p)1010 void ParamTraits<IPC::ChannelHandle>::Write(base::Pickle* m,
1011                                             const param_type& p) {
1012 #if defined(OS_WIN)
1013   // On Windows marshalling pipe handle is not supported.
1014   DCHECK(p.pipe.handle == NULL);
1015 #endif  // defined (OS_WIN)
1016   WriteParam(m, p.name);
1017 #if defined(OS_POSIX)
1018   WriteParam(m, p.socket);
1019 #endif
1020   WriteParam(m, p.mojo_handle);
1021 }
1022 
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)1023 bool ParamTraits<IPC::ChannelHandle>::Read(const base::Pickle* m,
1024                                            base::PickleIterator* iter,
1025                                            param_type* r) {
1026   return ReadParam(m, iter, &r->name)
1027 #if defined(OS_POSIX)
1028       && ReadParam(m, iter, &r->socket)
1029 #endif
1030       && ReadParam(m, iter, &r->mojo_handle);
1031 }
1032 
Log(const param_type & p,std::string * l)1033 void ParamTraits<IPC::ChannelHandle>::Log(const param_type& p,
1034                                           std::string* l) {
1035   l->append(base::StringPrintf("ChannelHandle(%s", p.name.c_str()));
1036 #if defined(OS_POSIX)
1037   l->append(", ");
1038   ParamTraits<base::FileDescriptor>::Log(p.socket, l);
1039 #endif
1040   l->append(", ");
1041   LogParam(p.mojo_handle, l);
1042   l->append(")");
1043 }
1044 
GetSize(base::PickleSizer * sizer,const param_type & p)1045 void ParamTraits<LogData>::GetSize(base::PickleSizer* sizer,
1046                                    const param_type& p) {
1047   GetParamSize(sizer, p.channel);
1048   GetParamSize(sizer, p.routing_id);
1049   GetParamSize(sizer, p.type);
1050   GetParamSize(sizer, p.flags);
1051   GetParamSize(sizer, p.sent);
1052   GetParamSize(sizer, p.receive);
1053   GetParamSize(sizer, p.dispatch);
1054   GetParamSize(sizer, p.message_name);
1055   GetParamSize(sizer, p.params);
1056 }
1057 
Write(base::Pickle * m,const param_type & p)1058 void ParamTraits<LogData>::Write(base::Pickle* m, const param_type& p) {
1059   WriteParam(m, p.channel);
1060   WriteParam(m, p.routing_id);
1061   WriteParam(m, p.type);
1062   WriteParam(m, p.flags);
1063   WriteParam(m, p.sent);
1064   WriteParam(m, p.receive);
1065   WriteParam(m, p.dispatch);
1066   WriteParam(m, p.message_name);
1067   WriteParam(m, p.params);
1068 }
1069 
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)1070 bool ParamTraits<LogData>::Read(const base::Pickle* m,
1071                                 base::PickleIterator* iter,
1072                                 param_type* r) {
1073   return
1074       ReadParam(m, iter, &r->channel) &&
1075       ReadParam(m, iter, &r->routing_id) &&
1076       ReadParam(m, iter, &r->type) &&
1077       ReadParam(m, iter, &r->flags) &&
1078       ReadParam(m, iter, &r->sent) &&
1079       ReadParam(m, iter, &r->receive) &&
1080       ReadParam(m, iter, &r->dispatch) &&
1081       ReadParam(m, iter, &r->message_name) &&
1082       ReadParam(m, iter, &r->params);
1083 }
1084 
Log(const param_type & p,std::string * l)1085 void ParamTraits<LogData>::Log(const param_type& p, std::string* l) {
1086   // Doesn't make sense to implement this!
1087 }
1088 
Write(base::Pickle * m,const Message & p)1089 void ParamTraits<Message>::Write(base::Pickle* m, const Message& p) {
1090 #if defined(OS_POSIX)
1091   // We don't serialize the file descriptors in the nested message, so there
1092   // better not be any.
1093   DCHECK(!p.HasAttachments());
1094 #endif
1095 
1096   // Don't just write out the message. This is used to send messages between
1097   // NaCl (Posix environment) and the browser (could be on Windows). The message
1098   // header formats differ between these systems (so does handle sharing, but
1099   // we already asserted we don't have any handles). So just write out the
1100   // parts of the header we use.
1101   //
1102   // Be careful also to use only explicitly-sized types. The NaCl environment
1103   // could be 64-bit and the host browser could be 32-bits. The nested message
1104   // may or may not be safe to send between 32-bit and 64-bit systems, but we
1105   // leave that up to the code sending the message to ensure.
1106   m->WriteUInt32(static_cast<uint32_t>(p.routing_id()));
1107   m->WriteUInt32(p.type());
1108   m->WriteUInt32(p.flags());
1109   m->WriteData(p.payload(), static_cast<uint32_t>(p.payload_size()));
1110 }
1111 
Read(const base::Pickle * m,base::PickleIterator * iter,Message * r)1112 bool ParamTraits<Message>::Read(const base::Pickle* m,
1113                                 base::PickleIterator* iter,
1114                                 Message* r) {
1115   uint32_t routing_id, type, flags;
1116   if (!iter->ReadUInt32(&routing_id) ||
1117       !iter->ReadUInt32(&type) ||
1118       !iter->ReadUInt32(&flags))
1119     return false;
1120 
1121   int payload_size;
1122   const char* payload;
1123   if (!iter->ReadData(&payload, &payload_size))
1124     return false;
1125 
1126   r->SetHeaderValues(static_cast<int32_t>(routing_id), type, flags);
1127   return r->WriteBytes(payload, payload_size);
1128 }
1129 
Log(const Message & p,std::string * l)1130 void ParamTraits<Message>::Log(const Message& p, std::string* l) {
1131   l->append("<IPC::Message>");
1132 }
1133 
1134 #if defined(OS_WIN)
GetSize(base::PickleSizer * sizer,const param_type & p)1135 void ParamTraits<HANDLE>::GetSize(base::PickleSizer* sizer,
1136                                   const param_type& p) {
1137   sizer->AddInt();
1138 }
1139 
1140 // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
1141 // bit systems. That's why we use the Windows macros to convert to 32 bits.
Write(base::Pickle * m,const param_type & p)1142 void ParamTraits<HANDLE>::Write(base::Pickle* m, const param_type& p) {
1143   m->WriteInt(HandleToLong(p));
1144 }
1145 
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)1146 bool ParamTraits<HANDLE>::Read(const base::Pickle* m,
1147                                base::PickleIterator* iter,
1148                                param_type* r) {
1149   int32_t temp;
1150   if (!iter->ReadInt(&temp))
1151     return false;
1152   *r = LongToHandle(temp);
1153   return true;
1154 }
1155 
Log(const param_type & p,std::string * l)1156 void ParamTraits<HANDLE>::Log(const param_type& p, std::string* l) {
1157   l->append(base::StringPrintf("0x%p", p));
1158 }
1159 
GetSize(base::PickleSizer * sizer,const param_type & p)1160 void ParamTraits<LOGFONT>::GetSize(base::PickleSizer* sizer,
1161                                    const param_type& p) {
1162   sizer->AddData(sizeof(LOGFONT));
1163 }
1164 
Write(base::Pickle * m,const param_type & p)1165 void ParamTraits<LOGFONT>::Write(base::Pickle* m, const param_type& p) {
1166   m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
1167 }
1168 
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)1169 bool ParamTraits<LOGFONT>::Read(const base::Pickle* m,
1170                                 base::PickleIterator* iter,
1171                                 param_type* r) {
1172   const char *data;
1173   int data_size = 0;
1174   if (iter->ReadData(&data, &data_size) && data_size == sizeof(LOGFONT)) {
1175     const LOGFONT *font = reinterpret_cast<LOGFONT*>(const_cast<char*>(data));
1176     if (_tcsnlen(font->lfFaceName, LF_FACESIZE) < LF_FACESIZE) {
1177       memcpy(r, data, sizeof(LOGFONT));
1178       return true;
1179     }
1180   }
1181 
1182   NOTREACHED();
1183   return false;
1184 }
1185 
Log(const param_type & p,std::string * l)1186 void ParamTraits<LOGFONT>::Log(const param_type& p, std::string* l) {
1187   l->append(base::StringPrintf("<LOGFONT>"));
1188 }
1189 
GetSize(base::PickleSizer * sizer,const param_type & p)1190 void ParamTraits<MSG>::GetSize(base::PickleSizer* sizer, const param_type& p) {
1191   sizer->AddData(sizeof(MSG));
1192 }
1193 
Write(base::Pickle * m,const param_type & p)1194 void ParamTraits<MSG>::Write(base::Pickle* m, const param_type& p) {
1195   m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
1196 }
1197 
Read(const base::Pickle * m,base::PickleIterator * iter,param_type * r)1198 bool ParamTraits<MSG>::Read(const base::Pickle* m,
1199                             base::PickleIterator* iter,
1200                             param_type* r) {
1201   const char *data;
1202   int data_size = 0;
1203   bool result = iter->ReadData(&data, &data_size);
1204   if (result && data_size == sizeof(MSG)) {
1205     memcpy(r, data, sizeof(MSG));
1206   } else {
1207     result = false;
1208     NOTREACHED();
1209   }
1210 
1211   return result;
1212 }
1213 
Log(const param_type & p,std::string * l)1214 void ParamTraits<MSG>::Log(const param_type& p, std::string* l) {
1215   l->append("<MSG>");
1216 }
1217 
1218 #endif  // OS_WIN
1219 
1220 }  // namespace IPC
1221