blob: 639ceddab7c6ebcc4d5088f4266b49f25eddaa4f [file] [log] [blame]
[email protected]a7c03d4f32012-01-24 02:36:051// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]946d1b22009-07-22 23:57:212// 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
avi246998d82015-12-22 02:39:047#include <stddef.h>
8#include <stdint.h>
9
[email protected]57999812013-02-24 05:40:5210#include "base/files/file_path.h"
[email protected]93d49d72009-10-23 20:00:2011#include "base/json/json_writer.h"
[email protected]3b63f8f42011-03-28 01:54:1512#include "base/memory/scoped_ptr.h"
[email protected]0238a162013-06-13 13:47:4613#include "base/strings/nullable_string16.h"
[email protected]4aa794a12013-06-11 06:32:1814#include "base/strings/string_number_conversions.h"
[email protected]906265872013-06-07 22:40:4515#include "base/strings/utf_string_conversions.h"
[email protected]b43e5562013-06-28 15:20:0216#include "base/time/time.h"
[email protected]946d1b22009-07-22 23:57:2117#include "base/values.h"
avi246998d82015-12-22 02:39:0418#include "build/build_config.h"
[email protected]bf5aedf02012-06-04 21:18:2519#include "ipc/ipc_channel_handle.h"
morrita1aa788c2015-01-31 05:45:4220#include "ipc/ipc_message_attachment.h"
morrita4b5c28e22015-01-14 21:17:0621#include "ipc/ipc_message_attachment_set.h"
[email protected]bf5aedf02012-06-04 21:18:2522
morrita1aa788c2015-01-31 05:45:4223#if defined(OS_POSIX)
24#include "ipc/ipc_platform_file_attachment_posix.h"
25#endif
26
erikchen5ea2ab72015-09-25 22:34:3127#if (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
scottmgd19b4f72015-06-19 22:51:0028#include "base/memory/shared_memory_handle.h"
erikchen5ea2ab72015-09-25 22:34:3129#endif // (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
scottmgd19b4f72015-06-19 22:51:0030
erikchenaf8299d2015-10-09 19:12:0631#if defined(OS_MACOSX) && !defined(OS_IOS)
32#include "ipc/mach_port_mac.h"
33#endif
34
morrita4b5c28e22015-01-14 21:17:0635#if defined(OS_WIN)
[email protected]2e02cfe82012-11-21 00:58:0036#include <tchar.h>
erikchen5ea2ab72015-09-25 22:34:3137#include "ipc/handle_win.h"
[email protected]7a4de7a62010-08-17 18:38:2438#endif
[email protected]946d1b22009-07-22 23:57:2139
40namespace IPC {
41
[email protected]bf5aedf02012-06-04 21:18:2542namespace {
43
[email protected]946d1b22009-07-22 23:57:2144const int kMaxRecursionDepth = 100;
45
[email protected]bf5aedf02012-06-04 21:18:2546template<typename CharType>
47void 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
[email protected]7d3cbc92013-03-18 22:33:0459 out->append(
60 base::StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
[email protected]bf5aedf02012-06-04 21:18:2561 }
62 if (data.size() > kMaxBytesToLog) {
[email protected]f8660f82013-03-30 17:29:2863 out->append(base::StringPrintf(
64 " and %u more bytes",
65 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
[email protected]bf5aedf02012-06-04 21:18:2566 }
67#endif
68}
[email protected]946d1b22009-07-22 23:57:2169
rockot502c94f2016-02-03 20:20:1670bool ReadValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:2571 base::PickleIterator* iter,
72 base::Value** value,
[email protected]bf5aedf02012-06-04 21:18:2573 int recursion);
[email protected]946d1b22009-07-22 23:57:2174
rockot0457af102016-02-05 02:12:3275void 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 DCHECK(result);
100 GetParamSize(sizer, result->GetString());
101 break;
102 }
103 case base::Value::TYPE_BINARY: {
104 const base::BinaryValue* binary =
105 static_cast<const base::BinaryValue*>(value);
106 sizer->AddData(static_cast<int>(binary->GetSize()));
107 break;
108 }
109 case base::Value::TYPE_DICTIONARY: {
110 sizer->AddInt();
111 const base::DictionaryValue* dict =
112 static_cast<const base::DictionaryValue*>(value);
113 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd();
114 it.Advance()) {
115 GetParamSize(sizer, it.key());
116 GetValueSize(sizer, &it.value(), recursion + 1);
117 }
118 break;
119 }
120 case base::Value::TYPE_LIST: {
121 sizer->AddInt();
122 const base::ListValue* list = static_cast<const base::ListValue*>(value);
123 for (base::ListValue::const_iterator it = list->begin();
124 it != list->end(); ++it) {
125 GetValueSize(sizer, *it, recursion + 1);
126 }
127 break;
128 }
129 default:
130 NOTREACHED() << "Invalid base::Value type.";
131 }
132}
133
rockot502c94f2016-02-03 20:20:16134void WriteValue(base::Pickle* m, const base::Value* value, int recursion) {
[email protected]dbc761a2012-07-26 01:29:21135 bool result;
[email protected]946d1b22009-07-22 23:57:21136 if (recursion > kMaxRecursionDepth) {
137 LOG(WARNING) << "Max recursion depth hit in WriteValue.";
138 return;
139 }
140
141 m->WriteInt(value->GetType());
142
143 switch (value->GetType()) {
[email protected]ea5ef4c2013-06-13 22:50:27144 case base::Value::TYPE_NULL:
[email protected]946d1b22009-07-22 23:57:21145 break;
[email protected]ea5ef4c2013-06-13 22:50:27146 case base::Value::TYPE_BOOLEAN: {
[email protected]946d1b22009-07-22 23:57:21147 bool val;
[email protected]dbc761a2012-07-26 01:29:21148 result = value->GetAsBoolean(&val);
149 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21150 WriteParam(m, val);
151 break;
152 }
[email protected]ea5ef4c2013-06-13 22:50:27153 case base::Value::TYPE_INTEGER: {
[email protected]946d1b22009-07-22 23:57:21154 int val;
[email protected]dbc761a2012-07-26 01:29:21155 result = value->GetAsInteger(&val);
156 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21157 WriteParam(m, val);
158 break;
159 }
[email protected]ea5ef4c2013-06-13 22:50:27160 case base::Value::TYPE_DOUBLE: {
[email protected]946d1b22009-07-22 23:57:21161 double val;
[email protected]dbc761a2012-07-26 01:29:21162 result = value->GetAsDouble(&val);
163 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21164 WriteParam(m, val);
165 break;
166 }
[email protected]ea5ef4c2013-06-13 22:50:27167 case base::Value::TYPE_STRING: {
[email protected]946d1b22009-07-22 23:57:21168 std::string val;
[email protected]dbc761a2012-07-26 01:29:21169 result = value->GetAsString(&val);
170 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21171 WriteParam(m, val);
172 break;
173 }
[email protected]ea5ef4c2013-06-13 22:50:27174 case base::Value::TYPE_BINARY: {
[email protected]b59ea312011-08-05 18:20:05175 const base::BinaryValue* binary =
176 static_cast<const base::BinaryValue*>(value);
[email protected]7ee1a44c2010-07-23 14:18:59177 m->WriteData(binary->GetBuffer(), static_cast<int>(binary->GetSize()));
[email protected]e4dad9fb2009-10-06 18:15:58178 break;
[email protected]946d1b22009-07-22 23:57:21179 }
[email protected]ea5ef4c2013-06-13 22:50:27180 case base::Value::TYPE_DICTIONARY: {
181 const base::DictionaryValue* dict =
182 static_cast<const base::DictionaryValue*>(value);
[email protected]946d1b22009-07-22 23:57:21183
[email protected]4dad9ad82009-11-25 20:47:52184 WriteParam(m, static_cast<int>(dict->size()));
[email protected]946d1b22009-07-22 23:57:21185
[email protected]ea5ef4c2013-06-13 22:50:27186 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd();
187 it.Advance()) {
[email protected]a899c0b02013-01-18 14:43:27188 WriteParam(m, it.key());
189 WriteValue(m, &it.value(), recursion + 1);
[email protected]946d1b22009-07-22 23:57:21190 }
191 break;
192 }
[email protected]ea5ef4c2013-06-13 22:50:27193 case base::Value::TYPE_LIST: {
194 const base::ListValue* list = static_cast<const base::ListValue*>(value);
[email protected]946d1b22009-07-22 23:57:21195 WriteParam(m, static_cast<int>(list->GetSize()));
[email protected]ea5ef4c2013-06-13 22:50:27196 for (base::ListValue::const_iterator it = list->begin();
197 it != list->end(); ++it) {
[email protected]a899c0b02013-01-18 14:43:27198 WriteValue(m, *it, recursion + 1);
[email protected]946d1b22009-07-22 23:57:21199 }
200 break;
201 }
202 }
203}
204
205// Helper for ReadValue that reads a DictionaryValue into a pre-allocated
206// object.
rockot502c94f2016-02-03 20:20:16207bool ReadDictionaryValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25208 base::PickleIterator* iter,
209 base::DictionaryValue* value,
210 int recursion) {
[email protected]946d1b22009-07-22 23:57:21211 int size;
212 if (!ReadParam(m, iter, &size))
213 return false;
214
215 for (int i = 0; i < size; ++i) {
[email protected]e7b418b2010-07-30 19:47:47216 std::string key;
[email protected]0c6c1e42013-06-21 19:42:19217 base::Value* subval;
[email protected]946d1b22009-07-22 23:57:21218 if (!ReadParam(m, iter, &key) ||
219 !ReadValue(m, iter, &subval, recursion + 1))
220 return false;
[email protected]d8b4aa42011-08-19 05:59:57221 value->SetWithoutPathExpansion(key, subval);
[email protected]946d1b22009-07-22 23:57:21222 }
223
224 return true;
225}
226
227// Helper for ReadValue that reads a ReadListValue into a pre-allocated
228// object.
rockot502c94f2016-02-03 20:20:16229bool ReadListValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25230 base::PickleIterator* iter,
231 base::ListValue* value,
232 int recursion) {
[email protected]946d1b22009-07-22 23:57:21233 int size;
234 if (!ReadParam(m, iter, &size))
235 return false;
236
237 for (int i = 0; i < size; ++i) {
[email protected]ea5ef4c2013-06-13 22:50:27238 base::Value* subval;
[email protected]946d1b22009-07-22 23:57:21239 if (!ReadValue(m, iter, &subval, recursion + 1))
240 return false;
241 value->Set(i, subval);
242 }
243
244 return true;
245}
246
rockot502c94f2016-02-03 20:20:16247bool ReadValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25248 base::PickleIterator* iter,
249 base::Value** value,
[email protected]bf5aedf02012-06-04 21:18:25250 int recursion) {
[email protected]946d1b22009-07-22 23:57:21251 if (recursion > kMaxRecursionDepth) {
252 LOG(WARNING) << "Max recursion depth hit in ReadValue.";
253 return false;
254 }
255
256 int type;
257 if (!ReadParam(m, iter, &type))
258 return false;
259
260 switch (type) {
[email protected]ea5ef4c2013-06-13 22:50:27261 case base::Value::TYPE_NULL:
estadea68b0442015-05-12 18:11:50262 *value = base::Value::CreateNullValue().release();
[email protected]946d1b22009-07-22 23:57:21263 break;
[email protected]ea5ef4c2013-06-13 22:50:27264 case base::Value::TYPE_BOOLEAN: {
[email protected]946d1b22009-07-22 23:57:21265 bool val;
266 if (!ReadParam(m, iter, &val))
267 return false;
[email protected]4038a132013-01-30 05:24:07268 *value = new base::FundamentalValue(val);
[email protected]946d1b22009-07-22 23:57:21269 break;
270 }
[email protected]ea5ef4c2013-06-13 22:50:27271 case base::Value::TYPE_INTEGER: {
[email protected]946d1b22009-07-22 23:57:21272 int val;
273 if (!ReadParam(m, iter, &val))
274 return false;
[email protected]4038a132013-01-30 05:24:07275 *value = new base::FundamentalValue(val);
[email protected]946d1b22009-07-22 23:57:21276 break;
277 }
[email protected]ea5ef4c2013-06-13 22:50:27278 case base::Value::TYPE_DOUBLE: {
[email protected]946d1b22009-07-22 23:57:21279 double val;
280 if (!ReadParam(m, iter, &val))
281 return false;
[email protected]4038a132013-01-30 05:24:07282 *value = new base::FundamentalValue(val);
[email protected]946d1b22009-07-22 23:57:21283 break;
284 }
[email protected]ea5ef4c2013-06-13 22:50:27285 case base::Value::TYPE_STRING: {
[email protected]946d1b22009-07-22 23:57:21286 std::string val;
287 if (!ReadParam(m, iter, &val))
288 return false;
[email protected]4038a132013-01-30 05:24:07289 *value = new base::StringValue(val);
[email protected]946d1b22009-07-22 23:57:21290 break;
291 }
[email protected]ea5ef4c2013-06-13 22:50:27292 case base::Value::TYPE_BINARY: {
[email protected]e4dad9fb2009-10-06 18:15:58293 const char* data;
294 int length;
avi48fc13b2014-12-28 23:31:48295 if (!iter->ReadData(&data, &length))
[email protected]e4dad9fb2009-10-06 18:15:58296 return false;
[email protected]b59ea312011-08-05 18:20:05297 *value = base::BinaryValue::CreateWithCopiedBuffer(data, length);
[email protected]946d1b22009-07-22 23:57:21298 break;
299 }
[email protected]ea5ef4c2013-06-13 22:50:27300 case base::Value::TYPE_DICTIONARY: {
301 scoped_ptr<base::DictionaryValue> val(new base::DictionaryValue());
[email protected]946d1b22009-07-22 23:57:21302 if (!ReadDictionaryValue(m, iter, val.get(), recursion))
303 return false;
304 *value = val.release();
305 break;
306 }
[email protected]ea5ef4c2013-06-13 22:50:27307 case base::Value::TYPE_LIST: {
308 scoped_ptr<base::ListValue> val(new base::ListValue());
[email protected]946d1b22009-07-22 23:57:21309 if (!ReadListValue(m, iter, val.get(), recursion))
310 return false;
311 *value = val.release();
312 break;
313 }
[email protected]e4dad9fb2009-10-06 18:15:58314 default:
[email protected]946d1b22009-07-22 23:57:21315 return false;
316 }
317
318 return true;
319}
320
[email protected]bf5aedf02012-06-04 21:18:25321} // namespace
322
323// -----------------------------------------------------------------------------
324
325LogData::LogData()
326 : routing_id(0),
327 type(0),
328 sent(0),
329 receive(0),
330 dispatch(0) {
331}
332
333LogData::~LogData() {
334}
335
[email protected]bf5aedf02012-06-04 21:18:25336void ParamTraits<bool>::Log(const param_type& p, std::string* l) {
337 l->append(p ? "true" : "false");
338}
339
rockot0457af102016-02-05 02:12:32340void ParamTraits<signed char>::GetSize(base::PickleSizer* sizer,
341 const param_type& p) {
342 sizer->AddBytes(sizeof(param_type));
343}
344
rockot502c94f2016-02-03 20:20:16345void ParamTraits<signed char>::Write(base::Pickle* m, const param_type& p) {
ortuno19ecf1842015-10-30 00:46:20346 m->WriteBytes(&p, sizeof(param_type));
347}
348
rockot502c94f2016-02-03 20:20:16349bool ParamTraits<signed char>::Read(const base::Pickle* m,
350 base::PickleIterator* iter,
351 param_type* r) {
ortuno19ecf1842015-10-30 00:46:20352 const char* data;
353 if (!iter->ReadBytes(&data, sizeof(param_type)))
354 return false;
355 memcpy(r, data, sizeof(param_type));
356 return true;
357}
358
359void ParamTraits<signed char>::Log(const param_type& p, std::string* l) {
360 l->append(base::IntToString(p));
361}
362
rockot0457af102016-02-05 02:12:32363void ParamTraits<unsigned char>::GetSize(base::PickleSizer* sizer,
364 const param_type& p) {
365 sizer->AddBytes(sizeof(param_type));
366}
367
rockot502c94f2016-02-03 20:20:16368void ParamTraits<unsigned char>::Write(base::Pickle* m, const param_type& p) {
[email protected]c1ee48d2013-07-12 23:12:28369 m->WriteBytes(&p, sizeof(param_type));
370}
371
rockot502c94f2016-02-03 20:20:16372bool ParamTraits<unsigned char>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25373 base::PickleIterator* iter,
374 param_type* r) {
[email protected]c1ee48d2013-07-12 23:12:28375 const char* data;
avi48fc13b2014-12-28 23:31:48376 if (!iter->ReadBytes(&data, sizeof(param_type)))
[email protected]c1ee48d2013-07-12 23:12:28377 return false;
378 memcpy(r, data, sizeof(param_type));
379 return true;
380}
381
382void ParamTraits<unsigned char>::Log(const param_type& p, std::string* l) {
383 l->append(base::UintToString(p));
384}
385
rockot0457af102016-02-05 02:12:32386void ParamTraits<unsigned short>::GetSize(base::PickleSizer* sizer,
387 const param_type& p) {
388 sizer->AddBytes(sizeof(param_type));
389}
390
rockot502c94f2016-02-03 20:20:16391void ParamTraits<unsigned short>::Write(base::Pickle* m, const param_type& p) {
[email protected]c1ee48d2013-07-12 23:12:28392 m->WriteBytes(&p, sizeof(param_type));
393}
394
rockot502c94f2016-02-03 20:20:16395bool ParamTraits<unsigned short>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25396 base::PickleIterator* iter,
[email protected]c1ee48d2013-07-12 23:12:28397 param_type* r) {
398 const char* data;
avi48fc13b2014-12-28 23:31:48399 if (!iter->ReadBytes(&data, sizeof(param_type)))
[email protected]c1ee48d2013-07-12 23:12:28400 return false;
401 memcpy(r, data, sizeof(param_type));
402 return true;
403}
404
405void ParamTraits<unsigned short>::Log(const param_type& p, std::string* l) {
406 l->append(base::UintToString(p));
407}
408
[email protected]252cad62010-08-18 18:33:57409void ParamTraits<int>::Log(const param_type& p, std::string* l) {
410 l->append(base::IntToString(p));
411}
412
413void ParamTraits<unsigned int>::Log(const param_type& p, std::string* l) {
414 l->append(base::UintToString(p));
415}
416
417void ParamTraits<long>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:57418 l->append(base::Int64ToString(static_cast<int64_t>(p)));
[email protected]252cad62010-08-18 18:33:57419}
420
421void ParamTraits<unsigned long>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:57422 l->append(base::Uint64ToString(static_cast<uint64_t>(p)));
[email protected]252cad62010-08-18 18:33:57423}
424
425void ParamTraits<long long>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:57426 l->append(base::Int64ToString(static_cast<int64_t>(p)));
[email protected]252cad62010-08-18 18:33:57427}
428
429void ParamTraits<unsigned long long>::Log(const param_type& p, std::string* l) {
430 l->append(base::Uint64ToString(p));
431}
[email protected]7a4de7a62010-08-17 18:38:24432
[email protected]bf5aedf02012-06-04 21:18:25433void ParamTraits<float>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:04434 l->append(base::StringPrintf("%e", p));
[email protected]7a4de7a62010-08-17 18:38:24435}
436
rockot0457af102016-02-05 02:12:32437void ParamTraits<double>::GetSize(base::PickleSizer* sizer,
438 const param_type& p) {
439 sizer->AddBytes(sizeof(param_type));
440}
441
rockot502c94f2016-02-03 20:20:16442void ParamTraits<double>::Write(base::Pickle* m, const param_type& p) {
[email protected]48328ff2013-10-31 09:27:31443 m->WriteBytes(reinterpret_cast<const char*>(&p), sizeof(param_type));
[email protected]d84e48b2010-10-21 22:04:52444}
445
rockot502c94f2016-02-03 20:20:16446bool ParamTraits<double>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25447 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25448 param_type* r) {
449 const char *data;
avi48fc13b2014-12-28 23:31:48450 if (!iter->ReadBytes(&data, sizeof(*r))) {
[email protected]bf5aedf02012-06-04 21:18:25451 NOTREACHED();
452 return false;
453 }
454 memcpy(r, data, sizeof(param_type));
455 return true;
[email protected]d84e48b2010-10-21 22:04:52456}
457
[email protected]bf5aedf02012-06-04 21:18:25458void ParamTraits<double>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:04459 l->append(base::StringPrintf("%e", p));
[email protected]1d14f582011-09-02 20:42:04460}
461
[email protected]bf5aedf02012-06-04 21:18:25462
463void ParamTraits<std::string>::Log(const param_type& p, std::string* l) {
464 l->append(p);
[email protected]1d14f582011-09-02 20:42:04465}
466
[email protected]476dafb2013-12-03 00:39:26467void ParamTraits<base::string16>::Log(const param_type& p, std::string* l) {
[email protected]ad65a3e2013-12-25 18:18:01468 l->append(base::UTF16ToUTF8(p));
[email protected]bf5aedf02012-06-04 21:18:25469}
[email protected]bf5aedf02012-06-04 21:18:25470
rockot0457af102016-02-05 02:12:32471void ParamTraits<std::vector<char>>::GetSize(base::PickleSizer* sizer,
472 const param_type& p) {
473 sizer->AddData(static_cast<int>(p.size()));
474}
475
rockot502c94f2016-02-03 20:20:16476void ParamTraits<std::vector<char>>::Write(base::Pickle* m,
477 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25478 if (p.empty()) {
479 m->WriteData(NULL, 0);
480 } else {
481 m->WriteData(&p.front(), static_cast<int>(p.size()));
482 }
483}
484
rockot502c94f2016-02-03 20:20:16485bool ParamTraits<std::vector<char>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25486 base::PickleIterator* iter,
487 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25488 const char *data;
489 int data_size = 0;
avi48fc13b2014-12-28 23:31:48490 if (!iter->ReadData(&data, &data_size) || data_size < 0)
[email protected]bf5aedf02012-06-04 21:18:25491 return false;
492 r->resize(data_size);
493 if (data_size)
494 memcpy(&r->front(), data, data_size);
495 return true;
496}
497
498void ParamTraits<std::vector<char> >::Log(const param_type& p, std::string* l) {
499 LogBytes(p, l);
500}
501
rockot0457af102016-02-05 02:12:32502void ParamTraits<std::vector<unsigned char>>::GetSize(base::PickleSizer* sizer,
503 const param_type& p) {
504 sizer->AddData(static_cast<int>(p.size()));
505}
506
rockot502c94f2016-02-03 20:20:16507void ParamTraits<std::vector<unsigned char>>::Write(base::Pickle* m,
508 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25509 if (p.empty()) {
510 m->WriteData(NULL, 0);
511 } else {
512 m->WriteData(reinterpret_cast<const char*>(&p.front()),
513 static_cast<int>(p.size()));
514 }
515}
516
rockot502c94f2016-02-03 20:20:16517bool ParamTraits<std::vector<unsigned char>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25518 base::PickleIterator* iter,
519 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25520 const char *data;
521 int data_size = 0;
avi48fc13b2014-12-28 23:31:48522 if (!iter->ReadData(&data, &data_size) || data_size < 0)
[email protected]bf5aedf02012-06-04 21:18:25523 return false;
524 r->resize(data_size);
525 if (data_size)
526 memcpy(&r->front(), data, data_size);
527 return true;
528}
529
530void ParamTraits<std::vector<unsigned char> >::Log(const param_type& p,
531 std::string* l) {
532 LogBytes(p, l);
533}
534
rockot0457af102016-02-05 02:12:32535void ParamTraits<std::vector<bool>>::GetSize(base::PickleSizer* sizer,
536 const param_type& p) {
537 GetParamSize(sizer, static_cast<int>(p.size()));
538 for (size_t i = 0; i < p.size(); ++i)
539 GetParamSize(sizer, static_cast<bool>(p[i]));
540}
541
rockot502c94f2016-02-03 20:20:16542void ParamTraits<std::vector<bool>>::Write(base::Pickle* m,
543 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25544 WriteParam(m, static_cast<int>(p.size()));
[email protected]d4124852013-03-20 20:25:00545 // Cast to bool below is required because libc++'s
546 // vector<bool>::const_reference is different from bool, and we want to avoid
547 // writing an extra specialization of ParamTraits for it.
[email protected]bf5aedf02012-06-04 21:18:25548 for (size_t i = 0; i < p.size(); i++)
[email protected]d4124852013-03-20 20:25:00549 WriteParam(m, static_cast<bool>(p[i]));
[email protected]bf5aedf02012-06-04 21:18:25550}
551
rockot502c94f2016-02-03 20:20:16552bool ParamTraits<std::vector<bool>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25553 base::PickleIterator* iter,
554 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25555 int size;
556 // ReadLength() checks for < 0 itself.
avi48fc13b2014-12-28 23:31:48557 if (!iter->ReadLength(&size))
[email protected]bf5aedf02012-06-04 21:18:25558 return false;
559 r->resize(size);
560 for (int i = 0; i < size; i++) {
561 bool value;
562 if (!ReadParam(m, iter, &value))
563 return false;
564 (*r)[i] = value;
565 }
566 return true;
567}
568
569void ParamTraits<std::vector<bool> >::Log(const param_type& p, std::string* l) {
570 for (size_t i = 0; i < p.size(); ++i) {
571 if (i != 0)
572 l->push_back(' ');
[email protected]d4124852013-03-20 20:25:00573 LogParam(static_cast<bool>(p[i]), l);
[email protected]bf5aedf02012-06-04 21:18:25574 }
[email protected]d84e48b2010-10-21 22:04:52575}
576
erikcheneece6c32015-07-07 22:13:11577void ParamTraits<BrokerableAttachment::AttachmentId>::Write(
rockot502c94f2016-02-03 20:20:16578 base::Pickle* m,
erikcheneece6c32015-07-07 22:13:11579 const param_type& p) {
erikchen06faf0c2015-08-27 19:49:58580 m->WriteBytes(p.nonce, BrokerableAttachment::kNonceSize);
erikcheneece6c32015-07-07 22:13:11581}
582
583bool ParamTraits<BrokerableAttachment::AttachmentId>::Read(
rockot502c94f2016-02-03 20:20:16584 const base::Pickle* m,
erikcheneece6c32015-07-07 22:13:11585 base::PickleIterator* iter,
586 param_type* r) {
587 const char* data;
erikchen06faf0c2015-08-27 19:49:58588 if (!iter->ReadBytes(&data, BrokerableAttachment::kNonceSize))
erikcheneece6c32015-07-07 22:13:11589 return false;
590 memcpy(r->nonce, data, BrokerableAttachment::kNonceSize);
591 return true;
592}
593
594void ParamTraits<BrokerableAttachment::AttachmentId>::Log(const param_type& p,
595 std::string* l) {
596 l->append(base::HexEncode(p.nonce, BrokerableAttachment::kNonceSize));
597}
598
rockot0457af102016-02-05 02:12:32599void ParamTraits<base::DictionaryValue>::GetSize(base::PickleSizer* sizer,
600 const param_type& p) {
601 GetValueSize(sizer, &p, 0);
602}
603
rockot502c94f2016-02-03 20:20:16604void ParamTraits<base::DictionaryValue>::Write(base::Pickle* m,
[email protected]ea5ef4c2013-06-13 22:50:27605 const param_type& p) {
[email protected]946d1b22009-07-22 23:57:21606 WriteValue(m, &p, 0);
607}
608
rockot502c94f2016-02-03 20:20:16609bool ParamTraits<base::DictionaryValue>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25610 base::PickleIterator* iter,
611 param_type* r) {
[email protected]946d1b22009-07-22 23:57:21612 int type;
[email protected]0c6c1e42013-06-21 19:42:19613 if (!ReadParam(m, iter, &type) || type != base::Value::TYPE_DICTIONARY)
[email protected]946d1b22009-07-22 23:57:21614 return false;
615
616 return ReadDictionaryValue(m, iter, r, 0);
617}
618
[email protected]ea5ef4c2013-06-13 22:50:27619void ParamTraits<base::DictionaryValue>::Log(const param_type& p,
620 std::string* l) {
[email protected]946d1b22009-07-22 23:57:21621 std::string json;
estade8d046462015-05-16 01:02:34622 base::JSONWriter::Write(p, &json);
[email protected]252cad62010-08-18 18:33:57623 l->append(json);
[email protected]946d1b22009-07-22 23:57:21624}
625
[email protected]7a4de7a62010-08-17 18:38:24626#if defined(OS_POSIX)
rockot502c94f2016-02-03 20:20:16627void ParamTraits<base::FileDescriptor>::Write(base::Pickle* m,
628 const param_type& p) {
[email protected]7a4de7a62010-08-17 18:38:24629 const bool valid = p.fd >= 0;
630 WriteParam(m, valid);
631
morrita96693852014-09-24 20:11:45632 if (!valid)
633 return;
634
635 if (p.auto_close) {
morrita1aa788c2015-01-31 05:45:42636 if (!m->WriteAttachment(
637 new internal::PlatformFileAttachment(base::ScopedFD(p.fd))))
morrita96693852014-09-24 20:11:45638 NOTREACHED();
639 } else {
morrita1aa788c2015-01-31 05:45:42640 if (!m->WriteAttachment(new internal::PlatformFileAttachment(p.fd)))
[email protected]7a4de7a62010-08-17 18:38:24641 NOTREACHED();
642 }
643}
644
rockot502c94f2016-02-03 20:20:16645bool ParamTraits<base::FileDescriptor>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25646 base::PickleIterator* iter,
[email protected]7a4de7a62010-08-17 18:38:24647 param_type* r) {
morrita96693852014-09-24 20:11:45648 *r = base::FileDescriptor();
649
[email protected]7a4de7a62010-08-17 18:38:24650 bool valid;
651 if (!ReadParam(m, iter, &valid))
652 return false;
653
morrita96693852014-09-24 20:11:45654 // TODO(morrita): Seems like this should return false.
655 if (!valid)
[email protected]7a4de7a62010-08-17 18:38:24656 return true;
[email protected]7a4de7a62010-08-17 18:38:24657
rockot502c94f2016-02-03 20:20:16658 scoped_refptr<base::Pickle::Attachment> attachment;
morrita1aa788c2015-01-31 05:45:42659 if (!m->ReadAttachment(iter, &attachment))
morrita96693852014-09-24 20:11:45660 return false;
661
rockot502c94f2016-02-03 20:20:16662 *r = base::FileDescriptor(
663 static_cast<MessageAttachment*>(attachment.get())->TakePlatformFile(),
664 true);
morrita96693852014-09-24 20:11:45665 return true;
[email protected]7a4de7a62010-08-17 18:38:24666}
667
668void ParamTraits<base::FileDescriptor>::Log(const param_type& p,
[email protected]252cad62010-08-18 18:33:57669 std::string* l) {
[email protected]7a4de7a62010-08-17 18:38:24670 if (p.auto_close) {
[email protected]7d3cbc92013-03-18 22:33:04671 l->append(base::StringPrintf("FD(%d auto-close)", p.fd));
[email protected]7a4de7a62010-08-17 18:38:24672 } else {
[email protected]7d3cbc92013-03-18 22:33:04673 l->append(base::StringPrintf("FD(%d)", p.fd));
[email protected]7a4de7a62010-08-17 18:38:24674 }
675}
676#endif // defined(OS_POSIX)
677
scottmgd19b4f72015-06-19 22:51:00678#if defined(OS_MACOSX) && !defined(OS_IOS)
rockot502c94f2016-02-03 20:20:16679void ParamTraits<base::SharedMemoryHandle>::Write(base::Pickle* m,
scottmgd19b4f72015-06-19 22:51:00680 const param_type& p) {
681 m->WriteInt(p.GetType());
682
erikchen0d779702015-10-02 23:49:26683 switch (p.GetType()) {
684 case base::SharedMemoryHandle::POSIX:
685 ParamTraits<base::FileDescriptor>::Write(m, p.GetFileDescriptor());
686 break;
687 case base::SharedMemoryHandle::MACH:
erikchenaf8299d2015-10-09 19:12:06688 MachPortMac mach_port_mac(p.GetMemoryObject());
689 ParamTraits<MachPortMac>::Write(m, mach_port_mac);
690 size_t size = 0;
691 bool result = p.GetSize(&size);
692 DCHECK(result);
693 ParamTraits<size_t>::Write(m, size);
erikchen328bf3f2015-10-24 00:46:54694
695 // If the caller intended to pass ownership to the IPC stack, release a
696 // reference.
697 if (p.OwnershipPassesToIPC())
698 p.Close();
699
erikchen0d779702015-10-02 23:49:26700 break;
701 }
scottmgd19b4f72015-06-19 22:51:00702}
703
rockot502c94f2016-02-03 20:20:16704bool ParamTraits<base::SharedMemoryHandle>::Read(const base::Pickle* m,
scottmgd19b4f72015-06-19 22:51:00705 base::PickleIterator* iter,
706 param_type* r) {
707 base::SharedMemoryHandle::TypeWireFormat type;
708 if (!iter->ReadInt(&type))
709 return false;
710
711 base::SharedMemoryHandle::Type shm_type = base::SharedMemoryHandle::POSIX;
712 switch (type) {
713 case base::SharedMemoryHandle::POSIX:
714 case base::SharedMemoryHandle::MACH: {
715 shm_type = static_cast<base::SharedMemoryHandle::Type>(type);
716 break;
717 }
erikchen0d779702015-10-02 23:49:26718 default: {
scottmgd19b4f72015-06-19 22:51:00719 return false;
erikchen0d779702015-10-02 23:49:26720 }
scottmgd19b4f72015-06-19 22:51:00721 }
722
erikchen0d779702015-10-02 23:49:26723 switch (shm_type) {
724 case base::SharedMemoryHandle::POSIX: {
725 base::FileDescriptor file_descriptor;
scottmgd19b4f72015-06-19 22:51:00726
erikchen0d779702015-10-02 23:49:26727 bool success =
728 ParamTraits<base::FileDescriptor>::Read(m, iter, &file_descriptor);
729 if (!success)
730 return false;
scottmgd19b4f72015-06-19 22:51:00731
erikchen0d779702015-10-02 23:49:26732 *r = base::SharedMemoryHandle(file_descriptor.fd,
733 file_descriptor.auto_close);
734 return true;
735 }
736 case base::SharedMemoryHandle::MACH: {
erikchenaf8299d2015-10-09 19:12:06737 MachPortMac mach_port_mac;
738 if (!ParamTraits<MachPortMac>::Read(m, iter, &mach_port_mac))
739 return false;
740
741 size_t size;
742 if (!ParamTraits<size_t>::Read(m, iter, &size))
743 return false;
744
745 *r = base::SharedMemoryHandle(mach_port_mac.get_mach_port(), size,
746 base::GetCurrentProcId());
erikchen0d779702015-10-02 23:49:26747 return true;
748 }
scottmgd19b4f72015-06-19 22:51:00749 }
scottmgd19b4f72015-06-19 22:51:00750}
751
752void ParamTraits<base::SharedMemoryHandle>::Log(const param_type& p,
753 std::string* l) {
erikchen0d779702015-10-02 23:49:26754 switch (p.GetType()) {
755 case base::SharedMemoryHandle::POSIX:
756 l->append("POSIX Fd: ");
757 ParamTraits<base::FileDescriptor>::Log(p.GetFileDescriptor(), l);
758 break;
759 case base::SharedMemoryHandle::MACH:
erikchenaf8299d2015-10-09 19:12:06760 l->append("Mach port: ");
761 LogParam(p.GetMemoryObject(), l);
erikchen0d779702015-10-02 23:49:26762 break;
scottmgd19b4f72015-06-19 22:51:00763 }
764}
erikchen0d779702015-10-02 23:49:26765
erikchen5ea2ab72015-09-25 22:34:31766#elif defined(OS_WIN)
rockot502c94f2016-02-03 20:20:16767void ParamTraits<base::SharedMemoryHandle>::Write(base::Pickle* m,
erikchen5ea2ab72015-09-25 22:34:31768 const param_type& p) {
erikchen5ea2ab72015-09-25 22:34:31769 m->WriteBool(p.NeedsBrokering());
770
771 if (p.NeedsBrokering()) {
772 HandleWin handle_win(p.GetHandle(), HandleWin::DUPLICATE);
773 ParamTraits<HandleWin>::Write(m, handle_win);
erikchen71bc3b22016-02-01 22:14:28774
775 // If the caller intended to pass ownership to the IPC stack, release a
776 // reference.
777 if (p.OwnershipPassesToIPC())
778 p.Close();
erikchen5ea2ab72015-09-25 22:34:31779 } else {
780 m->WriteInt(HandleToLong(p.GetHandle()));
781 }
782}
783
rockot502c94f2016-02-03 20:20:16784bool ParamTraits<base::SharedMemoryHandle>::Read(const base::Pickle* m,
erikchen5ea2ab72015-09-25 22:34:31785 base::PickleIterator* iter,
786 param_type* r) {
erikchen5ea2ab72015-09-25 22:34:31787 bool needs_brokering;
788 if (!iter->ReadBool(&needs_brokering))
789 return false;
790
791 if (needs_brokering) {
792 HandleWin handle_win;
793 if (!ParamTraits<HandleWin>::Read(m, iter, &handle_win))
794 return false;
erikchen3d87ecf72016-01-08 02:17:04795 *r = base::SharedMemoryHandle(handle_win.get_handle(),
796 base::GetCurrentProcId());
erikchen5ea2ab72015-09-25 22:34:31797 return true;
798 }
799
800 int handle_int;
801 if (!iter->ReadInt(&handle_int))
802 return false;
803 HANDLE handle = LongToHandle(handle_int);
erikchen3d87ecf72016-01-08 02:17:04804 *r = base::SharedMemoryHandle(handle, base::GetCurrentProcId());
erikchen5ea2ab72015-09-25 22:34:31805 return true;
806}
807
808void ParamTraits<base::SharedMemoryHandle>::Log(const param_type& p,
809 std::string* l) {
erikchen5ea2ab72015-09-25 22:34:31810 LogParam(p.GetHandle(), l);
811 l->append(" needs brokering: ");
812 LogParam(p.NeedsBrokering(), l);
813}
scottmgd19b4f72015-06-19 22:51:00814#endif // defined(OS_MACOSX) && !defined(OS_IOS)
815
rockot0457af102016-02-05 02:12:32816void ParamTraits<base::FilePath>::GetSize(base::PickleSizer* sizer,
817 const param_type& p) {
818 p.GetSizeForPickle(sizer);
819}
820
rockot502c94f2016-02-03 20:20:16821void ParamTraits<base::FilePath>::Write(base::Pickle* m, const param_type& p) {
[email protected]aeae59f2013-01-28 13:47:55822 p.WriteToPickle(m);
[email protected]bf5aedf02012-06-04 21:18:25823}
824
rockot502c94f2016-02-03 20:20:16825bool ParamTraits<base::FilePath>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25826 base::PickleIterator* iter,
[email protected]6d4b67a2013-02-10 04:49:30827 param_type* r) {
[email protected]aeae59f2013-01-28 13:47:55828 return r->ReadFromPickle(iter);
[email protected]bf5aedf02012-06-04 21:18:25829}
830
[email protected]6d4b67a2013-02-10 04:49:30831void ParamTraits<base::FilePath>::Log(const param_type& p, std::string* l) {
832 ParamTraits<base::FilePath::StringType>::Log(p.value(), l);
[email protected]bf5aedf02012-06-04 21:18:25833}
834
rockot0457af102016-02-05 02:12:32835void ParamTraits<base::ListValue>::GetSize(base::PickleSizer* sizer,
836 const param_type& p) {
837 GetValueSize(sizer, &p, 0);
838}
839
rockot502c94f2016-02-03 20:20:16840void ParamTraits<base::ListValue>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25841 WriteValue(m, &p, 0);
842}
843
rockot502c94f2016-02-03 20:20:16844bool ParamTraits<base::ListValue>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25845 base::PickleIterator* iter,
846 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25847 int type;
[email protected]0c6c1e42013-06-21 19:42:19848 if (!ReadParam(m, iter, &type) || type != base::Value::TYPE_LIST)
[email protected]bf5aedf02012-06-04 21:18:25849 return false;
850
851 return ReadListValue(m, iter, r, 0);
852}
853
[email protected]ea5ef4c2013-06-13 22:50:27854void ParamTraits<base::ListValue>::Log(const param_type& p, std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:25855 std::string json;
estade8d046462015-05-16 01:02:34856 base::JSONWriter::Write(p, &json);
[email protected]bf5aedf02012-06-04 21:18:25857 l->append(json);
858}
859
rockot0457af102016-02-05 02:12:32860void ParamTraits<base::NullableString16>::GetSize(base::PickleSizer* sizer,
861 const param_type& p) {
862 GetParamSize(sizer, p.string());
863 GetParamSize(sizer, p.is_null());
864}
865
rockot502c94f2016-02-03 20:20:16866void ParamTraits<base::NullableString16>::Write(base::Pickle* m,
[email protected]0238a162013-06-13 13:47:46867 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25868 WriteParam(m, p.string());
869 WriteParam(m, p.is_null());
870}
871
rockot502c94f2016-02-03 20:20:16872bool ParamTraits<base::NullableString16>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25873 base::PickleIterator* iter,
[email protected]0238a162013-06-13 13:47:46874 param_type* r) {
[email protected]476dafb2013-12-03 00:39:26875 base::string16 string;
[email protected]bf5aedf02012-06-04 21:18:25876 if (!ReadParam(m, iter, &string))
877 return false;
878 bool is_null;
879 if (!ReadParam(m, iter, &is_null))
880 return false;
[email protected]0238a162013-06-13 13:47:46881 *r = base::NullableString16(string, is_null);
[email protected]bf5aedf02012-06-04 21:18:25882 return true;
883}
884
[email protected]0238a162013-06-13 13:47:46885void ParamTraits<base::NullableString16>::Log(const param_type& p,
886 std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:25887 l->append("(");
888 LogParam(p.string(), l);
889 l->append(", ");
890 LogParam(p.is_null(), l);
891 l->append(")");
892}
893
rockot0457af102016-02-05 02:12:32894void ParamTraits<base::File::Info>::GetSize(base::PickleSizer* sizer,
895 const param_type& p) {
896 GetParamSize(sizer, p.size);
897 GetParamSize(sizer, p.is_directory);
898 GetParamSize(sizer, p.last_modified.ToDoubleT());
899 GetParamSize(sizer, p.last_accessed.ToDoubleT());
900 GetParamSize(sizer, p.creation_time.ToDoubleT());
901}
902
rockot502c94f2016-02-03 20:20:16903void ParamTraits<base::File::Info>::Write(base::Pickle* m,
[email protected]141bcc52014-01-27 21:36:00904 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25905 WriteParam(m, p.size);
906 WriteParam(m, p.is_directory);
907 WriteParam(m, p.last_modified.ToDoubleT());
908 WriteParam(m, p.last_accessed.ToDoubleT());
909 WriteParam(m, p.creation_time.ToDoubleT());
910}
911
rockot502c94f2016-02-03 20:20:16912bool ParamTraits<base::File::Info>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25913 base::PickleIterator* iter,
[email protected]141bcc52014-01-27 21:36:00914 param_type* p) {
[email protected]481c3e82014-07-18 01:40:47915 double last_modified, last_accessed, creation_time;
916 if (!ReadParam(m, iter, &p->size) ||
917 !ReadParam(m, iter, &p->is_directory) ||
918 !ReadParam(m, iter, &last_modified) ||
919 !ReadParam(m, iter, &last_accessed) ||
920 !ReadParam(m, iter, &creation_time))
921 return false;
922 p->last_modified = base::Time::FromDoubleT(last_modified);
923 p->last_accessed = base::Time::FromDoubleT(last_accessed);
924 p->creation_time = base::Time::FromDoubleT(creation_time);
925 return true;
[email protected]bf5aedf02012-06-04 21:18:25926}
927
[email protected]141bcc52014-01-27 21:36:00928void ParamTraits<base::File::Info>::Log(const param_type& p,
929 std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:25930 l->append("(");
931 LogParam(p.size, l);
932 l->append(",");
933 LogParam(p.is_directory, l);
934 l->append(",");
935 LogParam(p.last_modified.ToDoubleT(), l);
936 l->append(",");
937 LogParam(p.last_accessed.ToDoubleT(), l);
938 l->append(",");
939 LogParam(p.creation_time.ToDoubleT(), l);
940 l->append(")");
941}
942
rockot0457af102016-02-05 02:12:32943void ParamTraits<base::Time>::GetSize(base::PickleSizer* sizer,
944 const param_type& p) {
945 sizer->AddInt64();
946}
947
rockot502c94f2016-02-03 20:20:16948void ParamTraits<base::Time>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:57949 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:25950}
951
rockot502c94f2016-02-03 20:20:16952bool ParamTraits<base::Time>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25953 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25954 param_type* r) {
tfarina10a5c062015-09-04 18:47:57955 int64_t value;
956 if (!ParamTraits<int64_t>::Read(m, iter, &value))
[email protected]bf5aedf02012-06-04 21:18:25957 return false;
958 *r = base::Time::FromInternalValue(value);
959 return true;
960}
961
962void ParamTraits<base::Time>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:57963 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:25964}
965
rockot0457af102016-02-05 02:12:32966void ParamTraits<base::TimeDelta>::GetSize(base::PickleSizer* sizer,
967 const param_type& p) {
968 sizer->AddInt64();
969}
970
rockot502c94f2016-02-03 20:20:16971void ParamTraits<base::TimeDelta>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:57972 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:25973}
974
rockot502c94f2016-02-03 20:20:16975bool ParamTraits<base::TimeDelta>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25976 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25977 param_type* r) {
tfarina10a5c062015-09-04 18:47:57978 int64_t value;
979 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
[email protected]bf5aedf02012-06-04 21:18:25980 if (ret)
981 *r = base::TimeDelta::FromInternalValue(value);
982
983 return ret;
984}
985
986void ParamTraits<base::TimeDelta>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:57987 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:25988}
989
rockot0457af102016-02-05 02:12:32990void ParamTraits<base::TimeTicks>::GetSize(base::PickleSizer* sizer,
991 const param_type& p) {
992 sizer->AddInt64();
993}
994
rockot502c94f2016-02-03 20:20:16995void ParamTraits<base::TimeTicks>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:57996 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:25997}
998
rockot502c94f2016-02-03 20:20:16999bool ParamTraits<base::TimeTicks>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251000 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251001 param_type* r) {
tfarina10a5c062015-09-04 18:47:571002 int64_t value;
1003 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
[email protected]bf5aedf02012-06-04 21:18:251004 if (ret)
1005 *r = base::TimeTicks::FromInternalValue(value);
1006
1007 return ret;
1008}
1009
1010void ParamTraits<base::TimeTicks>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571011 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251012}
1013
rockot502c94f2016-02-03 20:20:161014void ParamTraits<IPC::ChannelHandle>::Write(base::Pickle* m,
1015 const param_type& p) {
[email protected]a7c03d4f32012-01-24 02:36:051016#if defined(OS_WIN)
1017 // On Windows marshalling pipe handle is not supported.
1018 DCHECK(p.pipe.handle == NULL);
1019#endif // defined (OS_WIN)
[email protected]7a4de7a62010-08-17 18:38:241020 WriteParam(m, p.name);
1021#if defined(OS_POSIX)
1022 WriteParam(m, p.socket);
1023#endif
1024}
1025
rockot502c94f2016-02-03 20:20:161026bool ParamTraits<IPC::ChannelHandle>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251027 base::PickleIterator* iter,
[email protected]7a4de7a62010-08-17 18:38:241028 param_type* r) {
1029 return ReadParam(m, iter, &r->name)
1030#if defined(OS_POSIX)
1031 && ReadParam(m, iter, &r->socket)
1032#endif
1033 ;
1034}
1035
1036void ParamTraits<IPC::ChannelHandle>::Log(const param_type& p,
[email protected]252cad62010-08-18 18:33:571037 std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:041038 l->append(base::StringPrintf("ChannelHandle(%s", p.name.c_str()));
[email protected]7a4de7a62010-08-17 18:38:241039#if defined(OS_POSIX)
[email protected]3cd3bce2011-09-23 10:32:191040 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:241041 ParamTraits<base::FileDescriptor>::Log(p.socket, l);
1042#endif
[email protected]252cad62010-08-18 18:33:571043 l->append(")");
[email protected]7a4de7a62010-08-17 18:38:241044}
1045
rockot0457af102016-02-05 02:12:321046void ParamTraits<LogData>::GetSize(base::PickleSizer* sizer,
1047 const param_type& p) {
1048 GetParamSize(sizer, p.channel);
1049 GetParamSize(sizer, p.routing_id);
1050 GetParamSize(sizer, p.type);
1051 GetParamSize(sizer, p.flags);
1052 GetParamSize(sizer, p.sent);
1053 GetParamSize(sizer, p.receive);
1054 GetParamSize(sizer, p.dispatch);
1055 GetParamSize(sizer, p.message_name);
1056 GetParamSize(sizer, p.params);
1057}
1058
rockot502c94f2016-02-03 20:20:161059void ParamTraits<LogData>::Write(base::Pickle* m, const param_type& p) {
[email protected]20f0487a2010-09-30 20:06:301060 WriteParam(m, p.channel);
1061 WriteParam(m, p.routing_id);
[email protected]8bf55ca2011-10-17 22:15:271062 WriteParam(m, p.type);
[email protected]20f0487a2010-09-30 20:06:301063 WriteParam(m, p.flags);
1064 WriteParam(m, p.sent);
1065 WriteParam(m, p.receive);
1066 WriteParam(m, p.dispatch);
[email protected]bae578e92012-11-15 03:17:451067 WriteParam(m, p.message_name);
[email protected]20f0487a2010-09-30 20:06:301068 WriteParam(m, p.params);
1069}
1070
rockot502c94f2016-02-03 20:20:161071bool ParamTraits<LogData>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251072 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:561073 param_type* r) {
[email protected]8bf55ca2011-10-17 22:15:271074 return
[email protected]20f0487a2010-09-30 20:06:301075 ReadParam(m, iter, &r->channel) &&
1076 ReadParam(m, iter, &r->routing_id) &&
[email protected]8bf55ca2011-10-17 22:15:271077 ReadParam(m, iter, &r->type) &&
[email protected]20f0487a2010-09-30 20:06:301078 ReadParam(m, iter, &r->flags) &&
1079 ReadParam(m, iter, &r->sent) &&
1080 ReadParam(m, iter, &r->receive) &&
1081 ReadParam(m, iter, &r->dispatch) &&
[email protected]bae578e92012-11-15 03:17:451082 ReadParam(m, iter, &r->message_name) &&
[email protected]20f0487a2010-09-30 20:06:301083 ReadParam(m, iter, &r->params);
[email protected]20f0487a2010-09-30 20:06:301084}
1085
[email protected]bf5aedf02012-06-04 21:18:251086void ParamTraits<LogData>::Log(const param_type& p, std::string* l) {
1087 // Doesn't make sense to implement this!
1088}
1089
rockot502c94f2016-02-03 20:20:161090void ParamTraits<Message>::Write(base::Pickle* m, const Message& p) {
[email protected]34d48612012-06-29 00:05:041091#if defined(OS_POSIX)
1092 // We don't serialize the file descriptors in the nested message, so there
1093 // better not be any.
morrita1aa788c2015-01-31 05:45:421094 DCHECK(!p.HasAttachments());
[email protected]34d48612012-06-29 00:05:041095#endif
1096
1097 // Don't just write out the message. This is used to send messages between
1098 // NaCl (Posix environment) and the browser (could be on Windows). The message
1099 // header formats differ between these systems (so does handle sharing, but
1100 // we already asserted we don't have any handles). So just write out the
1101 // parts of the header we use.
1102 //
1103 // Be careful also to use only explicitly-sized types. The NaCl environment
1104 // could be 64-bit and the host browser could be 32-bits. The nested message
1105 // may or may not be safe to send between 32-bit and 64-bit systems, but we
1106 // leave that up to the code sending the message to ensure.
tfarina10a5c062015-09-04 18:47:571107 m->WriteUInt32(static_cast<uint32_t>(p.routing_id()));
[email protected]34d48612012-06-29 00:05:041108 m->WriteUInt32(p.type());
1109 m->WriteUInt32(p.flags());
tfarina10a5c062015-09-04 18:47:571110 m->WriteData(p.payload(), static_cast<uint32_t>(p.payload_size()));
[email protected]bf5aedf02012-06-04 21:18:251111}
1112
rockot502c94f2016-02-03 20:20:161113bool ParamTraits<Message>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251114 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251115 Message* r) {
tfarina10a5c062015-09-04 18:47:571116 uint32_t routing_id, type, flags;
avi48fc13b2014-12-28 23:31:481117 if (!iter->ReadUInt32(&routing_id) ||
1118 !iter->ReadUInt32(&type) ||
1119 !iter->ReadUInt32(&flags))
[email protected]bf5aedf02012-06-04 21:18:251120 return false;
[email protected]34d48612012-06-29 00:05:041121
1122 int payload_size;
1123 const char* payload;
avi48fc13b2014-12-28 23:31:481124 if (!iter->ReadData(&payload, &payload_size))
[email protected]bf5aedf02012-06-04 21:18:251125 return false;
[email protected]34d48612012-06-29 00:05:041126
tfarina10a5c062015-09-04 18:47:571127 r->SetHeaderValues(static_cast<int32_t>(routing_id), type, flags);
[email protected]34d48612012-06-29 00:05:041128 return r->WriteBytes(payload, payload_size);
[email protected]bf5aedf02012-06-04 21:18:251129}
1130
1131void ParamTraits<Message>::Log(const Message& p, std::string* l) {
1132 l->append("<IPC::Message>");
1133}
1134
1135#if defined(OS_WIN)
rockot0457af102016-02-05 02:12:321136void ParamTraits<HANDLE>::GetSize(base::PickleSizer* sizer,
1137 const param_type& p) {
1138 sizer->AddInt();
1139}
1140
[email protected]bf5aedf02012-06-04 21:18:251141// Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
[email protected]4a635b72013-03-04 02:29:031142// bit systems. That's why we use the Windows macros to convert to 32 bits.
rockot502c94f2016-02-03 20:20:161143void ParamTraits<HANDLE>::Write(base::Pickle* m, const param_type& p) {
[email protected]4a635b72013-03-04 02:29:031144 m->WriteInt(HandleToLong(p));
[email protected]bf5aedf02012-06-04 21:18:251145}
1146
rockot502c94f2016-02-03 20:20:161147bool ParamTraits<HANDLE>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251148 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251149 param_type* r) {
tfarina10a5c062015-09-04 18:47:571150 int32_t temp;
avi48fc13b2014-12-28 23:31:481151 if (!iter->ReadInt(&temp))
[email protected]bf5aedf02012-06-04 21:18:251152 return false;
[email protected]4a635b72013-03-04 02:29:031153 *r = LongToHandle(temp);
[email protected]bf5aedf02012-06-04 21:18:251154 return true;
1155}
1156
1157void ParamTraits<HANDLE>::Log(const param_type& p, std::string* l) {
brucedawson5604a11d2015-10-06 19:22:001158 l->append(base::StringPrintf("0x%p", p));
[email protected]bf5aedf02012-06-04 21:18:251159}
1160
rockot0457af102016-02-05 02:12:321161void ParamTraits<LOGFONT>::GetSize(base::PickleSizer* sizer,
1162 const param_type& p) {
1163 sizer->AddData(sizeof(LOGFONT));
1164}
1165
rockot502c94f2016-02-03 20:20:161166void ParamTraits<LOGFONT>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251167 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
1168}
1169
rockot502c94f2016-02-03 20:20:161170bool ParamTraits<LOGFONT>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251171 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251172 param_type* r) {
1173 const char *data;
1174 int data_size = 0;
avi48fc13b2014-12-28 23:31:481175 if (iter->ReadData(&data, &data_size) && data_size == sizeof(LOGFONT)) {
[email protected]2e02cfe82012-11-21 00:58:001176 const LOGFONT *font = reinterpret_cast<LOGFONT*>(const_cast<char*>(data));
1177 if (_tcsnlen(font->lfFaceName, LF_FACESIZE) < LF_FACESIZE) {
1178 memcpy(r, data, sizeof(LOGFONT));
1179 return true;
1180 }
[email protected]bf5aedf02012-06-04 21:18:251181 }
1182
[email protected]2e02cfe82012-11-21 00:58:001183 NOTREACHED();
1184 return false;
[email protected]bf5aedf02012-06-04 21:18:251185}
1186
1187void ParamTraits<LOGFONT>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:041188 l->append(base::StringPrintf("<LOGFONT>"));
[email protected]bf5aedf02012-06-04 21:18:251189}
1190
rockot0457af102016-02-05 02:12:321191void ParamTraits<MSG>::GetSize(base::PickleSizer* sizer, const param_type& p) {
1192 sizer->AddData(sizeof(MSG));
1193}
1194
rockot502c94f2016-02-03 20:20:161195void ParamTraits<MSG>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251196 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
1197}
1198
rockot502c94f2016-02-03 20:20:161199bool ParamTraits<MSG>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251200 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251201 param_type* r) {
1202 const char *data;
1203 int data_size = 0;
avi48fc13b2014-12-28 23:31:481204 bool result = iter->ReadData(&data, &data_size);
[email protected]bf5aedf02012-06-04 21:18:251205 if (result && data_size == sizeof(MSG)) {
1206 memcpy(r, data, sizeof(MSG));
1207 } else {
1208 result = false;
1209 NOTREACHED();
1210 }
1211
1212 return result;
1213}
1214
1215void ParamTraits<MSG>::Log(const param_type& p, std::string* l) {
1216 l->append("<MSG>");
1217}
1218
1219#endif // OS_WIN
1220
[email protected]946d1b22009-07-22 23:57:211221} // namespace IPC