blob: cac4b1e9592462223cbe73d110f50fddf4635e82 [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"
[email protected]0238a162013-06-13 13:47:4613#include "base/strings/nullable_string16.h"
[email protected]4aa794a12013-06-11 06:32:1814#include "base/strings/string_number_conversions.h"
[email protected]906265872013-06-07 22:40:4515#include "base/strings/utf_string_conversions.h"
[email protected]b43e5562013-06-28 15:20:0216#include "base/time/time.h"
tguilbert4a5ac602016-09-19 21:11:2517#include "base/unguessable_token.h"
[email protected]946d1b22009-07-22 23:57:2118#include "base/values.h"
avi246998d82015-12-22 02:39:0419#include "build/build_config.h"
[email protected]bf5aedf02012-06-04 21:18:2520#include "ipc/ipc_channel_handle.h"
morrita1aa788c2015-01-31 05:45:4221#include "ipc/ipc_message_attachment.h"
morrita4b5c28e22015-01-14 21:17:0622#include "ipc/ipc_message_attachment_set.h"
amistry36182522016-06-27 06:34:4223#include "ipc/ipc_mojo_param_traits.h"
[email protected]bf5aedf02012-06-04 21:18:2524
morrita1aa788c2015-01-31 05:45:4225#if defined(OS_POSIX)
sammc9bf370c2016-11-14 03:29:0826#include "base/file_descriptor_posix.h"
morrita1aa788c2015-01-31 05:45:4227#include "ipc/ipc_platform_file_attachment_posix.h"
28#endif
29
erikchenaf8299d2015-10-09 19:12:0630#if defined(OS_MACOSX) && !defined(OS_IOS)
31#include "ipc/mach_port_mac.h"
32#endif
33
morrita4b5c28e22015-01-14 21:17:0634#if defined(OS_WIN)
[email protected]2e02cfe82012-11-21 00:58:0035#include <tchar.h>
erikchen5ea2ab72015-09-25 22:34:3136#include "ipc/handle_win.h"
erikchend804e1052017-04-29 02:24:3637#include "ipc/ipc_platform_file.h"
[email protected]7a4de7a62010-08-17 18:38:2438#endif
[email protected]946d1b22009-07-22 23:57:2139
Scott Graham3eebff02017-06-30 01:07:1040#if defined(OS_FUCHSIA)
41#include "ipc/handle_fuchsia.h"
42#endif
43
[email protected]946d1b22009-07-22 23:57:2144namespace IPC {
45
[email protected]bf5aedf02012-06-04 21:18:2546namespace {
47
joaodasilva383b174a2017-01-10 09:55:3648const int kMaxRecursionDepth = 200;
[email protected]946d1b22009-07-22 23:57:2149
[email protected]bf5aedf02012-06-04 21:18:2550template<typename CharType>
51void LogBytes(const std::vector<CharType>& data, std::string* out) {
52#if defined(OS_WIN)
53 // Windows has a GUI for logging, which can handle arbitrary binary data.
54 for (size_t i = 0; i < data.size(); ++i)
55 out->push_back(data[i]);
56#else
57 // On POSIX, we log to stdout, which we assume can display ASCII.
58 static const size_t kMaxBytesToLog = 100;
59 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
60 if (isprint(data[i]))
61 out->push_back(data[i]);
62 else
[email protected]7d3cbc92013-03-18 22:33:0463 out->append(
64 base::StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
[email protected]bf5aedf02012-06-04 21:18:2565 }
66 if (data.size() > kMaxBytesToLog) {
[email protected]f8660f82013-03-30 17:29:2867 out->append(base::StringPrintf(
68 " and %u more bytes",
69 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
[email protected]bf5aedf02012-06-04 21:18:2570 }
71#endif
72}
[email protected]946d1b22009-07-22 23:57:2173
rockot502c94f2016-02-03 20:20:1674bool ReadValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:2575 base::PickleIterator* iter,
jdoerrief1e72e32017-04-26 16:23:5576 std::unique_ptr<base::Value>* value,
[email protected]bf5aedf02012-06-04 21:18:2577 int recursion);
[email protected]946d1b22009-07-22 23:57:2178
rockot502c94f2016-02-03 20:20:1679void WriteValue(base::Pickle* m, const base::Value* value, int recursion) {
[email protected]dbc761a2012-07-26 01:29:2180 bool result;
[email protected]946d1b22009-07-22 23:57:2181 if (recursion > kMaxRecursionDepth) {
joaodasilva383b174a2017-01-10 09:55:3682 LOG(ERROR) << "Max recursion depth hit in WriteValue.";
[email protected]946d1b22009-07-22 23:57:2183 return;
84 }
85
jdoerrie76cee9c2017-10-06 22:42:4286 m->WriteInt(static_cast<int>(value->type()));
[email protected]946d1b22009-07-22 23:57:2187
jdoerrie76cee9c2017-10-06 22:42:4288 switch (value->type()) {
jdoerriedc72ee942016-12-07 15:43:2889 case base::Value::Type::NONE:
[email protected]946d1b22009-07-22 23:57:2190 break;
jdoerriedc72ee942016-12-07 15:43:2891 case base::Value::Type::BOOLEAN: {
[email protected]946d1b22009-07-22 23:57:2192 bool val;
[email protected]dbc761a2012-07-26 01:29:2193 result = value->GetAsBoolean(&val);
94 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:2195 WriteParam(m, val);
96 break;
97 }
jdoerriedc72ee942016-12-07 15:43:2898 case base::Value::Type::INTEGER: {
[email protected]946d1b22009-07-22 23:57:2199 int val;
[email protected]dbc761a2012-07-26 01:29:21100 result = value->GetAsInteger(&val);
101 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21102 WriteParam(m, val);
103 break;
104 }
jdoerriedc72ee942016-12-07 15:43:28105 case base::Value::Type::DOUBLE: {
[email protected]946d1b22009-07-22 23:57:21106 double val;
[email protected]dbc761a2012-07-26 01:29:21107 result = value->GetAsDouble(&val);
108 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21109 WriteParam(m, val);
110 break;
111 }
jdoerriedc72ee942016-12-07 15:43:28112 case base::Value::Type::STRING: {
[email protected]946d1b22009-07-22 23:57:21113 std::string val;
[email protected]dbc761a2012-07-26 01:29:21114 result = value->GetAsString(&val);
115 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21116 WriteParam(m, val);
117 break;
118 }
jdoerriedc72ee942016-12-07 15:43:28119 case base::Value::Type::BINARY: {
jdoerrie5328aff2017-04-25 20:08:15120 m->WriteData(value->GetBlob().data(),
Chris Palmerc5ea9b92017-09-25 22:53:22121 base::checked_cast<int>(value->GetBlob().size()));
[email protected]e4dad9fb2009-10-06 18:15:58122 break;
[email protected]946d1b22009-07-22 23:57:21123 }
jdoerriedc72ee942016-12-07 15:43:28124 case base::Value::Type::DICTIONARY: {
[email protected]ea5ef4c2013-06-13 22:50:27125 const base::DictionaryValue* dict =
126 static_cast<const base::DictionaryValue*>(value);
[email protected]946d1b22009-07-22 23:57:21127
Chris Palmerc5ea9b92017-09-25 22:53:22128 WriteParam(m, base::checked_cast<int>(dict->size()));
[email protected]946d1b22009-07-22 23:57:21129
[email protected]ea5ef4c2013-06-13 22:50:27130 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd();
131 it.Advance()) {
[email protected]a899c0b02013-01-18 14:43:27132 WriteParam(m, it.key());
133 WriteValue(m, &it.value(), recursion + 1);
[email protected]946d1b22009-07-22 23:57:21134 }
135 break;
136 }
jdoerriedc72ee942016-12-07 15:43:28137 case base::Value::Type::LIST: {
[email protected]ea5ef4c2013-06-13 22:50:27138 const base::ListValue* list = static_cast<const base::ListValue*>(value);
Chris Palmerc5ea9b92017-09-25 22:53:22139 WriteParam(m, base::checked_cast<int>(list->GetSize()));
dchengcb60e702016-05-25 18:30:47140 for (const auto& entry : *list) {
jdoerriea5676c62017-04-11 18:09:14141 WriteValue(m, &entry, recursion + 1);
[email protected]946d1b22009-07-22 23:57:21142 }
143 break;
144 }
145 }
146}
147
148// Helper for ReadValue that reads a DictionaryValue into a pre-allocated
149// object.
rockot502c94f2016-02-03 20:20:16150bool ReadDictionaryValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25151 base::PickleIterator* iter,
152 base::DictionaryValue* value,
153 int recursion) {
[email protected]946d1b22009-07-22 23:57:21154 int size;
155 if (!ReadParam(m, iter, &size))
156 return false;
157
158 for (int i = 0; i < size; ++i) {
[email protected]e7b418b2010-07-30 19:47:47159 std::string key;
jdoerrief1e72e32017-04-26 16:23:55160 std::unique_ptr<base::Value> subval;
[email protected]946d1b22009-07-22 23:57:21161 if (!ReadParam(m, iter, &key) ||
162 !ReadValue(m, iter, &subval, recursion + 1))
163 return false;
jdoerrief1e72e32017-04-26 16:23:55164 value->SetWithoutPathExpansion(key, std::move(subval));
[email protected]946d1b22009-07-22 23:57:21165 }
166
167 return true;
168}
169
170// Helper for ReadValue that reads a ReadListValue into a pre-allocated
171// object.
rockot502c94f2016-02-03 20:20:16172bool ReadListValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25173 base::PickleIterator* iter,
174 base::ListValue* value,
175 int recursion) {
[email protected]946d1b22009-07-22 23:57:21176 int size;
177 if (!ReadParam(m, iter, &size))
178 return false;
179
180 for (int i = 0; i < size; ++i) {
jdoerrief1e72e32017-04-26 16:23:55181 std::unique_ptr<base::Value> subval;
[email protected]946d1b22009-07-22 23:57:21182 if (!ReadValue(m, iter, &subval, recursion + 1))
183 return false;
jdoerrief1e72e32017-04-26 16:23:55184 value->Set(i, std::move(subval));
[email protected]946d1b22009-07-22 23:57:21185 }
186
187 return true;
188}
189
rockot502c94f2016-02-03 20:20:16190bool ReadValue(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25191 base::PickleIterator* iter,
jdoerrief1e72e32017-04-26 16:23:55192 std::unique_ptr<base::Value>* value,
[email protected]bf5aedf02012-06-04 21:18:25193 int recursion) {
[email protected]946d1b22009-07-22 23:57:21194 if (recursion > kMaxRecursionDepth) {
joaodasilva383b174a2017-01-10 09:55:36195 LOG(ERROR) << "Max recursion depth hit in ReadValue.";
[email protected]946d1b22009-07-22 23:57:21196 return false;
197 }
198
199 int type;
200 if (!ReadParam(m, iter, &type))
201 return false;
202
jdoerriedc72ee942016-12-07 15:43:28203 switch (static_cast<base::Value::Type>(type)) {
204 case base::Value::Type::NONE:
Jeremy Roman160eb922017-08-29 17:43:43205 *value = std::make_unique<base::Value>();
jdoerriee067999a2017-04-07 06:39:00206 break;
jdoerriedc72ee942016-12-07 15:43:28207 case base::Value::Type::BOOLEAN: {
[email protected]946d1b22009-07-22 23:57:21208 bool val;
209 if (!ReadParam(m, iter, &val))
210 return false;
Jeremy Roman160eb922017-08-29 17:43:43211 *value = std::make_unique<base::Value>(val);
[email protected]946d1b22009-07-22 23:57:21212 break;
213 }
jdoerriedc72ee942016-12-07 15:43:28214 case base::Value::Type::INTEGER: {
[email protected]946d1b22009-07-22 23:57:21215 int val;
216 if (!ReadParam(m, iter, &val))
217 return false;
Jeremy Roman160eb922017-08-29 17:43:43218 *value = std::make_unique<base::Value>(val);
[email protected]946d1b22009-07-22 23:57:21219 break;
220 }
jdoerriedc72ee942016-12-07 15:43:28221 case base::Value::Type::DOUBLE: {
[email protected]946d1b22009-07-22 23:57:21222 double val;
223 if (!ReadParam(m, iter, &val))
224 return false;
Jeremy Roman160eb922017-08-29 17:43:43225 *value = std::make_unique<base::Value>(val);
[email protected]946d1b22009-07-22 23:57:21226 break;
227 }
jdoerriedc72ee942016-12-07 15:43:28228 case base::Value::Type::STRING: {
[email protected]946d1b22009-07-22 23:57:21229 std::string val;
230 if (!ReadParam(m, iter, &val))
231 return false;
Jeremy Roman160eb922017-08-29 17:43:43232 *value = std::make_unique<base::Value>(std::move(val));
[email protected]946d1b22009-07-22 23:57:21233 break;
234 }
jdoerriedc72ee942016-12-07 15:43:28235 case base::Value::Type::BINARY: {
[email protected]e4dad9fb2009-10-06 18:15:58236 const char* data;
237 int length;
avi48fc13b2014-12-28 23:31:48238 if (!iter->ReadData(&data, &length))
[email protected]e4dad9fb2009-10-06 18:15:58239 return false;
jdoerrief1e72e32017-04-26 16:23:55240 *value = base::Value::CreateWithCopiedBuffer(data, length);
[email protected]946d1b22009-07-22 23:57:21241 break;
242 }
jdoerriedc72ee942016-12-07 15:43:28243 case base::Value::Type::DICTIONARY: {
jdoerrief1e72e32017-04-26 16:23:55244 base::DictionaryValue val;
245 if (!ReadDictionaryValue(m, iter, &val, recursion))
[email protected]946d1b22009-07-22 23:57:21246 return false;
Jeremy Roman160eb922017-08-29 17:43:43247 *value = std::make_unique<base::Value>(std::move(val));
[email protected]946d1b22009-07-22 23:57:21248 break;
249 }
jdoerriedc72ee942016-12-07 15:43:28250 case base::Value::Type::LIST: {
jdoerrief1e72e32017-04-26 16:23:55251 base::ListValue val;
252 if (!ReadListValue(m, iter, &val, recursion))
[email protected]946d1b22009-07-22 23:57:21253 return false;
Jeremy Roman160eb922017-08-29 17:43:43254 *value = std::make_unique<base::Value>(std::move(val));
[email protected]946d1b22009-07-22 23:57:21255 break;
256 }
[email protected]e4dad9fb2009-10-06 18:15:58257 default:
[email protected]946d1b22009-07-22 23:57:21258 return false;
259 }
260
261 return true;
262}
263
[email protected]bf5aedf02012-06-04 21:18:25264} // namespace
265
266// -----------------------------------------------------------------------------
267
268LogData::LogData()
269 : routing_id(0),
270 type(0),
271 sent(0),
272 receive(0),
273 dispatch(0) {
274}
275
vmpstrbf0d713a2016-03-24 20:22:54276LogData::LogData(const LogData& other) = default;
277
Chris Watkins2d879af2017-11-30 02:11:59278LogData::~LogData() = default;
[email protected]bf5aedf02012-06-04 21:18:25279
[email protected]bf5aedf02012-06-04 21:18:25280void ParamTraits<bool>::Log(const param_type& p, std::string* l) {
281 l->append(p ? "true" : "false");
282}
283
rockot502c94f2016-02-03 20:20:16284void ParamTraits<signed char>::Write(base::Pickle* m, const param_type& p) {
ortuno19ecf1842015-10-30 00:46:20285 m->WriteBytes(&p, sizeof(param_type));
286}
287
rockot502c94f2016-02-03 20:20:16288bool ParamTraits<signed char>::Read(const base::Pickle* m,
289 base::PickleIterator* iter,
290 param_type* r) {
ortuno19ecf1842015-10-30 00:46:20291 const char* data;
292 if (!iter->ReadBytes(&data, sizeof(param_type)))
293 return false;
294 memcpy(r, data, sizeof(param_type));
295 return true;
296}
297
298void ParamTraits<signed char>::Log(const param_type& p, std::string* l) {
299 l->append(base::IntToString(p));
300}
301
rockot502c94f2016-02-03 20:20:16302void ParamTraits<unsigned char>::Write(base::Pickle* m, const param_type& p) {
[email protected]c1ee48d2013-07-12 23:12:28303 m->WriteBytes(&p, sizeof(param_type));
304}
305
rockot502c94f2016-02-03 20:20:16306bool ParamTraits<unsigned char>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25307 base::PickleIterator* iter,
308 param_type* r) {
[email protected]c1ee48d2013-07-12 23:12:28309 const char* data;
avi48fc13b2014-12-28 23:31:48310 if (!iter->ReadBytes(&data, sizeof(param_type)))
[email protected]c1ee48d2013-07-12 23:12:28311 return false;
312 memcpy(r, data, sizeof(param_type));
313 return true;
314}
315
316void ParamTraits<unsigned char>::Log(const param_type& p, std::string* l) {
317 l->append(base::UintToString(p));
318}
319
rockot502c94f2016-02-03 20:20:16320void ParamTraits<unsigned short>::Write(base::Pickle* m, const param_type& p) {
[email protected]c1ee48d2013-07-12 23:12:28321 m->WriteBytes(&p, sizeof(param_type));
322}
323
rockot502c94f2016-02-03 20:20:16324bool ParamTraits<unsigned short>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25325 base::PickleIterator* iter,
[email protected]c1ee48d2013-07-12 23:12:28326 param_type* r) {
327 const char* data;
avi48fc13b2014-12-28 23:31:48328 if (!iter->ReadBytes(&data, sizeof(param_type)))
[email protected]c1ee48d2013-07-12 23:12:28329 return false;
330 memcpy(r, data, sizeof(param_type));
331 return true;
332}
333
334void ParamTraits<unsigned short>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09335 l->append(base::NumberToString(p));
[email protected]c1ee48d2013-07-12 23:12:28336}
337
[email protected]252cad62010-08-18 18:33:57338void ParamTraits<int>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09339 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57340}
341
342void ParamTraits<unsigned int>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09343 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57344}
345
Sergey Ulanova98ff6b52017-07-13 01:54:20346#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_FUCHSIA) || \
jamac78d7d82016-02-11 00:50:28347 (defined(OS_ANDROID) && defined(ARCH_CPU_64_BITS))
[email protected]252cad62010-08-18 18:33:57348void ParamTraits<long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09349 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57350}
351
352void ParamTraits<unsigned long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09353 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57354}
jam03d8a782016-02-10 20:13:39355#endif
[email protected]252cad62010-08-18 18:33:57356
357void ParamTraits<long long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09358 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57359}
360
361void ParamTraits<unsigned long long>::Log(const param_type& p, std::string* l) {
Daniel Cheng3d199b12017-12-12 03:51:09362 l->append(base::NumberToString(p));
[email protected]252cad62010-08-18 18:33:57363}
[email protected]7a4de7a62010-08-17 18:38:24364
[email protected]bf5aedf02012-06-04 21:18:25365void ParamTraits<float>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:04366 l->append(base::StringPrintf("%e", p));
[email protected]7a4de7a62010-08-17 18:38:24367}
368
rockot502c94f2016-02-03 20:20:16369void ParamTraits<double>::Write(base::Pickle* m, const param_type& p) {
[email protected]48328ff2013-10-31 09:27:31370 m->WriteBytes(reinterpret_cast<const char*>(&p), sizeof(param_type));
[email protected]d84e48b2010-10-21 22:04:52371}
372
rockot502c94f2016-02-03 20:20:16373bool ParamTraits<double>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25374 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25375 param_type* r) {
376 const char *data;
avi48fc13b2014-12-28 23:31:48377 if (!iter->ReadBytes(&data, sizeof(*r))) {
[email protected]bf5aedf02012-06-04 21:18:25378 NOTREACHED();
379 return false;
380 }
381 memcpy(r, data, sizeof(param_type));
382 return true;
[email protected]d84e48b2010-10-21 22:04:52383}
384
[email protected]bf5aedf02012-06-04 21:18:25385void ParamTraits<double>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:04386 l->append(base::StringPrintf("%e", p));
[email protected]1d14f582011-09-02 20:42:04387}
388
[email protected]bf5aedf02012-06-04 21:18:25389
390void ParamTraits<std::string>::Log(const param_type& p, std::string* l) {
391 l->append(p);
[email protected]1d14f582011-09-02 20:42:04392}
393
[email protected]476dafb2013-12-03 00:39:26394void ParamTraits<base::string16>::Log(const param_type& p, std::string* l) {
[email protected]ad65a3e2013-12-25 18:18:01395 l->append(base::UTF16ToUTF8(p));
[email protected]bf5aedf02012-06-04 21:18:25396}
[email protected]bf5aedf02012-06-04 21:18:25397
rockot502c94f2016-02-03 20:20:16398void ParamTraits<std::vector<char>>::Write(base::Pickle* m,
399 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25400 if (p.empty()) {
401 m->WriteData(NULL, 0);
402 } else {
Chris Palmerc5ea9b92017-09-25 22:53:22403 m->WriteData(&p.front(), base::checked_cast<int>(p.size()));
[email protected]bf5aedf02012-06-04 21:18:25404 }
405}
406
rockot502c94f2016-02-03 20:20:16407bool ParamTraits<std::vector<char>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25408 base::PickleIterator* iter,
409 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25410 const char *data;
411 int data_size = 0;
avi48fc13b2014-12-28 23:31:48412 if (!iter->ReadData(&data, &data_size) || data_size < 0)
[email protected]bf5aedf02012-06-04 21:18:25413 return false;
414 r->resize(data_size);
415 if (data_size)
416 memcpy(&r->front(), data, data_size);
417 return true;
418}
419
420void ParamTraits<std::vector<char> >::Log(const param_type& p, std::string* l) {
421 LogBytes(p, l);
422}
423
rockot502c94f2016-02-03 20:20:16424void ParamTraits<std::vector<unsigned char>>::Write(base::Pickle* m,
425 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25426 if (p.empty()) {
427 m->WriteData(NULL, 0);
428 } else {
429 m->WriteData(reinterpret_cast<const char*>(&p.front()),
Chris Palmerc5ea9b92017-09-25 22:53:22430 base::checked_cast<int>(p.size()));
[email protected]bf5aedf02012-06-04 21:18:25431 }
432}
433
rockot502c94f2016-02-03 20:20:16434bool ParamTraits<std::vector<unsigned char>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25435 base::PickleIterator* iter,
436 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25437 const char *data;
438 int data_size = 0;
avi48fc13b2014-12-28 23:31:48439 if (!iter->ReadData(&data, &data_size) || data_size < 0)
[email protected]bf5aedf02012-06-04 21:18:25440 return false;
441 r->resize(data_size);
442 if (data_size)
443 memcpy(&r->front(), data, data_size);
444 return true;
445}
446
447void ParamTraits<std::vector<unsigned char> >::Log(const param_type& p,
448 std::string* l) {
449 LogBytes(p, l);
450}
451
rockot502c94f2016-02-03 20:20:16452void ParamTraits<std::vector<bool>>::Write(base::Pickle* m,
453 const param_type& p) {
Chris Palmerc5ea9b92017-09-25 22:53:22454 WriteParam(m, base::checked_cast<int>(p.size()));
[email protected]d4124852013-03-20 20:25:00455 // Cast to bool below is required because libc++'s
456 // vector<bool>::const_reference is different from bool, and we want to avoid
457 // writing an extra specialization of ParamTraits for it.
[email protected]bf5aedf02012-06-04 21:18:25458 for (size_t i = 0; i < p.size(); i++)
[email protected]d4124852013-03-20 20:25:00459 WriteParam(m, static_cast<bool>(p[i]));
[email protected]bf5aedf02012-06-04 21:18:25460}
461
rockot502c94f2016-02-03 20:20:16462bool ParamTraits<std::vector<bool>>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25463 base::PickleIterator* iter,
464 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25465 int size;
466 // ReadLength() checks for < 0 itself.
avi48fc13b2014-12-28 23:31:48467 if (!iter->ReadLength(&size))
[email protected]bf5aedf02012-06-04 21:18:25468 return false;
469 r->resize(size);
470 for (int i = 0; i < size; i++) {
471 bool value;
472 if (!ReadParam(m, iter, &value))
473 return false;
474 (*r)[i] = value;
475 }
476 return true;
477}
478
479void ParamTraits<std::vector<bool> >::Log(const param_type& p, std::string* l) {
480 for (size_t i = 0; i < p.size(); ++i) {
481 if (i != 0)
482 l->push_back(' ');
[email protected]d4124852013-03-20 20:25:00483 LogParam(static_cast<bool>(p[i]), l);
[email protected]bf5aedf02012-06-04 21:18:25484 }
[email protected]d84e48b2010-10-21 22:04:52485}
486
rockot502c94f2016-02-03 20:20:16487void ParamTraits<base::DictionaryValue>::Write(base::Pickle* m,
[email protected]ea5ef4c2013-06-13 22:50:27488 const param_type& p) {
[email protected]946d1b22009-07-22 23:57:21489 WriteValue(m, &p, 0);
490}
491
rockot502c94f2016-02-03 20:20:16492bool ParamTraits<base::DictionaryValue>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25493 base::PickleIterator* iter,
494 param_type* r) {
[email protected]946d1b22009-07-22 23:57:21495 int type;
jdoerriedc72ee942016-12-07 15:43:28496 if (!ReadParam(m, iter, &type) ||
497 type != static_cast<int>(base::Value::Type::DICTIONARY))
[email protected]946d1b22009-07-22 23:57:21498 return false;
499
500 return ReadDictionaryValue(m, iter, r, 0);
501}
502
[email protected]ea5ef4c2013-06-13 22:50:27503void ParamTraits<base::DictionaryValue>::Log(const param_type& p,
504 std::string* l) {
[email protected]946d1b22009-07-22 23:57:21505 std::string json;
estade8d046462015-05-16 01:02:34506 base::JSONWriter::Write(p, &json);
[email protected]252cad62010-08-18 18:33:57507 l->append(json);
[email protected]946d1b22009-07-22 23:57:21508}
509
[email protected]7a4de7a62010-08-17 18:38:24510#if defined(OS_POSIX)
rockot502c94f2016-02-03 20:20:16511void ParamTraits<base::FileDescriptor>::Write(base::Pickle* m,
512 const param_type& p) {
erikchen14525202017-05-06 19:16:51513 // This serialization must be kept in sync with
erikchen9d6afd712017-05-18 17:49:06514 // nacl_message_scanner.cc:WriteHandle().
[email protected]7a4de7a62010-08-17 18:38:24515 const bool valid = p.fd >= 0;
516 WriteParam(m, valid);
517
morrita96693852014-09-24 20:11:45518 if (!valid)
519 return;
520
521 if (p.auto_close) {
morrita1aa788c2015-01-31 05:45:42522 if (!m->WriteAttachment(
523 new internal::PlatformFileAttachment(base::ScopedFD(p.fd))))
morrita96693852014-09-24 20:11:45524 NOTREACHED();
525 } else {
morrita1aa788c2015-01-31 05:45:42526 if (!m->WriteAttachment(new internal::PlatformFileAttachment(p.fd)))
[email protected]7a4de7a62010-08-17 18:38:24527 NOTREACHED();
528 }
529}
530
rockot502c94f2016-02-03 20:20:16531bool ParamTraits<base::FileDescriptor>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25532 base::PickleIterator* iter,
[email protected]7a4de7a62010-08-17 18:38:24533 param_type* r) {
morrita96693852014-09-24 20:11:45534 *r = base::FileDescriptor();
535
[email protected]7a4de7a62010-08-17 18:38:24536 bool valid;
537 if (!ReadParam(m, iter, &valid))
538 return false;
539
morrita96693852014-09-24 20:11:45540 if (!valid)
[email protected]7a4de7a62010-08-17 18:38:24541 return true;
[email protected]7a4de7a62010-08-17 18:38:24542
rockot502c94f2016-02-03 20:20:16543 scoped_refptr<base::Pickle::Attachment> attachment;
morrita1aa788c2015-01-31 05:45:42544 if (!m->ReadAttachment(iter, &attachment))
morrita96693852014-09-24 20:11:45545 return false;
546
sammc6ed3efb2016-11-23 03:17:35547 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
548 MessageAttachment::Type::PLATFORM_FILE) {
549 return false;
550 }
551
rockot502c94f2016-02-03 20:20:16552 *r = base::FileDescriptor(
sammc6ed3efb2016-11-23 03:17:35553 static_cast<internal::PlatformFileAttachment*>(attachment.get())
554 ->TakePlatformFile(),
rockot502c94f2016-02-03 20:20:16555 true);
morrita96693852014-09-24 20:11:45556 return true;
[email protected]7a4de7a62010-08-17 18:38:24557}
558
559void ParamTraits<base::FileDescriptor>::Log(const param_type& p,
[email protected]252cad62010-08-18 18:33:57560 std::string* l) {
[email protected]7a4de7a62010-08-17 18:38:24561 if (p.auto_close) {
[email protected]7d3cbc92013-03-18 22:33:04562 l->append(base::StringPrintf("FD(%d auto-close)", p.fd));
[email protected]7a4de7a62010-08-17 18:38:24563 } else {
[email protected]7d3cbc92013-03-18 22:33:04564 l->append(base::StringPrintf("FD(%d)", p.fd));
[email protected]7a4de7a62010-08-17 18:38:24565 }
566}
567#endif // defined(OS_POSIX)
568
Klaus Weidner3824a8882017-11-03 06:24:57569#if defined(OS_ANDROID)
570void ParamTraits<base::SharedMemoryHandle::Type>::Write(base::Pickle* m,
571 const param_type& p) {
572 DCHECK(static_cast<int>(p) >= 0 && p <= base::SharedMemoryHandle::Type::LAST);
573 m->WriteInt(static_cast<int>(p));
574}
575
576bool ParamTraits<base::SharedMemoryHandle::Type>::Read(
577 const base::Pickle* m,
578 base::PickleIterator* iter,
579 param_type* r) {
580 int value;
581 if (!iter->ReadInt(&value))
582 return false;
583 if (value < 0 ||
584 value > static_cast<int>(base::SharedMemoryHandle::Type::LAST))
585 return false;
586 *r = static_cast<param_type>(value);
587 return true;
588}
589
590void ParamTraits<base::SharedMemoryHandle::Type>::Log(const param_type& p,
591 std::string* l) {
592 l->append(base::IntToString(static_cast<int>(p)));
593}
594#endif
595
erikchen22a813b2017-04-28 17:10:50596void ParamTraits<base::SharedMemoryHandle>::Write(base::Pickle* m,
597 const param_type& p) {
erikchen14525202017-05-06 19:16:51598 // This serialization must be kept in sync with
erikchen9d6afd712017-05-18 17:49:06599 // nacl_message_scanner.cc:WriteHandle().
erikchen22a813b2017-04-28 17:10:50600 const bool valid = p.IsValid();
601 WriteParam(m, valid);
602
603 if (!valid)
604 return;
605
erikchen9d6afd712017-05-18 17:49:06606#if defined(OS_MACOSX) && !defined(OS_IOS)
607 MachPortMac mach_port_mac(p.GetMemoryObject());
608 WriteParam(m, mach_port_mac);
609#elif defined(OS_WIN)
Wez51eaaad2017-08-09 05:51:38610 HandleWin handle_win(p.GetHandle());
erikchen9d6afd712017-05-18 17:49:06611 WriteParam(m, handle_win);
Wez8c49ebc92017-08-10 17:11:13612#elif defined(OS_FUCHSIA)
613 HandleFuchsia handle_fuchsia(p.GetHandle());
614 WriteParam(m, handle_fuchsia);
erikchen9d6afd712017-05-18 17:49:06615#else
Klaus Weidner3824a8882017-11-03 06:24:57616#if defined(OS_ANDROID)
617 // Android transfers both ashmem and AHardwareBuffer SharedMemoryHandle
618 // subtypes, both are transferred via file descriptor but need to be handled
619 // differently by the receiver. Write the type to distinguish.
620 WriteParam(m, p.GetType());
David 'Digit' Turnere2a65762018-01-19 17:51:51621 WriteParam(m, p.IsReadOnly());
622
623 // Ensure the region is read-only before sending it through IPC.
624 if (p.IsReadOnly()) {
625 if (!p.IsRegionReadOnly()) {
626 LOG(ERROR) << "Sending unsealed read-only region through IPC";
627 p.SetRegionReadOnly();
628 }
629 }
Klaus Weidner3824a8882017-11-03 06:24:57630#endif
erikchen22a813b2017-04-28 17:10:50631 if (p.OwnershipPassesToIPC()) {
632 if (!m->WriteAttachment(new internal::PlatformFileAttachment(
633 base::ScopedFD(p.GetHandle()))))
634 NOTREACHED();
635 } else {
636 if (!m->WriteAttachment(
637 new internal::PlatformFileAttachment(p.GetHandle())))
638 NOTREACHED();
639 }
erikchen9d6afd712017-05-18 17:49:06640#endif
641
642#if (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
643 // If the caller intended to pass ownership to the IPC stack, release a
644 // reference.
645 if (p.OwnershipPassesToIPC())
646 p.Close();
647#endif
648
erikchen14525202017-05-06 19:16:51649 DCHECK(!p.GetGUID().is_empty());
650 WriteParam(m, p.GetGUID());
erikchen9d6afd712017-05-18 17:49:06651 WriteParam(m, static_cast<uint64_t>(p.GetSize()));
erikchen22a813b2017-04-28 17:10:50652}
653
654bool ParamTraits<base::SharedMemoryHandle>::Read(const base::Pickle* m,
655 base::PickleIterator* iter,
656 param_type* r) {
657 *r = base::SharedMemoryHandle();
658
659 bool valid;
660 if (!ReadParam(m, iter, &valid))
661 return false;
erikchen22a813b2017-04-28 17:10:50662 if (!valid)
663 return true;
664
erikchen9d6afd712017-05-18 17:49:06665#if defined(OS_MACOSX) && !defined(OS_IOS)
666 MachPortMac mach_port_mac;
667 if (!ReadParam(m, iter, &mach_port_mac))
668 return false;
669#elif defined(OS_WIN)
670 HandleWin handle_win;
671 if (!ReadParam(m, iter, &handle_win))
672 return false;
Scott Graham3eebff02017-06-30 01:07:10673#elif defined(OS_FUCHSIA)
674 HandleFuchsia handle_fuchsia;
675 if (!ReadParam(m, iter, &handle_fuchsia))
676 return false;
erikchen9d6afd712017-05-18 17:49:06677#else
Klaus Weidner3824a8882017-11-03 06:24:57678#if defined(OS_ANDROID)
679 // Android uses both ashmen and AHardwareBuffer subtypes, get the actual type
680 // for use as a constructor argument alongside the file descriptor.
681 base::SharedMemoryHandle::Type android_subtype;
David 'Digit' Turnere2a65762018-01-19 17:51:51682 bool is_read_only = false;
683 if (!ReadParam(m, iter, &android_subtype) ||
684 !ReadParam(m, iter, &is_read_only)) {
Klaus Weidner3824a8882017-11-03 06:24:57685 return false;
David 'Digit' Turnere2a65762018-01-19 17:51:51686 }
Klaus Weidner3824a8882017-11-03 06:24:57687#endif
erikchen22a813b2017-04-28 17:10:50688 scoped_refptr<base::Pickle::Attachment> attachment;
689 if (!m->ReadAttachment(iter, &attachment))
690 return false;
691
692 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
693 MessageAttachment::Type::PLATFORM_FILE) {
694 return false;
695 }
erikchen9d6afd712017-05-18 17:49:06696#endif
erikchen22a813b2017-04-28 17:10:50697
erikchen14525202017-05-06 19:16:51698 base::UnguessableToken guid;
erikchen9d6afd712017-05-18 17:49:06699 uint64_t size;
Alexandr Ilind497eee2018-04-19 22:50:54700 if (!ReadParam(m, iter, &guid) || !ReadParam(m, iter, &size) ||
701 !base::IsValueInRangeForNumericType<size_t>(size)) {
erikchen14525202017-05-06 19:16:51702 return false;
erikchen9d6afd712017-05-18 17:49:06703 }
erikchen14525202017-05-06 19:16:51704
erikchen9d6afd712017-05-18 17:49:06705#if defined(OS_MACOSX) && !defined(OS_IOS)
706 *r = base::SharedMemoryHandle(mach_port_mac.get_mach_port(),
707 static_cast<size_t>(size), guid);
708#elif defined(OS_WIN)
709 *r = base::SharedMemoryHandle(handle_win.get_handle(),
710 static_cast<size_t>(size), guid);
Scott Graham3eebff02017-06-30 01:07:10711#elif defined(OS_FUCHSIA)
712 *r = base::SharedMemoryHandle(handle_fuchsia.get_handle(),
713 static_cast<size_t>(size), guid);
Klaus Weidner3824a8882017-11-03 06:24:57714#elif defined(OS_ANDROID)
715 *r = base::SharedMemoryHandle(
716 android_subtype,
717 base::FileDescriptor(
718 static_cast<internal::PlatformFileAttachment*>(attachment.get())
719 ->TakePlatformFile(),
720 true),
721 static_cast<size_t>(size), guid);
David 'Digit' Turnere2a65762018-01-19 17:51:51722 if (is_read_only)
723 r->SetReadOnly();
erikchen9d6afd712017-05-18 17:49:06724#else
erikchen14525202017-05-06 19:16:51725 *r = base::SharedMemoryHandle(
726 base::FileDescriptor(
727 static_cast<internal::PlatformFileAttachment*>(attachment.get())
728 ->TakePlatformFile(),
729 true),
erikchen9d6afd712017-05-18 17:49:06730 static_cast<size_t>(size), guid);
731#endif
732
erikchen22a813b2017-04-28 17:10:50733 return true;
734}
735
736void ParamTraits<base::SharedMemoryHandle>::Log(const param_type& p,
737 std::string* l) {
erikchen9d6afd712017-05-18 17:49:06738#if defined(OS_MACOSX) && !defined(OS_IOS)
739 l->append("Mach port: ");
740 LogParam(p.GetMemoryObject(), l);
741#elif defined(OS_WIN)
742 l->append("HANDLE: ");
743 LogParam(p.GetHandle(), l);
744#else
745 l->append("FD: ");
746 LogParam(p.GetHandle(), l);
747#endif
748
erikchen14525202017-05-06 19:16:51749 l->append("GUID: ");
erikchen9d6afd712017-05-18 17:49:06750 LogParam(p.GetGUID(), l);
751 l->append("size: ");
752 LogParam(static_cast<uint64_t>(p.GetSize()), l);
David 'Digit' Turnere2a65762018-01-19 17:51:51753#if defined(OS_ANDROID)
754 l->append("read-only: ");
755 LogParam(p.IsReadOnly(), l);
756#endif
erikchen22a813b2017-04-28 17:10:50757}
scottmgd19b4f72015-06-19 22:51:00758
Alexandr Ilind497eee2018-04-19 22:50:54759void ParamTraits<base::ReadOnlySharedMemoryRegion>::Write(base::Pickle* m,
760 const param_type& p) {
761 base::subtle::PlatformSharedMemoryRegion handle =
762 base::ReadOnlySharedMemoryRegion::TakeHandleForSerialization(
763 std::move(const_cast<param_type&>(p)));
764 WriteParam(m, std::move(handle));
765}
766
767bool ParamTraits<base::ReadOnlySharedMemoryRegion>::Read(
768 const base::Pickle* m,
769 base::PickleIterator* iter,
770 param_type* r) {
771 base::subtle::PlatformSharedMemoryRegion handle;
772 if (!ReadParam(m, iter, &handle))
773 return false;
774
775 *r = base::ReadOnlySharedMemoryRegion::Deserialize(std::move(handle));
776 return true;
777}
778
779void ParamTraits<base::ReadOnlySharedMemoryRegion>::Log(const param_type& p,
780 std::string* l) {
781 *l = "<base::ReadOnlySharedMemoryRegion>";
782 // TODO(alexilin): currently there is no way to access underlying handle
783 // without destructing a ReadOnlySharedMemoryRegion instance.
784}
785
786void ParamTraits<base::WritableSharedMemoryRegion>::Write(base::Pickle* m,
787 const param_type& p) {
788 base::subtle::PlatformSharedMemoryRegion handle =
789 base::WritableSharedMemoryRegion::TakeHandleForSerialization(
790 std::move(const_cast<param_type&>(p)));
791 WriteParam(m, std::move(handle));
792}
793
794bool ParamTraits<base::WritableSharedMemoryRegion>::Read(
795 const base::Pickle* m,
796 base::PickleIterator* iter,
797 param_type* r) {
798 base::subtle::PlatformSharedMemoryRegion handle;
799 if (!ReadParam(m, iter, &handle))
800 return false;
801
802 *r = base::WritableSharedMemoryRegion::Deserialize(std::move(handle));
803 return true;
804}
805
806void ParamTraits<base::WritableSharedMemoryRegion>::Log(const param_type& p,
807 std::string* l) {
808 *l = "<base::WritableSharedMemoryRegion>";
809 // TODO(alexilin): currently there is no way to access underlying handle
810 // without destructing a ReadOnlySharedMemoryRegion instance.
811}
812
813void ParamTraits<base::UnsafeSharedMemoryRegion>::Write(base::Pickle* m,
814 const param_type& p) {
815 base::subtle::PlatformSharedMemoryRegion handle =
816 base::UnsafeSharedMemoryRegion::TakeHandleForSerialization(
817 std::move(const_cast<param_type&>(p)));
818 WriteParam(m, std::move(handle));
819}
820
821bool ParamTraits<base::UnsafeSharedMemoryRegion>::Read(
822 const base::Pickle* m,
823 base::PickleIterator* iter,
824 param_type* r) {
825 base::subtle::PlatformSharedMemoryRegion handle;
826 if (!ReadParam(m, iter, &handle))
827 return false;
828
829 *r = base::UnsafeSharedMemoryRegion::Deserialize(std::move(handle));
830 return true;
831}
832
833void ParamTraits<base::UnsafeSharedMemoryRegion>::Log(const param_type& p,
834 std::string* l) {
835 *l = "<base::UnsafeSharedMemoryRegion>";
836 // TODO(alexilin): currently there is no way to access underlying handle
837 // without destructing a ReadOnlySharedMemoryRegion instance.
838}
839
840void ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Write(
841 base::Pickle* m,
842 const param_type& p) {
843 const bool valid = p.IsValid();
844 WriteParam(m, valid);
845
846 if (!valid)
847 return;
848
849 WriteParam(m, p.GetMode());
850 WriteParam(m, static_cast<uint64_t>(p.GetSize()));
851 WriteParam(m, p.GetGUID());
852
853#if defined(OS_MACOSX) && !defined(OS_IOS)
854 base::mac::ScopedMachSendRight h =
855 const_cast<param_type&>(p).PassPlatformHandle();
856 MachPortMac mach_port_mac(h.release());
857 WriteParam(m, mach_port_mac);
858#elif defined(OS_FUCHSIA)
859 base::ScopedZxHandle h = const_cast<param_type&>(p).PassPlatformHandle();
860 HandleFuchsia handle_fuchsia(h.release());
861 WriteParam(m, handle_fuchsia);
862#elif defined(OS_WIN)
863 base::win::ScopedHandle h = const_cast<param_type&>(p).PassPlatformHandle();
864 HandleWin handle_win(h.Take());
865 WriteParam(m, handle_win);
866#elif defined(OS_ANDROID)
867 m->WriteAttachment(new internal::PlatformFileAttachment(
868 base::ScopedFD(const_cast<param_type&>(p).PassPlatformHandle())));
869#else
870 base::subtle::ScopedFDPair h =
871 const_cast<param_type&>(p).PassPlatformHandle();
872 m->WriteAttachment(new internal::PlatformFileAttachment(std::move(h.fd)));
873 if (p.GetMode() ==
874 base::subtle::PlatformSharedMemoryRegion::Mode::kWritable) {
875 m->WriteAttachment(
876 new internal::PlatformFileAttachment(std::move(h.readonly_fd)));
877 }
878#endif
879}
880
881bool ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Read(
882 const base::Pickle* m,
883 base::PickleIterator* iter,
884 param_type* r) {
885 bool valid;
886 if (!ReadParam(m, iter, &valid))
887 return false;
888 if (!valid) {
889 *r = base::subtle::PlatformSharedMemoryRegion();
890 return true;
891 }
892
893 base::subtle::PlatformSharedMemoryRegion::Mode mode;
894 uint64_t shm_size;
895 base::UnguessableToken guid;
896 if (!ReadParam(m, iter, &mode) || !ReadParam(m, iter, &shm_size) ||
897 !base::IsValueInRangeForNumericType<size_t>(shm_size) ||
898 !ReadParam(m, iter, &guid)) {
899 return false;
900 }
901 size_t size = static_cast<size_t>(shm_size);
902
903#if defined(OS_MACOSX) && !defined(OS_IOS)
904 MachPortMac mach_port_mac;
905 if (!ReadParam(m, iter, &mach_port_mac))
906 return false;
907 *r = base::subtle::PlatformSharedMemoryRegion::Take(
908 base::mac::ScopedMachSendRight(mach_port_mac.get_mach_port()), mode, size,
909 guid);
910#elif defined(OS_FUCHSIA)
911 HandleFuchsia handle_fuchsia;
912 if (!ReadParam(m, iter, &handle_fuchsia))
913 return false;
914 *r = base::subtle::PlatformSharedMemoryRegion::Take(
915 base::ScopedZxHandle(handle_fuchsia.get_handle()), mode, size, guid);
916#elif defined(OS_WIN)
917 HandleWin handle_win;
918 if (!ReadParam(m, iter, &handle_win))
919 return false;
920 *r = base::subtle::PlatformSharedMemoryRegion::Take(
921 base::win::ScopedHandle(handle_win.get_handle()), mode, size, guid);
922#else
923 scoped_refptr<base::Pickle::Attachment> attachment;
924 if (!m->ReadAttachment(iter, &attachment))
925 return false;
926 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
927 MessageAttachment::Type::PLATFORM_FILE) {
928 return false;
929 }
930
931#if defined(OS_ANDROID)
932 *r = base::subtle::PlatformSharedMemoryRegion::Take(
933 base::ScopedFD(
934 static_cast<internal::PlatformFileAttachment*>(attachment.get())
935 ->TakePlatformFile()),
936 mode, size, guid);
937#else
938 scoped_refptr<base::Pickle::Attachment> readonly_attachment;
939 if (mode == base::subtle::PlatformSharedMemoryRegion::Mode::kWritable) {
940 if (!m->ReadAttachment(iter, &readonly_attachment))
941 return false;
942
943 if (static_cast<MessageAttachment*>(readonly_attachment.get())->GetType() !=
944 MessageAttachment::Type::PLATFORM_FILE) {
945 return false;
946 }
947 }
948 *r = base::subtle::PlatformSharedMemoryRegion::Take(
949 base::subtle::ScopedFDPair(
950 base::ScopedFD(
951 static_cast<internal::PlatformFileAttachment*>(attachment.get())
952 ->TakePlatformFile()),
953 readonly_attachment
954 ? base::ScopedFD(static_cast<internal::PlatformFileAttachment*>(
955 readonly_attachment.get())
956 ->TakePlatformFile())
957 : base::ScopedFD()),
958 mode, size, guid);
959#endif // defined(OS_ANDROID)
960
961#endif
962
963 return true;
964}
965
966void ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Log(
967 const param_type& p,
968 std::string* l) {
969#if defined(OS_MACOSX) && !defined(OS_IOS)
970 l->append("Mach port: ");
971 LogParam(p.GetPlatformHandle(), l);
972#elif defined(OS_FUCHSIA) || defined(OS_WIN)
973 l->append("Handle: ");
974 LogParam(p.GetPlatformHandle(), l);
975#elif defined(OS_ANDROID)
976 l->append("FD: ");
977 LogParam(p.GetPlatformHandle(), l);
978#else
979 base::subtle::FDPair h = p.GetPlatformHandle();
980 l->append("FD: ");
981 LogParam(h.fd, l);
982 l->append("Read-only FD: ");
983 LogParam(h.readonly_fd, l);
984#endif
985
986 l->append("Mode: ");
987 LogParam(p.GetMode(), l);
988 l->append("size: ");
989 LogParam(static_cast<uint64_t>(p.GetSize()), l);
990 l->append("GUID: ");
991 LogParam(p.GetGUID(), l);
992}
993
994void ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Write(
995 base::Pickle* m,
996 const param_type& value) {
997 DCHECK(static_cast<int>(value) >= 0 &&
998 static_cast<int>(value) <= static_cast<int>(param_type::kMaxValue));
999 m->WriteInt(static_cast<int>(value));
1000}
1001
1002bool ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Read(
1003 const base::Pickle* m,
1004 base::PickleIterator* iter,
1005 param_type* p) {
1006 int value;
1007 if (!iter->ReadInt(&value))
1008 return false;
1009 if (!(static_cast<int>(value) >= 0 &&
1010 static_cast<int>(value) <= static_cast<int>(param_type::kMaxValue))) {
1011 return false;
1012 }
1013 *p = static_cast<param_type>(value);
1014 return true;
1015}
1016
1017void ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Log(
1018 const param_type& p,
1019 std::string* l) {
1020 LogParam(static_cast<int>(p), l);
1021}
1022
erikchend804e1052017-04-29 02:24:361023#if defined(OS_WIN)
erikchend804e1052017-04-29 02:24:361024void ParamTraits<PlatformFileForTransit>::Write(base::Pickle* m,
1025 const param_type& p) {
1026 m->WriteBool(p.IsValid());
1027 if (p.IsValid()) {
Wez51eaaad2017-08-09 05:51:381028 HandleWin handle_win(p.GetHandle());
erikchend804e1052017-04-29 02:24:361029 ParamTraits<HandleWin>::Write(m, handle_win);
1030 ::CloseHandle(p.GetHandle());
1031 }
1032}
1033
1034bool ParamTraits<PlatformFileForTransit>::Read(const base::Pickle* m,
1035 base::PickleIterator* iter,
1036 param_type* r) {
1037 bool is_valid;
1038 if (!iter->ReadBool(&is_valid))
1039 return false;
1040 if (!is_valid) {
1041 *r = PlatformFileForTransit();
1042 return true;
1043 }
1044
1045 HandleWin handle_win;
1046 if (!ParamTraits<HandleWin>::Read(m, iter, &handle_win))
1047 return false;
1048 *r = PlatformFileForTransit(handle_win.get_handle());
1049 return true;
1050}
1051
1052void ParamTraits<PlatformFileForTransit>::Log(const param_type& p,
1053 std::string* l) {
1054 LogParam(p.GetHandle(), l);
1055}
1056#endif // defined(OS_WIN)
1057
rockot502c94f2016-02-03 20:20:161058void ParamTraits<base::FilePath>::Write(base::Pickle* m, const param_type& p) {
[email protected]aeae59f2013-01-28 13:47:551059 p.WriteToPickle(m);
[email protected]bf5aedf02012-06-04 21:18:251060}
1061
rockot502c94f2016-02-03 20:20:161062bool ParamTraits<base::FilePath>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251063 base::PickleIterator* iter,
[email protected]6d4b67a2013-02-10 04:49:301064 param_type* r) {
[email protected]aeae59f2013-01-28 13:47:551065 return r->ReadFromPickle(iter);
[email protected]bf5aedf02012-06-04 21:18:251066}
1067
[email protected]6d4b67a2013-02-10 04:49:301068void ParamTraits<base::FilePath>::Log(const param_type& p, std::string* l) {
1069 ParamTraits<base::FilePath::StringType>::Log(p.value(), l);
[email protected]bf5aedf02012-06-04 21:18:251070}
1071
rockot502c94f2016-02-03 20:20:161072void ParamTraits<base::ListValue>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251073 WriteValue(m, &p, 0);
1074}
1075
rockot502c94f2016-02-03 20:20:161076bool ParamTraits<base::ListValue>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251077 base::PickleIterator* iter,
1078 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:251079 int type;
jdoerriedc72ee942016-12-07 15:43:281080 if (!ReadParam(m, iter, &type) ||
1081 type != static_cast<int>(base::Value::Type::LIST))
[email protected]bf5aedf02012-06-04 21:18:251082 return false;
1083
1084 return ReadListValue(m, iter, r, 0);
1085}
1086
[email protected]ea5ef4c2013-06-13 22:50:271087void ParamTraits<base::ListValue>::Log(const param_type& p, std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:251088 std::string json;
estade8d046462015-05-16 01:02:341089 base::JSONWriter::Write(p, &json);
[email protected]bf5aedf02012-06-04 21:18:251090 l->append(json);
1091}
1092
rockot502c94f2016-02-03 20:20:161093void ParamTraits<base::NullableString16>::Write(base::Pickle* m,
[email protected]0238a162013-06-13 13:47:461094 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251095 WriteParam(m, p.string());
1096 WriteParam(m, p.is_null());
1097}
1098
rockot502c94f2016-02-03 20:20:161099bool ParamTraits<base::NullableString16>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251100 base::PickleIterator* iter,
[email protected]0238a162013-06-13 13:47:461101 param_type* r) {
[email protected]476dafb2013-12-03 00:39:261102 base::string16 string;
[email protected]bf5aedf02012-06-04 21:18:251103 if (!ReadParam(m, iter, &string))
1104 return false;
1105 bool is_null;
1106 if (!ReadParam(m, iter, &is_null))
1107 return false;
[email protected]0238a162013-06-13 13:47:461108 *r = base::NullableString16(string, is_null);
[email protected]bf5aedf02012-06-04 21:18:251109 return true;
1110}
1111
[email protected]0238a162013-06-13 13:47:461112void ParamTraits<base::NullableString16>::Log(const param_type& p,
1113 std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:251114 l->append("(");
1115 LogParam(p.string(), l);
1116 l->append(", ");
1117 LogParam(p.is_null(), l);
1118 l->append(")");
1119}
1120
rockot502c94f2016-02-03 20:20:161121void ParamTraits<base::File::Info>::Write(base::Pickle* m,
[email protected]141bcc52014-01-27 21:36:001122 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251123 WriteParam(m, p.size);
1124 WriteParam(m, p.is_directory);
1125 WriteParam(m, p.last_modified.ToDoubleT());
1126 WriteParam(m, p.last_accessed.ToDoubleT());
1127 WriteParam(m, p.creation_time.ToDoubleT());
1128}
1129
rockot502c94f2016-02-03 20:20:161130bool ParamTraits<base::File::Info>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251131 base::PickleIterator* iter,
[email protected]141bcc52014-01-27 21:36:001132 param_type* p) {
[email protected]481c3e82014-07-18 01:40:471133 double last_modified, last_accessed, creation_time;
1134 if (!ReadParam(m, iter, &p->size) ||
1135 !ReadParam(m, iter, &p->is_directory) ||
1136 !ReadParam(m, iter, &last_modified) ||
1137 !ReadParam(m, iter, &last_accessed) ||
1138 !ReadParam(m, iter, &creation_time))
1139 return false;
1140 p->last_modified = base::Time::FromDoubleT(last_modified);
1141 p->last_accessed = base::Time::FromDoubleT(last_accessed);
1142 p->creation_time = base::Time::FromDoubleT(creation_time);
1143 return true;
[email protected]bf5aedf02012-06-04 21:18:251144}
1145
[email protected]141bcc52014-01-27 21:36:001146void ParamTraits<base::File::Info>::Log(const param_type& p,
1147 std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:251148 l->append("(");
1149 LogParam(p.size, l);
1150 l->append(",");
1151 LogParam(p.is_directory, l);
1152 l->append(",");
1153 LogParam(p.last_modified.ToDoubleT(), l);
1154 l->append(",");
1155 LogParam(p.last_accessed.ToDoubleT(), l);
1156 l->append(",");
1157 LogParam(p.creation_time.ToDoubleT(), l);
1158 l->append(")");
1159}
1160
rockot502c94f2016-02-03 20:20:161161void ParamTraits<base::Time>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571162 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251163}
1164
rockot502c94f2016-02-03 20:20:161165bool ParamTraits<base::Time>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251166 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251167 param_type* r) {
tfarina10a5c062015-09-04 18:47:571168 int64_t value;
1169 if (!ParamTraits<int64_t>::Read(m, iter, &value))
[email protected]bf5aedf02012-06-04 21:18:251170 return false;
1171 *r = base::Time::FromInternalValue(value);
1172 return true;
1173}
1174
1175void ParamTraits<base::Time>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571176 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251177}
1178
rockot502c94f2016-02-03 20:20:161179void ParamTraits<base::TimeDelta>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571180 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251181}
1182
rockot502c94f2016-02-03 20:20:161183bool ParamTraits<base::TimeDelta>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251184 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251185 param_type* r) {
tfarina10a5c062015-09-04 18:47:571186 int64_t value;
1187 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
[email protected]bf5aedf02012-06-04 21:18:251188 if (ret)
1189 *r = base::TimeDelta::FromInternalValue(value);
1190
1191 return ret;
1192}
1193
1194void ParamTraits<base::TimeDelta>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571195 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251196}
1197
rockot502c94f2016-02-03 20:20:161198void ParamTraits<base::TimeTicks>::Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:571199 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:251200}
1201
rockot502c94f2016-02-03 20:20:161202bool ParamTraits<base::TimeTicks>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251203 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251204 param_type* r) {
tfarina10a5c062015-09-04 18:47:571205 int64_t value;
1206 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
[email protected]bf5aedf02012-06-04 21:18:251207 if (ret)
1208 *r = base::TimeTicks::FromInternalValue(value);
1209
1210 return ret;
1211}
1212
1213void ParamTraits<base::TimeTicks>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:571214 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:251215}
1216
tguilbert4a5ac602016-09-19 21:11:251217// If base::UnguessableToken is no longer 128 bits, the IPC serialization logic
1218// below should be updated.
1219static_assert(sizeof(base::UnguessableToken) == 2 * sizeof(uint64_t),
1220 "base::UnguessableToken should be of size 2 * sizeof(uint64_t).");
1221
tguilbert4a5ac602016-09-19 21:11:251222void ParamTraits<base::UnguessableToken>::Write(base::Pickle* m,
1223 const param_type& p) {
1224 DCHECK(!p.is_empty());
1225
erikchen14525202017-05-06 19:16:511226 // This serialization must be kept in sync with
erikchen9d6afd712017-05-18 17:49:061227 // nacl_message_scanner.cc:WriteHandle().
tguilbert4a5ac602016-09-19 21:11:251228 ParamTraits<uint64_t>::Write(m, p.GetHighForSerialization());
1229 ParamTraits<uint64_t>::Write(m, p.GetLowForSerialization());
1230}
1231
1232bool ParamTraits<base::UnguessableToken>::Read(const base::Pickle* m,
1233 base::PickleIterator* iter,
1234 param_type* r) {
1235 uint64_t high, low;
1236 if (!ParamTraits<uint64_t>::Read(m, iter, &high) ||
1237 !ParamTraits<uint64_t>::Read(m, iter, &low))
1238 return false;
1239
1240 // Receiving a zeroed UnguessableToken is a security issue.
1241 if (high == 0 && low == 0)
1242 return false;
1243
1244 *r = base::UnguessableToken::Deserialize(high, low);
1245 return true;
1246}
1247
1248void ParamTraits<base::UnguessableToken>::Log(const param_type& p,
1249 std::string* l) {
1250 l->append(p.ToString());
1251}
1252
rockot502c94f2016-02-03 20:20:161253void ParamTraits<IPC::ChannelHandle>::Write(base::Pickle* m,
1254 const param_type& p) {
sammc9bf370c2016-11-14 03:29:081255#if defined(OS_NACL_SFI)
[email protected]7a4de7a62010-08-17 18:38:241256 WriteParam(m, p.socket);
sammc9bf370c2016-11-14 03:29:081257#else
amistry36182522016-06-27 06:34:421258 WriteParam(m, p.mojo_handle);
sammc9bf370c2016-11-14 03:29:081259#endif
[email protected]7a4de7a62010-08-17 18:38:241260}
1261
rockot502c94f2016-02-03 20:20:161262bool ParamTraits<IPC::ChannelHandle>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251263 base::PickleIterator* iter,
[email protected]7a4de7a62010-08-17 18:38:241264 param_type* r) {
sammc9bf370c2016-11-14 03:29:081265#if defined(OS_NACL_SFI)
1266 return ReadParam(m, iter, &r->socket);
1267#else
1268 return ReadParam(m, iter, &r->mojo_handle);
[email protected]7a4de7a62010-08-17 18:38:241269#endif
[email protected]7a4de7a62010-08-17 18:38:241270}
1271
1272void ParamTraits<IPC::ChannelHandle>::Log(const param_type& p,
[email protected]252cad62010-08-18 18:33:571273 std::string* l) {
sammc9bf370c2016-11-14 03:29:081274 l->append("ChannelHandle(");
1275#if defined(OS_NACL_SFI)
[email protected]7a4de7a62010-08-17 18:38:241276 ParamTraits<base::FileDescriptor>::Log(p.socket, l);
sammc9bf370c2016-11-14 03:29:081277#else
amistry36182522016-06-27 06:34:421278 LogParam(p.mojo_handle, l);
sammc9bf370c2016-11-14 03:29:081279#endif
[email protected]252cad62010-08-18 18:33:571280 l->append(")");
[email protected]7a4de7a62010-08-17 18:38:241281}
1282
rockot502c94f2016-02-03 20:20:161283void ParamTraits<LogData>::Write(base::Pickle* m, const param_type& p) {
[email protected]20f0487a2010-09-30 20:06:301284 WriteParam(m, p.channel);
1285 WriteParam(m, p.routing_id);
[email protected]8bf55ca2011-10-17 22:15:271286 WriteParam(m, p.type);
[email protected]20f0487a2010-09-30 20:06:301287 WriteParam(m, p.flags);
1288 WriteParam(m, p.sent);
1289 WriteParam(m, p.receive);
1290 WriteParam(m, p.dispatch);
[email protected]bae578e92012-11-15 03:17:451291 WriteParam(m, p.message_name);
[email protected]20f0487a2010-09-30 20:06:301292 WriteParam(m, p.params);
1293}
1294
rockot502c94f2016-02-03 20:20:161295bool ParamTraits<LogData>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251296 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:561297 param_type* r) {
[email protected]8bf55ca2011-10-17 22:15:271298 return
[email protected]20f0487a2010-09-30 20:06:301299 ReadParam(m, iter, &r->channel) &&
1300 ReadParam(m, iter, &r->routing_id) &&
[email protected]8bf55ca2011-10-17 22:15:271301 ReadParam(m, iter, &r->type) &&
[email protected]20f0487a2010-09-30 20:06:301302 ReadParam(m, iter, &r->flags) &&
1303 ReadParam(m, iter, &r->sent) &&
1304 ReadParam(m, iter, &r->receive) &&
1305 ReadParam(m, iter, &r->dispatch) &&
[email protected]bae578e92012-11-15 03:17:451306 ReadParam(m, iter, &r->message_name) &&
[email protected]20f0487a2010-09-30 20:06:301307 ReadParam(m, iter, &r->params);
[email protected]20f0487a2010-09-30 20:06:301308}
1309
[email protected]bf5aedf02012-06-04 21:18:251310void ParamTraits<LogData>::Log(const param_type& p, std::string* l) {
1311 // Doesn't make sense to implement this!
1312}
1313
rockot502c94f2016-02-03 20:20:161314void ParamTraits<Message>::Write(base::Pickle* m, const Message& p) {
[email protected]34d48612012-06-29 00:05:041315#if defined(OS_POSIX)
1316 // We don't serialize the file descriptors in the nested message, so there
1317 // better not be any.
morrita1aa788c2015-01-31 05:45:421318 DCHECK(!p.HasAttachments());
[email protected]34d48612012-06-29 00:05:041319#endif
1320
1321 // Don't just write out the message. This is used to send messages between
1322 // NaCl (Posix environment) and the browser (could be on Windows). The message
1323 // header formats differ between these systems (so does handle sharing, but
1324 // we already asserted we don't have any handles). So just write out the
1325 // parts of the header we use.
1326 //
1327 // Be careful also to use only explicitly-sized types. The NaCl environment
1328 // could be 64-bit and the host browser could be 32-bits. The nested message
1329 // may or may not be safe to send between 32-bit and 64-bit systems, but we
1330 // leave that up to the code sending the message to ensure.
tfarina10a5c062015-09-04 18:47:571331 m->WriteUInt32(static_cast<uint32_t>(p.routing_id()));
[email protected]34d48612012-06-29 00:05:041332 m->WriteUInt32(p.type());
1333 m->WriteUInt32(p.flags());
tfarina10a5c062015-09-04 18:47:571334 m->WriteData(p.payload(), static_cast<uint32_t>(p.payload_size()));
[email protected]bf5aedf02012-06-04 21:18:251335}
1336
rockot502c94f2016-02-03 20:20:161337bool ParamTraits<Message>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251338 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251339 Message* r) {
tfarina10a5c062015-09-04 18:47:571340 uint32_t routing_id, type, flags;
avi48fc13b2014-12-28 23:31:481341 if (!iter->ReadUInt32(&routing_id) ||
1342 !iter->ReadUInt32(&type) ||
1343 !iter->ReadUInt32(&flags))
[email protected]bf5aedf02012-06-04 21:18:251344 return false;
[email protected]34d48612012-06-29 00:05:041345
1346 int payload_size;
1347 const char* payload;
avi48fc13b2014-12-28 23:31:481348 if (!iter->ReadData(&payload, &payload_size))
[email protected]bf5aedf02012-06-04 21:18:251349 return false;
[email protected]34d48612012-06-29 00:05:041350
tfarina10a5c062015-09-04 18:47:571351 r->SetHeaderValues(static_cast<int32_t>(routing_id), type, flags);
Daniel Cheng0d89f9222017-09-22 05:05:071352 r->WriteBytes(payload, payload_size);
1353 return true;
[email protected]bf5aedf02012-06-04 21:18:251354}
1355
1356void ParamTraits<Message>::Log(const Message& p, std::string* l) {
1357 l->append("<IPC::Message>");
1358}
1359
1360#if defined(OS_WIN)
1361// Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
[email protected]4a635b72013-03-04 02:29:031362// bit systems. That's why we use the Windows macros to convert to 32 bits.
rockot502c94f2016-02-03 20:20:161363void ParamTraits<HANDLE>::Write(base::Pickle* m, const param_type& p) {
[email protected]4a635b72013-03-04 02:29:031364 m->WriteInt(HandleToLong(p));
[email protected]bf5aedf02012-06-04 21:18:251365}
1366
rockot502c94f2016-02-03 20:20:161367bool ParamTraits<HANDLE>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251368 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251369 param_type* r) {
tfarina10a5c062015-09-04 18:47:571370 int32_t temp;
avi48fc13b2014-12-28 23:31:481371 if (!iter->ReadInt(&temp))
[email protected]bf5aedf02012-06-04 21:18:251372 return false;
[email protected]4a635b72013-03-04 02:29:031373 *r = LongToHandle(temp);
[email protected]bf5aedf02012-06-04 21:18:251374 return true;
1375}
1376
1377void ParamTraits<HANDLE>::Log(const param_type& p, std::string* l) {
brucedawson5604a11d2015-10-06 19:22:001378 l->append(base::StringPrintf("0x%p", p));
[email protected]bf5aedf02012-06-04 21:18:251379}
1380
rockot502c94f2016-02-03 20:20:161381void ParamTraits<LOGFONT>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251382 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
1383}
1384
rockot502c94f2016-02-03 20:20:161385bool ParamTraits<LOGFONT>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251386 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251387 param_type* r) {
1388 const char *data;
1389 int data_size = 0;
avi48fc13b2014-12-28 23:31:481390 if (iter->ReadData(&data, &data_size) && data_size == sizeof(LOGFONT)) {
[email protected]2e02cfe82012-11-21 00:58:001391 const LOGFONT *font = reinterpret_cast<LOGFONT*>(const_cast<char*>(data));
1392 if (_tcsnlen(font->lfFaceName, LF_FACESIZE) < LF_FACESIZE) {
1393 memcpy(r, data, sizeof(LOGFONT));
1394 return true;
1395 }
[email protected]bf5aedf02012-06-04 21:18:251396 }
1397
[email protected]2e02cfe82012-11-21 00:58:001398 NOTREACHED();
1399 return false;
[email protected]bf5aedf02012-06-04 21:18:251400}
1401
1402void ParamTraits<LOGFONT>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:041403 l->append(base::StringPrintf("<LOGFONT>"));
[email protected]bf5aedf02012-06-04 21:18:251404}
1405
rockot502c94f2016-02-03 20:20:161406void ParamTraits<MSG>::Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:251407 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
1408}
1409
rockot502c94f2016-02-03 20:20:161410bool ParamTraits<MSG>::Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251411 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251412 param_type* r) {
1413 const char *data;
1414 int data_size = 0;
avi48fc13b2014-12-28 23:31:481415 bool result = iter->ReadData(&data, &data_size);
[email protected]bf5aedf02012-06-04 21:18:251416 if (result && data_size == sizeof(MSG)) {
1417 memcpy(r, data, sizeof(MSG));
1418 } else {
1419 result = false;
1420 NOTREACHED();
1421 }
1422
1423 return result;
1424}
1425
1426void ParamTraits<MSG>::Log(const param_type& p, std::string* l) {
1427 l->append("<MSG>");
1428}
1429
1430#endif // OS_WIN
1431
[email protected]946d1b22009-07-22 23:57:211432} // namespace IPC