blob: 0060f867277aa207fb106a937d292acab0723155 [file] [log] [blame]
amit@chromium.org37290742012-01-24 11:36:05 +09001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
agl@chromium.org1c6dcf22009-07-23 08:57:21 +09002// 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
avi42ebda42015-12-22 11:39:04 +09007#include <stddef.h>
8#include <stdint.h>
9
brettw@chromium.org59eef1f2013-02-24 14:40:52 +090010#include "base/files/file_path.h"
brettw@chromium.org7cd41eb2009-10-24 05:00:20 +090011#include "base/json/json_writer.h"
avi@chromium.orgd8179652013-06-13 22:47:46 +090012#include "base/strings/nullable_string16.h"
avi@chromium.orge7eaf392013-06-11 15:32:18 +090013#include "base/strings/string_number_conversions.h"
avi@chromium.org64535542013-06-08 07:40:45 +090014#include "base/strings/utf_string_conversions.h"
avi@chromium.org78a7e7b2013-06-29 00:20:02 +090015#include "base/time/time.h"
tguilbert76e690d2016-09-20 06:11:25 +090016#include "base/unguessable_token.h"
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090017#include "base/values.h"
avi42ebda42015-12-22 11:39:04 +090018#include "build/build_config.h"
brettw@chromium.orgce352e52012-06-05 06:18:25 +090019#include "ipc/ipc_channel_handle.h"
morrita7d1bfcc2015-01-31 14:45:42 +090020#include "ipc/ipc_message_attachment.h"
morrita33a35902015-01-15 06:17:06 +090021#include "ipc/ipc_message_attachment_set.h"
amistry70d63572016-06-27 15:34:42 +090022#include "ipc/ipc_mojo_param_traits.h"
brettw@chromium.orgce352e52012-06-05 06:18:25 +090023
morrita7d1bfcc2015-01-31 14:45:42 +090024#if defined(OS_POSIX)
25#include "ipc/ipc_platform_file_attachment_posix.h"
26#endif
27
erikchen18430e52015-09-26 07:34:31 +090028#if (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
scottmg81491272015-06-20 07:51:00 +090029#include "base/memory/shared_memory_handle.h"
erikchen18430e52015-09-26 07:34:31 +090030#endif // (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
scottmg81491272015-06-20 07:51:00 +090031
erikchenae16e0c2015-10-10 04:12:06 +090032#if defined(OS_MACOSX) && !defined(OS_IOS)
33#include "ipc/mach_port_mac.h"
34#endif
35
morrita33a35902015-01-15 06:17:06 +090036#if defined(OS_WIN)
jschuh@chromium.orgb9ee7d62012-11-21 09:58:00 +090037#include <tchar.h>
erikchen18430e52015-09-26 07:34:31 +090038#include "ipc/handle_win.h"
erg@google.come6ffcb52010-08-18 03:38:24 +090039#endif
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090040
41namespace IPC {
42
brettw@chromium.orgce352e52012-06-05 06:18:25 +090043namespace {
44
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090045const int kMaxRecursionDepth = 100;
46
brettw@chromium.orgce352e52012-06-05 06:18:25 +090047template<typename CharType>
48void LogBytes(const std::vector<CharType>& data, std::string* out) {
49#if defined(OS_WIN)
50 // Windows has a GUI for logging, which can handle arbitrary binary data.
51 for (size_t i = 0; i < data.size(); ++i)
52 out->push_back(data[i]);
53#else
54 // On POSIX, we log to stdout, which we assume can display ASCII.
55 static const size_t kMaxBytesToLog = 100;
56 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
57 if (isprint(data[i]))
58 out->push_back(data[i]);
59 else
groby@chromium.org6b4dc5e2013-03-19 07:33:04 +090060 out->append(
61 base::StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
brettw@chromium.orgce352e52012-06-05 06:18:25 +090062 }
63 if (data.size() > kMaxBytesToLog) {
groby@chromium.org22e93982013-03-31 02:29:28 +090064 out->append(base::StringPrintf(
65 " and %u more bytes",
66 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
brettw@chromium.orgce352e52012-06-05 06:18:25 +090067 }
68#endif
69}
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090070
rockot6dbfea52016-02-04 05:20:16 +090071bool ReadValue(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +090072 base::PickleIterator* iter,
73 base::Value** value,
brettw@chromium.orgce352e52012-06-05 06:18:25 +090074 int recursion);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090075
rockot15c8ac42016-02-05 11:12:32 +090076void GetValueSize(base::PickleSizer* sizer,
77 const base::Value* value,
78 int recursion) {
79 if (recursion > kMaxRecursionDepth) {
80 LOG(WARNING) << "Max recursion depth hit in GetValueSize.";
81 return;
82 }
83
84 sizer->AddInt();
85 switch (value->GetType()) {
86 case base::Value::TYPE_NULL:
87 break;
88 case base::Value::TYPE_BOOLEAN:
89 sizer->AddBool();
90 break;
91 case base::Value::TYPE_INTEGER:
92 sizer->AddInt();
93 break;
94 case base::Value::TYPE_DOUBLE:
95 sizer->AddDouble();
96 break;
97 case base::Value::TYPE_STRING: {
98 const base::StringValue* result;
99 value->GetAsString(&result);
amistry0bab7322016-04-08 13:21:54 +0900100 if (value->GetAsString(&result)) {
101 DCHECK(result);
102 GetParamSize(sizer, result->GetString());
103 } else {
104 std::string str;
105 bool as_string_result = value->GetAsString(&str);
106 DCHECK(as_string_result);
107 GetParamSize(sizer, str);
108 }
rockot15c8ac42016-02-05 11:12:32 +0900109 break;
110 }
111 case base::Value::TYPE_BINARY: {
112 const base::BinaryValue* binary =
113 static_cast<const base::BinaryValue*>(value);
114 sizer->AddData(static_cast<int>(binary->GetSize()));
115 break;
116 }
117 case base::Value::TYPE_DICTIONARY: {
118 sizer->AddInt();
119 const base::DictionaryValue* dict =
120 static_cast<const base::DictionaryValue*>(value);
121 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd();
122 it.Advance()) {
123 GetParamSize(sizer, it.key());
124 GetValueSize(sizer, &it.value(), recursion + 1);
125 }
126 break;
127 }
128 case base::Value::TYPE_LIST: {
129 sizer->AddInt();
130 const base::ListValue* list = static_cast<const base::ListValue*>(value);
dcheng1fa44fb2016-05-26 03:30:47 +0900131 for (const auto& entry : *list) {
132 GetValueSize(sizer, entry.get(), recursion + 1);
rockot15c8ac42016-02-05 11:12:32 +0900133 }
134 break;
135 }
136 default:
137 NOTREACHED() << "Invalid base::Value type.";
138 }
139}
140
rockot6dbfea52016-02-04 05:20:16 +0900141void WriteValue(base::Pickle* m, const base::Value* value, int recursion) {
orenb@chromium.org88de3872012-07-26 10:29:21 +0900142 bool result;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900143 if (recursion > kMaxRecursionDepth) {
144 LOG(WARNING) << "Max recursion depth hit in WriteValue.";
145 return;
146 }
147
148 m->WriteInt(value->GetType());
149
150 switch (value->GetType()) {
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900151 case base::Value::TYPE_NULL:
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900152 break;
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900153 case base::Value::TYPE_BOOLEAN: {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900154 bool val;
orenb@chromium.org88de3872012-07-26 10:29:21 +0900155 result = value->GetAsBoolean(&val);
156 DCHECK(result);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900157 WriteParam(m, val);
158 break;
159 }
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900160 case base::Value::TYPE_INTEGER: {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900161 int val;
orenb@chromium.org88de3872012-07-26 10:29:21 +0900162 result = value->GetAsInteger(&val);
163 DCHECK(result);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900164 WriteParam(m, val);
165 break;
166 }
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900167 case base::Value::TYPE_DOUBLE: {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900168 double val;
orenb@chromium.org88de3872012-07-26 10:29:21 +0900169 result = value->GetAsDouble(&val);
170 DCHECK(result);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900171 WriteParam(m, val);
172 break;
173 }
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900174 case base::Value::TYPE_STRING: {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900175 std::string val;
orenb@chromium.org88de3872012-07-26 10:29:21 +0900176 result = value->GetAsString(&val);
177 DCHECK(result);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900178 WriteParam(m, val);
179 break;
180 }
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900181 case base::Value::TYPE_BINARY: {
tfarina@chromium.org2e2a9022011-08-06 03:20:05 +0900182 const base::BinaryValue* binary =
183 static_cast<const base::BinaryValue*>(value);
thomasvl@google.com9a242072010-07-23 23:18:59 +0900184 m->WriteData(binary->GetBuffer(), static_cast<int>(binary->GetSize()));
mpcomplete@chromium.org554d4312009-10-07 03:15:58 +0900185 break;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900186 }
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900187 case base::Value::TYPE_DICTIONARY: {
188 const base::DictionaryValue* dict =
189 static_cast<const base::DictionaryValue*>(value);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900190
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900191 WriteParam(m, static_cast<int>(dict->size()));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900192
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900193 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd();
194 it.Advance()) {
pneubeck@chromium.orga2fbefc2013-01-18 23:43:27 +0900195 WriteParam(m, it.key());
196 WriteValue(m, &it.value(), recursion + 1);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900197 }
198 break;
199 }
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900200 case base::Value::TYPE_LIST: {
201 const base::ListValue* list = static_cast<const base::ListValue*>(value);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900202 WriteParam(m, static_cast<int>(list->GetSize()));
dcheng1fa44fb2016-05-26 03:30:47 +0900203 for (const auto& entry : *list) {
204 WriteValue(m, entry.get(), recursion + 1);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900205 }
206 break;
207 }
208 }
209}
210
211// Helper for ReadValue that reads a DictionaryValue into a pre-allocated
212// object.
rockot6dbfea52016-02-04 05:20:16 +0900213bool ReadDictionaryValue(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900214 base::PickleIterator* iter,
215 base::DictionaryValue* value,
216 int recursion) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900217 int size;
218 if (!ReadParam(m, iter, &size))
219 return false;
220
221 for (int i = 0; i < size; ++i) {
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900222 std::string key;
brettw@chromium.org32285192013-06-22 04:42:19 +0900223 base::Value* subval;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900224 if (!ReadParam(m, iter, &key) ||
225 !ReadValue(m, iter, &subval, recursion + 1))
226 return false;
kalman@chromium.org9c8b5732011-08-19 14:59:57 +0900227 value->SetWithoutPathExpansion(key, subval);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900228 }
229
230 return true;
231}
232
233// Helper for ReadValue that reads a ReadListValue into a pre-allocated
234// object.
rockot6dbfea52016-02-04 05:20:16 +0900235bool ReadListValue(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900236 base::PickleIterator* iter,
237 base::ListValue* value,
238 int recursion) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900239 int size;
240 if (!ReadParam(m, iter, &size))
241 return false;
242
243 for (int i = 0; i < size; ++i) {
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900244 base::Value* subval;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900245 if (!ReadValue(m, iter, &subval, recursion + 1))
246 return false;
247 value->Set(i, subval);
248 }
249
250 return true;
251}
252
rockot6dbfea52016-02-04 05:20:16 +0900253bool ReadValue(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900254 base::PickleIterator* iter,
255 base::Value** value,
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900256 int recursion) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900257 if (recursion > kMaxRecursionDepth) {
258 LOG(WARNING) << "Max recursion depth hit in ReadValue.";
259 return false;
260 }
261
262 int type;
263 if (!ReadParam(m, iter, &type))
264 return false;
265
266 switch (type) {
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900267 case base::Value::TYPE_NULL:
estade033e61e2015-05-13 03:11:50 +0900268 *value = base::Value::CreateNullValue().release();
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900269 break;
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900270 case base::Value::TYPE_BOOLEAN: {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900271 bool val;
272 if (!ReadParam(m, iter, &val))
273 return false;
tfarina@chromium.org4ef57d92013-01-30 14:24:07 +0900274 *value = new base::FundamentalValue(val);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900275 break;
276 }
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900277 case base::Value::TYPE_INTEGER: {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900278 int val;
279 if (!ReadParam(m, iter, &val))
280 return false;
tfarina@chromium.org4ef57d92013-01-30 14:24:07 +0900281 *value = new base::FundamentalValue(val);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900282 break;
283 }
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900284 case base::Value::TYPE_DOUBLE: {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900285 double val;
286 if (!ReadParam(m, iter, &val))
287 return false;
tfarina@chromium.org4ef57d92013-01-30 14:24:07 +0900288 *value = new base::FundamentalValue(val);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900289 break;
290 }
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900291 case base::Value::TYPE_STRING: {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900292 std::string val;
293 if (!ReadParam(m, iter, &val))
294 return false;
tfarina@chromium.org4ef57d92013-01-30 14:24:07 +0900295 *value = new base::StringValue(val);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900296 break;
297 }
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900298 case base::Value::TYPE_BINARY: {
mpcomplete@chromium.org554d4312009-10-07 03:15:58 +0900299 const char* data;
300 int length;
avic9f0ad02014-12-29 08:31:48 +0900301 if (!iter->ReadData(&data, &length))
mpcomplete@chromium.org554d4312009-10-07 03:15:58 +0900302 return false;
dcheng03c8f322016-06-16 19:48:42 +0900303 std::unique_ptr<base::BinaryValue> val =
304 base::BinaryValue::CreateWithCopiedBuffer(data, length);
305 *value = val.release();
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900306 break;
307 }
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900308 case base::Value::TYPE_DICTIONARY: {
danakjc3fb6c52016-04-23 13:21:09 +0900309 std::unique_ptr<base::DictionaryValue> val(new base::DictionaryValue());
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900310 if (!ReadDictionaryValue(m, iter, val.get(), recursion))
311 return false;
312 *value = val.release();
313 break;
314 }
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900315 case base::Value::TYPE_LIST: {
danakjc3fb6c52016-04-23 13:21:09 +0900316 std::unique_ptr<base::ListValue> val(new base::ListValue());
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900317 if (!ReadListValue(m, iter, val.get(), recursion))
318 return false;
319 *value = val.release();
320 break;
321 }
mpcomplete@chromium.org554d4312009-10-07 03:15:58 +0900322 default:
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900323 return false;
324 }
325
326 return true;
327}
328
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900329} // namespace
330
331// -----------------------------------------------------------------------------
332
333LogData::LogData()
334 : routing_id(0),
335 type(0),
336 sent(0),
337 receive(0),
338 dispatch(0) {
339}
340
vmpstrd661bf72016-03-25 05:22:54 +0900341LogData::LogData(const LogData& other) = default;
342
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900343LogData::~LogData() {
344}
345
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900346void ParamTraits<bool>::Log(const param_type& p, std::string* l) {
347 l->append(p ? "true" : "false");
348}
349
rockot15c8ac42016-02-05 11:12:32 +0900350void ParamTraits<signed char>::GetSize(base::PickleSizer* sizer,
351 const param_type& p) {
352 sizer->AddBytes(sizeof(param_type));
353}
354
rockot6dbfea52016-02-04 05:20:16 +0900355void ParamTraits<signed char>::Write(base::Pickle* m, const param_type& p) {
ortuno6e3f7b32015-10-30 09:46:20 +0900356 m->WriteBytes(&p, sizeof(param_type));
357}
358
rockot6dbfea52016-02-04 05:20:16 +0900359bool ParamTraits<signed char>::Read(const base::Pickle* m,
360 base::PickleIterator* iter,
361 param_type* r) {
ortuno6e3f7b32015-10-30 09:46:20 +0900362 const char* data;
363 if (!iter->ReadBytes(&data, sizeof(param_type)))
364 return false;
365 memcpy(r, data, sizeof(param_type));
366 return true;
367}
368
369void ParamTraits<signed char>::Log(const param_type& p, std::string* l) {
370 l->append(base::IntToString(p));
371}
372
rockot15c8ac42016-02-05 11:12:32 +0900373void ParamTraits<unsigned char>::GetSize(base::PickleSizer* sizer,
374 const param_type& p) {
375 sizer->AddBytes(sizeof(param_type));
376}
377
rockot6dbfea52016-02-04 05:20:16 +0900378void ParamTraits<unsigned char>::Write(base::Pickle* m, const param_type& p) {
tsepez@chromium.org09eb95f2013-07-13 08:12:28 +0900379 m->WriteBytes(&p, sizeof(param_type));
380}
381
rockot6dbfea52016-02-04 05:20:16 +0900382bool ParamTraits<unsigned char>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900383 base::PickleIterator* iter,
384 param_type* r) {
tsepez@chromium.org09eb95f2013-07-13 08:12:28 +0900385 const char* data;
avic9f0ad02014-12-29 08:31:48 +0900386 if (!iter->ReadBytes(&data, sizeof(param_type)))
tsepez@chromium.org09eb95f2013-07-13 08:12:28 +0900387 return false;
388 memcpy(r, data, sizeof(param_type));
389 return true;
390}
391
392void ParamTraits<unsigned char>::Log(const param_type& p, std::string* l) {
393 l->append(base::UintToString(p));
394}
395
rockot15c8ac42016-02-05 11:12:32 +0900396void ParamTraits<unsigned short>::GetSize(base::PickleSizer* sizer,
397 const param_type& p) {
398 sizer->AddBytes(sizeof(param_type));
399}
400
rockot6dbfea52016-02-04 05:20:16 +0900401void ParamTraits<unsigned short>::Write(base::Pickle* m, const param_type& p) {
tsepez@chromium.org09eb95f2013-07-13 08:12:28 +0900402 m->WriteBytes(&p, sizeof(param_type));
403}
404
rockot6dbfea52016-02-04 05:20:16 +0900405bool ParamTraits<unsigned short>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900406 base::PickleIterator* iter,
tsepez@chromium.org09eb95f2013-07-13 08:12:28 +0900407 param_type* r) {
408 const char* data;
avic9f0ad02014-12-29 08:31:48 +0900409 if (!iter->ReadBytes(&data, sizeof(param_type)))
tsepez@chromium.org09eb95f2013-07-13 08:12:28 +0900410 return false;
411 memcpy(r, data, sizeof(param_type));
412 return true;
413}
414
415void ParamTraits<unsigned short>::Log(const param_type& p, std::string* l) {
416 l->append(base::UintToString(p));
417}
418
erg@google.com8aca7272010-08-19 03:33:57 +0900419void ParamTraits<int>::Log(const param_type& p, std::string* l) {
420 l->append(base::IntToString(p));
421}
422
423void ParamTraits<unsigned int>::Log(const param_type& p, std::string* l) {
424 l->append(base::UintToString(p));
425}
426
jam739d8d12016-02-11 09:50:28 +0900427#if defined(OS_WIN) || defined(OS_LINUX) || \
428 (defined(OS_ANDROID) && defined(ARCH_CPU_64_BITS))
erg@google.com8aca7272010-08-19 03:33:57 +0900429void ParamTraits<long>::Log(const param_type& p, std::string* l) {
tfarina1cbfa082015-09-05 03:47:57 +0900430 l->append(base::Int64ToString(static_cast<int64_t>(p)));
erg@google.com8aca7272010-08-19 03:33:57 +0900431}
432
433void ParamTraits<unsigned long>::Log(const param_type& p, std::string* l) {
tfarina1cbfa082015-09-05 03:47:57 +0900434 l->append(base::Uint64ToString(static_cast<uint64_t>(p)));
erg@google.com8aca7272010-08-19 03:33:57 +0900435}
jam923e5462016-02-11 05:13:39 +0900436#endif
erg@google.com8aca7272010-08-19 03:33:57 +0900437
438void ParamTraits<long long>::Log(const param_type& p, std::string* l) {
tfarina1cbfa082015-09-05 03:47:57 +0900439 l->append(base::Int64ToString(static_cast<int64_t>(p)));
erg@google.com8aca7272010-08-19 03:33:57 +0900440}
441
442void ParamTraits<unsigned long long>::Log(const param_type& p, std::string* l) {
443 l->append(base::Uint64ToString(p));
444}
erg@google.come6ffcb52010-08-18 03:38:24 +0900445
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900446void ParamTraits<float>::Log(const param_type& p, std::string* l) {
groby@chromium.org6b4dc5e2013-03-19 07:33:04 +0900447 l->append(base::StringPrintf("%e", p));
erg@google.come6ffcb52010-08-18 03:38:24 +0900448}
449
rockot15c8ac42016-02-05 11:12:32 +0900450void ParamTraits<double>::GetSize(base::PickleSizer* sizer,
451 const param_type& p) {
452 sizer->AddBytes(sizeof(param_type));
453}
454
rockot6dbfea52016-02-04 05:20:16 +0900455void ParamTraits<double>::Write(base::Pickle* m, const param_type& p) {
piman@chromium.orgdd413b42013-10-31 18:27:31 +0900456 m->WriteBytes(reinterpret_cast<const char*>(&p), sizeof(param_type));
apatrick@chromium.org519c1c62010-10-22 07:04:52 +0900457}
458
rockot6dbfea52016-02-04 05:20:16 +0900459bool ParamTraits<double>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900460 base::PickleIterator* iter,
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900461 param_type* r) {
462 const char *data;
avic9f0ad02014-12-29 08:31:48 +0900463 if (!iter->ReadBytes(&data, sizeof(*r))) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900464 NOTREACHED();
465 return false;
466 }
467 memcpy(r, data, sizeof(param_type));
468 return true;
apatrick@chromium.org519c1c62010-10-22 07:04:52 +0900469}
470
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900471void ParamTraits<double>::Log(const param_type& p, std::string* l) {
groby@chromium.org6b4dc5e2013-03-19 07:33:04 +0900472 l->append(base::StringPrintf("%e", p));
isherman@chromium.org9952aaf2011-09-03 05:42:04 +0900473}
474
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900475
476void ParamTraits<std::string>::Log(const param_type& p, std::string* l) {
477 l->append(p);
isherman@chromium.org9952aaf2011-09-03 05:42:04 +0900478}
479
brettw@chromium.org5b040852013-12-03 09:39:26 +0900480void ParamTraits<base::string16>::Log(const param_type& p, std::string* l) {
avi@chromium.org4f87d8f2013-12-26 03:18:01 +0900481 l->append(base::UTF16ToUTF8(p));
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900482}
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900483
rockot15c8ac42016-02-05 11:12:32 +0900484void ParamTraits<std::vector<char>>::GetSize(base::PickleSizer* sizer,
485 const param_type& p) {
486 sizer->AddData(static_cast<int>(p.size()));
487}
488
rockot6dbfea52016-02-04 05:20:16 +0900489void ParamTraits<std::vector<char>>::Write(base::Pickle* m,
490 const param_type& p) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900491 if (p.empty()) {
492 m->WriteData(NULL, 0);
493 } else {
494 m->WriteData(&p.front(), static_cast<int>(p.size()));
495 }
496}
497
rockot6dbfea52016-02-04 05:20:16 +0900498bool ParamTraits<std::vector<char>>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900499 base::PickleIterator* iter,
500 param_type* r) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900501 const char *data;
502 int data_size = 0;
avic9f0ad02014-12-29 08:31:48 +0900503 if (!iter->ReadData(&data, &data_size) || data_size < 0)
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900504 return false;
505 r->resize(data_size);
506 if (data_size)
507 memcpy(&r->front(), data, data_size);
508 return true;
509}
510
511void ParamTraits<std::vector<char> >::Log(const param_type& p, std::string* l) {
512 LogBytes(p, l);
513}
514
rockot15c8ac42016-02-05 11:12:32 +0900515void ParamTraits<std::vector<unsigned char>>::GetSize(base::PickleSizer* sizer,
516 const param_type& p) {
517 sizer->AddData(static_cast<int>(p.size()));
518}
519
rockot6dbfea52016-02-04 05:20:16 +0900520void ParamTraits<std::vector<unsigned char>>::Write(base::Pickle* m,
521 const param_type& p) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900522 if (p.empty()) {
523 m->WriteData(NULL, 0);
524 } else {
525 m->WriteData(reinterpret_cast<const char*>(&p.front()),
526 static_cast<int>(p.size()));
527 }
528}
529
rockot6dbfea52016-02-04 05:20:16 +0900530bool ParamTraits<std::vector<unsigned char>>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900531 base::PickleIterator* iter,
532 param_type* r) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900533 const char *data;
534 int data_size = 0;
avic9f0ad02014-12-29 08:31:48 +0900535 if (!iter->ReadData(&data, &data_size) || data_size < 0)
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900536 return false;
537 r->resize(data_size);
538 if (data_size)
539 memcpy(&r->front(), data, data_size);
540 return true;
541}
542
543void ParamTraits<std::vector<unsigned char> >::Log(const param_type& p,
544 std::string* l) {
545 LogBytes(p, l);
546}
547
rockot15c8ac42016-02-05 11:12:32 +0900548void ParamTraits<std::vector<bool>>::GetSize(base::PickleSizer* sizer,
549 const param_type& p) {
550 GetParamSize(sizer, static_cast<int>(p.size()));
551 for (size_t i = 0; i < p.size(); ++i)
552 GetParamSize(sizer, static_cast<bool>(p[i]));
553}
554
rockot6dbfea52016-02-04 05:20:16 +0900555void ParamTraits<std::vector<bool>>::Write(base::Pickle* m,
556 const param_type& p) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900557 WriteParam(m, static_cast<int>(p.size()));
eugenis@chromium.org17085812013-03-21 05:25:00 +0900558 // Cast to bool below is required because libc++'s
559 // vector<bool>::const_reference is different from bool, and we want to avoid
560 // writing an extra specialization of ParamTraits for it.
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900561 for (size_t i = 0; i < p.size(); i++)
eugenis@chromium.org17085812013-03-21 05:25:00 +0900562 WriteParam(m, static_cast<bool>(p[i]));
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900563}
564
rockot6dbfea52016-02-04 05:20:16 +0900565bool ParamTraits<std::vector<bool>>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900566 base::PickleIterator* iter,
567 param_type* r) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900568 int size;
569 // ReadLength() checks for < 0 itself.
avic9f0ad02014-12-29 08:31:48 +0900570 if (!iter->ReadLength(&size))
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900571 return false;
572 r->resize(size);
573 for (int i = 0; i < size; i++) {
574 bool value;
575 if (!ReadParam(m, iter, &value))
576 return false;
577 (*r)[i] = value;
578 }
579 return true;
580}
581
582void ParamTraits<std::vector<bool> >::Log(const param_type& p, std::string* l) {
583 for (size_t i = 0; i < p.size(); ++i) {
584 if (i != 0)
585 l->push_back(' ');
eugenis@chromium.org17085812013-03-21 05:25:00 +0900586 LogParam(static_cast<bool>(p[i]), l);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900587 }
apatrick@chromium.org519c1c62010-10-22 07:04:52 +0900588}
589
erikchenfdd43fe2015-07-08 07:13:11 +0900590void ParamTraits<BrokerableAttachment::AttachmentId>::Write(
rockot6dbfea52016-02-04 05:20:16 +0900591 base::Pickle* m,
erikchenfdd43fe2015-07-08 07:13:11 +0900592 const param_type& p) {
erikchenc5778442015-08-28 04:49:58 +0900593 m->WriteBytes(p.nonce, BrokerableAttachment::kNonceSize);
erikchenfdd43fe2015-07-08 07:13:11 +0900594}
595
596bool ParamTraits<BrokerableAttachment::AttachmentId>::Read(
rockot6dbfea52016-02-04 05:20:16 +0900597 const base::Pickle* m,
erikchenfdd43fe2015-07-08 07:13:11 +0900598 base::PickleIterator* iter,
599 param_type* r) {
600 const char* data;
erikchenc5778442015-08-28 04:49:58 +0900601 if (!iter->ReadBytes(&data, BrokerableAttachment::kNonceSize))
erikchenfdd43fe2015-07-08 07:13:11 +0900602 return false;
603 memcpy(r->nonce, data, BrokerableAttachment::kNonceSize);
604 return true;
605}
606
607void ParamTraits<BrokerableAttachment::AttachmentId>::Log(const param_type& p,
608 std::string* l) {
609 l->append(base::HexEncode(p.nonce, BrokerableAttachment::kNonceSize));
610}
611
rockot15c8ac42016-02-05 11:12:32 +0900612void ParamTraits<base::DictionaryValue>::GetSize(base::PickleSizer* sizer,
613 const param_type& p) {
614 GetValueSize(sizer, &p, 0);
615}
616
rockot6dbfea52016-02-04 05:20:16 +0900617void ParamTraits<base::DictionaryValue>::Write(base::Pickle* m,
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900618 const param_type& p) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900619 WriteValue(m, &p, 0);
620}
621
rockot6dbfea52016-02-04 05:20:16 +0900622bool ParamTraits<base::DictionaryValue>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900623 base::PickleIterator* iter,
624 param_type* r) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900625 int type;
brettw@chromium.org32285192013-06-22 04:42:19 +0900626 if (!ReadParam(m, iter, &type) || type != base::Value::TYPE_DICTIONARY)
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900627 return false;
628
629 return ReadDictionaryValue(m, iter, r, 0);
630}
631
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900632void ParamTraits<base::DictionaryValue>::Log(const param_type& p,
633 std::string* l) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900634 std::string json;
estadeb5f30dd2015-05-16 10:02:34 +0900635 base::JSONWriter::Write(p, &json);
erg@google.com8aca7272010-08-19 03:33:57 +0900636 l->append(json);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900637}
638
erg@google.come6ffcb52010-08-18 03:38:24 +0900639#if defined(OS_POSIX)
jam7f5c5742016-05-12 06:05:05 +0900640void ParamTraits<base::FileDescriptor>::GetSize(base::PickleSizer* sizer,
641 const param_type& p) {
642 GetParamSize(sizer, p.fd >= 0);
amistry70d63572016-06-27 15:34:42 +0900643 if (p.fd >= 0)
644 sizer->AddAttachment();
jam7f5c5742016-05-12 06:05:05 +0900645}
646
rockot6dbfea52016-02-04 05:20:16 +0900647void ParamTraits<base::FileDescriptor>::Write(base::Pickle* m,
648 const param_type& p) {
erg@google.come6ffcb52010-08-18 03:38:24 +0900649 const bool valid = p.fd >= 0;
650 WriteParam(m, valid);
651
morritaab207252014-09-25 05:11:45 +0900652 if (!valid)
653 return;
654
655 if (p.auto_close) {
morrita7d1bfcc2015-01-31 14:45:42 +0900656 if (!m->WriteAttachment(
657 new internal::PlatformFileAttachment(base::ScopedFD(p.fd))))
morritaab207252014-09-25 05:11:45 +0900658 NOTREACHED();
659 } else {
morrita7d1bfcc2015-01-31 14:45:42 +0900660 if (!m->WriteAttachment(new internal::PlatformFileAttachment(p.fd)))
erg@google.come6ffcb52010-08-18 03:38:24 +0900661 NOTREACHED();
662 }
663}
664
rockot6dbfea52016-02-04 05:20:16 +0900665bool ParamTraits<base::FileDescriptor>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900666 base::PickleIterator* iter,
erg@google.come6ffcb52010-08-18 03:38:24 +0900667 param_type* r) {
morritaab207252014-09-25 05:11:45 +0900668 *r = base::FileDescriptor();
669
erg@google.come6ffcb52010-08-18 03:38:24 +0900670 bool valid;
671 if (!ReadParam(m, iter, &valid))
672 return false;
673
morritaab207252014-09-25 05:11:45 +0900674 // TODO(morrita): Seems like this should return false.
675 if (!valid)
erg@google.come6ffcb52010-08-18 03:38:24 +0900676 return true;
erg@google.come6ffcb52010-08-18 03:38:24 +0900677
rockot6dbfea52016-02-04 05:20:16 +0900678 scoped_refptr<base::Pickle::Attachment> attachment;
morrita7d1bfcc2015-01-31 14:45:42 +0900679 if (!m->ReadAttachment(iter, &attachment))
morritaab207252014-09-25 05:11:45 +0900680 return false;
681
rockot6dbfea52016-02-04 05:20:16 +0900682 *r = base::FileDescriptor(
683 static_cast<MessageAttachment*>(attachment.get())->TakePlatformFile(),
684 true);
morritaab207252014-09-25 05:11:45 +0900685 return true;
erg@google.come6ffcb52010-08-18 03:38:24 +0900686}
687
688void ParamTraits<base::FileDescriptor>::Log(const param_type& p,
erg@google.com8aca7272010-08-19 03:33:57 +0900689 std::string* l) {
erg@google.come6ffcb52010-08-18 03:38:24 +0900690 if (p.auto_close) {
groby@chromium.org6b4dc5e2013-03-19 07:33:04 +0900691 l->append(base::StringPrintf("FD(%d auto-close)", p.fd));
erg@google.come6ffcb52010-08-18 03:38:24 +0900692 } else {
groby@chromium.org6b4dc5e2013-03-19 07:33:04 +0900693 l->append(base::StringPrintf("FD(%d)", p.fd));
erg@google.come6ffcb52010-08-18 03:38:24 +0900694 }
695}
696#endif // defined(OS_POSIX)
697
scottmg81491272015-06-20 07:51:00 +0900698#if defined(OS_MACOSX) && !defined(OS_IOS)
jam7f5c5742016-05-12 06:05:05 +0900699void ParamTraits<base::SharedMemoryHandle>::GetSize(base::PickleSizer* sizer,
700 const param_type& p) {
701 GetParamSize(sizer, p.GetMemoryObject());
702 uint32_t dummy = 0;
703 GetParamSize(sizer, dummy);
704}
705
rockot6dbfea52016-02-04 05:20:16 +0900706void ParamTraits<base::SharedMemoryHandle>::Write(base::Pickle* m,
scottmg81491272015-06-20 07:51:00 +0900707 const param_type& p) {
erikchena355c822016-04-19 03:39:15 +0900708 MachPortMac mach_port_mac(p.GetMemoryObject());
709 ParamTraits<MachPortMac>::Write(m, mach_port_mac);
710 size_t size = 0;
711 bool result = p.GetSize(&size);
712 DCHECK(result);
713 ParamTraits<uint32_t>::Write(m, static_cast<uint32_t>(size));
scottmg81491272015-06-20 07:51:00 +0900714
erikchena355c822016-04-19 03:39:15 +0900715 // If the caller intended to pass ownership to the IPC stack, release a
716 // reference.
717 if (p.OwnershipPassesToIPC())
718 p.Close();
scottmg81491272015-06-20 07:51:00 +0900719}
720
rockot6dbfea52016-02-04 05:20:16 +0900721bool ParamTraits<base::SharedMemoryHandle>::Read(const base::Pickle* m,
scottmg81491272015-06-20 07:51:00 +0900722 base::PickleIterator* iter,
723 param_type* r) {
erikchena355c822016-04-19 03:39:15 +0900724 MachPortMac mach_port_mac;
725 if (!ParamTraits<MachPortMac>::Read(m, iter, &mach_port_mac))
scottmg81491272015-06-20 07:51:00 +0900726 return false;
727
erikchena355c822016-04-19 03:39:15 +0900728 uint32_t size;
729 if (!ParamTraits<uint32_t>::Read(m, iter, &size))
730 return false;
scottmg81491272015-06-20 07:51:00 +0900731
erikchena355c822016-04-19 03:39:15 +0900732 *r = base::SharedMemoryHandle(mach_port_mac.get_mach_port(),
733 static_cast<size_t>(size),
734 base::GetCurrentProcId());
735 return true;
scottmg81491272015-06-20 07:51:00 +0900736}
737
738void ParamTraits<base::SharedMemoryHandle>::Log(const param_type& p,
739 std::string* l) {
erikchena355c822016-04-19 03:39:15 +0900740 l->append("Mach port: ");
741 LogParam(p.GetMemoryObject(), l);
scottmg81491272015-06-20 07:51:00 +0900742}
erikchen347f5cb2015-10-03 08:49:26 +0900743
erikchen18430e52015-09-26 07:34:31 +0900744#elif defined(OS_WIN)
jam7f5c5742016-05-12 06:05:05 +0900745void ParamTraits<base::SharedMemoryHandle>::GetSize(base::PickleSizer* s,
746 const param_type& p) {
747 GetParamSize(s, p.NeedsBrokering());
748 if (p.NeedsBrokering()) {
749 GetParamSize(s, p.GetHandle());
750 } else {
751 GetParamSize(s, HandleToLong(p.GetHandle()));
752 }
753}
754
rockot6dbfea52016-02-04 05:20:16 +0900755void ParamTraits<base::SharedMemoryHandle>::Write(base::Pickle* m,
erikchen18430e52015-09-26 07:34:31 +0900756 const param_type& p) {
erikchen18430e52015-09-26 07:34:31 +0900757 m->WriteBool(p.NeedsBrokering());
758
759 if (p.NeedsBrokering()) {
760 HandleWin handle_win(p.GetHandle(), HandleWin::DUPLICATE);
761 ParamTraits<HandleWin>::Write(m, handle_win);
erikcheneeaf5f92016-02-02 07:14:28 +0900762
763 // If the caller intended to pass ownership to the IPC stack, release a
764 // reference.
erikchenb23e3a42016-03-30 07:26:42 +0900765 if (p.OwnershipPassesToIPC() && p.BelongsToCurrentProcess())
erikcheneeaf5f92016-02-02 07:14:28 +0900766 p.Close();
erikchen18430e52015-09-26 07:34:31 +0900767 } else {
768 m->WriteInt(HandleToLong(p.GetHandle()));
769 }
770}
771
rockot6dbfea52016-02-04 05:20:16 +0900772bool ParamTraits<base::SharedMemoryHandle>::Read(const base::Pickle* m,
erikchen18430e52015-09-26 07:34:31 +0900773 base::PickleIterator* iter,
774 param_type* r) {
erikchen18430e52015-09-26 07:34:31 +0900775 bool needs_brokering;
776 if (!iter->ReadBool(&needs_brokering))
777 return false;
778
779 if (needs_brokering) {
780 HandleWin handle_win;
781 if (!ParamTraits<HandleWin>::Read(m, iter, &handle_win))
782 return false;
erikchen97211e12016-01-08 11:17:04 +0900783 *r = base::SharedMemoryHandle(handle_win.get_handle(),
784 base::GetCurrentProcId());
erikchen18430e52015-09-26 07:34:31 +0900785 return true;
786 }
787
788 int handle_int;
789 if (!iter->ReadInt(&handle_int))
790 return false;
791 HANDLE handle = LongToHandle(handle_int);
erikchen97211e12016-01-08 11:17:04 +0900792 *r = base::SharedMemoryHandle(handle, base::GetCurrentProcId());
erikchen18430e52015-09-26 07:34:31 +0900793 return true;
794}
795
796void ParamTraits<base::SharedMemoryHandle>::Log(const param_type& p,
797 std::string* l) {
erikchen18430e52015-09-26 07:34:31 +0900798 LogParam(p.GetHandle(), l);
799 l->append(" needs brokering: ");
800 LogParam(p.NeedsBrokering(), l);
801}
scottmg81491272015-06-20 07:51:00 +0900802#endif // defined(OS_MACOSX) && !defined(OS_IOS)
803
rockot15c8ac42016-02-05 11:12:32 +0900804void ParamTraits<base::FilePath>::GetSize(base::PickleSizer* sizer,
805 const param_type& p) {
806 p.GetSizeForPickle(sizer);
807}
808
rockot6dbfea52016-02-04 05:20:16 +0900809void ParamTraits<base::FilePath>::Write(base::Pickle* m, const param_type& p) {
aedla@chromium.org51127b92013-01-28 22:47:55 +0900810 p.WriteToPickle(m);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900811}
812
rockot6dbfea52016-02-04 05:20:16 +0900813bool ParamTraits<base::FilePath>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900814 base::PickleIterator* iter,
brettw@chromium.org22b3fda2013-02-10 13:49:30 +0900815 param_type* r) {
aedla@chromium.org51127b92013-01-28 22:47:55 +0900816 return r->ReadFromPickle(iter);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900817}
818
brettw@chromium.org22b3fda2013-02-10 13:49:30 +0900819void ParamTraits<base::FilePath>::Log(const param_type& p, std::string* l) {
820 ParamTraits<base::FilePath::StringType>::Log(p.value(), l);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900821}
822
rockot15c8ac42016-02-05 11:12:32 +0900823void ParamTraits<base::ListValue>::GetSize(base::PickleSizer* sizer,
824 const param_type& p) {
825 GetValueSize(sizer, &p, 0);
826}
827
rockot6dbfea52016-02-04 05:20:16 +0900828void ParamTraits<base::ListValue>::Write(base::Pickle* m, const param_type& p) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900829 WriteValue(m, &p, 0);
830}
831
rockot6dbfea52016-02-04 05:20:16 +0900832bool ParamTraits<base::ListValue>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900833 base::PickleIterator* iter,
834 param_type* r) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900835 int type;
brettw@chromium.org32285192013-06-22 04:42:19 +0900836 if (!ReadParam(m, iter, &type) || type != base::Value::TYPE_LIST)
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900837 return false;
838
839 return ReadListValue(m, iter, r, 0);
840}
841
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900842void ParamTraits<base::ListValue>::Log(const param_type& p, std::string* l) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900843 std::string json;
estadeb5f30dd2015-05-16 10:02:34 +0900844 base::JSONWriter::Write(p, &json);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900845 l->append(json);
846}
847
rockot15c8ac42016-02-05 11:12:32 +0900848void ParamTraits<base::NullableString16>::GetSize(base::PickleSizer* sizer,
849 const param_type& p) {
850 GetParamSize(sizer, p.string());
851 GetParamSize(sizer, p.is_null());
852}
853
rockot6dbfea52016-02-04 05:20:16 +0900854void ParamTraits<base::NullableString16>::Write(base::Pickle* m,
avi@chromium.orgd8179652013-06-13 22:47:46 +0900855 const param_type& p) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900856 WriteParam(m, p.string());
857 WriteParam(m, p.is_null());
858}
859
rockot6dbfea52016-02-04 05:20:16 +0900860bool ParamTraits<base::NullableString16>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900861 base::PickleIterator* iter,
avi@chromium.orgd8179652013-06-13 22:47:46 +0900862 param_type* r) {
brettw@chromium.org5b040852013-12-03 09:39:26 +0900863 base::string16 string;
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900864 if (!ReadParam(m, iter, &string))
865 return false;
866 bool is_null;
867 if (!ReadParam(m, iter, &is_null))
868 return false;
avi@chromium.orgd8179652013-06-13 22:47:46 +0900869 *r = base::NullableString16(string, is_null);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900870 return true;
871}
872
avi@chromium.orgd8179652013-06-13 22:47:46 +0900873void ParamTraits<base::NullableString16>::Log(const param_type& p,
874 std::string* l) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900875 l->append("(");
876 LogParam(p.string(), l);
877 l->append(", ");
878 LogParam(p.is_null(), l);
879 l->append(")");
880}
881
rockot15c8ac42016-02-05 11:12:32 +0900882void ParamTraits<base::File::Info>::GetSize(base::PickleSizer* sizer,
883 const param_type& p) {
884 GetParamSize(sizer, p.size);
885 GetParamSize(sizer, p.is_directory);
886 GetParamSize(sizer, p.last_modified.ToDoubleT());
887 GetParamSize(sizer, p.last_accessed.ToDoubleT());
888 GetParamSize(sizer, p.creation_time.ToDoubleT());
889}
890
rockot6dbfea52016-02-04 05:20:16 +0900891void ParamTraits<base::File::Info>::Write(base::Pickle* m,
rvargas@chromium.org9e469f62014-01-28 06:36:00 +0900892 const param_type& p) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900893 WriteParam(m, p.size);
894 WriteParam(m, p.is_directory);
895 WriteParam(m, p.last_modified.ToDoubleT());
896 WriteParam(m, p.last_accessed.ToDoubleT());
897 WriteParam(m, p.creation_time.ToDoubleT());
898}
899
rockot6dbfea52016-02-04 05:20:16 +0900900bool ParamTraits<base::File::Info>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900901 base::PickleIterator* iter,
rvargas@chromium.org9e469f62014-01-28 06:36:00 +0900902 param_type* p) {
pkasting@chromium.org150a8492014-07-18 10:40:47 +0900903 double last_modified, last_accessed, creation_time;
904 if (!ReadParam(m, iter, &p->size) ||
905 !ReadParam(m, iter, &p->is_directory) ||
906 !ReadParam(m, iter, &last_modified) ||
907 !ReadParam(m, iter, &last_accessed) ||
908 !ReadParam(m, iter, &creation_time))
909 return false;
910 p->last_modified = base::Time::FromDoubleT(last_modified);
911 p->last_accessed = base::Time::FromDoubleT(last_accessed);
912 p->creation_time = base::Time::FromDoubleT(creation_time);
913 return true;
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900914}
915
rvargas@chromium.org9e469f62014-01-28 06:36:00 +0900916void ParamTraits<base::File::Info>::Log(const param_type& p,
917 std::string* l) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900918 l->append("(");
919 LogParam(p.size, l);
920 l->append(",");
921 LogParam(p.is_directory, l);
922 l->append(",");
923 LogParam(p.last_modified.ToDoubleT(), l);
924 l->append(",");
925 LogParam(p.last_accessed.ToDoubleT(), l);
926 l->append(",");
927 LogParam(p.creation_time.ToDoubleT(), l);
928 l->append(")");
929}
930
rockot15c8ac42016-02-05 11:12:32 +0900931void ParamTraits<base::Time>::GetSize(base::PickleSizer* sizer,
932 const param_type& p) {
933 sizer->AddInt64();
934}
935
rockot6dbfea52016-02-04 05:20:16 +0900936void ParamTraits<base::Time>::Write(base::Pickle* m, const param_type& p) {
tfarina1cbfa082015-09-05 03:47:57 +0900937 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900938}
939
rockot6dbfea52016-02-04 05:20:16 +0900940bool ParamTraits<base::Time>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900941 base::PickleIterator* iter,
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900942 param_type* r) {
tfarina1cbfa082015-09-05 03:47:57 +0900943 int64_t value;
944 if (!ParamTraits<int64_t>::Read(m, iter, &value))
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900945 return false;
946 *r = base::Time::FromInternalValue(value);
947 return true;
948}
949
950void ParamTraits<base::Time>::Log(const param_type& p, std::string* l) {
tfarina1cbfa082015-09-05 03:47:57 +0900951 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900952}
953
rockot15c8ac42016-02-05 11:12:32 +0900954void ParamTraits<base::TimeDelta>::GetSize(base::PickleSizer* sizer,
955 const param_type& p) {
956 sizer->AddInt64();
957}
958
rockot6dbfea52016-02-04 05:20:16 +0900959void ParamTraits<base::TimeDelta>::Write(base::Pickle* m, const param_type& p) {
tfarina1cbfa082015-09-05 03:47:57 +0900960 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900961}
962
rockot6dbfea52016-02-04 05:20:16 +0900963bool ParamTraits<base::TimeDelta>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900964 base::PickleIterator* iter,
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900965 param_type* r) {
tfarina1cbfa082015-09-05 03:47:57 +0900966 int64_t value;
967 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900968 if (ret)
969 *r = base::TimeDelta::FromInternalValue(value);
970
971 return ret;
972}
973
974void ParamTraits<base::TimeDelta>::Log(const param_type& p, std::string* l) {
tfarina1cbfa082015-09-05 03:47:57 +0900975 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900976}
977
rockot15c8ac42016-02-05 11:12:32 +0900978void ParamTraits<base::TimeTicks>::GetSize(base::PickleSizer* sizer,
979 const param_type& p) {
980 sizer->AddInt64();
981}
982
rockot6dbfea52016-02-04 05:20:16 +0900983void ParamTraits<base::TimeTicks>::Write(base::Pickle* m, const param_type& p) {
tfarina1cbfa082015-09-05 03:47:57 +0900984 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900985}
986
rockot6dbfea52016-02-04 05:20:16 +0900987bool ParamTraits<base::TimeTicks>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900988 base::PickleIterator* iter,
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900989 param_type* r) {
tfarina1cbfa082015-09-05 03:47:57 +0900990 int64_t value;
991 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900992 if (ret)
993 *r = base::TimeTicks::FromInternalValue(value);
994
995 return ret;
996}
997
998void ParamTraits<base::TimeTicks>::Log(const param_type& p, std::string* l) {
tfarina1cbfa082015-09-05 03:47:57 +0900999 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001000}
1001
tguilbert76e690d2016-09-20 06:11:25 +09001002// If base::UnguessableToken is no longer 128 bits, the IPC serialization logic
1003// below should be updated.
1004static_assert(sizeof(base::UnguessableToken) == 2 * sizeof(uint64_t),
1005 "base::UnguessableToken should be of size 2 * sizeof(uint64_t).");
1006
1007void ParamTraits<base::UnguessableToken>::GetSize(base::PickleSizer* sizer,
1008 const param_type& p) {
1009 sizer->AddBytes(2 * sizeof(uint64_t));
1010}
1011
1012void ParamTraits<base::UnguessableToken>::Write(base::Pickle* m,
1013 const param_type& p) {
1014 DCHECK(!p.is_empty());
1015
1016 ParamTraits<uint64_t>::Write(m, p.GetHighForSerialization());
1017 ParamTraits<uint64_t>::Write(m, p.GetLowForSerialization());
1018}
1019
1020bool ParamTraits<base::UnguessableToken>::Read(const base::Pickle* m,
1021 base::PickleIterator* iter,
1022 param_type* r) {
1023 uint64_t high, low;
1024 if (!ParamTraits<uint64_t>::Read(m, iter, &high) ||
1025 !ParamTraits<uint64_t>::Read(m, iter, &low))
1026 return false;
1027
1028 // Receiving a zeroed UnguessableToken is a security issue.
1029 if (high == 0 && low == 0)
1030 return false;
1031
1032 *r = base::UnguessableToken::Deserialize(high, low);
1033 return true;
1034}
1035
1036void ParamTraits<base::UnguessableToken>::Log(const param_type& p,
1037 std::string* l) {
1038 l->append(p.ToString());
1039}
1040
jam1ea1e0d2016-05-14 00:09:58 +09001041void ParamTraits<IPC::ChannelHandle>::GetSize(base::PickleSizer* sizer,
1042 const param_type& p) {
1043 GetParamSize(sizer, p.name);
1044#if defined(OS_POSIX)
1045 GetParamSize(sizer, p.socket);
1046#endif
amistry70d63572016-06-27 15:34:42 +09001047 GetParamSize(sizer, p.mojo_handle);
jam1ea1e0d2016-05-14 00:09:58 +09001048}
1049
rockot6dbfea52016-02-04 05:20:16 +09001050void ParamTraits<IPC::ChannelHandle>::Write(base::Pickle* m,
1051 const param_type& p) {
amit@chromium.org37290742012-01-24 11:36:05 +09001052#if defined(OS_WIN)
1053 // On Windows marshalling pipe handle is not supported.
1054 DCHECK(p.pipe.handle == NULL);
1055#endif // defined (OS_WIN)
erg@google.come6ffcb52010-08-18 03:38:24 +09001056 WriteParam(m, p.name);
1057#if defined(OS_POSIX)
1058 WriteParam(m, p.socket);
1059#endif
amistry70d63572016-06-27 15:34:42 +09001060 WriteParam(m, p.mojo_handle);
erg@google.come6ffcb52010-08-18 03:38:24 +09001061}
1062
rockot6dbfea52016-02-04 05:20:16 +09001063bool ParamTraits<IPC::ChannelHandle>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +09001064 base::PickleIterator* iter,
erg@google.come6ffcb52010-08-18 03:38:24 +09001065 param_type* r) {
1066 return ReadParam(m, iter, &r->name)
1067#if defined(OS_POSIX)
1068 && ReadParam(m, iter, &r->socket)
1069#endif
amistry70d63572016-06-27 15:34:42 +09001070 && ReadParam(m, iter, &r->mojo_handle);
erg@google.come6ffcb52010-08-18 03:38:24 +09001071}
1072
1073void ParamTraits<IPC::ChannelHandle>::Log(const param_type& p,
erg@google.com8aca7272010-08-19 03:33:57 +09001074 std::string* l) {
groby@chromium.org6b4dc5e2013-03-19 07:33:04 +09001075 l->append(base::StringPrintf("ChannelHandle(%s", p.name.c_str()));
erg@google.come6ffcb52010-08-18 03:38:24 +09001076#if defined(OS_POSIX)
steveblock@chromium.org7a470312011-09-23 19:32:19 +09001077 l->append(", ");
erg@google.come6ffcb52010-08-18 03:38:24 +09001078 ParamTraits<base::FileDescriptor>::Log(p.socket, l);
1079#endif
amistry70d63572016-06-27 15:34:42 +09001080 l->append(", ");
1081 LogParam(p.mojo_handle, l);
erg@google.com8aca7272010-08-19 03:33:57 +09001082 l->append(")");
erg@google.come6ffcb52010-08-18 03:38:24 +09001083}
1084
rockot15c8ac42016-02-05 11:12:32 +09001085void ParamTraits<LogData>::GetSize(base::PickleSizer* sizer,
1086 const param_type& p) {
1087 GetParamSize(sizer, p.channel);
1088 GetParamSize(sizer, p.routing_id);
1089 GetParamSize(sizer, p.type);
1090 GetParamSize(sizer, p.flags);
1091 GetParamSize(sizer, p.sent);
1092 GetParamSize(sizer, p.receive);
1093 GetParamSize(sizer, p.dispatch);
1094 GetParamSize(sizer, p.message_name);
1095 GetParamSize(sizer, p.params);
1096}
1097
rockot6dbfea52016-02-04 05:20:16 +09001098void ParamTraits<LogData>::Write(base::Pickle* m, const param_type& p) {
erg@google.com20b66e32010-10-01 05:06:30 +09001099 WriteParam(m, p.channel);
1100 WriteParam(m, p.routing_id);
jam@chromium.org1d8d4d12011-10-18 07:15:27 +09001101 WriteParam(m, p.type);
erg@google.com20b66e32010-10-01 05:06:30 +09001102 WriteParam(m, p.flags);
1103 WriteParam(m, p.sent);
1104 WriteParam(m, p.receive);
1105 WriteParam(m, p.dispatch);
tsepez@chromium.org6639c182012-11-15 12:17:45 +09001106 WriteParam(m, p.message_name);
erg@google.com20b66e32010-10-01 05:06:30 +09001107 WriteParam(m, p.params);
1108}
1109
rockot6dbfea52016-02-04 05:20:16 +09001110bool ParamTraits<LogData>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +09001111 base::PickleIterator* iter,
jbates@chromium.org0fc87362012-03-08 05:42:56 +09001112 param_type* r) {
jam@chromium.org1d8d4d12011-10-18 07:15:27 +09001113 return
erg@google.com20b66e32010-10-01 05:06:30 +09001114 ReadParam(m, iter, &r->channel) &&
1115 ReadParam(m, iter, &r->routing_id) &&
jam@chromium.org1d8d4d12011-10-18 07:15:27 +09001116 ReadParam(m, iter, &r->type) &&
erg@google.com20b66e32010-10-01 05:06:30 +09001117 ReadParam(m, iter, &r->flags) &&
1118 ReadParam(m, iter, &r->sent) &&
1119 ReadParam(m, iter, &r->receive) &&
1120 ReadParam(m, iter, &r->dispatch) &&
tsepez@chromium.org6639c182012-11-15 12:17:45 +09001121 ReadParam(m, iter, &r->message_name) &&
erg@google.com20b66e32010-10-01 05:06:30 +09001122 ReadParam(m, iter, &r->params);
erg@google.com20b66e32010-10-01 05:06:30 +09001123}
1124
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001125void ParamTraits<LogData>::Log(const param_type& p, std::string* l) {
1126 // Doesn't make sense to implement this!
1127}
1128
rockot6dbfea52016-02-04 05:20:16 +09001129void ParamTraits<Message>::Write(base::Pickle* m, const Message& p) {
brettw@chromium.orgf48910a2012-06-29 09:05:04 +09001130#if defined(OS_POSIX)
1131 // We don't serialize the file descriptors in the nested message, so there
1132 // better not be any.
morrita7d1bfcc2015-01-31 14:45:42 +09001133 DCHECK(!p.HasAttachments());
brettw@chromium.orgf48910a2012-06-29 09:05:04 +09001134#endif
1135
1136 // Don't just write out the message. This is used to send messages between
1137 // NaCl (Posix environment) and the browser (could be on Windows). The message
1138 // header formats differ between these systems (so does handle sharing, but
1139 // we already asserted we don't have any handles). So just write out the
1140 // parts of the header we use.
1141 //
1142 // Be careful also to use only explicitly-sized types. The NaCl environment
1143 // could be 64-bit and the host browser could be 32-bits. The nested message
1144 // may or may not be safe to send between 32-bit and 64-bit systems, but we
1145 // leave that up to the code sending the message to ensure.
tfarina1cbfa082015-09-05 03:47:57 +09001146 m->WriteUInt32(static_cast<uint32_t>(p.routing_id()));
brettw@chromium.orgf48910a2012-06-29 09:05:04 +09001147 m->WriteUInt32(p.type());
1148 m->WriteUInt32(p.flags());
tfarina1cbfa082015-09-05 03:47:57 +09001149 m->WriteData(p.payload(), static_cast<uint32_t>(p.payload_size()));
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001150}
1151
rockot6dbfea52016-02-04 05:20:16 +09001152bool ParamTraits<Message>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +09001153 base::PickleIterator* iter,
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001154 Message* r) {
tfarina1cbfa082015-09-05 03:47:57 +09001155 uint32_t routing_id, type, flags;
avic9f0ad02014-12-29 08:31:48 +09001156 if (!iter->ReadUInt32(&routing_id) ||
1157 !iter->ReadUInt32(&type) ||
1158 !iter->ReadUInt32(&flags))
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001159 return false;
brettw@chromium.orgf48910a2012-06-29 09:05:04 +09001160
1161 int payload_size;
1162 const char* payload;
avic9f0ad02014-12-29 08:31:48 +09001163 if (!iter->ReadData(&payload, &payload_size))
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001164 return false;
brettw@chromium.orgf48910a2012-06-29 09:05:04 +09001165
tfarina1cbfa082015-09-05 03:47:57 +09001166 r->SetHeaderValues(static_cast<int32_t>(routing_id), type, flags);
brettw@chromium.orgf48910a2012-06-29 09:05:04 +09001167 return r->WriteBytes(payload, payload_size);
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001168}
1169
1170void ParamTraits<Message>::Log(const Message& p, std::string* l) {
1171 l->append("<IPC::Message>");
1172}
1173
1174#if defined(OS_WIN)
rockot15c8ac42016-02-05 11:12:32 +09001175void ParamTraits<HANDLE>::GetSize(base::PickleSizer* sizer,
1176 const param_type& p) {
1177 sizer->AddInt();
1178}
1179
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001180// Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
jschuh@chromium.orgfb87c342013-03-04 11:29:03 +09001181// bit systems. That's why we use the Windows macros to convert to 32 bits.
rockot6dbfea52016-02-04 05:20:16 +09001182void ParamTraits<HANDLE>::Write(base::Pickle* m, const param_type& p) {
jschuh@chromium.orgfb87c342013-03-04 11:29:03 +09001183 m->WriteInt(HandleToLong(p));
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001184}
1185
rockot6dbfea52016-02-04 05:20:16 +09001186bool ParamTraits<HANDLE>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +09001187 base::PickleIterator* iter,
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001188 param_type* r) {
tfarina1cbfa082015-09-05 03:47:57 +09001189 int32_t temp;
avic9f0ad02014-12-29 08:31:48 +09001190 if (!iter->ReadInt(&temp))
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001191 return false;
jschuh@chromium.orgfb87c342013-03-04 11:29:03 +09001192 *r = LongToHandle(temp);
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001193 return true;
1194}
1195
1196void ParamTraits<HANDLE>::Log(const param_type& p, std::string* l) {
brucedawsond7e5dfd2015-10-07 04:22:00 +09001197 l->append(base::StringPrintf("0x%p", p));
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001198}
1199
rockot15c8ac42016-02-05 11:12:32 +09001200void ParamTraits<LOGFONT>::GetSize(base::PickleSizer* sizer,
1201 const param_type& p) {
1202 sizer->AddData(sizeof(LOGFONT));
1203}
1204
rockot6dbfea52016-02-04 05:20:16 +09001205void ParamTraits<LOGFONT>::Write(base::Pickle* m, const param_type& p) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001206 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
1207}
1208
rockot6dbfea52016-02-04 05:20:16 +09001209bool ParamTraits<LOGFONT>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +09001210 base::PickleIterator* iter,
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001211 param_type* r) {
1212 const char *data;
1213 int data_size = 0;
avic9f0ad02014-12-29 08:31:48 +09001214 if (iter->ReadData(&data, &data_size) && data_size == sizeof(LOGFONT)) {
jschuh@chromium.orgb9ee7d62012-11-21 09:58:00 +09001215 const LOGFONT *font = reinterpret_cast<LOGFONT*>(const_cast<char*>(data));
1216 if (_tcsnlen(font->lfFaceName, LF_FACESIZE) < LF_FACESIZE) {
1217 memcpy(r, data, sizeof(LOGFONT));
1218 return true;
1219 }
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001220 }
1221
jschuh@chromium.orgb9ee7d62012-11-21 09:58:00 +09001222 NOTREACHED();
1223 return false;
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001224}
1225
1226void ParamTraits<LOGFONT>::Log(const param_type& p, std::string* l) {
groby@chromium.org6b4dc5e2013-03-19 07:33:04 +09001227 l->append(base::StringPrintf("<LOGFONT>"));
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001228}
1229
rockot15c8ac42016-02-05 11:12:32 +09001230void ParamTraits<MSG>::GetSize(base::PickleSizer* sizer, const param_type& p) {
1231 sizer->AddData(sizeof(MSG));
1232}
1233
rockot6dbfea52016-02-04 05:20:16 +09001234void ParamTraits<MSG>::Write(base::Pickle* m, const param_type& p) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001235 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
1236}
1237
rockot6dbfea52016-02-04 05:20:16 +09001238bool ParamTraits<MSG>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +09001239 base::PickleIterator* iter,
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001240 param_type* r) {
1241 const char *data;
1242 int data_size = 0;
avic9f0ad02014-12-29 08:31:48 +09001243 bool result = iter->ReadData(&data, &data_size);
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001244 if (result && data_size == sizeof(MSG)) {
1245 memcpy(r, data, sizeof(MSG));
1246 } else {
1247 result = false;
1248 NOTREACHED();
1249 }
1250
1251 return result;
1252}
1253
1254void ParamTraits<MSG>::Log(const param_type& p, std::string* l) {
1255 l->append("<MSG>");
1256}
1257
1258#endif // OS_WIN
1259
agl@chromium.org1c6dcf22009-07-23 08:57:21 +09001260} // namespace IPC