blob: dd065fd07f784734f20cd3998ca95764682829d2 [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:
Jeremy Roman160eb922017-08-29 17:43:43269 *value = std::make_unique<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;
Jeremy Roman160eb922017-08-29 17:43:43275 *value = std::make_unique<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;
Jeremy Roman160eb922017-08-29 17:43:43282 *value = std::make_unique<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;
Jeremy Roman160eb922017-08-29 17:43:43289 *value = std::make_unique<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;
Jeremy Roman160eb922017-08-29 17:43:43296 *value = std::make_unique<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;
Jeremy Roman160eb922017-08-29 17:43:43311 *value = std::make_unique<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;
Jeremy Roman160eb922017-08-29 17:43:43318 *value = std::make_unique<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
Sergey Ulanova98ff6b52017-07-13 01:54:20426#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_FUCHSIA) || \
jamac78d7d82016-02-11 00:50:28427 (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)
Wez51eaaad2017-08-09 05:51:38715 HandleWin handle_win(p.GetHandle());
erikchen9d6afd712017-05-18 17:49:06716 WriteParam(m, handle_win);
Wez8c49ebc92017-08-10 17:11:13717#elif defined(OS_FUCHSIA)
718 HandleFuchsia handle_fuchsia(p.GetHandle());
719 WriteParam(m, handle_fuchsia);
erikchen9d6afd712017-05-18 17:49:06720#else
erikchen22a813b2017-04-28 17:10:50721 if (p.OwnershipPassesToIPC()) {
722 if (!m->WriteAttachment(new internal::PlatformFileAttachment(
723 base::ScopedFD(p.GetHandle()))))
724 NOTREACHED();
725 } else {
726 if (!m->WriteAttachment(
727 new internal::PlatformFileAttachment(p.GetHandle())))
728 NOTREACHED();
729 }
erikchen9d6afd712017-05-18 17:49:06730#endif
731
732#if (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
733 // If the caller intended to pass ownership to the IPC stack, release a
734 // reference.
735 if (p.OwnershipPassesToIPC())
736 p.Close();
737#endif
738
erikchen14525202017-05-06 19:16:51739 DCHECK(!p.GetGUID().is_empty());
740 WriteParam(m, p.GetGUID());
erikchen9d6afd712017-05-18 17:49:06741 WriteParam(m, static_cast<uint64_t>(p.GetSize()));
erikchen22a813b2017-04-28 17:10:50742}
743
744bool ParamTraits<base::SharedMemoryHandle>::Read(const base::Pickle* m,
745 base::PickleIterator* iter,
746 param_type* r) {
747 *r = base::SharedMemoryHandle();
748
749 bool valid;
750 if (!ReadParam(m, iter, &valid))
751 return false;
erikchen22a813b2017-04-28 17:10:50752 if (!valid)
753 return true;
754
erikchen9d6afd712017-05-18 17:49:06755#if defined(OS_MACOSX) && !defined(OS_IOS)
756 MachPortMac mach_port_mac;
757 if (!ReadParam(m, iter, &mach_port_mac))
758 return false;
759#elif defined(OS_WIN)
760 HandleWin handle_win;
761 if (!ReadParam(m, iter, &handle_win))
762 return false;
Scott Graham3eebff02017-06-30 01:07:10763#elif defined(OS_FUCHSIA)
764 HandleFuchsia handle_fuchsia;
765 if (!ReadParam(m, iter, &handle_fuchsia))
766 return false;
erikchen9d6afd712017-05-18 17:49:06767#else
erikchen22a813b2017-04-28 17:10:50768 scoped_refptr<base::Pickle::Attachment> attachment;
769 if (!m->ReadAttachment(iter, &attachment))
770 return false;
771
772 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
773 MessageAttachment::Type::PLATFORM_FILE) {
774 return false;
775 }
erikchen9d6afd712017-05-18 17:49:06776#endif
erikchen22a813b2017-04-28 17:10:50777
erikchen14525202017-05-06 19:16:51778 base::UnguessableToken guid;
erikchen9d6afd712017-05-18 17:49:06779 uint64_t size;
780 if (!ReadParam(m, iter, &guid) || !ReadParam(m, iter, &size)) {
erikchen14525202017-05-06 19:16:51781 return false;
erikchen9d6afd712017-05-18 17:49:06782 }
erikchen14525202017-05-06 19:16:51783
erikchen9d6afd712017-05-18 17:49:06784#if defined(OS_MACOSX) && !defined(OS_IOS)
785 *r = base::SharedMemoryHandle(mach_port_mac.get_mach_port(),
786 static_cast<size_t>(size), guid);
787#elif defined(OS_WIN)
788 *r = base::SharedMemoryHandle(handle_win.get_handle(),
789 static_cast<size_t>(size), guid);
Scott Graham3eebff02017-06-30 01:07:10790#elif defined(OS_FUCHSIA)
791 *r = base::SharedMemoryHandle(handle_fuchsia.get_handle(),
792 static_cast<size_t>(size), guid);
erikchen9d6afd712017-05-18 17:49:06793#else
erikchen14525202017-05-06 19:16:51794 *r = base::SharedMemoryHandle(
795 base::FileDescriptor(
796 static_cast<internal::PlatformFileAttachment*>(attachment.get())
797 ->TakePlatformFile(),
798 true),
erikchen9d6afd712017-05-18 17:49:06799 static_cast<size_t>(size), guid);
800#endif
801
erikchen22a813b2017-04-28 17:10:50802 return true;
803}
804
805void ParamTraits<base::SharedMemoryHandle>::Log(const param_type& p,
806 std::string* l) {
erikchen9d6afd712017-05-18 17:49:06807#if defined(OS_MACOSX) && !defined(OS_IOS)
808 l->append("Mach port: ");
809 LogParam(p.GetMemoryObject(), l);
810#elif defined(OS_WIN)
811 l->append("HANDLE: ");
812 LogParam(p.GetHandle(), l);
813#else
814 l->append("FD: ");
815 LogParam(p.GetHandle(), l);
816#endif
817
erikchen14525202017-05-06 19:16:51818 l->append("GUID: ");
erikchen9d6afd712017-05-18 17:49:06819 LogParam(p.GetGUID(), l);
820 l->append("size: ");
821 LogParam(static_cast<uint64_t>(p.GetSize()), l);
erikchen22a813b2017-04-28 17:10:50822}
scottmgd19b4f72015-06-19 22:51:00823
erikchend804e1052017-04-29 02:24:36824#if defined(OS_WIN)
825void ParamTraits<PlatformFileForTransit>::GetSize(base::PickleSizer* s,
826 const param_type& p) {
827 GetParamSize(s, p.IsValid());
828 if (p.IsValid())
829 GetParamSize(s, p.GetHandle());
830}
831
832void ParamTraits<PlatformFileForTransit>::Write(base::Pickle* m,
833 const param_type& p) {
834 m->WriteBool(p.IsValid());
835 if (p.IsValid()) {
Wez51eaaad2017-08-09 05:51:38836 HandleWin handle_win(p.GetHandle());
erikchend804e1052017-04-29 02:24:36837 ParamTraits<HandleWin>::Write(m, handle_win);
838 ::CloseHandle(p.GetHandle());
839 }
840}
841
842bool ParamTraits<PlatformFileForTransit>::Read(const base::Pickle* m,
843 base::PickleIterator* iter,
844 param_type* r) {
845 bool is_valid;
846 if (!iter->ReadBool(&is_valid))
847 return false;
848 if (!is_valid) {
849 *r = PlatformFileForTransit();
850 return true;
851 }
852
853 HandleWin handle_win;
854 if (!ParamTraits<HandleWin>::Read(m, iter, &handle_win))
855 return false;
856 *r = PlatformFileForTransit(handle_win.get_handle());
857 return true;
858}
859
860void ParamTraits<PlatformFileForTransit>::Log(const param_type& p,
861 std::string* l) {
862 LogParam(p.GetHandle(), l);
863}
864#endif // defined(OS_WIN)
865
rockot0457af102016-02-05 02:12:32866void ParamTraits<base::FilePath>::GetSize(base::PickleSizer* sizer,
867 const param_type& p) {
868 p.GetSizeForPickle(sizer);
869}
870
rockot502c94f2016-02-03 20:20:16871void ParamTraits<base::FilePath>::Write(base::Pickle* m, const param_type& p) {
[email protected]aeae59f2013-01-28 13:47:55872 p.WriteToPickle(m);
[email protected]bf5aedf02012-06-04 21:18:25873}
874
rockot502c94f2016-02-03 20:20:16875bool ParamTraits<base::FilePath>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25876 base::PickleIterator* iter,
[email protected]6d4b67a2013-02-10 04:49:30877 param_type* r) {
[email protected]aeae59f2013-01-28 13:47:55878 return r->ReadFromPickle(iter);
[email protected]bf5aedf02012-06-04 21:18:25879}
880
[email protected]6d4b67a2013-02-10 04:49:30881void ParamTraits<base::FilePath>::Log(const param_type& p, std::string* l) {
882 ParamTraits<base::FilePath::StringType>::Log(p.value(), l);
[email protected]bf5aedf02012-06-04 21:18:25883}
884
rockot0457af102016-02-05 02:12:32885void ParamTraits<base::ListValue>::GetSize(base::PickleSizer* sizer,
886 const param_type& p) {
887 GetValueSize(sizer, &p, 0);
888}
889
rockot502c94f2016-02-03 20:20:16890void ParamTraits<base::ListValue>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25891 WriteValue(m, &p, 0);
892}
893
rockot502c94f2016-02-03 20:20:16894bool ParamTraits<base::ListValue>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25895 base::PickleIterator* iter,
896 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25897 int type;
jdoerriedc72ee942016-12-07 15:43:28898 if (!ReadParam(m, iter, &type) ||
899 type != static_cast<int>(base::Value::Type::LIST))
[email protected]bf5aedf02012-06-04 21:18:25900 return false;
901
902 return ReadListValue(m, iter, r, 0);
903}
904
[email protected]ea5ef4c2013-06-13 22:50:27905void ParamTraits<base::ListValue>::Log(const param_type& p, std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:25906 std::string json;
estade8d046462015-05-16 01:02:34907 base::JSONWriter::Write(p, &json);
[email protected]bf5aedf02012-06-04 21:18:25908 l->append(json);
909}
910
rockot0457af102016-02-05 02:12:32911void ParamTraits<base::NullableString16>::GetSize(base::PickleSizer* sizer,
912 const param_type& p) {
913 GetParamSize(sizer, p.string());
914 GetParamSize(sizer, p.is_null());
915}
916
rockot502c94f2016-02-03 20:20:16917void ParamTraits<base::NullableString16>::Write(base::Pickle* m,
[email protected]0238a162013-06-13 13:47:46918 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25919 WriteParam(m, p.string());
920 WriteParam(m, p.is_null());
921}
922
rockot502c94f2016-02-03 20:20:16923bool ParamTraits<base::NullableString16>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25924 base::PickleIterator* iter,
[email protected]0238a162013-06-13 13:47:46925 param_type* r) {
[email protected]476dafb2013-12-03 00:39:26926 base::string16 string;
[email protected]bf5aedf02012-06-04 21:18:25927 if (!ReadParam(m, iter, &string))
928 return false;
929 bool is_null;
930 if (!ReadParam(m, iter, &is_null))
931 return false;
[email protected]0238a162013-06-13 13:47:46932 *r = base::NullableString16(string, is_null);
[email protected]bf5aedf02012-06-04 21:18:25933 return true;
934}
935
[email protected]0238a162013-06-13 13:47:46936void ParamTraits<base::NullableString16>::Log(const param_type& p,
937 std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:25938 l->append("(");
939 LogParam(p.string(), l);
940 l->append(", ");
941 LogParam(p.is_null(), l);
942 l->append(")");
943}
944
rockot0457af102016-02-05 02:12:32945void ParamTraits<base::File::Info>::GetSize(base::PickleSizer* sizer,
946 const param_type& p) {
947 GetParamSize(sizer, p.size);
948 GetParamSize(sizer, p.is_directory);
949 GetParamSize(sizer, p.last_modified.ToDoubleT());
950 GetParamSize(sizer, p.last_accessed.ToDoubleT());
951 GetParamSize(sizer, p.creation_time.ToDoubleT());
952}
953
rockot502c94f2016-02-03 20:20:16954void ParamTraits<base::File::Info>::Write(base::Pickle* m,
[email protected]141bcc52014-01-27 21:36:00955 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25956 WriteParam(m, p.size);
957 WriteParam(m, p.is_directory);
958 WriteParam(m, p.last_modified.ToDoubleT());
959 WriteParam(m, p.last_accessed.ToDoubleT());
960 WriteParam(m, p.creation_time.ToDoubleT());
961}
962
rockot502c94f2016-02-03 20:20:16963bool ParamTraits<base::File::Info>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25964 base::PickleIterator* iter,
[email protected]141bcc52014-01-27 21:36:00965 param_type* p) {
[email protected]481c3e82014-07-18 01:40:47966 double last_modified, last_accessed, creation_time;
967 if (!ReadParam(m, iter, &p->size) ||
968 !ReadParam(m, iter, &p->is_directory) ||
969 !ReadParam(m, iter, &last_modified) ||
970 !ReadParam(m, iter, &last_accessed) ||
971 !ReadParam(m, iter, &creation_time))
972 return false;
973 p->last_modified = base::Time::FromDoubleT(last_modified);
974 p->last_accessed = base::Time::FromDoubleT(last_accessed);
975 p->creation_time = base::Time::FromDoubleT(creation_time);
976 return true;
[email protected]bf5aedf02012-06-04 21:18:25977}
978
[email protected]141bcc52014-01-27 21:36:00979void ParamTraits<base::File::Info>::Log(const param_type& p,
980 std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:25981 l->append("(");
982 LogParam(p.size, l);
983 l->append(",");
984 LogParam(p.is_directory, l);
985 l->append(",");
986 LogParam(p.last_modified.ToDoubleT(), l);
987 l->append(",");
988 LogParam(p.last_accessed.ToDoubleT(), l);
989 l->append(",");
990 LogParam(p.creation_time.ToDoubleT(), l);
991 l->append(")");
992}
993
rockot0457af102016-02-05 02:12:32994void ParamTraits<base::Time>::GetSize(base::PickleSizer* sizer,
995 const param_type& p) {
996 sizer->AddInt64();
997}
998
rockot502c94f2016-02-03 20:20:16999void ParamTraits<base::Time>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571000 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251001}
1002
rockot502c94f2016-02-03 20:20:161003bool ParamTraits<base::Time>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251004 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251005 param_type* r) {
tfarina10a5c062015-09-04 18:47:571006 int64_t value;
1007 if (!ParamTraits<int64_t>::Read(m, iter, &value))
[email protected]bf5aedf02012-06-04 21:18:251008 return false;
1009 *r = base::Time::FromInternalValue(value);
1010 return true;
1011}
1012
1013void ParamTraits<base::Time>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571014 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251015}
1016
rockot0457af102016-02-05 02:12:321017void ParamTraits<base::TimeDelta>::GetSize(base::PickleSizer* sizer,
1018 const param_type& p) {
1019 sizer->AddInt64();
1020}
1021
rockot502c94f2016-02-03 20:20:161022void ParamTraits<base::TimeDelta>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571023 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251024}
1025
rockot502c94f2016-02-03 20:20:161026bool ParamTraits<base::TimeDelta>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251027 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251028 param_type* r) {
tfarina10a5c062015-09-04 18:47:571029 int64_t value;
1030 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
[email protected]bf5aedf02012-06-04 21:18:251031 if (ret)
1032 *r = base::TimeDelta::FromInternalValue(value);
1033
1034 return ret;
1035}
1036
1037void ParamTraits<base::TimeDelta>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571038 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251039}
1040
rockot0457af102016-02-05 02:12:321041void ParamTraits<base::TimeTicks>::GetSize(base::PickleSizer* sizer,
1042 const param_type& p) {
1043 sizer->AddInt64();
1044}
1045
rockot502c94f2016-02-03 20:20:161046void ParamTraits<base::TimeTicks>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571047 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251048}
1049
rockot502c94f2016-02-03 20:20:161050bool ParamTraits<base::TimeTicks>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251051 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251052 param_type* r) {
tfarina10a5c062015-09-04 18:47:571053 int64_t value;
1054 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
[email protected]bf5aedf02012-06-04 21:18:251055 if (ret)
1056 *r = base::TimeTicks::FromInternalValue(value);
1057
1058 return ret;
1059}
1060
1061void ParamTraits<base::TimeTicks>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571062 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251063}
1064
tguilbert4a5ac602016-09-19 21:11:251065// If base::UnguessableToken is no longer 128 bits, the IPC serialization logic
1066// below should be updated.
1067static_assert(sizeof(base::UnguessableToken) == 2 * sizeof(uint64_t),
1068 "base::UnguessableToken should be of size 2 * sizeof(uint64_t).");
1069
1070void ParamTraits<base::UnguessableToken>::GetSize(base::PickleSizer* sizer,
1071 const param_type& p) {
1072 sizer->AddBytes(2 * sizeof(uint64_t));
1073}
1074
1075void ParamTraits<base::UnguessableToken>::Write(base::Pickle* m,
1076 const param_type& p) {
1077 DCHECK(!p.is_empty());
1078
erikchen14525202017-05-06 19:16:511079 // This serialization must be kept in sync with
erikchen9d6afd712017-05-18 17:49:061080 // nacl_message_scanner.cc:WriteHandle().
tguilbert4a5ac602016-09-19 21:11:251081 ParamTraits<uint64_t>::Write(m, p.GetHighForSerialization());
1082 ParamTraits<uint64_t>::Write(m, p.GetLowForSerialization());
1083}
1084
1085bool ParamTraits<base::UnguessableToken>::Read(const base::Pickle* m,
1086 base::PickleIterator* iter,
1087 param_type* r) {
1088 uint64_t high, low;
1089 if (!ParamTraits<uint64_t>::Read(m, iter, &high) ||
1090 !ParamTraits<uint64_t>::Read(m, iter, &low))
1091 return false;
1092
1093 // Receiving a zeroed UnguessableToken is a security issue.
1094 if (high == 0 && low == 0)
1095 return false;
1096
1097 *r = base::UnguessableToken::Deserialize(high, low);
1098 return true;
1099}
1100
1101void ParamTraits<base::UnguessableToken>::Log(const param_type& p,
1102 std::string* l) {
1103 l->append(p.ToString());
1104}
1105
jam3db6b6d2016-05-13 15:09:581106void ParamTraits<IPC::ChannelHandle>::GetSize(base::PickleSizer* sizer,
1107 const param_type& p) {
sammc9bf370c2016-11-14 03:29:081108#if defined(OS_NACL_SFI)
jam3db6b6d2016-05-13 15:09:581109 GetParamSize(sizer, p.socket);
sammc9bf370c2016-11-14 03:29:081110#else
amistry36182522016-06-27 06:34:421111 GetParamSize(sizer, p.mojo_handle);
sammc9bf370c2016-11-14 03:29:081112#endif
jam3db6b6d2016-05-13 15:09:581113}
1114
rockot502c94f2016-02-03 20:20:161115void ParamTraits<IPC::ChannelHandle>::Write(base::Pickle* m,
1116 const param_type& p) {
sammc9bf370c2016-11-14 03:29:081117#if defined(OS_NACL_SFI)
[email protected]7a4de7a62010-08-17 18:38:241118 WriteParam(m, p.socket);
sammc9bf370c2016-11-14 03:29:081119#else
amistry36182522016-06-27 06:34:421120 WriteParam(m, p.mojo_handle);
sammc9bf370c2016-11-14 03:29:081121#endif
[email protected]7a4de7a62010-08-17 18:38:241122}
1123
rockot502c94f2016-02-03 20:20:161124bool ParamTraits<IPC::ChannelHandle>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251125 base::PickleIterator* iter,
[email protected]7a4de7a62010-08-17 18:38:241126 param_type* r) {
sammc9bf370c2016-11-14 03:29:081127#if defined(OS_NACL_SFI)
1128 return ReadParam(m, iter, &r->socket);
1129#else
1130 return ReadParam(m, iter, &r->mojo_handle);
[email protected]7a4de7a62010-08-17 18:38:241131#endif
[email protected]7a4de7a62010-08-17 18:38:241132}
1133
1134void ParamTraits<IPC::ChannelHandle>::Log(const param_type& p,
[email protected]252cad62010-08-18 18:33:571135 std::string* l) {
sammc9bf370c2016-11-14 03:29:081136 l->append("ChannelHandle(");
1137#if defined(OS_NACL_SFI)
[email protected]7a4de7a62010-08-17 18:38:241138 ParamTraits<base::FileDescriptor>::Log(p.socket, l);
sammc9bf370c2016-11-14 03:29:081139#else
amistry36182522016-06-27 06:34:421140 LogParam(p.mojo_handle, l);
sammc9bf370c2016-11-14 03:29:081141#endif
[email protected]252cad62010-08-18 18:33:571142 l->append(")");
[email protected]7a4de7a62010-08-17 18:38:241143}
1144
rockot0457af102016-02-05 02:12:321145void ParamTraits<LogData>::GetSize(base::PickleSizer* sizer,
1146 const param_type& p) {
1147 GetParamSize(sizer, p.channel);
1148 GetParamSize(sizer, p.routing_id);
1149 GetParamSize(sizer, p.type);
1150 GetParamSize(sizer, p.flags);
1151 GetParamSize(sizer, p.sent);
1152 GetParamSize(sizer, p.receive);
1153 GetParamSize(sizer, p.dispatch);
1154 GetParamSize(sizer, p.message_name);
1155 GetParamSize(sizer, p.params);
1156}
1157
rockot502c94f2016-02-03 20:20:161158void ParamTraits<LogData>::Write(base::Pickle* m, const param_type& p) {
[email protected]20f0487a2010-09-30 20:06:301159 WriteParam(m, p.channel);
1160 WriteParam(m, p.routing_id);
[email protected]8bf55ca2011-10-17 22:15:271161 WriteParam(m, p.type);
[email protected]20f0487a2010-09-30 20:06:301162 WriteParam(m, p.flags);
1163 WriteParam(m, p.sent);
1164 WriteParam(m, p.receive);
1165 WriteParam(m, p.dispatch);
[email protected]bae578e92012-11-15 03:17:451166 WriteParam(m, p.message_name);
[email protected]20f0487a2010-09-30 20:06:301167 WriteParam(m, p.params);
1168}
1169
rockot502c94f2016-02-03 20:20:161170bool ParamTraits<LogData>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251171 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:561172 param_type* r) {
[email protected]8bf55ca2011-10-17 22:15:271173 return
[email protected]20f0487a2010-09-30 20:06:301174 ReadParam(m, iter, &r->channel) &&
1175 ReadParam(m, iter, &r->routing_id) &&
[email protected]8bf55ca2011-10-17 22:15:271176 ReadParam(m, iter, &r->type) &&
[email protected]20f0487a2010-09-30 20:06:301177 ReadParam(m, iter, &r->flags) &&
1178 ReadParam(m, iter, &r->sent) &&
1179 ReadParam(m, iter, &r->receive) &&
1180 ReadParam(m, iter, &r->dispatch) &&
[email protected]bae578e92012-11-15 03:17:451181 ReadParam(m, iter, &r->message_name) &&
[email protected]20f0487a2010-09-30 20:06:301182 ReadParam(m, iter, &r->params);
[email protected]20f0487a2010-09-30 20:06:301183}
1184
[email protected]bf5aedf02012-06-04 21:18:251185void ParamTraits<LogData>::Log(const param_type& p, std::string* l) {
1186 // Doesn't make sense to implement this!
1187}
1188
rockot502c94f2016-02-03 20:20:161189void ParamTraits<Message>::Write(base::Pickle* m, const Message& p) {
[email protected]34d48612012-06-29 00:05:041190#if defined(OS_POSIX)
1191 // We don't serialize the file descriptors in the nested message, so there
1192 // better not be any.
morrita1aa788c2015-01-31 05:45:421193 DCHECK(!p.HasAttachments());
[email protected]34d48612012-06-29 00:05:041194#endif
1195
1196 // Don't just write out the message. This is used to send messages between
1197 // NaCl (Posix environment) and the browser (could be on Windows). The message
1198 // header formats differ between these systems (so does handle sharing, but
1199 // we already asserted we don't have any handles). So just write out the
1200 // parts of the header we use.
1201 //
1202 // Be careful also to use only explicitly-sized types. The NaCl environment
1203 // could be 64-bit and the host browser could be 32-bits. The nested message
1204 // may or may not be safe to send between 32-bit and 64-bit systems, but we
1205 // leave that up to the code sending the message to ensure.
tfarina10a5c062015-09-04 18:47:571206 m->WriteUInt32(static_cast<uint32_t>(p.routing_id()));
[email protected]34d48612012-06-29 00:05:041207 m->WriteUInt32(p.type());
1208 m->WriteUInt32(p.flags());
tfarina10a5c062015-09-04 18:47:571209 m->WriteData(p.payload(), static_cast<uint32_t>(p.payload_size()));
[email protected]bf5aedf02012-06-04 21:18:251210}
1211
rockot502c94f2016-02-03 20:20:161212bool ParamTraits<Message>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251213 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251214 Message* r) {
tfarina10a5c062015-09-04 18:47:571215 uint32_t routing_id, type, flags;
avi48fc13b2014-12-28 23:31:481216 if (!iter->ReadUInt32(&routing_id) ||
1217 !iter->ReadUInt32(&type) ||
1218 !iter->ReadUInt32(&flags))
[email protected]bf5aedf02012-06-04 21:18:251219 return false;
[email protected]34d48612012-06-29 00:05:041220
1221 int payload_size;
1222 const char* payload;
avi48fc13b2014-12-28 23:31:481223 if (!iter->ReadData(&payload, &payload_size))
[email protected]bf5aedf02012-06-04 21:18:251224 return false;
[email protected]34d48612012-06-29 00:05:041225
tfarina10a5c062015-09-04 18:47:571226 r->SetHeaderValues(static_cast<int32_t>(routing_id), type, flags);
[email protected]34d48612012-06-29 00:05:041227 return r->WriteBytes(payload, payload_size);
[email protected]bf5aedf02012-06-04 21:18:251228}
1229
1230void ParamTraits<Message>::Log(const Message& p, std::string* l) {
1231 l->append("<IPC::Message>");
1232}
1233
1234#if defined(OS_WIN)
rockot0457af102016-02-05 02:12:321235void ParamTraits<HANDLE>::GetSize(base::PickleSizer* sizer,
1236 const param_type& p) {
1237 sizer->AddInt();
1238}
1239
[email protected]bf5aedf02012-06-04 21:18:251240// Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
[email protected]4a635b72013-03-04 02:29:031241// bit systems. That's why we use the Windows macros to convert to 32 bits.
rockot502c94f2016-02-03 20:20:161242void ParamTraits<HANDLE>::Write(base::Pickle* m, const param_type& p) {
[email protected]4a635b72013-03-04 02:29:031243 m->WriteInt(HandleToLong(p));
[email protected]bf5aedf02012-06-04 21:18:251244}
1245
rockot502c94f2016-02-03 20:20:161246bool ParamTraits<HANDLE>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251247 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251248 param_type* r) {
tfarina10a5c062015-09-04 18:47:571249 int32_t temp;
avi48fc13b2014-12-28 23:31:481250 if (!iter->ReadInt(&temp))
[email protected]bf5aedf02012-06-04 21:18:251251 return false;
[email protected]4a635b72013-03-04 02:29:031252 *r = LongToHandle(temp);
[email protected]bf5aedf02012-06-04 21:18:251253 return true;
1254}
1255
1256void ParamTraits<HANDLE>::Log(const param_type& p, std::string* l) {
brucedawson5604a11d2015-10-06 19:22:001257 l->append(base::StringPrintf("0x%p", p));
[email protected]bf5aedf02012-06-04 21:18:251258}
1259
rockot0457af102016-02-05 02:12:321260void ParamTraits<LOGFONT>::GetSize(base::PickleSizer* sizer,
1261 const param_type& p) {
1262 sizer->AddData(sizeof(LOGFONT));
1263}
1264
rockot502c94f2016-02-03 20:20:161265void ParamTraits<LOGFONT>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251266 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
1267}
1268
rockot502c94f2016-02-03 20:20:161269bool ParamTraits<LOGFONT>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251270 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251271 param_type* r) {
1272 const char *data;
1273 int data_size = 0;
avi48fc13b2014-12-28 23:31:481274 if (iter->ReadData(&data, &data_size) && data_size == sizeof(LOGFONT)) {
[email protected]2e02cfe82012-11-21 00:58:001275 const LOGFONT *font = reinterpret_cast<LOGFONT*>(const_cast<char*>(data));
1276 if (_tcsnlen(font->lfFaceName, LF_FACESIZE) < LF_FACESIZE) {
1277 memcpy(r, data, sizeof(LOGFONT));
1278 return true;
1279 }
[email protected]bf5aedf02012-06-04 21:18:251280 }
1281
[email protected]2e02cfe82012-11-21 00:58:001282 NOTREACHED();
1283 return false;
[email protected]bf5aedf02012-06-04 21:18:251284}
1285
1286void ParamTraits<LOGFONT>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:041287 l->append(base::StringPrintf("<LOGFONT>"));
[email protected]bf5aedf02012-06-04 21:18:251288}
1289
rockot0457af102016-02-05 02:12:321290void ParamTraits<MSG>::GetSize(base::PickleSizer* sizer, const param_type& p) {
1291 sizer->AddData(sizeof(MSG));
1292}
1293
rockot502c94f2016-02-03 20:20:161294void ParamTraits<MSG>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251295 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
1296}
1297
rockot502c94f2016-02-03 20:20:161298bool ParamTraits<MSG>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251299 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251300 param_type* r) {
1301 const char *data;
1302 int data_size = 0;
avi48fc13b2014-12-28 23:31:481303 bool result = iter->ReadData(&data, &data_size);
[email protected]bf5aedf02012-06-04 21:18:251304 if (result && data_size == sizeof(MSG)) {
1305 memcpy(r, data, sizeof(MSG));
1306 } else {
1307 result = false;
1308 NOTREACHED();
1309 }
1310
1311 return result;
1312}
1313
1314void ParamTraits<MSG>::Log(const param_type& p, std::string* l) {
1315 l->append("<MSG>");
1316}
1317
1318#endif // OS_WIN
1319
[email protected]946d1b22009-07-22 23:57:211320} // namespace IPC