blob: be83e5a236bb2322e66b36d13aa0640759cdc691 [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)
sammc5aeaa8a2016-11-14 12:29:08 +090025#include "base/file_descriptor_posix.h"
morrita7d1bfcc2015-01-31 14:45:42 +090026#include "ipc/ipc_platform_file_attachment_posix.h"
27#endif
28
erikchen18430e52015-09-26 07:34:31 +090029#if (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
scottmg81491272015-06-20 07:51:00 +090030#include "base/memory/shared_memory_handle.h"
erikchen18430e52015-09-26 07:34:31 +090031#endif // (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
scottmg81491272015-06-20 07:51:00 +090032
erikchenae16e0c2015-10-10 04:12:06 +090033#if defined(OS_MACOSX) && !defined(OS_IOS)
34#include "ipc/mach_port_mac.h"
35#endif
36
morrita33a35902015-01-15 06:17:06 +090037#if defined(OS_WIN)
jschuh@chromium.orgb9ee7d62012-11-21 09:58:00 +090038#include <tchar.h>
erikchen18430e52015-09-26 07:34:31 +090039#include "ipc/handle_win.h"
erg@google.come6ffcb52010-08-18 03:38:24 +090040#endif
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090041
42namespace IPC {
43
brettw@chromium.orgce352e52012-06-05 06:18:25 +090044namespace {
45
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090046const int kMaxRecursionDepth = 100;
47
brettw@chromium.orgce352e52012-06-05 06:18:25 +090048template<typename CharType>
49void LogBytes(const std::vector<CharType>& data, std::string* out) {
50#if defined(OS_WIN)
51 // Windows has a GUI for logging, which can handle arbitrary binary data.
52 for (size_t i = 0; i < data.size(); ++i)
53 out->push_back(data[i]);
54#else
55 // On POSIX, we log to stdout, which we assume can display ASCII.
56 static const size_t kMaxBytesToLog = 100;
57 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
58 if (isprint(data[i]))
59 out->push_back(data[i]);
60 else
groby@chromium.org6b4dc5e2013-03-19 07:33:04 +090061 out->append(
62 base::StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
brettw@chromium.orgce352e52012-06-05 06:18:25 +090063 }
64 if (data.size() > kMaxBytesToLog) {
groby@chromium.org22e93982013-03-31 02:29:28 +090065 out->append(base::StringPrintf(
66 " and %u more bytes",
67 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
brettw@chromium.orgce352e52012-06-05 06:18:25 +090068 }
69#endif
70}
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090071
rockot6dbfea52016-02-04 05:20:16 +090072bool ReadValue(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +090073 base::PickleIterator* iter,
74 base::Value** value,
brettw@chromium.orgce352e52012-06-05 06:18:25 +090075 int recursion);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090076
rockot15c8ac42016-02-05 11:12:32 +090077void GetValueSize(base::PickleSizer* sizer,
78 const base::Value* value,
79 int recursion) {
80 if (recursion > kMaxRecursionDepth) {
81 LOG(WARNING) << "Max recursion depth hit in GetValueSize.";
82 return;
83 }
84
85 sizer->AddInt();
86 switch (value->GetType()) {
87 case base::Value::TYPE_NULL:
88 break;
89 case base::Value::TYPE_BOOLEAN:
90 sizer->AddBool();
91 break;
92 case base::Value::TYPE_INTEGER:
93 sizer->AddInt();
94 break;
95 case base::Value::TYPE_DOUBLE:
96 sizer->AddDouble();
97 break;
98 case base::Value::TYPE_STRING: {
99 const base::StringValue* result;
100 value->GetAsString(&result);
amistry0bab7322016-04-08 13:21:54 +0900101 if (value->GetAsString(&result)) {
102 DCHECK(result);
103 GetParamSize(sizer, result->GetString());
104 } else {
105 std::string str;
106 bool as_string_result = value->GetAsString(&str);
107 DCHECK(as_string_result);
108 GetParamSize(sizer, str);
109 }
rockot15c8ac42016-02-05 11:12:32 +0900110 break;
111 }
112 case base::Value::TYPE_BINARY: {
113 const base::BinaryValue* binary =
114 static_cast<const base::BinaryValue*>(value);
115 sizer->AddData(static_cast<int>(binary->GetSize()));
116 break;
117 }
118 case base::Value::TYPE_DICTIONARY: {
119 sizer->AddInt();
120 const base::DictionaryValue* dict =
121 static_cast<const base::DictionaryValue*>(value);
122 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd();
123 it.Advance()) {
124 GetParamSize(sizer, it.key());
125 GetValueSize(sizer, &it.value(), recursion + 1);
126 }
127 break;
128 }
129 case base::Value::TYPE_LIST: {
130 sizer->AddInt();
131 const base::ListValue* list = static_cast<const base::ListValue*>(value);
dcheng1fa44fb2016-05-26 03:30:47 +0900132 for (const auto& entry : *list) {
133 GetValueSize(sizer, entry.get(), recursion + 1);
rockot15c8ac42016-02-05 11:12:32 +0900134 }
135 break;
136 }
137 default:
138 NOTREACHED() << "Invalid base::Value type.";
139 }
140}
141
rockot6dbfea52016-02-04 05:20:16 +0900142void WriteValue(base::Pickle* m, const base::Value* value, int recursion) {
orenb@chromium.org88de3872012-07-26 10:29:21 +0900143 bool result;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900144 if (recursion > kMaxRecursionDepth) {
145 LOG(WARNING) << "Max recursion depth hit in WriteValue.";
146 return;
147 }
148
149 m->WriteInt(value->GetType());
150
151 switch (value->GetType()) {
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900152 case base::Value::TYPE_NULL:
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900153 break;
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900154 case base::Value::TYPE_BOOLEAN: {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900155 bool val;
orenb@chromium.org88de3872012-07-26 10:29:21 +0900156 result = value->GetAsBoolean(&val);
157 DCHECK(result);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900158 WriteParam(m, val);
159 break;
160 }
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900161 case base::Value::TYPE_INTEGER: {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900162 int val;
orenb@chromium.org88de3872012-07-26 10:29:21 +0900163 result = value->GetAsInteger(&val);
164 DCHECK(result);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900165 WriteParam(m, val);
166 break;
167 }
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900168 case base::Value::TYPE_DOUBLE: {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900169 double val;
orenb@chromium.org88de3872012-07-26 10:29:21 +0900170 result = value->GetAsDouble(&val);
171 DCHECK(result);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900172 WriteParam(m, val);
173 break;
174 }
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900175 case base::Value::TYPE_STRING: {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900176 std::string val;
orenb@chromium.org88de3872012-07-26 10:29:21 +0900177 result = value->GetAsString(&val);
178 DCHECK(result);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900179 WriteParam(m, val);
180 break;
181 }
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900182 case base::Value::TYPE_BINARY: {
tfarina@chromium.org2e2a9022011-08-06 03:20:05 +0900183 const base::BinaryValue* binary =
184 static_cast<const base::BinaryValue*>(value);
thomasvl@google.com9a242072010-07-23 23:18:59 +0900185 m->WriteData(binary->GetBuffer(), static_cast<int>(binary->GetSize()));
mpcomplete@chromium.org554d4312009-10-07 03:15:58 +0900186 break;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900187 }
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900188 case base::Value::TYPE_DICTIONARY: {
189 const base::DictionaryValue* dict =
190 static_cast<const base::DictionaryValue*>(value);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900191
pkasting@chromium.org36515db2009-11-26 05:47:52 +0900192 WriteParam(m, static_cast<int>(dict->size()));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900193
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900194 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd();
195 it.Advance()) {
pneubeck@chromium.orga2fbefc2013-01-18 23:43:27 +0900196 WriteParam(m, it.key());
197 WriteValue(m, &it.value(), recursion + 1);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900198 }
199 break;
200 }
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900201 case base::Value::TYPE_LIST: {
202 const base::ListValue* list = static_cast<const base::ListValue*>(value);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900203 WriteParam(m, static_cast<int>(list->GetSize()));
dcheng1fa44fb2016-05-26 03:30:47 +0900204 for (const auto& entry : *list) {
205 WriteValue(m, entry.get(), recursion + 1);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900206 }
207 break;
208 }
209 }
210}
211
212// Helper for ReadValue that reads a DictionaryValue into a pre-allocated
213// object.
rockot6dbfea52016-02-04 05:20:16 +0900214bool ReadDictionaryValue(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900215 base::PickleIterator* iter,
216 base::DictionaryValue* value,
217 int recursion) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900218 int size;
219 if (!ReadParam(m, iter, &size))
220 return false;
221
222 for (int i = 0; i < size; ++i) {
viettrungluu@chromium.org178423d2010-07-31 04:47:47 +0900223 std::string key;
brettw@chromium.org32285192013-06-22 04:42:19 +0900224 base::Value* subval;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900225 if (!ReadParam(m, iter, &key) ||
226 !ReadValue(m, iter, &subval, recursion + 1))
227 return false;
kalman@chromium.org9c8b5732011-08-19 14:59:57 +0900228 value->SetWithoutPathExpansion(key, subval);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900229 }
230
231 return true;
232}
233
234// Helper for ReadValue that reads a ReadListValue into a pre-allocated
235// object.
rockot6dbfea52016-02-04 05:20:16 +0900236bool ReadListValue(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900237 base::PickleIterator* iter,
238 base::ListValue* value,
239 int recursion) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900240 int size;
241 if (!ReadParam(m, iter, &size))
242 return false;
243
244 for (int i = 0; i < size; ++i) {
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900245 base::Value* subval;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900246 if (!ReadValue(m, iter, &subval, recursion + 1))
247 return false;
248 value->Set(i, subval);
249 }
250
251 return true;
252}
253
rockot6dbfea52016-02-04 05:20:16 +0900254bool ReadValue(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900255 base::PickleIterator* iter,
256 base::Value** value,
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900257 int recursion) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900258 if (recursion > kMaxRecursionDepth) {
259 LOG(WARNING) << "Max recursion depth hit in ReadValue.";
260 return false;
261 }
262
263 int type;
264 if (!ReadParam(m, iter, &type))
265 return false;
266
267 switch (type) {
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900268 case base::Value::TYPE_NULL:
estade033e61e2015-05-13 03:11:50 +0900269 *value = base::Value::CreateNullValue().release();
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900270 break;
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900271 case base::Value::TYPE_BOOLEAN: {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900272 bool val;
273 if (!ReadParam(m, iter, &val))
274 return false;
tfarina@chromium.org4ef57d92013-01-30 14:24:07 +0900275 *value = new base::FundamentalValue(val);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900276 break;
277 }
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900278 case base::Value::TYPE_INTEGER: {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900279 int val;
280 if (!ReadParam(m, iter, &val))
281 return false;
tfarina@chromium.org4ef57d92013-01-30 14:24:07 +0900282 *value = new base::FundamentalValue(val);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900283 break;
284 }
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900285 case base::Value::TYPE_DOUBLE: {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900286 double val;
287 if (!ReadParam(m, iter, &val))
288 return false;
tfarina@chromium.org4ef57d92013-01-30 14:24:07 +0900289 *value = new base::FundamentalValue(val);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900290 break;
291 }
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900292 case base::Value::TYPE_STRING: {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900293 std::string val;
294 if (!ReadParam(m, iter, &val))
295 return false;
tfarina@chromium.org4ef57d92013-01-30 14:24:07 +0900296 *value = new base::StringValue(val);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900297 break;
298 }
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900299 case base::Value::TYPE_BINARY: {
mpcomplete@chromium.org554d4312009-10-07 03:15:58 +0900300 const char* data;
301 int length;
avic9f0ad02014-12-29 08:31:48 +0900302 if (!iter->ReadData(&data, &length))
mpcomplete@chromium.org554d4312009-10-07 03:15:58 +0900303 return false;
dcheng03c8f322016-06-16 19:48:42 +0900304 std::unique_ptr<base::BinaryValue> val =
305 base::BinaryValue::CreateWithCopiedBuffer(data, length);
306 *value = val.release();
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900307 break;
308 }
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900309 case base::Value::TYPE_DICTIONARY: {
danakjc3fb6c52016-04-23 13:21:09 +0900310 std::unique_ptr<base::DictionaryValue> val(new base::DictionaryValue());
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900311 if (!ReadDictionaryValue(m, iter, val.get(), recursion))
312 return false;
313 *value = val.release();
314 break;
315 }
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900316 case base::Value::TYPE_LIST: {
danakjc3fb6c52016-04-23 13:21:09 +0900317 std::unique_ptr<base::ListValue> val(new base::ListValue());
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900318 if (!ReadListValue(m, iter, val.get(), recursion))
319 return false;
320 *value = val.release();
321 break;
322 }
mpcomplete@chromium.org554d4312009-10-07 03:15:58 +0900323 default:
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900324 return false;
325 }
326
327 return true;
328}
329
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900330} // namespace
331
332// -----------------------------------------------------------------------------
333
334LogData::LogData()
335 : routing_id(0),
336 type(0),
337 sent(0),
338 receive(0),
339 dispatch(0) {
340}
341
vmpstrd661bf72016-03-25 05:22:54 +0900342LogData::LogData(const LogData& other) = default;
343
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900344LogData::~LogData() {
345}
346
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900347void ParamTraits<bool>::Log(const param_type& p, std::string* l) {
348 l->append(p ? "true" : "false");
349}
350
rockot15c8ac42016-02-05 11:12:32 +0900351void ParamTraits<signed char>::GetSize(base::PickleSizer* sizer,
352 const param_type& p) {
353 sizer->AddBytes(sizeof(param_type));
354}
355
rockot6dbfea52016-02-04 05:20:16 +0900356void ParamTraits<signed char>::Write(base::Pickle* m, const param_type& p) {
ortuno6e3f7b32015-10-30 09:46:20 +0900357 m->WriteBytes(&p, sizeof(param_type));
358}
359
rockot6dbfea52016-02-04 05:20:16 +0900360bool ParamTraits<signed char>::Read(const base::Pickle* m,
361 base::PickleIterator* iter,
362 param_type* r) {
ortuno6e3f7b32015-10-30 09:46:20 +0900363 const char* data;
364 if (!iter->ReadBytes(&data, sizeof(param_type)))
365 return false;
366 memcpy(r, data, sizeof(param_type));
367 return true;
368}
369
370void ParamTraits<signed char>::Log(const param_type& p, std::string* l) {
371 l->append(base::IntToString(p));
372}
373
rockot15c8ac42016-02-05 11:12:32 +0900374void ParamTraits<unsigned char>::GetSize(base::PickleSizer* sizer,
375 const param_type& p) {
376 sizer->AddBytes(sizeof(param_type));
377}
378
rockot6dbfea52016-02-04 05:20:16 +0900379void ParamTraits<unsigned char>::Write(base::Pickle* m, const param_type& p) {
tsepez@chromium.org09eb95f2013-07-13 08:12:28 +0900380 m->WriteBytes(&p, sizeof(param_type));
381}
382
rockot6dbfea52016-02-04 05:20:16 +0900383bool ParamTraits<unsigned char>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900384 base::PickleIterator* iter,
385 param_type* r) {
tsepez@chromium.org09eb95f2013-07-13 08:12:28 +0900386 const char* data;
avic9f0ad02014-12-29 08:31:48 +0900387 if (!iter->ReadBytes(&data, sizeof(param_type)))
tsepez@chromium.org09eb95f2013-07-13 08:12:28 +0900388 return false;
389 memcpy(r, data, sizeof(param_type));
390 return true;
391}
392
393void ParamTraits<unsigned char>::Log(const param_type& p, std::string* l) {
394 l->append(base::UintToString(p));
395}
396
rockot15c8ac42016-02-05 11:12:32 +0900397void ParamTraits<unsigned short>::GetSize(base::PickleSizer* sizer,
398 const param_type& p) {
399 sizer->AddBytes(sizeof(param_type));
400}
401
rockot6dbfea52016-02-04 05:20:16 +0900402void ParamTraits<unsigned short>::Write(base::Pickle* m, const param_type& p) {
tsepez@chromium.org09eb95f2013-07-13 08:12:28 +0900403 m->WriteBytes(&p, sizeof(param_type));
404}
405
rockot6dbfea52016-02-04 05:20:16 +0900406bool ParamTraits<unsigned short>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900407 base::PickleIterator* iter,
tsepez@chromium.org09eb95f2013-07-13 08:12:28 +0900408 param_type* r) {
409 const char* data;
avic9f0ad02014-12-29 08:31:48 +0900410 if (!iter->ReadBytes(&data, sizeof(param_type)))
tsepez@chromium.org09eb95f2013-07-13 08:12:28 +0900411 return false;
412 memcpy(r, data, sizeof(param_type));
413 return true;
414}
415
416void ParamTraits<unsigned short>::Log(const param_type& p, std::string* l) {
417 l->append(base::UintToString(p));
418}
419
erg@google.com8aca7272010-08-19 03:33:57 +0900420void ParamTraits<int>::Log(const param_type& p, std::string* l) {
421 l->append(base::IntToString(p));
422}
423
424void ParamTraits<unsigned int>::Log(const param_type& p, std::string* l) {
425 l->append(base::UintToString(p));
426}
427
jam739d8d12016-02-11 09:50:28 +0900428#if defined(OS_WIN) || defined(OS_LINUX) || \
429 (defined(OS_ANDROID) && defined(ARCH_CPU_64_BITS))
erg@google.com8aca7272010-08-19 03:33:57 +0900430void ParamTraits<long>::Log(const param_type& p, std::string* l) {
tfarina1cbfa082015-09-05 03:47:57 +0900431 l->append(base::Int64ToString(static_cast<int64_t>(p)));
erg@google.com8aca7272010-08-19 03:33:57 +0900432}
433
434void ParamTraits<unsigned long>::Log(const param_type& p, std::string* l) {
tfarina1cbfa082015-09-05 03:47:57 +0900435 l->append(base::Uint64ToString(static_cast<uint64_t>(p)));
erg@google.com8aca7272010-08-19 03:33:57 +0900436}
jam923e5462016-02-11 05:13:39 +0900437#endif
erg@google.com8aca7272010-08-19 03:33:57 +0900438
439void ParamTraits<long long>::Log(const param_type& p, std::string* l) {
tfarina1cbfa082015-09-05 03:47:57 +0900440 l->append(base::Int64ToString(static_cast<int64_t>(p)));
erg@google.com8aca7272010-08-19 03:33:57 +0900441}
442
443void ParamTraits<unsigned long long>::Log(const param_type& p, std::string* l) {
444 l->append(base::Uint64ToString(p));
445}
erg@google.come6ffcb52010-08-18 03:38:24 +0900446
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900447void ParamTraits<float>::Log(const param_type& p, std::string* l) {
groby@chromium.org6b4dc5e2013-03-19 07:33:04 +0900448 l->append(base::StringPrintf("%e", p));
erg@google.come6ffcb52010-08-18 03:38:24 +0900449}
450
rockot15c8ac42016-02-05 11:12:32 +0900451void ParamTraits<double>::GetSize(base::PickleSizer* sizer,
452 const param_type& p) {
453 sizer->AddBytes(sizeof(param_type));
454}
455
rockot6dbfea52016-02-04 05:20:16 +0900456void ParamTraits<double>::Write(base::Pickle* m, const param_type& p) {
piman@chromium.orgdd413b42013-10-31 18:27:31 +0900457 m->WriteBytes(reinterpret_cast<const char*>(&p), sizeof(param_type));
apatrick@chromium.org519c1c62010-10-22 07:04:52 +0900458}
459
rockot6dbfea52016-02-04 05:20:16 +0900460bool ParamTraits<double>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900461 base::PickleIterator* iter,
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900462 param_type* r) {
463 const char *data;
avic9f0ad02014-12-29 08:31:48 +0900464 if (!iter->ReadBytes(&data, sizeof(*r))) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900465 NOTREACHED();
466 return false;
467 }
468 memcpy(r, data, sizeof(param_type));
469 return true;
apatrick@chromium.org519c1c62010-10-22 07:04:52 +0900470}
471
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900472void ParamTraits<double>::Log(const param_type& p, std::string* l) {
groby@chromium.org6b4dc5e2013-03-19 07:33:04 +0900473 l->append(base::StringPrintf("%e", p));
isherman@chromium.org9952aaf2011-09-03 05:42:04 +0900474}
475
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900476
477void ParamTraits<std::string>::Log(const param_type& p, std::string* l) {
478 l->append(p);
isherman@chromium.org9952aaf2011-09-03 05:42:04 +0900479}
480
brettw@chromium.org5b040852013-12-03 09:39:26 +0900481void ParamTraits<base::string16>::Log(const param_type& p, std::string* l) {
avi@chromium.org4f87d8f2013-12-26 03:18:01 +0900482 l->append(base::UTF16ToUTF8(p));
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900483}
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900484
rockot15c8ac42016-02-05 11:12:32 +0900485void ParamTraits<std::vector<char>>::GetSize(base::PickleSizer* sizer,
486 const param_type& p) {
487 sizer->AddData(static_cast<int>(p.size()));
488}
489
rockot6dbfea52016-02-04 05:20:16 +0900490void ParamTraits<std::vector<char>>::Write(base::Pickle* m,
491 const param_type& p) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900492 if (p.empty()) {
493 m->WriteData(NULL, 0);
494 } else {
495 m->WriteData(&p.front(), static_cast<int>(p.size()));
496 }
497}
498
rockot6dbfea52016-02-04 05:20:16 +0900499bool ParamTraits<std::vector<char>>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900500 base::PickleIterator* iter,
501 param_type* r) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900502 const char *data;
503 int data_size = 0;
avic9f0ad02014-12-29 08:31:48 +0900504 if (!iter->ReadData(&data, &data_size) || data_size < 0)
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900505 return false;
506 r->resize(data_size);
507 if (data_size)
508 memcpy(&r->front(), data, data_size);
509 return true;
510}
511
512void ParamTraits<std::vector<char> >::Log(const param_type& p, std::string* l) {
513 LogBytes(p, l);
514}
515
rockot15c8ac42016-02-05 11:12:32 +0900516void ParamTraits<std::vector<unsigned char>>::GetSize(base::PickleSizer* sizer,
517 const param_type& p) {
518 sizer->AddData(static_cast<int>(p.size()));
519}
520
rockot6dbfea52016-02-04 05:20:16 +0900521void ParamTraits<std::vector<unsigned char>>::Write(base::Pickle* m,
522 const param_type& p) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900523 if (p.empty()) {
524 m->WriteData(NULL, 0);
525 } else {
526 m->WriteData(reinterpret_cast<const char*>(&p.front()),
527 static_cast<int>(p.size()));
528 }
529}
530
rockot6dbfea52016-02-04 05:20:16 +0900531bool ParamTraits<std::vector<unsigned char>>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900532 base::PickleIterator* iter,
533 param_type* r) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900534 const char *data;
535 int data_size = 0;
avic9f0ad02014-12-29 08:31:48 +0900536 if (!iter->ReadData(&data, &data_size) || data_size < 0)
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900537 return false;
538 r->resize(data_size);
539 if (data_size)
540 memcpy(&r->front(), data, data_size);
541 return true;
542}
543
544void ParamTraits<std::vector<unsigned char> >::Log(const param_type& p,
545 std::string* l) {
546 LogBytes(p, l);
547}
548
rockot15c8ac42016-02-05 11:12:32 +0900549void ParamTraits<std::vector<bool>>::GetSize(base::PickleSizer* sizer,
550 const param_type& p) {
551 GetParamSize(sizer, static_cast<int>(p.size()));
552 for (size_t i = 0; i < p.size(); ++i)
553 GetParamSize(sizer, static_cast<bool>(p[i]));
554}
555
rockot6dbfea52016-02-04 05:20:16 +0900556void ParamTraits<std::vector<bool>>::Write(base::Pickle* m,
557 const param_type& p) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900558 WriteParam(m, static_cast<int>(p.size()));
eugenis@chromium.org17085812013-03-21 05:25:00 +0900559 // Cast to bool below is required because libc++'s
560 // vector<bool>::const_reference is different from bool, and we want to avoid
561 // writing an extra specialization of ParamTraits for it.
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900562 for (size_t i = 0; i < p.size(); i++)
eugenis@chromium.org17085812013-03-21 05:25:00 +0900563 WriteParam(m, static_cast<bool>(p[i]));
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900564}
565
rockot6dbfea52016-02-04 05:20:16 +0900566bool ParamTraits<std::vector<bool>>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900567 base::PickleIterator* iter,
568 param_type* r) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900569 int size;
570 // ReadLength() checks for < 0 itself.
avic9f0ad02014-12-29 08:31:48 +0900571 if (!iter->ReadLength(&size))
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900572 return false;
573 r->resize(size);
574 for (int i = 0; i < size; i++) {
575 bool value;
576 if (!ReadParam(m, iter, &value))
577 return false;
578 (*r)[i] = value;
579 }
580 return true;
581}
582
583void ParamTraits<std::vector<bool> >::Log(const param_type& p, std::string* l) {
584 for (size_t i = 0; i < p.size(); ++i) {
585 if (i != 0)
586 l->push_back(' ');
eugenis@chromium.org17085812013-03-21 05:25:00 +0900587 LogParam(static_cast<bool>(p[i]), l);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900588 }
apatrick@chromium.org519c1c62010-10-22 07:04:52 +0900589}
590
rockot15c8ac42016-02-05 11:12:32 +0900591void ParamTraits<base::DictionaryValue>::GetSize(base::PickleSizer* sizer,
592 const param_type& p) {
593 GetValueSize(sizer, &p, 0);
594}
595
rockot6dbfea52016-02-04 05:20:16 +0900596void ParamTraits<base::DictionaryValue>::Write(base::Pickle* m,
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900597 const param_type& p) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900598 WriteValue(m, &p, 0);
599}
600
rockot6dbfea52016-02-04 05:20:16 +0900601bool ParamTraits<base::DictionaryValue>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900602 base::PickleIterator* iter,
603 param_type* r) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900604 int type;
brettw@chromium.org32285192013-06-22 04:42:19 +0900605 if (!ReadParam(m, iter, &type) || type != base::Value::TYPE_DICTIONARY)
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900606 return false;
607
608 return ReadDictionaryValue(m, iter, r, 0);
609}
610
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900611void ParamTraits<base::DictionaryValue>::Log(const param_type& p,
612 std::string* l) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900613 std::string json;
estadeb5f30dd2015-05-16 10:02:34 +0900614 base::JSONWriter::Write(p, &json);
erg@google.com8aca7272010-08-19 03:33:57 +0900615 l->append(json);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900616}
617
erg@google.come6ffcb52010-08-18 03:38:24 +0900618#if defined(OS_POSIX)
jam7f5c5742016-05-12 06:05:05 +0900619void ParamTraits<base::FileDescriptor>::GetSize(base::PickleSizer* sizer,
620 const param_type& p) {
621 GetParamSize(sizer, p.fd >= 0);
amistry70d63572016-06-27 15:34:42 +0900622 if (p.fd >= 0)
623 sizer->AddAttachment();
jam7f5c5742016-05-12 06:05:05 +0900624}
625
rockot6dbfea52016-02-04 05:20:16 +0900626void ParamTraits<base::FileDescriptor>::Write(base::Pickle* m,
627 const param_type& p) {
erg@google.come6ffcb52010-08-18 03:38:24 +0900628 const bool valid = p.fd >= 0;
629 WriteParam(m, valid);
630
morritaab207252014-09-25 05:11:45 +0900631 if (!valid)
632 return;
633
634 if (p.auto_close) {
morrita7d1bfcc2015-01-31 14:45:42 +0900635 if (!m->WriteAttachment(
636 new internal::PlatformFileAttachment(base::ScopedFD(p.fd))))
morritaab207252014-09-25 05:11:45 +0900637 NOTREACHED();
638 } else {
morrita7d1bfcc2015-01-31 14:45:42 +0900639 if (!m->WriteAttachment(new internal::PlatformFileAttachment(p.fd)))
erg@google.come6ffcb52010-08-18 03:38:24 +0900640 NOTREACHED();
641 }
642}
643
rockot6dbfea52016-02-04 05:20:16 +0900644bool ParamTraits<base::FileDescriptor>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900645 base::PickleIterator* iter,
erg@google.come6ffcb52010-08-18 03:38:24 +0900646 param_type* r) {
morritaab207252014-09-25 05:11:45 +0900647 *r = base::FileDescriptor();
648
erg@google.come6ffcb52010-08-18 03:38:24 +0900649 bool valid;
650 if (!ReadParam(m, iter, &valid))
651 return false;
652
morritaab207252014-09-25 05:11:45 +0900653 // TODO(morrita): Seems like this should return false.
654 if (!valid)
erg@google.come6ffcb52010-08-18 03:38:24 +0900655 return true;
erg@google.come6ffcb52010-08-18 03:38:24 +0900656
rockot6dbfea52016-02-04 05:20:16 +0900657 scoped_refptr<base::Pickle::Attachment> attachment;
morrita7d1bfcc2015-01-31 14:45:42 +0900658 if (!m->ReadAttachment(iter, &attachment))
morritaab207252014-09-25 05:11:45 +0900659 return false;
660
sammc14583362016-11-23 12:17:35 +0900661 if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
662 MessageAttachment::Type::PLATFORM_FILE) {
663 return false;
664 }
665
rockot6dbfea52016-02-04 05:20:16 +0900666 *r = base::FileDescriptor(
sammc14583362016-11-23 12:17:35 +0900667 static_cast<internal::PlatformFileAttachment*>(attachment.get())
668 ->TakePlatformFile(),
rockot6dbfea52016-02-04 05:20:16 +0900669 true);
morritaab207252014-09-25 05:11:45 +0900670 return true;
erg@google.come6ffcb52010-08-18 03:38:24 +0900671}
672
673void ParamTraits<base::FileDescriptor>::Log(const param_type& p,
erg@google.com8aca7272010-08-19 03:33:57 +0900674 std::string* l) {
erg@google.come6ffcb52010-08-18 03:38:24 +0900675 if (p.auto_close) {
groby@chromium.org6b4dc5e2013-03-19 07:33:04 +0900676 l->append(base::StringPrintf("FD(%d auto-close)", p.fd));
erg@google.come6ffcb52010-08-18 03:38:24 +0900677 } else {
groby@chromium.org6b4dc5e2013-03-19 07:33:04 +0900678 l->append(base::StringPrintf("FD(%d)", p.fd));
erg@google.come6ffcb52010-08-18 03:38:24 +0900679 }
680}
681#endif // defined(OS_POSIX)
682
scottmg81491272015-06-20 07:51:00 +0900683#if defined(OS_MACOSX) && !defined(OS_IOS)
jam7f5c5742016-05-12 06:05:05 +0900684void ParamTraits<base::SharedMemoryHandle>::GetSize(base::PickleSizer* sizer,
685 const param_type& p) {
686 GetParamSize(sizer, p.GetMemoryObject());
687 uint32_t dummy = 0;
688 GetParamSize(sizer, dummy);
689}
690
rockot6dbfea52016-02-04 05:20:16 +0900691void ParamTraits<base::SharedMemoryHandle>::Write(base::Pickle* m,
scottmg81491272015-06-20 07:51:00 +0900692 const param_type& p) {
erikchena355c822016-04-19 03:39:15 +0900693 MachPortMac mach_port_mac(p.GetMemoryObject());
694 ParamTraits<MachPortMac>::Write(m, mach_port_mac);
695 size_t size = 0;
696 bool result = p.GetSize(&size);
697 DCHECK(result);
698 ParamTraits<uint32_t>::Write(m, static_cast<uint32_t>(size));
scottmg81491272015-06-20 07:51:00 +0900699
erikchena355c822016-04-19 03:39:15 +0900700 // If the caller intended to pass ownership to the IPC stack, release a
701 // reference.
702 if (p.OwnershipPassesToIPC())
703 p.Close();
scottmg81491272015-06-20 07:51:00 +0900704}
705
rockot6dbfea52016-02-04 05:20:16 +0900706bool ParamTraits<base::SharedMemoryHandle>::Read(const base::Pickle* m,
scottmg81491272015-06-20 07:51:00 +0900707 base::PickleIterator* iter,
708 param_type* r) {
erikchena355c822016-04-19 03:39:15 +0900709 MachPortMac mach_port_mac;
710 if (!ParamTraits<MachPortMac>::Read(m, iter, &mach_port_mac))
scottmg81491272015-06-20 07:51:00 +0900711 return false;
712
erikchena355c822016-04-19 03:39:15 +0900713 uint32_t size;
714 if (!ParamTraits<uint32_t>::Read(m, iter, &size))
715 return false;
scottmg81491272015-06-20 07:51:00 +0900716
erikchena355c822016-04-19 03:39:15 +0900717 *r = base::SharedMemoryHandle(mach_port_mac.get_mach_port(),
718 static_cast<size_t>(size),
719 base::GetCurrentProcId());
720 return true;
scottmg81491272015-06-20 07:51:00 +0900721}
722
723void ParamTraits<base::SharedMemoryHandle>::Log(const param_type& p,
724 std::string* l) {
erikchena355c822016-04-19 03:39:15 +0900725 l->append("Mach port: ");
726 LogParam(p.GetMemoryObject(), l);
scottmg81491272015-06-20 07:51:00 +0900727}
erikchen347f5cb2015-10-03 08:49:26 +0900728
erikchen18430e52015-09-26 07:34:31 +0900729#elif defined(OS_WIN)
jam7f5c5742016-05-12 06:05:05 +0900730void ParamTraits<base::SharedMemoryHandle>::GetSize(base::PickleSizer* s,
731 const param_type& p) {
732 GetParamSize(s, p.NeedsBrokering());
733 if (p.NeedsBrokering()) {
734 GetParamSize(s, p.GetHandle());
735 } else {
736 GetParamSize(s, HandleToLong(p.GetHandle()));
737 }
738}
739
rockot6dbfea52016-02-04 05:20:16 +0900740void ParamTraits<base::SharedMemoryHandle>::Write(base::Pickle* m,
erikchen18430e52015-09-26 07:34:31 +0900741 const param_type& p) {
erikchen18430e52015-09-26 07:34:31 +0900742 m->WriteBool(p.NeedsBrokering());
743
744 if (p.NeedsBrokering()) {
745 HandleWin handle_win(p.GetHandle(), HandleWin::DUPLICATE);
746 ParamTraits<HandleWin>::Write(m, handle_win);
erikcheneeaf5f92016-02-02 07:14:28 +0900747
748 // If the caller intended to pass ownership to the IPC stack, release a
749 // reference.
erikchenb23e3a42016-03-30 07:26:42 +0900750 if (p.OwnershipPassesToIPC() && p.BelongsToCurrentProcess())
erikcheneeaf5f92016-02-02 07:14:28 +0900751 p.Close();
erikchen18430e52015-09-26 07:34:31 +0900752 } else {
753 m->WriteInt(HandleToLong(p.GetHandle()));
754 }
755}
756
rockot6dbfea52016-02-04 05:20:16 +0900757bool ParamTraits<base::SharedMemoryHandle>::Read(const base::Pickle* m,
erikchen18430e52015-09-26 07:34:31 +0900758 base::PickleIterator* iter,
759 param_type* r) {
erikchen18430e52015-09-26 07:34:31 +0900760 bool needs_brokering;
761 if (!iter->ReadBool(&needs_brokering))
762 return false;
763
764 if (needs_brokering) {
765 HandleWin handle_win;
766 if (!ParamTraits<HandleWin>::Read(m, iter, &handle_win))
767 return false;
erikchen97211e12016-01-08 11:17:04 +0900768 *r = base::SharedMemoryHandle(handle_win.get_handle(),
769 base::GetCurrentProcId());
erikchen18430e52015-09-26 07:34:31 +0900770 return true;
771 }
772
773 int handle_int;
774 if (!iter->ReadInt(&handle_int))
775 return false;
776 HANDLE handle = LongToHandle(handle_int);
erikchen97211e12016-01-08 11:17:04 +0900777 *r = base::SharedMemoryHandle(handle, base::GetCurrentProcId());
erikchen18430e52015-09-26 07:34:31 +0900778 return true;
779}
780
781void ParamTraits<base::SharedMemoryHandle>::Log(const param_type& p,
782 std::string* l) {
erikchen18430e52015-09-26 07:34:31 +0900783 LogParam(p.GetHandle(), l);
784 l->append(" needs brokering: ");
785 LogParam(p.NeedsBrokering(), l);
786}
scottmg81491272015-06-20 07:51:00 +0900787#endif // defined(OS_MACOSX) && !defined(OS_IOS)
788
rockot15c8ac42016-02-05 11:12:32 +0900789void ParamTraits<base::FilePath>::GetSize(base::PickleSizer* sizer,
790 const param_type& p) {
791 p.GetSizeForPickle(sizer);
792}
793
rockot6dbfea52016-02-04 05:20:16 +0900794void ParamTraits<base::FilePath>::Write(base::Pickle* m, const param_type& p) {
aedla@chromium.org51127b92013-01-28 22:47:55 +0900795 p.WriteToPickle(m);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900796}
797
rockot6dbfea52016-02-04 05:20:16 +0900798bool ParamTraits<base::FilePath>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900799 base::PickleIterator* iter,
brettw@chromium.org22b3fda2013-02-10 13:49:30 +0900800 param_type* r) {
aedla@chromium.org51127b92013-01-28 22:47:55 +0900801 return r->ReadFromPickle(iter);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900802}
803
brettw@chromium.org22b3fda2013-02-10 13:49:30 +0900804void ParamTraits<base::FilePath>::Log(const param_type& p, std::string* l) {
805 ParamTraits<base::FilePath::StringType>::Log(p.value(), l);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900806}
807
rockot15c8ac42016-02-05 11:12:32 +0900808void ParamTraits<base::ListValue>::GetSize(base::PickleSizer* sizer,
809 const param_type& p) {
810 GetValueSize(sizer, &p, 0);
811}
812
rockot6dbfea52016-02-04 05:20:16 +0900813void ParamTraits<base::ListValue>::Write(base::Pickle* m, const param_type& p) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900814 WriteValue(m, &p, 0);
815}
816
rockot6dbfea52016-02-04 05:20:16 +0900817bool ParamTraits<base::ListValue>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900818 base::PickleIterator* iter,
819 param_type* r) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900820 int type;
brettw@chromium.org32285192013-06-22 04:42:19 +0900821 if (!ReadParam(m, iter, &type) || type != base::Value::TYPE_LIST)
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900822 return false;
823
824 return ReadListValue(m, iter, r, 0);
825}
826
brettw@chromium.orgccffb7d2013-06-14 07:50:27 +0900827void ParamTraits<base::ListValue>::Log(const param_type& p, std::string* l) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900828 std::string json;
estadeb5f30dd2015-05-16 10:02:34 +0900829 base::JSONWriter::Write(p, &json);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900830 l->append(json);
831}
832
rockot15c8ac42016-02-05 11:12:32 +0900833void ParamTraits<base::NullableString16>::GetSize(base::PickleSizer* sizer,
834 const param_type& p) {
835 GetParamSize(sizer, p.string());
836 GetParamSize(sizer, p.is_null());
837}
838
rockot6dbfea52016-02-04 05:20:16 +0900839void ParamTraits<base::NullableString16>::Write(base::Pickle* m,
avi@chromium.orgd8179652013-06-13 22:47:46 +0900840 const param_type& p) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900841 WriteParam(m, p.string());
842 WriteParam(m, p.is_null());
843}
844
rockot6dbfea52016-02-04 05:20:16 +0900845bool ParamTraits<base::NullableString16>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900846 base::PickleIterator* iter,
avi@chromium.orgd8179652013-06-13 22:47:46 +0900847 param_type* r) {
brettw@chromium.org5b040852013-12-03 09:39:26 +0900848 base::string16 string;
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900849 if (!ReadParam(m, iter, &string))
850 return false;
851 bool is_null;
852 if (!ReadParam(m, iter, &is_null))
853 return false;
avi@chromium.orgd8179652013-06-13 22:47:46 +0900854 *r = base::NullableString16(string, is_null);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900855 return true;
856}
857
avi@chromium.orgd8179652013-06-13 22:47:46 +0900858void ParamTraits<base::NullableString16>::Log(const param_type& p,
859 std::string* l) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900860 l->append("(");
861 LogParam(p.string(), l);
862 l->append(", ");
863 LogParam(p.is_null(), l);
864 l->append(")");
865}
866
rockot15c8ac42016-02-05 11:12:32 +0900867void ParamTraits<base::File::Info>::GetSize(base::PickleSizer* sizer,
868 const param_type& p) {
869 GetParamSize(sizer, p.size);
870 GetParamSize(sizer, p.is_directory);
871 GetParamSize(sizer, p.last_modified.ToDoubleT());
872 GetParamSize(sizer, p.last_accessed.ToDoubleT());
873 GetParamSize(sizer, p.creation_time.ToDoubleT());
874}
875
rockot6dbfea52016-02-04 05:20:16 +0900876void ParamTraits<base::File::Info>::Write(base::Pickle* m,
rvargas@chromium.org9e469f62014-01-28 06:36:00 +0900877 const param_type& p) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900878 WriteParam(m, p.size);
879 WriteParam(m, p.is_directory);
880 WriteParam(m, p.last_modified.ToDoubleT());
881 WriteParam(m, p.last_accessed.ToDoubleT());
882 WriteParam(m, p.creation_time.ToDoubleT());
883}
884
rockot6dbfea52016-02-04 05:20:16 +0900885bool ParamTraits<base::File::Info>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900886 base::PickleIterator* iter,
rvargas@chromium.org9e469f62014-01-28 06:36:00 +0900887 param_type* p) {
pkasting@chromium.org150a8492014-07-18 10:40:47 +0900888 double last_modified, last_accessed, creation_time;
889 if (!ReadParam(m, iter, &p->size) ||
890 !ReadParam(m, iter, &p->is_directory) ||
891 !ReadParam(m, iter, &last_modified) ||
892 !ReadParam(m, iter, &last_accessed) ||
893 !ReadParam(m, iter, &creation_time))
894 return false;
895 p->last_modified = base::Time::FromDoubleT(last_modified);
896 p->last_accessed = base::Time::FromDoubleT(last_accessed);
897 p->creation_time = base::Time::FromDoubleT(creation_time);
898 return true;
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900899}
900
rvargas@chromium.org9e469f62014-01-28 06:36:00 +0900901void ParamTraits<base::File::Info>::Log(const param_type& p,
902 std::string* l) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900903 l->append("(");
904 LogParam(p.size, l);
905 l->append(",");
906 LogParam(p.is_directory, l);
907 l->append(",");
908 LogParam(p.last_modified.ToDoubleT(), l);
909 l->append(",");
910 LogParam(p.last_accessed.ToDoubleT(), l);
911 l->append(",");
912 LogParam(p.creation_time.ToDoubleT(), l);
913 l->append(")");
914}
915
rockot15c8ac42016-02-05 11:12:32 +0900916void ParamTraits<base::Time>::GetSize(base::PickleSizer* sizer,
917 const param_type& p) {
918 sizer->AddInt64();
919}
920
rockot6dbfea52016-02-04 05:20:16 +0900921void ParamTraits<base::Time>::Write(base::Pickle* m, const param_type& p) {
tfarina1cbfa082015-09-05 03:47:57 +0900922 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900923}
924
rockot6dbfea52016-02-04 05:20:16 +0900925bool ParamTraits<base::Time>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900926 base::PickleIterator* iter,
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900927 param_type* r) {
tfarina1cbfa082015-09-05 03:47:57 +0900928 int64_t value;
929 if (!ParamTraits<int64_t>::Read(m, iter, &value))
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900930 return false;
931 *r = base::Time::FromInternalValue(value);
932 return true;
933}
934
935void ParamTraits<base::Time>::Log(const param_type& p, std::string* l) {
tfarina1cbfa082015-09-05 03:47:57 +0900936 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900937}
938
rockot15c8ac42016-02-05 11:12:32 +0900939void ParamTraits<base::TimeDelta>::GetSize(base::PickleSizer* sizer,
940 const param_type& p) {
941 sizer->AddInt64();
942}
943
rockot6dbfea52016-02-04 05:20:16 +0900944void ParamTraits<base::TimeDelta>::Write(base::Pickle* m, const param_type& p) {
tfarina1cbfa082015-09-05 03:47:57 +0900945 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900946}
947
rockot6dbfea52016-02-04 05:20:16 +0900948bool ParamTraits<base::TimeDelta>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900949 base::PickleIterator* iter,
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900950 param_type* r) {
tfarina1cbfa082015-09-05 03:47:57 +0900951 int64_t value;
952 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900953 if (ret)
954 *r = base::TimeDelta::FromInternalValue(value);
955
956 return ret;
957}
958
959void ParamTraits<base::TimeDelta>::Log(const param_type& p, std::string* l) {
tfarina1cbfa082015-09-05 03:47:57 +0900960 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900961}
962
rockot15c8ac42016-02-05 11:12:32 +0900963void ParamTraits<base::TimeTicks>::GetSize(base::PickleSizer* sizer,
964 const param_type& p) {
965 sizer->AddInt64();
966}
967
rockot6dbfea52016-02-04 05:20:16 +0900968void ParamTraits<base::TimeTicks>::Write(base::Pickle* m, const param_type& p) {
tfarina1cbfa082015-09-05 03:47:57 +0900969 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900970}
971
rockot6dbfea52016-02-04 05:20:16 +0900972bool ParamTraits<base::TimeTicks>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900973 base::PickleIterator* iter,
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900974 param_type* r) {
tfarina1cbfa082015-09-05 03:47:57 +0900975 int64_t value;
976 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900977 if (ret)
978 *r = base::TimeTicks::FromInternalValue(value);
979
980 return ret;
981}
982
983void ParamTraits<base::TimeTicks>::Log(const param_type& p, std::string* l) {
tfarina1cbfa082015-09-05 03:47:57 +0900984 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900985}
986
tguilbert76e690d2016-09-20 06:11:25 +0900987// If base::UnguessableToken is no longer 128 bits, the IPC serialization logic
988// below should be updated.
989static_assert(sizeof(base::UnguessableToken) == 2 * sizeof(uint64_t),
990 "base::UnguessableToken should be of size 2 * sizeof(uint64_t).");
991
992void ParamTraits<base::UnguessableToken>::GetSize(base::PickleSizer* sizer,
993 const param_type& p) {
994 sizer->AddBytes(2 * sizeof(uint64_t));
995}
996
997void ParamTraits<base::UnguessableToken>::Write(base::Pickle* m,
998 const param_type& p) {
999 DCHECK(!p.is_empty());
1000
1001 ParamTraits<uint64_t>::Write(m, p.GetHighForSerialization());
1002 ParamTraits<uint64_t>::Write(m, p.GetLowForSerialization());
1003}
1004
1005bool ParamTraits<base::UnguessableToken>::Read(const base::Pickle* m,
1006 base::PickleIterator* iter,
1007 param_type* r) {
1008 uint64_t high, low;
1009 if (!ParamTraits<uint64_t>::Read(m, iter, &high) ||
1010 !ParamTraits<uint64_t>::Read(m, iter, &low))
1011 return false;
1012
1013 // Receiving a zeroed UnguessableToken is a security issue.
1014 if (high == 0 && low == 0)
1015 return false;
1016
1017 *r = base::UnguessableToken::Deserialize(high, low);
1018 return true;
1019}
1020
1021void ParamTraits<base::UnguessableToken>::Log(const param_type& p,
1022 std::string* l) {
1023 l->append(p.ToString());
1024}
1025
jam1ea1e0d2016-05-14 00:09:58 +09001026void ParamTraits<IPC::ChannelHandle>::GetSize(base::PickleSizer* sizer,
1027 const param_type& p) {
sammc5aeaa8a2016-11-14 12:29:08 +09001028#if defined(OS_NACL_SFI)
jam1ea1e0d2016-05-14 00:09:58 +09001029 GetParamSize(sizer, p.socket);
sammc5aeaa8a2016-11-14 12:29:08 +09001030#else
amistry70d63572016-06-27 15:34:42 +09001031 GetParamSize(sizer, p.mojo_handle);
sammc5aeaa8a2016-11-14 12:29:08 +09001032#endif
jam1ea1e0d2016-05-14 00:09:58 +09001033}
1034
rockot6dbfea52016-02-04 05:20:16 +09001035void ParamTraits<IPC::ChannelHandle>::Write(base::Pickle* m,
1036 const param_type& p) {
sammc5aeaa8a2016-11-14 12:29:08 +09001037#if defined(OS_NACL_SFI)
erg@google.come6ffcb52010-08-18 03:38:24 +09001038 WriteParam(m, p.socket);
sammc5aeaa8a2016-11-14 12:29:08 +09001039#else
amistry70d63572016-06-27 15:34:42 +09001040 WriteParam(m, p.mojo_handle);
sammc5aeaa8a2016-11-14 12:29:08 +09001041#endif
erg@google.come6ffcb52010-08-18 03:38:24 +09001042}
1043
rockot6dbfea52016-02-04 05:20:16 +09001044bool ParamTraits<IPC::ChannelHandle>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +09001045 base::PickleIterator* iter,
erg@google.come6ffcb52010-08-18 03:38:24 +09001046 param_type* r) {
sammc5aeaa8a2016-11-14 12:29:08 +09001047#if defined(OS_NACL_SFI)
1048 return ReadParam(m, iter, &r->socket);
1049#else
1050 return ReadParam(m, iter, &r->mojo_handle);
erg@google.come6ffcb52010-08-18 03:38:24 +09001051#endif
erg@google.come6ffcb52010-08-18 03:38:24 +09001052}
1053
1054void ParamTraits<IPC::ChannelHandle>::Log(const param_type& p,
erg@google.com8aca7272010-08-19 03:33:57 +09001055 std::string* l) {
sammc5aeaa8a2016-11-14 12:29:08 +09001056 l->append("ChannelHandle(");
1057#if defined(OS_NACL_SFI)
erg@google.come6ffcb52010-08-18 03:38:24 +09001058 ParamTraits<base::FileDescriptor>::Log(p.socket, l);
sammc5aeaa8a2016-11-14 12:29:08 +09001059#else
amistry70d63572016-06-27 15:34:42 +09001060 LogParam(p.mojo_handle, l);
sammc5aeaa8a2016-11-14 12:29:08 +09001061#endif
erg@google.com8aca7272010-08-19 03:33:57 +09001062 l->append(")");
erg@google.come6ffcb52010-08-18 03:38:24 +09001063}
1064
rockot15c8ac42016-02-05 11:12:32 +09001065void ParamTraits<LogData>::GetSize(base::PickleSizer* sizer,
1066 const param_type& p) {
1067 GetParamSize(sizer, p.channel);
1068 GetParamSize(sizer, p.routing_id);
1069 GetParamSize(sizer, p.type);
1070 GetParamSize(sizer, p.flags);
1071 GetParamSize(sizer, p.sent);
1072 GetParamSize(sizer, p.receive);
1073 GetParamSize(sizer, p.dispatch);
1074 GetParamSize(sizer, p.message_name);
1075 GetParamSize(sizer, p.params);
1076}
1077
rockot6dbfea52016-02-04 05:20:16 +09001078void ParamTraits<LogData>::Write(base::Pickle* m, const param_type& p) {
erg@google.com20b66e32010-10-01 05:06:30 +09001079 WriteParam(m, p.channel);
1080 WriteParam(m, p.routing_id);
jam@chromium.org1d8d4d12011-10-18 07:15:27 +09001081 WriteParam(m, p.type);
erg@google.com20b66e32010-10-01 05:06:30 +09001082 WriteParam(m, p.flags);
1083 WriteParam(m, p.sent);
1084 WriteParam(m, p.receive);
1085 WriteParam(m, p.dispatch);
tsepez@chromium.org6639c182012-11-15 12:17:45 +09001086 WriteParam(m, p.message_name);
erg@google.com20b66e32010-10-01 05:06:30 +09001087 WriteParam(m, p.params);
1088}
1089
rockot6dbfea52016-02-04 05:20:16 +09001090bool ParamTraits<LogData>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +09001091 base::PickleIterator* iter,
jbates@chromium.org0fc87362012-03-08 05:42:56 +09001092 param_type* r) {
jam@chromium.org1d8d4d12011-10-18 07:15:27 +09001093 return
erg@google.com20b66e32010-10-01 05:06:30 +09001094 ReadParam(m, iter, &r->channel) &&
1095 ReadParam(m, iter, &r->routing_id) &&
jam@chromium.org1d8d4d12011-10-18 07:15:27 +09001096 ReadParam(m, iter, &r->type) &&
erg@google.com20b66e32010-10-01 05:06:30 +09001097 ReadParam(m, iter, &r->flags) &&
1098 ReadParam(m, iter, &r->sent) &&
1099 ReadParam(m, iter, &r->receive) &&
1100 ReadParam(m, iter, &r->dispatch) &&
tsepez@chromium.org6639c182012-11-15 12:17:45 +09001101 ReadParam(m, iter, &r->message_name) &&
erg@google.com20b66e32010-10-01 05:06:30 +09001102 ReadParam(m, iter, &r->params);
erg@google.com20b66e32010-10-01 05:06:30 +09001103}
1104
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001105void ParamTraits<LogData>::Log(const param_type& p, std::string* l) {
1106 // Doesn't make sense to implement this!
1107}
1108
rockot6dbfea52016-02-04 05:20:16 +09001109void ParamTraits<Message>::Write(base::Pickle* m, const Message& p) {
brettw@chromium.orgf48910a2012-06-29 09:05:04 +09001110#if defined(OS_POSIX)
1111 // We don't serialize the file descriptors in the nested message, so there
1112 // better not be any.
morrita7d1bfcc2015-01-31 14:45:42 +09001113 DCHECK(!p.HasAttachments());
brettw@chromium.orgf48910a2012-06-29 09:05:04 +09001114#endif
1115
1116 // Don't just write out the message. This is used to send messages between
1117 // NaCl (Posix environment) and the browser (could be on Windows). The message
1118 // header formats differ between these systems (so does handle sharing, but
1119 // we already asserted we don't have any handles). So just write out the
1120 // parts of the header we use.
1121 //
1122 // Be careful also to use only explicitly-sized types. The NaCl environment
1123 // could be 64-bit and the host browser could be 32-bits. The nested message
1124 // may or may not be safe to send between 32-bit and 64-bit systems, but we
1125 // leave that up to the code sending the message to ensure.
tfarina1cbfa082015-09-05 03:47:57 +09001126 m->WriteUInt32(static_cast<uint32_t>(p.routing_id()));
brettw@chromium.orgf48910a2012-06-29 09:05:04 +09001127 m->WriteUInt32(p.type());
1128 m->WriteUInt32(p.flags());
tfarina1cbfa082015-09-05 03:47:57 +09001129 m->WriteData(p.payload(), static_cast<uint32_t>(p.payload_size()));
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001130}
1131
rockot6dbfea52016-02-04 05:20:16 +09001132bool ParamTraits<Message>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +09001133 base::PickleIterator* iter,
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001134 Message* r) {
tfarina1cbfa082015-09-05 03:47:57 +09001135 uint32_t routing_id, type, flags;
avic9f0ad02014-12-29 08:31:48 +09001136 if (!iter->ReadUInt32(&routing_id) ||
1137 !iter->ReadUInt32(&type) ||
1138 !iter->ReadUInt32(&flags))
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001139 return false;
brettw@chromium.orgf48910a2012-06-29 09:05:04 +09001140
1141 int payload_size;
1142 const char* payload;
avic9f0ad02014-12-29 08:31:48 +09001143 if (!iter->ReadData(&payload, &payload_size))
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001144 return false;
brettw@chromium.orgf48910a2012-06-29 09:05:04 +09001145
tfarina1cbfa082015-09-05 03:47:57 +09001146 r->SetHeaderValues(static_cast<int32_t>(routing_id), type, flags);
brettw@chromium.orgf48910a2012-06-29 09:05:04 +09001147 return r->WriteBytes(payload, payload_size);
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001148}
1149
1150void ParamTraits<Message>::Log(const Message& p, std::string* l) {
1151 l->append("<IPC::Message>");
1152}
1153
1154#if defined(OS_WIN)
rockot15c8ac42016-02-05 11:12:32 +09001155void ParamTraits<HANDLE>::GetSize(base::PickleSizer* sizer,
1156 const param_type& p) {
1157 sizer->AddInt();
1158}
1159
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001160// Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
jschuh@chromium.orgfb87c342013-03-04 11:29:03 +09001161// bit systems. That's why we use the Windows macros to convert to 32 bits.
rockot6dbfea52016-02-04 05:20:16 +09001162void ParamTraits<HANDLE>::Write(base::Pickle* m, const param_type& p) {
jschuh@chromium.orgfb87c342013-03-04 11:29:03 +09001163 m->WriteInt(HandleToLong(p));
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001164}
1165
rockot6dbfea52016-02-04 05:20:16 +09001166bool ParamTraits<HANDLE>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +09001167 base::PickleIterator* iter,
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001168 param_type* r) {
tfarina1cbfa082015-09-05 03:47:57 +09001169 int32_t temp;
avic9f0ad02014-12-29 08:31:48 +09001170 if (!iter->ReadInt(&temp))
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001171 return false;
jschuh@chromium.orgfb87c342013-03-04 11:29:03 +09001172 *r = LongToHandle(temp);
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001173 return true;
1174}
1175
1176void ParamTraits<HANDLE>::Log(const param_type& p, std::string* l) {
brucedawsond7e5dfd2015-10-07 04:22:00 +09001177 l->append(base::StringPrintf("0x%p", p));
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001178}
1179
rockot15c8ac42016-02-05 11:12:32 +09001180void ParamTraits<LOGFONT>::GetSize(base::PickleSizer* sizer,
1181 const param_type& p) {
1182 sizer->AddData(sizeof(LOGFONT));
1183}
1184
rockot6dbfea52016-02-04 05:20:16 +09001185void ParamTraits<LOGFONT>::Write(base::Pickle* m, const param_type& p) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001186 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
1187}
1188
rockot6dbfea52016-02-04 05:20:16 +09001189bool ParamTraits<LOGFONT>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +09001190 base::PickleIterator* iter,
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001191 param_type* r) {
1192 const char *data;
1193 int data_size = 0;
avic9f0ad02014-12-29 08:31:48 +09001194 if (iter->ReadData(&data, &data_size) && data_size == sizeof(LOGFONT)) {
jschuh@chromium.orgb9ee7d62012-11-21 09:58:00 +09001195 const LOGFONT *font = reinterpret_cast<LOGFONT*>(const_cast<char*>(data));
1196 if (_tcsnlen(font->lfFaceName, LF_FACESIZE) < LF_FACESIZE) {
1197 memcpy(r, data, sizeof(LOGFONT));
1198 return true;
1199 }
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001200 }
1201
jschuh@chromium.orgb9ee7d62012-11-21 09:58:00 +09001202 NOTREACHED();
1203 return false;
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001204}
1205
1206void ParamTraits<LOGFONT>::Log(const param_type& p, std::string* l) {
groby@chromium.org6b4dc5e2013-03-19 07:33:04 +09001207 l->append(base::StringPrintf("<LOGFONT>"));
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001208}
1209
rockot15c8ac42016-02-05 11:12:32 +09001210void ParamTraits<MSG>::GetSize(base::PickleSizer* sizer, const param_type& p) {
1211 sizer->AddData(sizeof(MSG));
1212}
1213
rockot6dbfea52016-02-04 05:20:16 +09001214void ParamTraits<MSG>::Write(base::Pickle* m, const param_type& p) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001215 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
1216}
1217
rockot6dbfea52016-02-04 05:20:16 +09001218bool ParamTraits<MSG>::Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +09001219 base::PickleIterator* iter,
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001220 param_type* r) {
1221 const char *data;
1222 int data_size = 0;
avic9f0ad02014-12-29 08:31:48 +09001223 bool result = iter->ReadData(&data, &data_size);
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001224 if (result && data_size == sizeof(MSG)) {
1225 memcpy(r, data, sizeof(MSG));
1226 } else {
1227 result = false;
1228 NOTREACHED();
1229 }
1230
1231 return result;
1232}
1233
1234void ParamTraits<MSG>::Log(const param_type& p, std::string* l) {
1235 l->append("<MSG>");
1236}
1237
1238#endif // OS_WIN
1239
agl@chromium.org1c6dcf22009-07-23 08:57:21 +09001240} // namespace IPC