blob: 1a7966e8a14610e0df2bc13b412ea7d15a8f056a [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"
jdoerrief1e72e32017-04-26 16:23:5512#include "base/memory/ptr_util.h"
erikchen22a813b2017-04-28 17:10:5013#include "base/memory/shared_memory_handle.h"
[email protected]0238a162013-06-13 13:47:4614#include "base/strings/nullable_string16.h"
[email protected]4aa794a12013-06-11 06:32:1815#include "base/strings/string_number_conversions.h"
[email protected]906265872013-06-07 22:40:4516#include "base/strings/utf_string_conversions.h"
[email protected]b43e5562013-06-28 15:20:0217#include "base/time/time.h"
tguilbert4a5ac602016-09-19 21:11:2518#include "base/unguessable_token.h"
[email protected]946d1b22009-07-22 23:57:2119#include "base/values.h"
avi246998d82015-12-22 02:39:0420#include "build/build_config.h"
[email protected]bf5aedf02012-06-04 21:18:2521#include "ipc/ipc_channel_handle.h"
morrita1aa788c2015-01-31 05:45:4222#include "ipc/ipc_message_attachment.h"
morrita4b5c28e22015-01-14 21:17:0623#include "ipc/ipc_message_attachment_set.h"
amistry36182522016-06-27 06:34:4224#include "ipc/ipc_mojo_param_traits.h"
[email protected]bf5aedf02012-06-04 21:18:2525
morrita1aa788c2015-01-31 05:45:4226#if defined(OS_POSIX)
sammc9bf370c2016-11-14 03:29:0827#include "base/file_descriptor_posix.h"
morrita1aa788c2015-01-31 05:45:4228#include "ipc/ipc_platform_file_attachment_posix.h"
29#endif
30
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"
erikchend804e1052017-04-29 02:24:3638#include "ipc/ipc_platform_file.h"
[email protected]7a4de7a62010-08-17 18:38:2439#endif
[email protected]946d1b22009-07-22 23:57:2140
Scott Graham3eebff02017-06-30 01:07:1041#if defined(OS_FUCHSIA)
42#include "ipc/handle_fuchsia.h"
43#endif
44
[email protected]946d1b22009-07-22 23:57:2145namespace IPC {
46
[email protected]bf5aedf02012-06-04 21:18:2547namespace {
48
joaodasilva383b174a2017-01-10 09:55:3649const int kMaxRecursionDepth = 200;
[email protected]946d1b22009-07-22 23:57:2150
[email protected]bf5aedf02012-06-04 21:18:2551template<typename CharType>
52void LogBytes(const std::vector<CharType>& data, std::string* out) {
53#if defined(OS_WIN)
54 // Windows has a GUI for logging, which can handle arbitrary binary data.
55 for (size_t i = 0; i < data.size(); ++i)
56 out->push_back(data[i]);
57#else
58 // On POSIX, we log to stdout, which we assume can display ASCII.
59 static const size_t kMaxBytesToLog = 100;
60 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
61 if (isprint(data[i]))
62 out->push_back(data[i]);
63 else
[email protected]7d3cbc92013-03-18 22:33:0464 out->append(
65 base::StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
[email protected]bf5aedf02012-06-04 21:18:2566 }
67 if (data.size() > kMaxBytesToLog) {
[email protected]f8660f82013-03-30 17:29:2868 out->append(base::StringPrintf(
69 " and %u more bytes",
70 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
[email protected]bf5aedf02012-06-04 21:18:2571 }
72#endif
73}
[email protected]946d1b22009-07-22 23:57:2174
rockot502c94f2016-02-03 20:20:1675bool ReadValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:2576 base::PickleIterator* iter,
jdoerrief1e72e32017-04-26 16:23:5577 std::unique_ptr<base::Value>* value,
[email protected]bf5aedf02012-06-04 21:18:2578 int recursion);
[email protected]946d1b22009-07-22 23:57:2179
rockot0457af102016-02-05 02:12:3280void GetValueSize(base::PickleSizer* sizer,
81 const base::Value* value,
82 int recursion) {
83 if (recursion > kMaxRecursionDepth) {
joaodasilva383b174a2017-01-10 09:55:3684 LOG(ERROR) << "Max recursion depth hit in GetValueSize.";
rockot0457af102016-02-05 02:12:3285 return;
86 }
87
88 sizer->AddInt();
89 switch (value->GetType()) {
jdoerriedc72ee942016-12-07 15:43:2890 case base::Value::Type::NONE:
rockot0457af102016-02-05 02:12:3291 break;
jdoerriedc72ee942016-12-07 15:43:2892 case base::Value::Type::BOOLEAN:
rockot0457af102016-02-05 02:12:3293 sizer->AddBool();
94 break;
jdoerriedc72ee942016-12-07 15:43:2895 case base::Value::Type::INTEGER:
rockot0457af102016-02-05 02:12:3296 sizer->AddInt();
97 break;
jdoerriedc72ee942016-12-07 15:43:2898 case base::Value::Type::DOUBLE:
rockot0457af102016-02-05 02:12:3299 sizer->AddDouble();
100 break;
jdoerriedc72ee942016-12-07 15:43:28101 case base::Value::Type::STRING: {
jdoerrie122c4da2017-03-06 11:12:04102 const base::Value* result;
rockot0457af102016-02-05 02:12:32103 value->GetAsString(&result);
amistryc7a7a762016-04-08 04:21:54104 if (value->GetAsString(&result)) {
105 DCHECK(result);
106 GetParamSize(sizer, result->GetString());
107 } else {
108 std::string str;
109 bool as_string_result = value->GetAsString(&str);
110 DCHECK(as_string_result);
111 GetParamSize(sizer, str);
112 }
rockot0457af102016-02-05 02:12:32113 break;
114 }
jdoerriedc72ee942016-12-07 15:43:28115 case base::Value::Type::BINARY: {
jdoerrie5328aff2017-04-25 20:08:15116 sizer->AddData(static_cast<int>(value->GetBlob().size()));
rockot0457af102016-02-05 02:12:32117 break;
118 }
jdoerriedc72ee942016-12-07 15:43:28119 case base::Value::Type::DICTIONARY: {
rockot0457af102016-02-05 02:12:32120 sizer->AddInt();
121 const base::DictionaryValue* dict =
122 static_cast<const base::DictionaryValue*>(value);
123 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd();
124 it.Advance()) {
125 GetParamSize(sizer, it.key());
126 GetValueSize(sizer, &it.value(), recursion + 1);
127 }
128 break;
129 }
jdoerriedc72ee942016-12-07 15:43:28130 case base::Value::Type::LIST: {
rockot0457af102016-02-05 02:12:32131 sizer->AddInt();
132 const base::ListValue* list = static_cast<const base::ListValue*>(value);
dchengcb60e702016-05-25 18:30:47133 for (const auto& entry : *list) {
jdoerriea5676c62017-04-11 18:09:14134 GetValueSize(sizer, &entry, recursion + 1);
rockot0457af102016-02-05 02:12:32135 }
136 break;
137 }
138 default:
139 NOTREACHED() << "Invalid base::Value type.";
140 }
141}
142
rockot502c94f2016-02-03 20:20:16143void WriteValue(base::Pickle* m, const base::Value* value, int recursion) {
[email protected]dbc761a2012-07-26 01:29:21144 bool result;
[email protected]946d1b22009-07-22 23:57:21145 if (recursion > kMaxRecursionDepth) {
joaodasilva383b174a2017-01-10 09:55:36146 LOG(ERROR) << "Max recursion depth hit in WriteValue.";
[email protected]946d1b22009-07-22 23:57:21147 return;
148 }
149
jdoerriedc72ee942016-12-07 15:43:28150 m->WriteInt(static_cast<int>(value->GetType()));
[email protected]946d1b22009-07-22 23:57:21151
152 switch (value->GetType()) {
jdoerriedc72ee942016-12-07 15:43:28153 case base::Value::Type::NONE:
[email protected]946d1b22009-07-22 23:57:21154 break;
jdoerriedc72ee942016-12-07 15:43:28155 case base::Value::Type::BOOLEAN: {
[email protected]946d1b22009-07-22 23:57:21156 bool val;
[email protected]dbc761a2012-07-26 01:29:21157 result = value->GetAsBoolean(&val);
158 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21159 WriteParam(m, val);
160 break;
161 }
jdoerriedc72ee942016-12-07 15:43:28162 case base::Value::Type::INTEGER: {
[email protected]946d1b22009-07-22 23:57:21163 int val;
[email protected]dbc761a2012-07-26 01:29:21164 result = value->GetAsInteger(&val);
165 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21166 WriteParam(m, val);
167 break;
168 }
jdoerriedc72ee942016-12-07 15:43:28169 case base::Value::Type::DOUBLE: {
[email protected]946d1b22009-07-22 23:57:21170 double val;
[email protected]dbc761a2012-07-26 01:29:21171 result = value->GetAsDouble(&val);
172 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21173 WriteParam(m, val);
174 break;
175 }
jdoerriedc72ee942016-12-07 15:43:28176 case base::Value::Type::STRING: {
[email protected]946d1b22009-07-22 23:57:21177 std::string val;
[email protected]dbc761a2012-07-26 01:29:21178 result = value->GetAsString(&val);
179 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21180 WriteParam(m, val);
181 break;
182 }
jdoerriedc72ee942016-12-07 15:43:28183 case base::Value::Type::BINARY: {
jdoerrie5328aff2017-04-25 20:08:15184 m->WriteData(value->GetBlob().data(),
185 static_cast<int>(value->GetBlob().size()));
[email protected]e4dad9fb2009-10-06 18:15:58186 break;
[email protected]946d1b22009-07-22 23:57:21187 }
jdoerriedc72ee942016-12-07 15:43:28188 case base::Value::Type::DICTIONARY: {
[email protected]ea5ef4c2013-06-13 22:50:27189 const base::DictionaryValue* dict =
190 static_cast<const base::DictionaryValue*>(value);
[email protected]946d1b22009-07-22 23:57:21191
[email protected]4dad9ad82009-11-25 20:47:52192 WriteParam(m, static_cast<int>(dict->size()));
[email protected]946d1b22009-07-22 23:57:21193
[email protected]ea5ef4c2013-06-13 22:50:27194 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd();
195 it.Advance()) {
[email protected]a899c0b02013-01-18 14:43:27196 WriteParam(m, it.key());
197 WriteValue(m, &it.value(), recursion + 1);
[email protected]946d1b22009-07-22 23:57:21198 }
199 break;
200 }
jdoerriedc72ee942016-12-07 15:43:28201 case base::Value::Type::LIST: {
[email protected]ea5ef4c2013-06-13 22:50:27202 const base::ListValue* list = static_cast<const base::ListValue*>(value);
[email protected]946d1b22009-07-22 23:57:21203 WriteParam(m, static_cast<int>(list->GetSize()));
dchengcb60e702016-05-25 18:30:47204 for (const auto& entry : *list) {
jdoerriea5676c62017-04-11 18:09:14205 WriteValue(m, &entry, recursion + 1);
[email protected]946d1b22009-07-22 23:57:21206 }
207 break;
208 }
209 }
210}
211
212// Helper for ReadValue that reads a DictionaryValue into a pre-allocated
213// object.
rockot502c94f2016-02-03 20:20:16214bool ReadDictionaryValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25215 base::PickleIterator* iter,
216 base::DictionaryValue* value,
217 int recursion) {
[email protected]946d1b22009-07-22 23:57:21218 int size;
219 if (!ReadParam(m, iter, &size))
220 return false;
221
222 for (int i = 0; i < size; ++i) {
[email protected]e7b418b2010-07-30 19:47:47223 std::string key;
jdoerrief1e72e32017-04-26 16:23:55224 std::unique_ptr<base::Value> subval;
[email protected]946d1b22009-07-22 23:57:21225 if (!ReadParam(m, iter, &key) ||
226 !ReadValue(m, iter, &subval, recursion + 1))
227 return false;
jdoerrief1e72e32017-04-26 16:23:55228 value->SetWithoutPathExpansion(key, std::move(subval));
[email protected]946d1b22009-07-22 23:57:21229 }
230
231 return true;
232}
233
234// Helper for ReadValue that reads a ReadListValue into a pre-allocated
235// object.
rockot502c94f2016-02-03 20:20:16236bool ReadListValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25237 base::PickleIterator* iter,
238 base::ListValue* value,
239 int recursion) {
[email protected]946d1b22009-07-22 23:57:21240 int size;
241 if (!ReadParam(m, iter, &size))
242 return false;
243
244 for (int i = 0; i < size; ++i) {
jdoerrief1e72e32017-04-26 16:23:55245 std::unique_ptr<base::Value> subval;
[email protected]946d1b22009-07-22 23:57:21246 if (!ReadValue(m, iter, &subval, recursion + 1))
247 return false;
jdoerrief1e72e32017-04-26 16:23:55248 value->Set(i, std::move(subval));
[email protected]946d1b22009-07-22 23:57:21249 }
250
251 return true;
252}
253
rockot502c94f2016-02-03 20:20:16254bool ReadValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25255 base::PickleIterator* iter,
jdoerrief1e72e32017-04-26 16:23:55256 std::unique_ptr<base::Value>* value,
[email protected]bf5aedf02012-06-04 21:18:25257 int recursion) {
[email protected]946d1b22009-07-22 23:57:21258 if (recursion > kMaxRecursionDepth) {
joaodasilva383b174a2017-01-10 09:55:36259 LOG(ERROR) << "Max recursion depth hit in ReadValue.";
[email protected]946d1b22009-07-22 23:57:21260 return false;
261 }
262
263 int type;
264 if (!ReadParam(m, iter, &type))
265 return false;
266
jdoerriedc72ee942016-12-07 15:43:28267 switch (static_cast<base::Value::Type>(type)) {
268 case base::Value::Type::NONE:
jdoerrief1e72e32017-04-26 16:23:55269 *value = base::MakeUnique<base::Value>();
jdoerriee067999a2017-04-07 06:39:00270 break;
jdoerriedc72ee942016-12-07 15:43:28271 case base::Value::Type::BOOLEAN: {
[email protected]946d1b22009-07-22 23:57:21272 bool val;
273 if (!ReadParam(m, iter, &val))
274 return false;
jdoerrief1e72e32017-04-26 16:23:55275 *value = base::MakeUnique<base::Value>(val);
[email protected]946d1b22009-07-22 23:57:21276 break;
277 }
jdoerriedc72ee942016-12-07 15:43:28278 case base::Value::Type::INTEGER: {
[email protected]946d1b22009-07-22 23:57:21279 int val;
280 if (!ReadParam(m, iter, &val))
281 return false;
jdoerrief1e72e32017-04-26 16:23:55282 *value = base::MakeUnique<base::Value>(val);
[email protected]946d1b22009-07-22 23:57:21283 break;
284 }
jdoerriedc72ee942016-12-07 15:43:28285 case base::Value::Type::DOUBLE: {
[email protected]946d1b22009-07-22 23:57:21286 double val;
287 if (!ReadParam(m, iter, &val))
288 return false;
jdoerrief1e72e32017-04-26 16:23:55289 *value = base::MakeUnique<base::Value>(val);
[email protected]946d1b22009-07-22 23:57:21290 break;
291 }
jdoerriedc72ee942016-12-07 15:43:28292 case base::Value::Type::STRING: {
[email protected]946d1b22009-07-22 23:57:21293 std::string val;
294 if (!ReadParam(m, iter, &val))
295 return false;
jdoerrief1e72e32017-04-26 16:23:55296 *value = base::MakeUnique<base::Value>(std::move(val));
[email protected]946d1b22009-07-22 23:57:21297 break;
298 }
jdoerriedc72ee942016-12-07 15:43:28299 case base::Value::Type::BINARY: {
[email protected]e4dad9fb2009-10-06 18:15:58300 const char* data;
301 int length;
avi48fc13b2014-12-28 23:31:48302 if (!iter->ReadData(&data, &length))
[email protected]e4dad9fb2009-10-06 18:15:58303 return false;
jdoerrief1e72e32017-04-26 16:23:55304 *value = base::Value::CreateWithCopiedBuffer(data, length);
[email protected]946d1b22009-07-22 23:57:21305 break;
306 }
jdoerriedc72ee942016-12-07 15:43:28307 case base::Value::Type::DICTIONARY: {
jdoerrief1e72e32017-04-26 16:23:55308 base::DictionaryValue val;
309 if (!ReadDictionaryValue(m, iter, &val, recursion))
[email protected]946d1b22009-07-22 23:57:21310 return false;
jdoerrief1e72e32017-04-26 16:23:55311 *value = base::MakeUnique<base::Value>(std::move(val));
[email protected]946d1b22009-07-22 23:57:21312 break;
313 }
jdoerriedc72ee942016-12-07 15:43:28314 case base::Value::Type::LIST: {
jdoerrief1e72e32017-04-26 16:23:55315 base::ListValue val;
316 if (!ReadListValue(m, iter, &val, recursion))
[email protected]946d1b22009-07-22 23:57:21317 return false;
jdoerrief1e72e32017-04-26 16:23:55318 *value = base::MakeUnique<base::Value>(std::move(val));
[email protected]946d1b22009-07-22 23:57:21319 break;
320 }
[email protected]e4dad9fb2009-10-06 18:15:58321 default:
[email protected]946d1b22009-07-22 23:57:21322 return false;
323 }
324
325 return true;
326}
327
[email protected]bf5aedf02012-06-04 21:18:25328} // namespace
329
330// -----------------------------------------------------------------------------
331
332LogData::LogData()
333 : routing_id(0),
334 type(0),
335 sent(0),
336 receive(0),
337 dispatch(0) {
338}
339
vmpstrbf0d713a2016-03-24 20:22:54340LogData::LogData(const LogData& other) = default;
341
[email protected]bf5aedf02012-06-04 21:18:25342LogData::~LogData() {
343}
344
[email protected]bf5aedf02012-06-04 21:18:25345void ParamTraits<bool>::Log(const param_type& p, std::string* l) {
346 l->append(p ? "true" : "false");
347}
348
rockot0457af102016-02-05 02:12:32349void ParamTraits<signed char>::GetSize(base::PickleSizer* sizer,
350 const param_type& p) {
351 sizer->AddBytes(sizeof(param_type));
352}
353
rockot502c94f2016-02-03 20:20:16354void ParamTraits<signed char>::Write(base::Pickle* m, const param_type& p) {
ortuno19ecf1842015-10-30 00:46:20355 m->WriteBytes(&p, sizeof(param_type));
356}
357
rockot502c94f2016-02-03 20:20:16358bool ParamTraits<signed char>::Read(const base::Pickle* m,
359 base::PickleIterator* iter,
360 param_type* r) {
ortuno19ecf1842015-10-30 00:46:20361 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
368void ParamTraits<signed char>::Log(const param_type& p, std::string* l) {
369 l->append(base::IntToString(p));
370}
371
rockot0457af102016-02-05 02:12:32372void ParamTraits<unsigned char>::GetSize(base::PickleSizer* sizer,
373 const param_type& p) {
374 sizer->AddBytes(sizeof(param_type));
375}
376
rockot502c94f2016-02-03 20:20:16377void ParamTraits<unsigned char>::Write(base::Pickle* m, const param_type& p) {
[email protected]c1ee48d2013-07-12 23:12:28378 m->WriteBytes(&p, sizeof(param_type));
379}
380
rockot502c94f2016-02-03 20:20:16381bool ParamTraits<unsigned char>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25382 base::PickleIterator* iter,
383 param_type* r) {
[email protected]c1ee48d2013-07-12 23:12:28384 const char* data;
avi48fc13b2014-12-28 23:31:48385 if (!iter->ReadBytes(&data, sizeof(param_type)))
[email protected]c1ee48d2013-07-12 23:12:28386 return false;
387 memcpy(r, data, sizeof(param_type));
388 return true;
389}
390
391void ParamTraits<unsigned char>::Log(const param_type& p, std::string* l) {
392 l->append(base::UintToString(p));
393}
394
rockot0457af102016-02-05 02:12:32395void ParamTraits<unsigned short>::GetSize(base::PickleSizer* sizer,
396 const param_type& p) {
397 sizer->AddBytes(sizeof(param_type));
398}
399
rockot502c94f2016-02-03 20:20:16400void ParamTraits<unsigned short>::Write(base::Pickle* m, const param_type& p) {
[email protected]c1ee48d2013-07-12 23:12:28401 m->WriteBytes(&p, sizeof(param_type));
402}
403
rockot502c94f2016-02-03 20:20:16404bool ParamTraits<unsigned short>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25405 base::PickleIterator* iter,
[email protected]c1ee48d2013-07-12 23:12:28406 param_type* r) {
407 const char* data;
avi48fc13b2014-12-28 23:31:48408 if (!iter->ReadBytes(&data, sizeof(param_type)))
[email protected]c1ee48d2013-07-12 23:12:28409 return false;
410 memcpy(r, data, sizeof(param_type));
411 return true;
412}
413
414void ParamTraits<unsigned short>::Log(const param_type& p, std::string* l) {
415 l->append(base::UintToString(p));
416}
417
[email protected]252cad62010-08-18 18:33:57418void ParamTraits<int>::Log(const param_type& p, std::string* l) {
419 l->append(base::IntToString(p));
420}
421
422void ParamTraits<unsigned int>::Log(const param_type& p, std::string* l) {
423 l->append(base::UintToString(p));
424}
425
jamac78d7d82016-02-11 00:50:28426#if defined(OS_WIN) || defined(OS_LINUX) || \
427 (defined(OS_ANDROID) && defined(ARCH_CPU_64_BITS))
[email protected]252cad62010-08-18 18:33:57428void ParamTraits<long>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:57429 l->append(base::Int64ToString(static_cast<int64_t>(p)));
[email protected]252cad62010-08-18 18:33:57430}
431
432void ParamTraits<unsigned long>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:57433 l->append(base::Uint64ToString(static_cast<uint64_t>(p)));
[email protected]252cad62010-08-18 18:33:57434}
jam03d8a782016-02-10 20:13:39435#endif
[email protected]252cad62010-08-18 18:33:57436
437void ParamTraits<long long>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:57438 l->append(base::Int64ToString(static_cast<int64_t>(p)));
[email protected]252cad62010-08-18 18:33:57439}
440
441void ParamTraits<unsigned long long>::Log(const param_type& p, std::string* l) {
442 l->append(base::Uint64ToString(p));
443}
[email protected]7a4de7a62010-08-17 18:38:24444
[email protected]bf5aedf02012-06-04 21:18:25445void ParamTraits<float>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:04446 l->append(base::StringPrintf("%e", p));
[email protected]7a4de7a62010-08-17 18:38:24447}
448
rockot0457af102016-02-05 02:12:32449void ParamTraits<double>::GetSize(base::PickleSizer* sizer,
450 const param_type& p) {
451 sizer->AddBytes(sizeof(param_type));
452}
453
rockot502c94f2016-02-03 20:20:16454void ParamTraits<double>::Write(base::Pickle* m, const param_type& p) {
[email protected]48328ff2013-10-31 09:27:31455 m->WriteBytes(reinterpret_cast<const char*>(&p), sizeof(param_type));
[email protected]d84e48b2010-10-21 22:04:52456}
457
rockot502c94f2016-02-03 20:20:16458bool ParamTraits<double>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25459 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25460 param_type* r) {
461 const char *data;
avi48fc13b2014-12-28 23:31:48462 if (!iter->ReadBytes(&data, sizeof(*r))) {
[email protected]bf5aedf02012-06-04 21:18:25463 NOTREACHED();
464 return false;
465 }
466 memcpy(r, data, sizeof(param_type));
467 return true;
[email protected]d84e48b2010-10-21 22:04:52468}
469
[email protected]bf5aedf02012-06-04 21:18:25470void ParamTraits<double>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:04471 l->append(base::StringPrintf("%e", p));
[email protected]1d14f582011-09-02 20:42:04472}
473
[email protected]bf5aedf02012-06-04 21:18:25474
475void ParamTraits<std::string>::Log(const param_type& p, std::string* l) {
476 l->append(p);
[email protected]1d14f582011-09-02 20:42:04477}
478
[email protected]476dafb2013-12-03 00:39:26479void ParamTraits<base::string16>::Log(const param_type& p, std::string* l) {
[email protected]ad65a3e2013-12-25 18:18:01480 l->append(base::UTF16ToUTF8(p));
[email protected]bf5aedf02012-06-04 21:18:25481}
[email protected]bf5aedf02012-06-04 21:18:25482
rockot0457af102016-02-05 02:12:32483void ParamTraits<std::vector<char>>::GetSize(base::PickleSizer* sizer,
484 const param_type& p) {
485 sizer->AddData(static_cast<int>(p.size()));
486}
487
rockot502c94f2016-02-03 20:20:16488void ParamTraits<std::vector<char>>::Write(base::Pickle* m,
489 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25490 if (p.empty()) {
491 m->WriteData(NULL, 0);
492 } else {
493 m->WriteData(&p.front(), static_cast<int>(p.size()));
494 }
495}
496
rockot502c94f2016-02-03 20:20:16497bool ParamTraits<std::vector<char>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25498 base::PickleIterator* iter,
499 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25500 const char *data;
501 int data_size = 0;
avi48fc13b2014-12-28 23:31:48502 if (!iter->ReadData(&data, &data_size) || data_size < 0)
[email protected]bf5aedf02012-06-04 21:18:25503 return false;
504 r->resize(data_size);
505 if (data_size)
506 memcpy(&r->front(), data, data_size);
507 return true;
508}
509
510void ParamTraits<std::vector<char> >::Log(const param_type& p, std::string* l) {
511 LogBytes(p, l);
512}
513
rockot0457af102016-02-05 02:12:32514void ParamTraits<std::vector<unsigned char>>::GetSize(base::PickleSizer* sizer,
515 const param_type& p) {
516 sizer->AddData(static_cast<int>(p.size()));
517}
518
rockot502c94f2016-02-03 20:20:16519void ParamTraits<std::vector<unsigned char>>::Write(base::Pickle* m,
520 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25521 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
rockot502c94f2016-02-03 20:20:16529bool ParamTraits<std::vector<unsigned char>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25530 base::PickleIterator* iter,
531 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25532 const char *data;
533 int data_size = 0;
avi48fc13b2014-12-28 23:31:48534 if (!iter->ReadData(&data, &data_size) || data_size < 0)
[email protected]bf5aedf02012-06-04 21:18:25535 return false;
536 r->resize(data_size);
537 if (data_size)
538 memcpy(&r->front(), data, data_size);
539 return true;
540}
541
542void ParamTraits<std::vector<unsigned char> >::Log(const param_type& p,
543 std::string* l) {
544 LogBytes(p, l);
545}
546
rockot0457af102016-02-05 02:12:32547void 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
rockot502c94f2016-02-03 20:20:16554void ParamTraits<std::vector<bool>>::Write(base::Pickle* m,
555 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25556 WriteParam(m, static_cast<int>(p.size()));
[email protected]d4124852013-03-20 20:25:00557 // 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.
[email protected]bf5aedf02012-06-04 21:18:25560 for (size_t i = 0; i < p.size(); i++)
[email protected]d4124852013-03-20 20:25:00561 WriteParam(m, static_cast<bool>(p[i]));
[email protected]bf5aedf02012-06-04 21:18:25562}
563
rockot502c94f2016-02-03 20:20:16564bool ParamTraits<std::vector<bool>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25565 base::PickleIterator* iter,
566 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25567 int size;
568 // ReadLength() checks for < 0 itself.
avi48fc13b2014-12-28 23:31:48569 if (!iter->ReadLength(&size))
[email protected]bf5aedf02012-06-04 21:18:25570 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
581void 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(' ');
[email protected]d4124852013-03-20 20:25:00585 LogParam(static_cast<bool>(p[i]), l);
[email protected]bf5aedf02012-06-04 21:18:25586 }
[email protected]d84e48b2010-10-21 22:04:52587}
588
rockot0457af102016-02-05 02:12:32589void ParamTraits<base::DictionaryValue>::GetSize(base::PickleSizer* sizer,
590 const param_type& p) {
591 GetValueSize(sizer, &p, 0);
592}
593
rockot502c94f2016-02-03 20:20:16594void ParamTraits<base::DictionaryValue>::Write(base::Pickle* m,
[email protected]ea5ef4c2013-06-13 22:50:27595 const param_type& p) {
[email protected]946d1b22009-07-22 23:57:21596 WriteValue(m, &p, 0);
597}
598
rockot502c94f2016-02-03 20:20:16599bool ParamTraits<base::DictionaryValue>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25600 base::PickleIterator* iter,
601 param_type* r) {
[email protected]946d1b22009-07-22 23:57:21602 int type;
jdoerriedc72ee942016-12-07 15:43:28603 if (!ReadParam(m, iter, &type) ||
604 type != static_cast<int>(base::Value::Type::DICTIONARY))
[email protected]946d1b22009-07-22 23:57:21605 return false;
606
607 return ReadDictionaryValue(m, iter, r, 0);
608}
609
[email protected]ea5ef4c2013-06-13 22:50:27610void ParamTraits<base::DictionaryValue>::Log(const param_type& p,
611 std::string* l) {
[email protected]946d1b22009-07-22 23:57:21612 std::string json;
estade8d046462015-05-16 01:02:34613 base::JSONWriter::Write(p, &json);
[email protected]252cad62010-08-18 18:33:57614 l->append(json);
[email protected]946d1b22009-07-22 23:57:21615}
616
[email protected]7a4de7a62010-08-17 18:38:24617#if defined(OS_POSIX)
jam45eceef2016-05-11 21:05:05618void ParamTraits<base::FileDescriptor>::GetSize(base::PickleSizer* sizer,
619 const param_type& p) {
620 GetParamSize(sizer, p.fd >= 0);
amistry36182522016-06-27 06:34:42621 if (p.fd >= 0)
622 sizer->AddAttachment();
jam45eceef2016-05-11 21:05:05623}
624
rockot502c94f2016-02-03 20:20:16625void ParamTraits<base::FileDescriptor>::Write(base::Pickle* m,
626 const param_type& p) {
erikchen14525202017-05-06 19:16:51627 // This serialization must be kept in sync with
erikchen9d6afd712017-05-18 17:49:06628 // nacl_message_scanner.cc:WriteHandle().
[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 if (!valid)
[email protected]7a4de7a62010-08-17 18:38:24655 return true;
[email protected]7a4de7a62010-08-17 18:38:24656
rockot502c94f2016-02-03 20:20:16657 scoped_refptr<base::Pickle::Attachment> attachment;
morrita1aa788c2015-01-31 05:45:42658 if (!m->ReadAttachment(iter, &attachment))
morrita96693852014-09-24 20:11:45659 return false;
660
sammc6ed3efb2016-11-23 03:17:35661 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
662 MessageAttachment::Type::PLATFORM_FILE) {
663 return false;
664 }
665
rockot502c94f2016-02-03 20:20:16666 *r = base::FileDescriptor(
sammc6ed3efb2016-11-23 03:17:35667 static_cast<internal::PlatformFileAttachment*>(attachment.get())
668 ->TakePlatformFile(),
rockot502c94f2016-02-03 20:20:16669 true);
morrita96693852014-09-24 20:11:45670 return true;
[email protected]7a4de7a62010-08-17 18:38:24671}
672
673void ParamTraits<base::FileDescriptor>::Log(const param_type& p,
[email protected]252cad62010-08-18 18:33:57674 std::string* l) {
[email protected]7a4de7a62010-08-17 18:38:24675 if (p.auto_close) {
[email protected]7d3cbc92013-03-18 22:33:04676 l->append(base::StringPrintf("FD(%d auto-close)", p.fd));
[email protected]7a4de7a62010-08-17 18:38:24677 } else {
[email protected]7d3cbc92013-03-18 22:33:04678 l->append(base::StringPrintf("FD(%d)", p.fd));
[email protected]7a4de7a62010-08-17 18:38:24679 }
680}
681#endif // defined(OS_POSIX)
682
erikchen9d6afd712017-05-18 17:49:06683void ParamTraits<base::SharedMemoryHandle>::GetSize(base::PickleSizer* sizer,
684 const param_type& p) {
685 GetParamSize(sizer, p.IsValid());
686 if (!p.IsValid())
687 return;
688
scottmgd19b4f72015-06-19 22:51:00689#if defined(OS_MACOSX) && !defined(OS_IOS)
erikchen9d6afd712017-05-18 17:49:06690 GetParamSize(sizer, p.GetMemoryObject());
erikchen14525202017-05-06 19:16:51691#elif defined(OS_WIN)
erikchen9d6afd712017-05-18 17:49:06692 GetParamSize(sizer, p.GetHandle());
693#else
694 sizer->AddAttachment();
695#endif
erikchen14525202017-05-06 19:16:51696
erikchen9d6afd712017-05-18 17:49:06697 GetParamSize(sizer, p.GetGUID());
698 GetParamSize(sizer, static_cast<uint64_t>(p.GetSize()));
erikchen22a813b2017-04-28 17:10:50699}
700
701void ParamTraits<base::SharedMemoryHandle>::Write(base::Pickle* m,
702 const param_type& p) {
erikchen14525202017-05-06 19:16:51703 // This serialization must be kept in sync with
erikchen9d6afd712017-05-18 17:49:06704 // nacl_message_scanner.cc:WriteHandle().
erikchen22a813b2017-04-28 17:10:50705 const bool valid = p.IsValid();
706 WriteParam(m, valid);
707
708 if (!valid)
709 return;
710
erikchen9d6afd712017-05-18 17:49:06711#if defined(OS_MACOSX) && !defined(OS_IOS)
712 MachPortMac mach_port_mac(p.GetMemoryObject());
713 WriteParam(m, mach_port_mac);
714#elif defined(OS_WIN)
715 HandleWin handle_win(p.GetHandle(), HandleWin::DUPLICATE);
716 WriteParam(m, handle_win);
717#else
erikchen22a813b2017-04-28 17:10:50718 if (p.OwnershipPassesToIPC()) {
719 if (!m->WriteAttachment(new internal::PlatformFileAttachment(
720 base::ScopedFD(p.GetHandle()))))
721 NOTREACHED();
722 } else {
723 if (!m->WriteAttachment(
724 new internal::PlatformFileAttachment(p.GetHandle())))
725 NOTREACHED();
726 }
erikchen9d6afd712017-05-18 17:49:06727#endif
728
729#if (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
730 // If the caller intended to pass ownership to the IPC stack, release a
731 // reference.
732 if (p.OwnershipPassesToIPC())
733 p.Close();
734#endif
735
erikchen14525202017-05-06 19:16:51736 DCHECK(!p.GetGUID().is_empty());
737 WriteParam(m, p.GetGUID());
erikchen9d6afd712017-05-18 17:49:06738 WriteParam(m, static_cast<uint64_t>(p.GetSize()));
erikchen22a813b2017-04-28 17:10:50739}
740
741bool ParamTraits<base::SharedMemoryHandle>::Read(const base::Pickle* m,
742 base::PickleIterator* iter,
743 param_type* r) {
744 *r = base::SharedMemoryHandle();
745
746 bool valid;
747 if (!ReadParam(m, iter, &valid))
748 return false;
erikchen22a813b2017-04-28 17:10:50749 if (!valid)
750 return true;
751
erikchen9d6afd712017-05-18 17:49:06752#if defined(OS_MACOSX) && !defined(OS_IOS)
753 MachPortMac mach_port_mac;
754 if (!ReadParam(m, iter, &mach_port_mac))
755 return false;
756#elif defined(OS_WIN)
757 HandleWin handle_win;
758 if (!ReadParam(m, iter, &handle_win))
759 return false;
Scott Graham3eebff02017-06-30 01:07:10760#elif defined(OS_FUCHSIA)
761 HandleFuchsia handle_fuchsia;
762 if (!ReadParam(m, iter, &handle_fuchsia))
763 return false;
erikchen9d6afd712017-05-18 17:49:06764#else
erikchen22a813b2017-04-28 17:10:50765 scoped_refptr<base::Pickle::Attachment> attachment;
766 if (!m->ReadAttachment(iter, &attachment))
767 return false;
768
769 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
770 MessageAttachment::Type::PLATFORM_FILE) {
771 return false;
772 }
erikchen9d6afd712017-05-18 17:49:06773#endif
erikchen22a813b2017-04-28 17:10:50774
erikchen14525202017-05-06 19:16:51775 base::UnguessableToken guid;
erikchen9d6afd712017-05-18 17:49:06776 uint64_t size;
777 if (!ReadParam(m, iter, &guid) || !ReadParam(m, iter, &size)) {
erikchen14525202017-05-06 19:16:51778 return false;
erikchen9d6afd712017-05-18 17:49:06779 }
erikchen14525202017-05-06 19:16:51780
erikchen9d6afd712017-05-18 17:49:06781#if defined(OS_MACOSX) && !defined(OS_IOS)
782 *r = base::SharedMemoryHandle(mach_port_mac.get_mach_port(),
783 static_cast<size_t>(size), guid);
784#elif defined(OS_WIN)
785 *r = base::SharedMemoryHandle(handle_win.get_handle(),
786 static_cast<size_t>(size), guid);
Scott Graham3eebff02017-06-30 01:07:10787#elif defined(OS_FUCHSIA)
788 *r = base::SharedMemoryHandle(handle_fuchsia.get_handle(),
789 static_cast<size_t>(size), guid);
erikchen9d6afd712017-05-18 17:49:06790#else
erikchen14525202017-05-06 19:16:51791 *r = base::SharedMemoryHandle(
792 base::FileDescriptor(
793 static_cast<internal::PlatformFileAttachment*>(attachment.get())
794 ->TakePlatformFile(),
795 true),
erikchen9d6afd712017-05-18 17:49:06796 static_cast<size_t>(size), guid);
797#endif
798
erikchen22a813b2017-04-28 17:10:50799 return true;
800}
801
802void ParamTraits<base::SharedMemoryHandle>::Log(const param_type& p,
803 std::string* l) {
erikchen9d6afd712017-05-18 17:49:06804#if defined(OS_MACOSX) && !defined(OS_IOS)
805 l->append("Mach port: ");
806 LogParam(p.GetMemoryObject(), l);
807#elif defined(OS_WIN)
808 l->append("HANDLE: ");
809 LogParam(p.GetHandle(), l);
810#else
811 l->append("FD: ");
812 LogParam(p.GetHandle(), l);
813#endif
814
erikchen14525202017-05-06 19:16:51815 l->append("GUID: ");
erikchen9d6afd712017-05-18 17:49:06816 LogParam(p.GetGUID(), l);
817 l->append("size: ");
818 LogParam(static_cast<uint64_t>(p.GetSize()), l);
erikchen22a813b2017-04-28 17:10:50819}
scottmgd19b4f72015-06-19 22:51:00820
erikchend804e1052017-04-29 02:24:36821#if defined(OS_WIN)
822void ParamTraits<PlatformFileForTransit>::GetSize(base::PickleSizer* s,
823 const param_type& p) {
824 GetParamSize(s, p.IsValid());
825 if (p.IsValid())
826 GetParamSize(s, p.GetHandle());
827}
828
829void ParamTraits<PlatformFileForTransit>::Write(base::Pickle* m,
830 const param_type& p) {
831 m->WriteBool(p.IsValid());
832 if (p.IsValid()) {
833 HandleWin handle_win(p.GetHandle(), HandleWin::DUPLICATE);
834 ParamTraits<HandleWin>::Write(m, handle_win);
835 ::CloseHandle(p.GetHandle());
836 }
837}
838
839bool ParamTraits<PlatformFileForTransit>::Read(const base::Pickle* m,
840 base::PickleIterator* iter,
841 param_type* r) {
842 bool is_valid;
843 if (!iter->ReadBool(&is_valid))
844 return false;
845 if (!is_valid) {
846 *r = PlatformFileForTransit();
847 return true;
848 }
849
850 HandleWin handle_win;
851 if (!ParamTraits<HandleWin>::Read(m, iter, &handle_win))
852 return false;
853 *r = PlatformFileForTransit(handle_win.get_handle());
854 return true;
855}
856
857void ParamTraits<PlatformFileForTransit>::Log(const param_type& p,
858 std::string* l) {
859 LogParam(p.GetHandle(), l);
860}
861#endif // defined(OS_WIN)
862
rockot0457af102016-02-05 02:12:32863void ParamTraits<base::FilePath>::GetSize(base::PickleSizer* sizer,
864 const param_type& p) {
865 p.GetSizeForPickle(sizer);
866}
867
rockot502c94f2016-02-03 20:20:16868void ParamTraits<base::FilePath>::Write(base::Pickle* m, const param_type& p) {
[email protected]aeae59f2013-01-28 13:47:55869 p.WriteToPickle(m);
[email protected]bf5aedf02012-06-04 21:18:25870}
871
rockot502c94f2016-02-03 20:20:16872bool ParamTraits<base::FilePath>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25873 base::PickleIterator* iter,
[email protected]6d4b67a2013-02-10 04:49:30874 param_type* r) {
[email protected]aeae59f2013-01-28 13:47:55875 return r->ReadFromPickle(iter);
[email protected]bf5aedf02012-06-04 21:18:25876}
877
[email protected]6d4b67a2013-02-10 04:49:30878void ParamTraits<base::FilePath>::Log(const param_type& p, std::string* l) {
879 ParamTraits<base::FilePath::StringType>::Log(p.value(), l);
[email protected]bf5aedf02012-06-04 21:18:25880}
881
rockot0457af102016-02-05 02:12:32882void ParamTraits<base::ListValue>::GetSize(base::PickleSizer* sizer,
883 const param_type& p) {
884 GetValueSize(sizer, &p, 0);
885}
886
rockot502c94f2016-02-03 20:20:16887void ParamTraits<base::ListValue>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25888 WriteValue(m, &p, 0);
889}
890
rockot502c94f2016-02-03 20:20:16891bool ParamTraits<base::ListValue>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25892 base::PickleIterator* iter,
893 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25894 int type;
jdoerriedc72ee942016-12-07 15:43:28895 if (!ReadParam(m, iter, &type) ||
896 type != static_cast<int>(base::Value::Type::LIST))
[email protected]bf5aedf02012-06-04 21:18:25897 return false;
898
899 return ReadListValue(m, iter, r, 0);
900}
901
[email protected]ea5ef4c2013-06-13 22:50:27902void ParamTraits<base::ListValue>::Log(const param_type& p, std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:25903 std::string json;
estade8d046462015-05-16 01:02:34904 base::JSONWriter::Write(p, &json);
[email protected]bf5aedf02012-06-04 21:18:25905 l->append(json);
906}
907
rockot0457af102016-02-05 02:12:32908void ParamTraits<base::NullableString16>::GetSize(base::PickleSizer* sizer,
909 const param_type& p) {
910 GetParamSize(sizer, p.string());
911 GetParamSize(sizer, p.is_null());
912}
913
rockot502c94f2016-02-03 20:20:16914void ParamTraits<base::NullableString16>::Write(base::Pickle* m,
[email protected]0238a162013-06-13 13:47:46915 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25916 WriteParam(m, p.string());
917 WriteParam(m, p.is_null());
918}
919
rockot502c94f2016-02-03 20:20:16920bool ParamTraits<base::NullableString16>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25921 base::PickleIterator* iter,
[email protected]0238a162013-06-13 13:47:46922 param_type* r) {
[email protected]476dafb2013-12-03 00:39:26923 base::string16 string;
[email protected]bf5aedf02012-06-04 21:18:25924 if (!ReadParam(m, iter, &string))
925 return false;
926 bool is_null;
927 if (!ReadParam(m, iter, &is_null))
928 return false;
[email protected]0238a162013-06-13 13:47:46929 *r = base::NullableString16(string, is_null);
[email protected]bf5aedf02012-06-04 21:18:25930 return true;
931}
932
[email protected]0238a162013-06-13 13:47:46933void ParamTraits<base::NullableString16>::Log(const param_type& p,
934 std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:25935 l->append("(");
936 LogParam(p.string(), l);
937 l->append(", ");
938 LogParam(p.is_null(), l);
939 l->append(")");
940}
941
rockot0457af102016-02-05 02:12:32942void ParamTraits<base::File::Info>::GetSize(base::PickleSizer* sizer,
943 const param_type& p) {
944 GetParamSize(sizer, p.size);
945 GetParamSize(sizer, p.is_directory);
946 GetParamSize(sizer, p.last_modified.ToDoubleT());
947 GetParamSize(sizer, p.last_accessed.ToDoubleT());
948 GetParamSize(sizer, p.creation_time.ToDoubleT());
949}
950
rockot502c94f2016-02-03 20:20:16951void ParamTraits<base::File::Info>::Write(base::Pickle* m,
[email protected]141bcc52014-01-27 21:36:00952 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25953 WriteParam(m, p.size);
954 WriteParam(m, p.is_directory);
955 WriteParam(m, p.last_modified.ToDoubleT());
956 WriteParam(m, p.last_accessed.ToDoubleT());
957 WriteParam(m, p.creation_time.ToDoubleT());
958}
959
rockot502c94f2016-02-03 20:20:16960bool ParamTraits<base::File::Info>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25961 base::PickleIterator* iter,
[email protected]141bcc52014-01-27 21:36:00962 param_type* p) {
[email protected]481c3e82014-07-18 01:40:47963 double last_modified, last_accessed, creation_time;
964 if (!ReadParam(m, iter, &p->size) ||
965 !ReadParam(m, iter, &p->is_directory) ||
966 !ReadParam(m, iter, &last_modified) ||
967 !ReadParam(m, iter, &last_accessed) ||
968 !ReadParam(m, iter, &creation_time))
969 return false;
970 p->last_modified = base::Time::FromDoubleT(last_modified);
971 p->last_accessed = base::Time::FromDoubleT(last_accessed);
972 p->creation_time = base::Time::FromDoubleT(creation_time);
973 return true;
[email protected]bf5aedf02012-06-04 21:18:25974}
975
[email protected]141bcc52014-01-27 21:36:00976void ParamTraits<base::File::Info>::Log(const param_type& p,
977 std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:25978 l->append("(");
979 LogParam(p.size, l);
980 l->append(",");
981 LogParam(p.is_directory, l);
982 l->append(",");
983 LogParam(p.last_modified.ToDoubleT(), l);
984 l->append(",");
985 LogParam(p.last_accessed.ToDoubleT(), l);
986 l->append(",");
987 LogParam(p.creation_time.ToDoubleT(), l);
988 l->append(")");
989}
990
rockot0457af102016-02-05 02:12:32991void ParamTraits<base::Time>::GetSize(base::PickleSizer* sizer,
992 const param_type& p) {
993 sizer->AddInt64();
994}
995
rockot502c94f2016-02-03 20:20:16996void ParamTraits<base::Time>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:57997 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:25998}
999
rockot502c94f2016-02-03 20:20:161000bool ParamTraits<base::Time>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251001 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251002 param_type* r) {
tfarina10a5c062015-09-04 18:47:571003 int64_t value;
1004 if (!ParamTraits<int64_t>::Read(m, iter, &value))
[email protected]bf5aedf02012-06-04 21:18:251005 return false;
1006 *r = base::Time::FromInternalValue(value);
1007 return true;
1008}
1009
1010void ParamTraits<base::Time>::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
rockot0457af102016-02-05 02:12:321014void ParamTraits<base::TimeDelta>::GetSize(base::PickleSizer* sizer,
1015 const param_type& p) {
1016 sizer->AddInt64();
1017}
1018
rockot502c94f2016-02-03 20:20:161019void ParamTraits<base::TimeDelta>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571020 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251021}
1022
rockot502c94f2016-02-03 20:20:161023bool ParamTraits<base::TimeDelta>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251024 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251025 param_type* r) {
tfarina10a5c062015-09-04 18:47:571026 int64_t value;
1027 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
[email protected]bf5aedf02012-06-04 21:18:251028 if (ret)
1029 *r = base::TimeDelta::FromInternalValue(value);
1030
1031 return ret;
1032}
1033
1034void ParamTraits<base::TimeDelta>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571035 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251036}
1037
rockot0457af102016-02-05 02:12:321038void ParamTraits<base::TimeTicks>::GetSize(base::PickleSizer* sizer,
1039 const param_type& p) {
1040 sizer->AddInt64();
1041}
1042
rockot502c94f2016-02-03 20:20:161043void ParamTraits<base::TimeTicks>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571044 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251045}
1046
rockot502c94f2016-02-03 20:20:161047bool ParamTraits<base::TimeTicks>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251048 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251049 param_type* r) {
tfarina10a5c062015-09-04 18:47:571050 int64_t value;
1051 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
[email protected]bf5aedf02012-06-04 21:18:251052 if (ret)
1053 *r = base::TimeTicks::FromInternalValue(value);
1054
1055 return ret;
1056}
1057
1058void ParamTraits<base::TimeTicks>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571059 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251060}
1061
tguilbert4a5ac602016-09-19 21:11:251062// If base::UnguessableToken is no longer 128 bits, the IPC serialization logic
1063// below should be updated.
1064static_assert(sizeof(base::UnguessableToken) == 2 * sizeof(uint64_t),
1065 "base::UnguessableToken should be of size 2 * sizeof(uint64_t).");
1066
1067void ParamTraits<base::UnguessableToken>::GetSize(base::PickleSizer* sizer,
1068 const param_type& p) {
1069 sizer->AddBytes(2 * sizeof(uint64_t));
1070}
1071
1072void ParamTraits<base::UnguessableToken>::Write(base::Pickle* m,
1073 const param_type& p) {
1074 DCHECK(!p.is_empty());
1075
erikchen14525202017-05-06 19:16:511076 // This serialization must be kept in sync with
erikchen9d6afd712017-05-18 17:49:061077 // nacl_message_scanner.cc:WriteHandle().
tguilbert4a5ac602016-09-19 21:11:251078 ParamTraits<uint64_t>::Write(m, p.GetHighForSerialization());
1079 ParamTraits<uint64_t>::Write(m, p.GetLowForSerialization());
1080}
1081
1082bool ParamTraits<base::UnguessableToken>::Read(const base::Pickle* m,
1083 base::PickleIterator* iter,
1084 param_type* r) {
1085 uint64_t high, low;
1086 if (!ParamTraits<uint64_t>::Read(m, iter, &high) ||
1087 !ParamTraits<uint64_t>::Read(m, iter, &low))
1088 return false;
1089
1090 // Receiving a zeroed UnguessableToken is a security issue.
1091 if (high == 0 && low == 0)
1092 return false;
1093
1094 *r = base::UnguessableToken::Deserialize(high, low);
1095 return true;
1096}
1097
1098void ParamTraits<base::UnguessableToken>::Log(const param_type& p,
1099 std::string* l) {
1100 l->append(p.ToString());
1101}
1102
jam3db6b6d2016-05-13 15:09:581103void ParamTraits<IPC::ChannelHandle>::GetSize(base::PickleSizer* sizer,
1104 const param_type& p) {
sammc9bf370c2016-11-14 03:29:081105#if defined(OS_NACL_SFI)
jam3db6b6d2016-05-13 15:09:581106 GetParamSize(sizer, p.socket);
sammc9bf370c2016-11-14 03:29:081107#else
amistry36182522016-06-27 06:34:421108 GetParamSize(sizer, p.mojo_handle);
sammc9bf370c2016-11-14 03:29:081109#endif
jam3db6b6d2016-05-13 15:09:581110}
1111
rockot502c94f2016-02-03 20:20:161112void ParamTraits<IPC::ChannelHandle>::Write(base::Pickle* m,
1113 const param_type& p) {
sammc9bf370c2016-11-14 03:29:081114#if defined(OS_NACL_SFI)
[email protected]7a4de7a62010-08-17 18:38:241115 WriteParam(m, p.socket);
sammc9bf370c2016-11-14 03:29:081116#else
amistry36182522016-06-27 06:34:421117 WriteParam(m, p.mojo_handle);
sammc9bf370c2016-11-14 03:29:081118#endif
[email protected]7a4de7a62010-08-17 18:38:241119}
1120
rockot502c94f2016-02-03 20:20:161121bool ParamTraits<IPC::ChannelHandle>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251122 base::PickleIterator* iter,
[email protected]7a4de7a62010-08-17 18:38:241123 param_type* r) {
sammc9bf370c2016-11-14 03:29:081124#if defined(OS_NACL_SFI)
1125 return ReadParam(m, iter, &r->socket);
1126#else
1127 return ReadParam(m, iter, &r->mojo_handle);
[email protected]7a4de7a62010-08-17 18:38:241128#endif
[email protected]7a4de7a62010-08-17 18:38:241129}
1130
1131void ParamTraits<IPC::ChannelHandle>::Log(const param_type& p,
[email protected]252cad62010-08-18 18:33:571132 std::string* l) {
sammc9bf370c2016-11-14 03:29:081133 l->append("ChannelHandle(");
1134#if defined(OS_NACL_SFI)
[email protected]7a4de7a62010-08-17 18:38:241135 ParamTraits<base::FileDescriptor>::Log(p.socket, l);
sammc9bf370c2016-11-14 03:29:081136#else
amistry36182522016-06-27 06:34:421137 LogParam(p.mojo_handle, l);
sammc9bf370c2016-11-14 03:29:081138#endif
[email protected]252cad62010-08-18 18:33:571139 l->append(")");
[email protected]7a4de7a62010-08-17 18:38:241140}
1141
rockot0457af102016-02-05 02:12:321142void ParamTraits<LogData>::GetSize(base::PickleSizer* sizer,
1143 const param_type& p) {
1144 GetParamSize(sizer, p.channel);
1145 GetParamSize(sizer, p.routing_id);
1146 GetParamSize(sizer, p.type);
1147 GetParamSize(sizer, p.flags);
1148 GetParamSize(sizer, p.sent);
1149 GetParamSize(sizer, p.receive);
1150 GetParamSize(sizer, p.dispatch);
1151 GetParamSize(sizer, p.message_name);
1152 GetParamSize(sizer, p.params);
1153}
1154
rockot502c94f2016-02-03 20:20:161155void ParamTraits<LogData>::Write(base::Pickle* m, const param_type& p) {
[email protected]20f0487a2010-09-30 20:06:301156 WriteParam(m, p.channel);
1157 WriteParam(m, p.routing_id);
[email protected]8bf55ca2011-10-17 22:15:271158 WriteParam(m, p.type);
[email protected]20f0487a2010-09-30 20:06:301159 WriteParam(m, p.flags);
1160 WriteParam(m, p.sent);
1161 WriteParam(m, p.receive);
1162 WriteParam(m, p.dispatch);
[email protected]bae578e92012-11-15 03:17:451163 WriteParam(m, p.message_name);
[email protected]20f0487a2010-09-30 20:06:301164 WriteParam(m, p.params);
1165}
1166
rockot502c94f2016-02-03 20:20:161167bool ParamTraits<LogData>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251168 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:561169 param_type* r) {
[email protected]8bf55ca2011-10-17 22:15:271170 return
[email protected]20f0487a2010-09-30 20:06:301171 ReadParam(m, iter, &r->channel) &&
1172 ReadParam(m, iter, &r->routing_id) &&
[email protected]8bf55ca2011-10-17 22:15:271173 ReadParam(m, iter, &r->type) &&
[email protected]20f0487a2010-09-30 20:06:301174 ReadParam(m, iter, &r->flags) &&
1175 ReadParam(m, iter, &r->sent) &&
1176 ReadParam(m, iter, &r->receive) &&
1177 ReadParam(m, iter, &r->dispatch) &&
[email protected]bae578e92012-11-15 03:17:451178 ReadParam(m, iter, &r->message_name) &&
[email protected]20f0487a2010-09-30 20:06:301179 ReadParam(m, iter, &r->params);
[email protected]20f0487a2010-09-30 20:06:301180}
1181
[email protected]bf5aedf02012-06-04 21:18:251182void ParamTraits<LogData>::Log(const param_type& p, std::string* l) {
1183 // Doesn't make sense to implement this!
1184}
1185
rockot502c94f2016-02-03 20:20:161186void ParamTraits<Message>::Write(base::Pickle* m, const Message& p) {
[email protected]34d48612012-06-29 00:05:041187#if defined(OS_POSIX)
1188 // We don't serialize the file descriptors in the nested message, so there
1189 // better not be any.
morrita1aa788c2015-01-31 05:45:421190 DCHECK(!p.HasAttachments());
[email protected]34d48612012-06-29 00:05:041191#endif
1192
1193 // Don't just write out the message. This is used to send messages between
1194 // NaCl (Posix environment) and the browser (could be on Windows). The message
1195 // header formats differ between these systems (so does handle sharing, but
1196 // we already asserted we don't have any handles). So just write out the
1197 // parts of the header we use.
1198 //
1199 // Be careful also to use only explicitly-sized types. The NaCl environment
1200 // could be 64-bit and the host browser could be 32-bits. The nested message
1201 // may or may not be safe to send between 32-bit and 64-bit systems, but we
1202 // leave that up to the code sending the message to ensure.
tfarina10a5c062015-09-04 18:47:571203 m->WriteUInt32(static_cast<uint32_t>(p.routing_id()));
[email protected]34d48612012-06-29 00:05:041204 m->WriteUInt32(p.type());
1205 m->WriteUInt32(p.flags());
tfarina10a5c062015-09-04 18:47:571206 m->WriteData(p.payload(), static_cast<uint32_t>(p.payload_size()));
[email protected]bf5aedf02012-06-04 21:18:251207}
1208
rockot502c94f2016-02-03 20:20:161209bool ParamTraits<Message>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251210 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251211 Message* r) {
tfarina10a5c062015-09-04 18:47:571212 uint32_t routing_id, type, flags;
avi48fc13b2014-12-28 23:31:481213 if (!iter->ReadUInt32(&routing_id) ||
1214 !iter->ReadUInt32(&type) ||
1215 !iter->ReadUInt32(&flags))
[email protected]bf5aedf02012-06-04 21:18:251216 return false;
[email protected]34d48612012-06-29 00:05:041217
1218 int payload_size;
1219 const char* payload;
avi48fc13b2014-12-28 23:31:481220 if (!iter->ReadData(&payload, &payload_size))
[email protected]bf5aedf02012-06-04 21:18:251221 return false;
[email protected]34d48612012-06-29 00:05:041222
tfarina10a5c062015-09-04 18:47:571223 r->SetHeaderValues(static_cast<int32_t>(routing_id), type, flags);
[email protected]34d48612012-06-29 00:05:041224 return r->WriteBytes(payload, payload_size);
[email protected]bf5aedf02012-06-04 21:18:251225}
1226
1227void ParamTraits<Message>::Log(const Message& p, std::string* l) {
1228 l->append("<IPC::Message>");
1229}
1230
1231#if defined(OS_WIN)
rockot0457af102016-02-05 02:12:321232void ParamTraits<HANDLE>::GetSize(base::PickleSizer* sizer,
1233 const param_type& p) {
1234 sizer->AddInt();
1235}
1236
[email protected]bf5aedf02012-06-04 21:18:251237// Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
[email protected]4a635b72013-03-04 02:29:031238// bit systems. That's why we use the Windows macros to convert to 32 bits.
rockot502c94f2016-02-03 20:20:161239void ParamTraits<HANDLE>::Write(base::Pickle* m, const param_type& p) {
[email protected]4a635b72013-03-04 02:29:031240 m->WriteInt(HandleToLong(p));
[email protected]bf5aedf02012-06-04 21:18:251241}
1242
rockot502c94f2016-02-03 20:20:161243bool ParamTraits<HANDLE>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251244 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251245 param_type* r) {
tfarina10a5c062015-09-04 18:47:571246 int32_t temp;
avi48fc13b2014-12-28 23:31:481247 if (!iter->ReadInt(&temp))
[email protected]bf5aedf02012-06-04 21:18:251248 return false;
[email protected]4a635b72013-03-04 02:29:031249 *r = LongToHandle(temp);
[email protected]bf5aedf02012-06-04 21:18:251250 return true;
1251}
1252
1253void ParamTraits<HANDLE>::Log(const param_type& p, std::string* l) {
brucedawson5604a11d2015-10-06 19:22:001254 l->append(base::StringPrintf("0x%p", p));
[email protected]bf5aedf02012-06-04 21:18:251255}
1256
rockot0457af102016-02-05 02:12:321257void ParamTraits<LOGFONT>::GetSize(base::PickleSizer* sizer,
1258 const param_type& p) {
1259 sizer->AddData(sizeof(LOGFONT));
1260}
1261
rockot502c94f2016-02-03 20:20:161262void ParamTraits<LOGFONT>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251263 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
1264}
1265
rockot502c94f2016-02-03 20:20:161266bool ParamTraits<LOGFONT>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251267 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251268 param_type* r) {
1269 const char *data;
1270 int data_size = 0;
avi48fc13b2014-12-28 23:31:481271 if (iter->ReadData(&data, &data_size) && data_size == sizeof(LOGFONT)) {
[email protected]2e02cfe82012-11-21 00:58:001272 const LOGFONT *font = reinterpret_cast<LOGFONT*>(const_cast<char*>(data));
1273 if (_tcsnlen(font->lfFaceName, LF_FACESIZE) < LF_FACESIZE) {
1274 memcpy(r, data, sizeof(LOGFONT));
1275 return true;
1276 }
[email protected]bf5aedf02012-06-04 21:18:251277 }
1278
[email protected]2e02cfe82012-11-21 00:58:001279 NOTREACHED();
1280 return false;
[email protected]bf5aedf02012-06-04 21:18:251281}
1282
1283void ParamTraits<LOGFONT>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:041284 l->append(base::StringPrintf("<LOGFONT>"));
[email protected]bf5aedf02012-06-04 21:18:251285}
1286
rockot0457af102016-02-05 02:12:321287void ParamTraits<MSG>::GetSize(base::PickleSizer* sizer, const param_type& p) {
1288 sizer->AddData(sizeof(MSG));
1289}
1290
rockot502c94f2016-02-03 20:20:161291void ParamTraits<MSG>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251292 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
1293}
1294
rockot502c94f2016-02-03 20:20:161295bool ParamTraits<MSG>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251296 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251297 param_type* r) {
1298 const char *data;
1299 int data_size = 0;
avi48fc13b2014-12-28 23:31:481300 bool result = iter->ReadData(&data, &data_size);
[email protected]bf5aedf02012-06-04 21:18:251301 if (result && data_size == sizeof(MSG)) {
1302 memcpy(r, data, sizeof(MSG));
1303 } else {
1304 result = false;
1305 NOTREACHED();
1306 }
1307
1308 return result;
1309}
1310
1311void ParamTraits<MSG>::Log(const param_type& p, std::string* l) {
1312 l->append("<MSG>");
1313}
1314
1315#endif // OS_WIN
1316
[email protected]946d1b22009-07-22 23:57:211317} // namespace IPC