blob: ea88b55a2a5129260bdc984b35e97ee0171b9ad5 [file] [log] [blame]
[email protected]a7c03d4f32012-01-24 02:36:051// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]946d1b22009-07-22 23:57:212// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ipc/ipc_message_utils.h"
6
avi246998d82015-12-22 02:39:047#include <stddef.h>
8#include <stdint.h>
9
[email protected]57999812013-02-24 05:40:5210#include "base/files/file_path.h"
[email protected]93d49d72009-10-23 20:00:2011#include "base/json/json_writer.h"
[email protected]3b63f8f42011-03-28 01:54:1512#include "base/memory/scoped_ptr.h"
[email protected]0238a162013-06-13 13:47:4613#include "base/strings/nullable_string16.h"
[email protected]4aa794a12013-06-11 06:32:1814#include "base/strings/string_number_conversions.h"
[email protected]906265872013-06-07 22:40:4515#include "base/strings/utf_string_conversions.h"
[email protected]b43e5562013-06-28 15:20:0216#include "base/time/time.h"
[email protected]946d1b22009-07-22 23:57:2117#include "base/values.h"
avi246998d82015-12-22 02:39:0418#include "build/build_config.h"
[email protected]bf5aedf02012-06-04 21:18:2519#include "ipc/ipc_channel_handle.h"
morrita1aa788c2015-01-31 05:45:4220#include "ipc/ipc_message_attachment.h"
morrita4b5c28e22015-01-14 21:17:0621#include "ipc/ipc_message_attachment_set.h"
[email protected]bf5aedf02012-06-04 21:18:2522
morrita1aa788c2015-01-31 05:45:4223#if defined(OS_POSIX)
24#include "ipc/ipc_platform_file_attachment_posix.h"
25#endif
26
erikchen5ea2ab72015-09-25 22:34:3127#if (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
scottmgd19b4f72015-06-19 22:51:0028#include "base/memory/shared_memory_handle.h"
erikchen5ea2ab72015-09-25 22:34:3129#endif // (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
scottmgd19b4f72015-06-19 22:51:0030
erikchenaf8299d2015-10-09 19:12:0631#if defined(OS_MACOSX) && !defined(OS_IOS)
32#include "ipc/mach_port_mac.h"
33#endif
34
morrita4b5c28e22015-01-14 21:17:0635#if defined(OS_WIN)
[email protected]2e02cfe82012-11-21 00:58:0036#include <tchar.h>
erikchen5ea2ab72015-09-25 22:34:3137#include "ipc/handle_win.h"
[email protected]7a4de7a62010-08-17 18:38:2438#endif
[email protected]946d1b22009-07-22 23:57:2139
40namespace IPC {
41
[email protected]bf5aedf02012-06-04 21:18:2542namespace {
43
[email protected]946d1b22009-07-22 23:57:2144const int kMaxRecursionDepth = 100;
45
[email protected]bf5aedf02012-06-04 21:18:2546template<typename CharType>
47void LogBytes(const std::vector<CharType>& data, std::string* out) {
48#if defined(OS_WIN)
49 // Windows has a GUI for logging, which can handle arbitrary binary data.
50 for (size_t i = 0; i < data.size(); ++i)
51 out->push_back(data[i]);
52#else
53 // On POSIX, we log to stdout, which we assume can display ASCII.
54 static const size_t kMaxBytesToLog = 100;
55 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
56 if (isprint(data[i]))
57 out->push_back(data[i]);
58 else
[email protected]7d3cbc92013-03-18 22:33:0459 out->append(
60 base::StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
[email protected]bf5aedf02012-06-04 21:18:2561 }
62 if (data.size() > kMaxBytesToLog) {
[email protected]f8660f82013-03-30 17:29:2863 out->append(base::StringPrintf(
64 " and %u more bytes",
65 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
[email protected]bf5aedf02012-06-04 21:18:2566 }
67#endif
68}
[email protected]946d1b22009-07-22 23:57:2169
brettwbd4d7112015-06-03 04:29:2570bool ReadValue(const Message* m,
71 base::PickleIterator* iter,
72 base::Value** value,
[email protected]bf5aedf02012-06-04 21:18:2573 int recursion);
[email protected]946d1b22009-07-22 23:57:2174
[email protected]ea5ef4c2013-06-13 22:50:2775void WriteValue(Message* m, const base::Value* value, int recursion) {
[email protected]dbc761a2012-07-26 01:29:2176 bool result;
[email protected]946d1b22009-07-22 23:57:2177 if (recursion > kMaxRecursionDepth) {
78 LOG(WARNING) << "Max recursion depth hit in WriteValue.";
79 return;
80 }
81
82 m->WriteInt(value->GetType());
83
84 switch (value->GetType()) {
[email protected]ea5ef4c2013-06-13 22:50:2785 case base::Value::TYPE_NULL:
[email protected]946d1b22009-07-22 23:57:2186 break;
[email protected]ea5ef4c2013-06-13 22:50:2787 case base::Value::TYPE_BOOLEAN: {
[email protected]946d1b22009-07-22 23:57:2188 bool val;
[email protected]dbc761a2012-07-26 01:29:2189 result = value->GetAsBoolean(&val);
90 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:2191 WriteParam(m, val);
92 break;
93 }
[email protected]ea5ef4c2013-06-13 22:50:2794 case base::Value::TYPE_INTEGER: {
[email protected]946d1b22009-07-22 23:57:2195 int val;
[email protected]dbc761a2012-07-26 01:29:2196 result = value->GetAsInteger(&val);
97 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:2198 WriteParam(m, val);
99 break;
100 }
[email protected]ea5ef4c2013-06-13 22:50:27101 case base::Value::TYPE_DOUBLE: {
[email protected]946d1b22009-07-22 23:57:21102 double val;
[email protected]dbc761a2012-07-26 01:29:21103 result = value->GetAsDouble(&val);
104 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21105 WriteParam(m, val);
106 break;
107 }
[email protected]ea5ef4c2013-06-13 22:50:27108 case base::Value::TYPE_STRING: {
[email protected]946d1b22009-07-22 23:57:21109 std::string val;
[email protected]dbc761a2012-07-26 01:29:21110 result = value->GetAsString(&val);
111 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:21112 WriteParam(m, val);
113 break;
114 }
[email protected]ea5ef4c2013-06-13 22:50:27115 case base::Value::TYPE_BINARY: {
[email protected]b59ea312011-08-05 18:20:05116 const base::BinaryValue* binary =
117 static_cast<const base::BinaryValue*>(value);
[email protected]7ee1a44c2010-07-23 14:18:59118 m->WriteData(binary->GetBuffer(), static_cast<int>(binary->GetSize()));
[email protected]e4dad9fb2009-10-06 18:15:58119 break;
[email protected]946d1b22009-07-22 23:57:21120 }
[email protected]ea5ef4c2013-06-13 22:50:27121 case base::Value::TYPE_DICTIONARY: {
122 const base::DictionaryValue* dict =
123 static_cast<const base::DictionaryValue*>(value);
[email protected]946d1b22009-07-22 23:57:21124
[email protected]4dad9ad82009-11-25 20:47:52125 WriteParam(m, static_cast<int>(dict->size()));
[email protected]946d1b22009-07-22 23:57:21126
[email protected]ea5ef4c2013-06-13 22:50:27127 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd();
128 it.Advance()) {
[email protected]a899c0b02013-01-18 14:43:27129 WriteParam(m, it.key());
130 WriteValue(m, &it.value(), recursion + 1);
[email protected]946d1b22009-07-22 23:57:21131 }
132 break;
133 }
[email protected]ea5ef4c2013-06-13 22:50:27134 case base::Value::TYPE_LIST: {
135 const base::ListValue* list = static_cast<const base::ListValue*>(value);
[email protected]946d1b22009-07-22 23:57:21136 WriteParam(m, static_cast<int>(list->GetSize()));
[email protected]ea5ef4c2013-06-13 22:50:27137 for (base::ListValue::const_iterator it = list->begin();
138 it != list->end(); ++it) {
[email protected]a899c0b02013-01-18 14:43:27139 WriteValue(m, *it, recursion + 1);
[email protected]946d1b22009-07-22 23:57:21140 }
141 break;
142 }
143 }
144}
145
146// Helper for ReadValue that reads a DictionaryValue into a pre-allocated
147// object.
brettwbd4d7112015-06-03 04:29:25148bool ReadDictionaryValue(const Message* m,
149 base::PickleIterator* iter,
150 base::DictionaryValue* value,
151 int recursion) {
[email protected]946d1b22009-07-22 23:57:21152 int size;
153 if (!ReadParam(m, iter, &size))
154 return false;
155
156 for (int i = 0; i < size; ++i) {
[email protected]e7b418b2010-07-30 19:47:47157 std::string key;
[email protected]0c6c1e42013-06-21 19:42:19158 base::Value* subval;
[email protected]946d1b22009-07-22 23:57:21159 if (!ReadParam(m, iter, &key) ||
160 !ReadValue(m, iter, &subval, recursion + 1))
161 return false;
[email protected]d8b4aa42011-08-19 05:59:57162 value->SetWithoutPathExpansion(key, subval);
[email protected]946d1b22009-07-22 23:57:21163 }
164
165 return true;
166}
167
168// Helper for ReadValue that reads a ReadListValue into a pre-allocated
169// object.
brettwbd4d7112015-06-03 04:29:25170bool ReadListValue(const Message* m,
171 base::PickleIterator* iter,
172 base::ListValue* value,
173 int recursion) {
[email protected]946d1b22009-07-22 23:57:21174 int size;
175 if (!ReadParam(m, iter, &size))
176 return false;
177
178 for (int i = 0; i < size; ++i) {
[email protected]ea5ef4c2013-06-13 22:50:27179 base::Value* subval;
[email protected]946d1b22009-07-22 23:57:21180 if (!ReadValue(m, iter, &subval, recursion + 1))
181 return false;
182 value->Set(i, subval);
183 }
184
185 return true;
186}
187
brettwbd4d7112015-06-03 04:29:25188bool ReadValue(const Message* m,
189 base::PickleIterator* iter,
190 base::Value** value,
[email protected]bf5aedf02012-06-04 21:18:25191 int recursion) {
[email protected]946d1b22009-07-22 23:57:21192 if (recursion > kMaxRecursionDepth) {
193 LOG(WARNING) << "Max recursion depth hit in ReadValue.";
194 return false;
195 }
196
197 int type;
198 if (!ReadParam(m, iter, &type))
199 return false;
200
201 switch (type) {
[email protected]ea5ef4c2013-06-13 22:50:27202 case base::Value::TYPE_NULL:
estadea68b0442015-05-12 18:11:50203 *value = base::Value::CreateNullValue().release();
[email protected]946d1b22009-07-22 23:57:21204 break;
[email protected]ea5ef4c2013-06-13 22:50:27205 case base::Value::TYPE_BOOLEAN: {
[email protected]946d1b22009-07-22 23:57:21206 bool val;
207 if (!ReadParam(m, iter, &val))
208 return false;
[email protected]4038a132013-01-30 05:24:07209 *value = new base::FundamentalValue(val);
[email protected]946d1b22009-07-22 23:57:21210 break;
211 }
[email protected]ea5ef4c2013-06-13 22:50:27212 case base::Value::TYPE_INTEGER: {
[email protected]946d1b22009-07-22 23:57:21213 int val;
214 if (!ReadParam(m, iter, &val))
215 return false;
[email protected]4038a132013-01-30 05:24:07216 *value = new base::FundamentalValue(val);
[email protected]946d1b22009-07-22 23:57:21217 break;
218 }
[email protected]ea5ef4c2013-06-13 22:50:27219 case base::Value::TYPE_DOUBLE: {
[email protected]946d1b22009-07-22 23:57:21220 double val;
221 if (!ReadParam(m, iter, &val))
222 return false;
[email protected]4038a132013-01-30 05:24:07223 *value = new base::FundamentalValue(val);
[email protected]946d1b22009-07-22 23:57:21224 break;
225 }
[email protected]ea5ef4c2013-06-13 22:50:27226 case base::Value::TYPE_STRING: {
[email protected]946d1b22009-07-22 23:57:21227 std::string val;
228 if (!ReadParam(m, iter, &val))
229 return false;
[email protected]4038a132013-01-30 05:24:07230 *value = new base::StringValue(val);
[email protected]946d1b22009-07-22 23:57:21231 break;
232 }
[email protected]ea5ef4c2013-06-13 22:50:27233 case base::Value::TYPE_BINARY: {
[email protected]e4dad9fb2009-10-06 18:15:58234 const char* data;
235 int length;
avi48fc13b2014-12-28 23:31:48236 if (!iter->ReadData(&data, &length))
[email protected]e4dad9fb2009-10-06 18:15:58237 return false;
[email protected]b59ea312011-08-05 18:20:05238 *value = base::BinaryValue::CreateWithCopiedBuffer(data, length);
[email protected]946d1b22009-07-22 23:57:21239 break;
240 }
[email protected]ea5ef4c2013-06-13 22:50:27241 case base::Value::TYPE_DICTIONARY: {
242 scoped_ptr<base::DictionaryValue> val(new base::DictionaryValue());
[email protected]946d1b22009-07-22 23:57:21243 if (!ReadDictionaryValue(m, iter, val.get(), recursion))
244 return false;
245 *value = val.release();
246 break;
247 }
[email protected]ea5ef4c2013-06-13 22:50:27248 case base::Value::TYPE_LIST: {
249 scoped_ptr<base::ListValue> val(new base::ListValue());
[email protected]946d1b22009-07-22 23:57:21250 if (!ReadListValue(m, iter, val.get(), recursion))
251 return false;
252 *value = val.release();
253 break;
254 }
[email protected]e4dad9fb2009-10-06 18:15:58255 default:
[email protected]946d1b22009-07-22 23:57:21256 return false;
257 }
258
259 return true;
260}
261
[email protected]bf5aedf02012-06-04 21:18:25262} // namespace
263
264// -----------------------------------------------------------------------------
265
266LogData::LogData()
267 : routing_id(0),
268 type(0),
269 sent(0),
270 receive(0),
271 dispatch(0) {
272}
273
274LogData::~LogData() {
275}
276
[email protected]bf5aedf02012-06-04 21:18:25277void ParamTraits<bool>::Log(const param_type& p, std::string* l) {
278 l->append(p ? "true" : "false");
279}
280
ortuno19ecf1842015-10-30 00:46:20281void ParamTraits<signed char>::Write(Message* m, const param_type& p) {
282 m->WriteBytes(&p, sizeof(param_type));
283}
284
285bool ParamTraits<signed char>::Read(const Message* m,
286 base::PickleIterator* iter,
287 param_type* r) {
288 const char* data;
289 if (!iter->ReadBytes(&data, sizeof(param_type)))
290 return false;
291 memcpy(r, data, sizeof(param_type));
292 return true;
293}
294
295void ParamTraits<signed char>::Log(const param_type& p, std::string* l) {
296 l->append(base::IntToString(p));
297}
298
[email protected]c1ee48d2013-07-12 23:12:28299void ParamTraits<unsigned char>::Write(Message* m, const param_type& p) {
300 m->WriteBytes(&p, sizeof(param_type));
301}
302
brettwbd4d7112015-06-03 04:29:25303bool ParamTraits<unsigned char>::Read(const Message* m,
304 base::PickleIterator* iter,
305 param_type* r) {
[email protected]c1ee48d2013-07-12 23:12:28306 const char* data;
avi48fc13b2014-12-28 23:31:48307 if (!iter->ReadBytes(&data, sizeof(param_type)))
[email protected]c1ee48d2013-07-12 23:12:28308 return false;
309 memcpy(r, data, sizeof(param_type));
310 return true;
311}
312
313void ParamTraits<unsigned char>::Log(const param_type& p, std::string* l) {
314 l->append(base::UintToString(p));
315}
316
317void ParamTraits<unsigned short>::Write(Message* m, const param_type& p) {
318 m->WriteBytes(&p, sizeof(param_type));
319}
320
brettwbd4d7112015-06-03 04:29:25321bool ParamTraits<unsigned short>::Read(const Message* m,
322 base::PickleIterator* iter,
[email protected]c1ee48d2013-07-12 23:12:28323 param_type* r) {
324 const char* data;
avi48fc13b2014-12-28 23:31:48325 if (!iter->ReadBytes(&data, sizeof(param_type)))
[email protected]c1ee48d2013-07-12 23:12:28326 return false;
327 memcpy(r, data, sizeof(param_type));
328 return true;
329}
330
331void ParamTraits<unsigned short>::Log(const param_type& p, std::string* l) {
332 l->append(base::UintToString(p));
333}
334
[email protected]252cad62010-08-18 18:33:57335void ParamTraits<int>::Log(const param_type& p, std::string* l) {
336 l->append(base::IntToString(p));
337}
338
339void ParamTraits<unsigned int>::Log(const param_type& p, std::string* l) {
340 l->append(base::UintToString(p));
341}
342
343void ParamTraits<long>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:57344 l->append(base::Int64ToString(static_cast<int64_t>(p)));
[email protected]252cad62010-08-18 18:33:57345}
346
347void ParamTraits<unsigned long>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:57348 l->append(base::Uint64ToString(static_cast<uint64_t>(p)));
[email protected]252cad62010-08-18 18:33:57349}
350
351void ParamTraits<long long>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:57352 l->append(base::Int64ToString(static_cast<int64_t>(p)));
[email protected]252cad62010-08-18 18:33:57353}
354
355void ParamTraits<unsigned long long>::Log(const param_type& p, std::string* l) {
356 l->append(base::Uint64ToString(p));
357}
[email protected]7a4de7a62010-08-17 18:38:24358
[email protected]bf5aedf02012-06-04 21:18:25359void ParamTraits<float>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:04360 l->append(base::StringPrintf("%e", p));
[email protected]7a4de7a62010-08-17 18:38:24361}
362
[email protected]bf5aedf02012-06-04 21:18:25363void ParamTraits<double>::Write(Message* m, const param_type& p) {
[email protected]48328ff2013-10-31 09:27:31364 m->WriteBytes(reinterpret_cast<const char*>(&p), sizeof(param_type));
[email protected]d84e48b2010-10-21 22:04:52365}
366
brettwbd4d7112015-06-03 04:29:25367bool ParamTraits<double>::Read(const Message* m,
368 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25369 param_type* r) {
370 const char *data;
avi48fc13b2014-12-28 23:31:48371 if (!iter->ReadBytes(&data, sizeof(*r))) {
[email protected]bf5aedf02012-06-04 21:18:25372 NOTREACHED();
373 return false;
374 }
375 memcpy(r, data, sizeof(param_type));
376 return true;
[email protected]d84e48b2010-10-21 22:04:52377}
378
[email protected]bf5aedf02012-06-04 21:18:25379void ParamTraits<double>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:04380 l->append(base::StringPrintf("%e", p));
[email protected]1d14f582011-09-02 20:42:04381}
382
[email protected]bf5aedf02012-06-04 21:18:25383
384void ParamTraits<std::string>::Log(const param_type& p, std::string* l) {
385 l->append(p);
[email protected]1d14f582011-09-02 20:42:04386}
387
[email protected]476dafb2013-12-03 00:39:26388void ParamTraits<base::string16>::Log(const param_type& p, std::string* l) {
[email protected]ad65a3e2013-12-25 18:18:01389 l->append(base::UTF16ToUTF8(p));
[email protected]bf5aedf02012-06-04 21:18:25390}
[email protected]bf5aedf02012-06-04 21:18:25391
392void ParamTraits<std::vector<char> >::Write(Message* m, const param_type& p) {
393 if (p.empty()) {
394 m->WriteData(NULL, 0);
395 } else {
396 m->WriteData(&p.front(), static_cast<int>(p.size()));
397 }
398}
399
brettwbd4d7112015-06-03 04:29:25400bool ParamTraits<std::vector<char>>::Read(const Message* m,
401 base::PickleIterator* iter,
402 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25403 const char *data;
404 int data_size = 0;
avi48fc13b2014-12-28 23:31:48405 if (!iter->ReadData(&data, &data_size) || data_size < 0)
[email protected]bf5aedf02012-06-04 21:18:25406 return false;
407 r->resize(data_size);
408 if (data_size)
409 memcpy(&r->front(), data, data_size);
410 return true;
411}
412
413void ParamTraits<std::vector<char> >::Log(const param_type& p, std::string* l) {
414 LogBytes(p, l);
415}
416
417void ParamTraits<std::vector<unsigned char> >::Write(Message* m,
418 const param_type& p) {
419 if (p.empty()) {
420 m->WriteData(NULL, 0);
421 } else {
422 m->WriteData(reinterpret_cast<const char*>(&p.front()),
423 static_cast<int>(p.size()));
424 }
425}
426
brettwbd4d7112015-06-03 04:29:25427bool ParamTraits<std::vector<unsigned char>>::Read(const Message* m,
428 base::PickleIterator* iter,
429 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25430 const char *data;
431 int data_size = 0;
avi48fc13b2014-12-28 23:31:48432 if (!iter->ReadData(&data, &data_size) || data_size < 0)
[email protected]bf5aedf02012-06-04 21:18:25433 return false;
434 r->resize(data_size);
435 if (data_size)
436 memcpy(&r->front(), data, data_size);
437 return true;
438}
439
440void ParamTraits<std::vector<unsigned char> >::Log(const param_type& p,
441 std::string* l) {
442 LogBytes(p, l);
443}
444
445void ParamTraits<std::vector<bool> >::Write(Message* m, const param_type& p) {
446 WriteParam(m, static_cast<int>(p.size()));
[email protected]d4124852013-03-20 20:25:00447 // Cast to bool below is required because libc++'s
448 // vector<bool>::const_reference is different from bool, and we want to avoid
449 // writing an extra specialization of ParamTraits for it.
[email protected]bf5aedf02012-06-04 21:18:25450 for (size_t i = 0; i < p.size(); i++)
[email protected]d4124852013-03-20 20:25:00451 WriteParam(m, static_cast<bool>(p[i]));
[email protected]bf5aedf02012-06-04 21:18:25452}
453
brettwbd4d7112015-06-03 04:29:25454bool ParamTraits<std::vector<bool>>::Read(const Message* m,
455 base::PickleIterator* iter,
456 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25457 int size;
458 // ReadLength() checks for < 0 itself.
avi48fc13b2014-12-28 23:31:48459 if (!iter->ReadLength(&size))
[email protected]bf5aedf02012-06-04 21:18:25460 return false;
461 r->resize(size);
462 for (int i = 0; i < size; i++) {
463 bool value;
464 if (!ReadParam(m, iter, &value))
465 return false;
466 (*r)[i] = value;
467 }
468 return true;
469}
470
471void ParamTraits<std::vector<bool> >::Log(const param_type& p, std::string* l) {
472 for (size_t i = 0; i < p.size(); ++i) {
473 if (i != 0)
474 l->push_back(' ');
[email protected]d4124852013-03-20 20:25:00475 LogParam(static_cast<bool>(p[i]), l);
[email protected]bf5aedf02012-06-04 21:18:25476 }
[email protected]d84e48b2010-10-21 22:04:52477}
478
erikcheneece6c32015-07-07 22:13:11479void ParamTraits<BrokerableAttachment::AttachmentId>::Write(
480 Message* m,
481 const param_type& p) {
erikchen06faf0c2015-08-27 19:49:58482 m->WriteBytes(p.nonce, BrokerableAttachment::kNonceSize);
erikcheneece6c32015-07-07 22:13:11483}
484
485bool ParamTraits<BrokerableAttachment::AttachmentId>::Read(
486 const Message* m,
487 base::PickleIterator* iter,
488 param_type* r) {
489 const char* data;
erikchen06faf0c2015-08-27 19:49:58490 if (!iter->ReadBytes(&data, BrokerableAttachment::kNonceSize))
erikcheneece6c32015-07-07 22:13:11491 return false;
492 memcpy(r->nonce, data, BrokerableAttachment::kNonceSize);
493 return true;
494}
495
496void ParamTraits<BrokerableAttachment::AttachmentId>::Log(const param_type& p,
497 std::string* l) {
498 l->append(base::HexEncode(p.nonce, BrokerableAttachment::kNonceSize));
499}
500
[email protected]ea5ef4c2013-06-13 22:50:27501void ParamTraits<base::DictionaryValue>::Write(Message* m,
502 const param_type& p) {
[email protected]946d1b22009-07-22 23:57:21503 WriteValue(m, &p, 0);
504}
505
brettwbd4d7112015-06-03 04:29:25506bool ParamTraits<base::DictionaryValue>::Read(const Message* m,
507 base::PickleIterator* iter,
508 param_type* r) {
[email protected]946d1b22009-07-22 23:57:21509 int type;
[email protected]0c6c1e42013-06-21 19:42:19510 if (!ReadParam(m, iter, &type) || type != base::Value::TYPE_DICTIONARY)
[email protected]946d1b22009-07-22 23:57:21511 return false;
512
513 return ReadDictionaryValue(m, iter, r, 0);
514}
515
[email protected]ea5ef4c2013-06-13 22:50:27516void ParamTraits<base::DictionaryValue>::Log(const param_type& p,
517 std::string* l) {
[email protected]946d1b22009-07-22 23:57:21518 std::string json;
estade8d046462015-05-16 01:02:34519 base::JSONWriter::Write(p, &json);
[email protected]252cad62010-08-18 18:33:57520 l->append(json);
[email protected]946d1b22009-07-22 23:57:21521}
522
[email protected]7a4de7a62010-08-17 18:38:24523#if defined(OS_POSIX)
524void ParamTraits<base::FileDescriptor>::Write(Message* m, const param_type& p) {
525 const bool valid = p.fd >= 0;
526 WriteParam(m, valid);
527
morrita96693852014-09-24 20:11:45528 if (!valid)
529 return;
530
531 if (p.auto_close) {
morrita1aa788c2015-01-31 05:45:42532 if (!m->WriteAttachment(
533 new internal::PlatformFileAttachment(base::ScopedFD(p.fd))))
morrita96693852014-09-24 20:11:45534 NOTREACHED();
535 } else {
morrita1aa788c2015-01-31 05:45:42536 if (!m->WriteAttachment(new internal::PlatformFileAttachment(p.fd)))
[email protected]7a4de7a62010-08-17 18:38:24537 NOTREACHED();
538 }
539}
540
[email protected]ce208f872012-03-07 20:42:56541bool ParamTraits<base::FileDescriptor>::Read(const Message* m,
brettwbd4d7112015-06-03 04:29:25542 base::PickleIterator* iter,
[email protected]7a4de7a62010-08-17 18:38:24543 param_type* r) {
morrita96693852014-09-24 20:11:45544 *r = base::FileDescriptor();
545
[email protected]7a4de7a62010-08-17 18:38:24546 bool valid;
547 if (!ReadParam(m, iter, &valid))
548 return false;
549
morrita96693852014-09-24 20:11:45550 // TODO(morrita): Seems like this should return false.
551 if (!valid)
[email protected]7a4de7a62010-08-17 18:38:24552 return true;
[email protected]7a4de7a62010-08-17 18:38:24553
morrita1aa788c2015-01-31 05:45:42554 scoped_refptr<MessageAttachment> attachment;
555 if (!m->ReadAttachment(iter, &attachment))
morrita96693852014-09-24 20:11:45556 return false;
557
morrita1aa788c2015-01-31 05:45:42558 *r = base::FileDescriptor(attachment->TakePlatformFile(), true);
morrita96693852014-09-24 20:11:45559 return true;
[email protected]7a4de7a62010-08-17 18:38:24560}
561
562void ParamTraits<base::FileDescriptor>::Log(const param_type& p,
[email protected]252cad62010-08-18 18:33:57563 std::string* l) {
[email protected]7a4de7a62010-08-17 18:38:24564 if (p.auto_close) {
[email protected]7d3cbc92013-03-18 22:33:04565 l->append(base::StringPrintf("FD(%d auto-close)", p.fd));
[email protected]7a4de7a62010-08-17 18:38:24566 } else {
[email protected]7d3cbc92013-03-18 22:33:04567 l->append(base::StringPrintf("FD(%d)", p.fd));
[email protected]7a4de7a62010-08-17 18:38:24568 }
569}
570#endif // defined(OS_POSIX)
571
scottmgd19b4f72015-06-19 22:51:00572#if defined(OS_MACOSX) && !defined(OS_IOS)
573void ParamTraits<base::SharedMemoryHandle>::Write(Message* m,
574 const param_type& p) {
575 m->WriteInt(p.GetType());
576
erikchen0d779702015-10-02 23:49:26577 switch (p.GetType()) {
578 case base::SharedMemoryHandle::POSIX:
579 ParamTraits<base::FileDescriptor>::Write(m, p.GetFileDescriptor());
580 break;
581 case base::SharedMemoryHandle::MACH:
erikchenaf8299d2015-10-09 19:12:06582 MachPortMac mach_port_mac(p.GetMemoryObject());
583 ParamTraits<MachPortMac>::Write(m, mach_port_mac);
584 size_t size = 0;
585 bool result = p.GetSize(&size);
586 DCHECK(result);
587 ParamTraits<size_t>::Write(m, size);
erikchen328bf3f2015-10-24 00:46:54588
589 // If the caller intended to pass ownership to the IPC stack, release a
590 // reference.
591 if (p.OwnershipPassesToIPC())
592 p.Close();
593
erikchen0d779702015-10-02 23:49:26594 break;
595 }
scottmgd19b4f72015-06-19 22:51:00596}
597
598bool ParamTraits<base::SharedMemoryHandle>::Read(const Message* m,
599 base::PickleIterator* iter,
600 param_type* r) {
601 base::SharedMemoryHandle::TypeWireFormat type;
602 if (!iter->ReadInt(&type))
603 return false;
604
605 base::SharedMemoryHandle::Type shm_type = base::SharedMemoryHandle::POSIX;
606 switch (type) {
607 case base::SharedMemoryHandle::POSIX:
608 case base::SharedMemoryHandle::MACH: {
609 shm_type = static_cast<base::SharedMemoryHandle::Type>(type);
610 break;
611 }
erikchen0d779702015-10-02 23:49:26612 default: {
scottmgd19b4f72015-06-19 22:51:00613 return false;
erikchen0d779702015-10-02 23:49:26614 }
scottmgd19b4f72015-06-19 22:51:00615 }
616
erikchen0d779702015-10-02 23:49:26617 switch (shm_type) {
618 case base::SharedMemoryHandle::POSIX: {
619 base::FileDescriptor file_descriptor;
scottmgd19b4f72015-06-19 22:51:00620
erikchen0d779702015-10-02 23:49:26621 bool success =
622 ParamTraits<base::FileDescriptor>::Read(m, iter, &file_descriptor);
623 if (!success)
624 return false;
scottmgd19b4f72015-06-19 22:51:00625
erikchen0d779702015-10-02 23:49:26626 *r = base::SharedMemoryHandle(file_descriptor.fd,
627 file_descriptor.auto_close);
628 return true;
629 }
630 case base::SharedMemoryHandle::MACH: {
erikchenaf8299d2015-10-09 19:12:06631 MachPortMac mach_port_mac;
632 if (!ParamTraits<MachPortMac>::Read(m, iter, &mach_port_mac))
633 return false;
634
635 size_t size;
636 if (!ParamTraits<size_t>::Read(m, iter, &size))
637 return false;
638
639 *r = base::SharedMemoryHandle(mach_port_mac.get_mach_port(), size,
640 base::GetCurrentProcId());
erikchen0d779702015-10-02 23:49:26641 return true;
642 }
scottmgd19b4f72015-06-19 22:51:00643 }
scottmgd19b4f72015-06-19 22:51:00644}
645
646void ParamTraits<base::SharedMemoryHandle>::Log(const param_type& p,
647 std::string* l) {
erikchen0d779702015-10-02 23:49:26648 switch (p.GetType()) {
649 case base::SharedMemoryHandle::POSIX:
650 l->append("POSIX Fd: ");
651 ParamTraits<base::FileDescriptor>::Log(p.GetFileDescriptor(), l);
652 break;
653 case base::SharedMemoryHandle::MACH:
erikchenaf8299d2015-10-09 19:12:06654 l->append("Mach port: ");
655 LogParam(p.GetMemoryObject(), l);
erikchen0d779702015-10-02 23:49:26656 break;
scottmgd19b4f72015-06-19 22:51:00657 }
658}
erikchen0d779702015-10-02 23:49:26659
erikchen5ea2ab72015-09-25 22:34:31660#elif defined(OS_WIN)
661void ParamTraits<base::SharedMemoryHandle>::Write(Message* m,
662 const param_type& p) {
erikchen5ea2ab72015-09-25 22:34:31663 m->WriteBool(p.NeedsBrokering());
664
665 if (p.NeedsBrokering()) {
666 HandleWin handle_win(p.GetHandle(), HandleWin::DUPLICATE);
667 ParamTraits<HandleWin>::Write(m, handle_win);
668 } else {
669 m->WriteInt(HandleToLong(p.GetHandle()));
670 }
671}
672
673bool ParamTraits<base::SharedMemoryHandle>::Read(const Message* m,
674 base::PickleIterator* iter,
675 param_type* r) {
erikchen5ea2ab72015-09-25 22:34:31676 bool needs_brokering;
677 if (!iter->ReadBool(&needs_brokering))
678 return false;
679
680 if (needs_brokering) {
681 HandleWin handle_win;
682 if (!ParamTraits<HandleWin>::Read(m, iter, &handle_win))
683 return false;
erikchen3d87ecf72016-01-08 02:17:04684 *r = base::SharedMemoryHandle(handle_win.get_handle(),
685 base::GetCurrentProcId());
erikchen5ea2ab72015-09-25 22:34:31686 return true;
687 }
688
689 int handle_int;
690 if (!iter->ReadInt(&handle_int))
691 return false;
692 HANDLE handle = LongToHandle(handle_int);
erikchen3d87ecf72016-01-08 02:17:04693 *r = base::SharedMemoryHandle(handle, base::GetCurrentProcId());
erikchen5ea2ab72015-09-25 22:34:31694 return true;
695}
696
697void ParamTraits<base::SharedMemoryHandle>::Log(const param_type& p,
698 std::string* l) {
erikchen5ea2ab72015-09-25 22:34:31699 LogParam(p.GetHandle(), l);
700 l->append(" needs brokering: ");
701 LogParam(p.NeedsBrokering(), l);
702}
scottmgd19b4f72015-06-19 22:51:00703#endif // defined(OS_MACOSX) && !defined(OS_IOS)
704
[email protected]6d4b67a2013-02-10 04:49:30705void ParamTraits<base::FilePath>::Write(Message* m, const param_type& p) {
[email protected]aeae59f2013-01-28 13:47:55706 p.WriteToPickle(m);
[email protected]bf5aedf02012-06-04 21:18:25707}
708
[email protected]6d4b67a2013-02-10 04:49:30709bool ParamTraits<base::FilePath>::Read(const Message* m,
brettwbd4d7112015-06-03 04:29:25710 base::PickleIterator* iter,
[email protected]6d4b67a2013-02-10 04:49:30711 param_type* r) {
[email protected]aeae59f2013-01-28 13:47:55712 return r->ReadFromPickle(iter);
[email protected]bf5aedf02012-06-04 21:18:25713}
714
[email protected]6d4b67a2013-02-10 04:49:30715void ParamTraits<base::FilePath>::Log(const param_type& p, std::string* l) {
716 ParamTraits<base::FilePath::StringType>::Log(p.value(), l);
[email protected]bf5aedf02012-06-04 21:18:25717}
718
[email protected]ea5ef4c2013-06-13 22:50:27719void ParamTraits<base::ListValue>::Write(Message* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25720 WriteValue(m, &p, 0);
721}
722
brettwbd4d7112015-06-03 04:29:25723bool ParamTraits<base::ListValue>::Read(const Message* m,
724 base::PickleIterator* iter,
725 param_type* r) {
[email protected]bf5aedf02012-06-04 21:18:25726 int type;
[email protected]0c6c1e42013-06-21 19:42:19727 if (!ReadParam(m, iter, &type) || type != base::Value::TYPE_LIST)
[email protected]bf5aedf02012-06-04 21:18:25728 return false;
729
730 return ReadListValue(m, iter, r, 0);
731}
732
[email protected]ea5ef4c2013-06-13 22:50:27733void ParamTraits<base::ListValue>::Log(const param_type& p, std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:25734 std::string json;
estade8d046462015-05-16 01:02:34735 base::JSONWriter::Write(p, &json);
[email protected]bf5aedf02012-06-04 21:18:25736 l->append(json);
737}
738
[email protected]0238a162013-06-13 13:47:46739void ParamTraits<base::NullableString16>::Write(Message* m,
740 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25741 WriteParam(m, p.string());
742 WriteParam(m, p.is_null());
743}
744
[email protected]0238a162013-06-13 13:47:46745bool ParamTraits<base::NullableString16>::Read(const Message* m,
brettwbd4d7112015-06-03 04:29:25746 base::PickleIterator* iter,
[email protected]0238a162013-06-13 13:47:46747 param_type* r) {
[email protected]476dafb2013-12-03 00:39:26748 base::string16 string;
[email protected]bf5aedf02012-06-04 21:18:25749 if (!ReadParam(m, iter, &string))
750 return false;
751 bool is_null;
752 if (!ReadParam(m, iter, &is_null))
753 return false;
[email protected]0238a162013-06-13 13:47:46754 *r = base::NullableString16(string, is_null);
[email protected]bf5aedf02012-06-04 21:18:25755 return true;
756}
757
[email protected]0238a162013-06-13 13:47:46758void ParamTraits<base::NullableString16>::Log(const param_type& p,
759 std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:25760 l->append("(");
761 LogParam(p.string(), l);
762 l->append(", ");
763 LogParam(p.is_null(), l);
764 l->append(")");
765}
766
[email protected]141bcc52014-01-27 21:36:00767void ParamTraits<base::File::Info>::Write(Message* m,
768 const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25769 WriteParam(m, p.size);
770 WriteParam(m, p.is_directory);
771 WriteParam(m, p.last_modified.ToDoubleT());
772 WriteParam(m, p.last_accessed.ToDoubleT());
773 WriteParam(m, p.creation_time.ToDoubleT());
774}
775
[email protected]141bcc52014-01-27 21:36:00776bool ParamTraits<base::File::Info>::Read(const Message* m,
brettwbd4d7112015-06-03 04:29:25777 base::PickleIterator* iter,
[email protected]141bcc52014-01-27 21:36:00778 param_type* p) {
[email protected]481c3e82014-07-18 01:40:47779 double last_modified, last_accessed, creation_time;
780 if (!ReadParam(m, iter, &p->size) ||
781 !ReadParam(m, iter, &p->is_directory) ||
782 !ReadParam(m, iter, &last_modified) ||
783 !ReadParam(m, iter, &last_accessed) ||
784 !ReadParam(m, iter, &creation_time))
785 return false;
786 p->last_modified = base::Time::FromDoubleT(last_modified);
787 p->last_accessed = base::Time::FromDoubleT(last_accessed);
788 p->creation_time = base::Time::FromDoubleT(creation_time);
789 return true;
[email protected]bf5aedf02012-06-04 21:18:25790}
791
[email protected]141bcc52014-01-27 21:36:00792void ParamTraits<base::File::Info>::Log(const param_type& p,
793 std::string* l) {
[email protected]bf5aedf02012-06-04 21:18:25794 l->append("(");
795 LogParam(p.size, l);
796 l->append(",");
797 LogParam(p.is_directory, l);
798 l->append(",");
799 LogParam(p.last_modified.ToDoubleT(), l);
800 l->append(",");
801 LogParam(p.last_accessed.ToDoubleT(), l);
802 l->append(",");
803 LogParam(p.creation_time.ToDoubleT(), l);
804 l->append(")");
805}
806
807void ParamTraits<base::Time>::Write(Message* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:57808 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:25809}
810
brettwbd4d7112015-06-03 04:29:25811bool ParamTraits<base::Time>::Read(const Message* m,
812 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25813 param_type* r) {
tfarina10a5c062015-09-04 18:47:57814 int64_t value;
815 if (!ParamTraits<int64_t>::Read(m, iter, &value))
[email protected]bf5aedf02012-06-04 21:18:25816 return false;
817 *r = base::Time::FromInternalValue(value);
818 return true;
819}
820
821void ParamTraits<base::Time>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:57822 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:25823}
824
825void ParamTraits<base::TimeDelta>::Write(Message* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:57826 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:25827}
828
829bool ParamTraits<base::TimeDelta>::Read(const Message* m,
brettwbd4d7112015-06-03 04:29:25830 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25831 param_type* r) {
tfarina10a5c062015-09-04 18:47:57832 int64_t value;
833 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
[email protected]bf5aedf02012-06-04 21:18:25834 if (ret)
835 *r = base::TimeDelta::FromInternalValue(value);
836
837 return ret;
838}
839
840void ParamTraits<base::TimeDelta>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:57841 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:25842}
843
844void ParamTraits<base::TimeTicks>::Write(Message* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:57845 ParamTraits<int64_t>::Write(m, p.ToInternalValue());
[email protected]bf5aedf02012-06-04 21:18:25846}
847
848bool ParamTraits<base::TimeTicks>::Read(const Message* m,
brettwbd4d7112015-06-03 04:29:25849 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25850 param_type* r) {
tfarina10a5c062015-09-04 18:47:57851 int64_t value;
852 bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
[email protected]bf5aedf02012-06-04 21:18:25853 if (ret)
854 *r = base::TimeTicks::FromInternalValue(value);
855
856 return ret;
857}
858
859void ParamTraits<base::TimeTicks>::Log(const param_type& p, std::string* l) {
tfarina10a5c062015-09-04 18:47:57860 ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
[email protected]bf5aedf02012-06-04 21:18:25861}
862
[email protected]7a4de7a62010-08-17 18:38:24863void ParamTraits<IPC::ChannelHandle>::Write(Message* m, const param_type& p) {
[email protected]a7c03d4f32012-01-24 02:36:05864#if defined(OS_WIN)
865 // On Windows marshalling pipe handle is not supported.
866 DCHECK(p.pipe.handle == NULL);
867#endif // defined (OS_WIN)
[email protected]7a4de7a62010-08-17 18:38:24868 WriteParam(m, p.name);
869#if defined(OS_POSIX)
870 WriteParam(m, p.socket);
871#endif
872}
873
[email protected]ce208f872012-03-07 20:42:56874bool ParamTraits<IPC::ChannelHandle>::Read(const Message* m,
brettwbd4d7112015-06-03 04:29:25875 base::PickleIterator* iter,
[email protected]7a4de7a62010-08-17 18:38:24876 param_type* r) {
877 return ReadParam(m, iter, &r->name)
878#if defined(OS_POSIX)
879 && ReadParam(m, iter, &r->socket)
880#endif
881 ;
882}
883
884void ParamTraits<IPC::ChannelHandle>::Log(const param_type& p,
[email protected]252cad62010-08-18 18:33:57885 std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:04886 l->append(base::StringPrintf("ChannelHandle(%s", p.name.c_str()));
[email protected]7a4de7a62010-08-17 18:38:24887#if defined(OS_POSIX)
[email protected]3cd3bce2011-09-23 10:32:19888 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:24889 ParamTraits<base::FileDescriptor>::Log(p.socket, l);
890#endif
[email protected]252cad62010-08-18 18:33:57891 l->append(")");
[email protected]7a4de7a62010-08-17 18:38:24892}
893
[email protected]20f0487a2010-09-30 20:06:30894void ParamTraits<LogData>::Write(Message* m, const param_type& p) {
895 WriteParam(m, p.channel);
896 WriteParam(m, p.routing_id);
[email protected]8bf55ca2011-10-17 22:15:27897 WriteParam(m, p.type);
[email protected]20f0487a2010-09-30 20:06:30898 WriteParam(m, p.flags);
899 WriteParam(m, p.sent);
900 WriteParam(m, p.receive);
901 WriteParam(m, p.dispatch);
[email protected]bae578e92012-11-15 03:17:45902 WriteParam(m, p.message_name);
[email protected]20f0487a2010-09-30 20:06:30903 WriteParam(m, p.params);
904}
905
[email protected]ce208f872012-03-07 20:42:56906bool ParamTraits<LogData>::Read(const Message* m,
brettwbd4d7112015-06-03 04:29:25907 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:56908 param_type* r) {
[email protected]8bf55ca2011-10-17 22:15:27909 return
[email protected]20f0487a2010-09-30 20:06:30910 ReadParam(m, iter, &r->channel) &&
911 ReadParam(m, iter, &r->routing_id) &&
[email protected]8bf55ca2011-10-17 22:15:27912 ReadParam(m, iter, &r->type) &&
[email protected]20f0487a2010-09-30 20:06:30913 ReadParam(m, iter, &r->flags) &&
914 ReadParam(m, iter, &r->sent) &&
915 ReadParam(m, iter, &r->receive) &&
916 ReadParam(m, iter, &r->dispatch) &&
[email protected]bae578e92012-11-15 03:17:45917 ReadParam(m, iter, &r->message_name) &&
[email protected]20f0487a2010-09-30 20:06:30918 ReadParam(m, iter, &r->params);
[email protected]20f0487a2010-09-30 20:06:30919}
920
[email protected]bf5aedf02012-06-04 21:18:25921void ParamTraits<LogData>::Log(const param_type& p, std::string* l) {
922 // Doesn't make sense to implement this!
923}
924
925void ParamTraits<Message>::Write(Message* m, const Message& p) {
[email protected]34d48612012-06-29 00:05:04926#if defined(OS_POSIX)
927 // We don't serialize the file descriptors in the nested message, so there
928 // better not be any.
morrita1aa788c2015-01-31 05:45:42929 DCHECK(!p.HasAttachments());
[email protected]34d48612012-06-29 00:05:04930#endif
931
932 // Don't just write out the message. This is used to send messages between
933 // NaCl (Posix environment) and the browser (could be on Windows). The message
934 // header formats differ between these systems (so does handle sharing, but
935 // we already asserted we don't have any handles). So just write out the
936 // parts of the header we use.
937 //
938 // Be careful also to use only explicitly-sized types. The NaCl environment
939 // could be 64-bit and the host browser could be 32-bits. The nested message
940 // may or may not be safe to send between 32-bit and 64-bit systems, but we
941 // leave that up to the code sending the message to ensure.
tfarina10a5c062015-09-04 18:47:57942 m->WriteUInt32(static_cast<uint32_t>(p.routing_id()));
[email protected]34d48612012-06-29 00:05:04943 m->WriteUInt32(p.type());
944 m->WriteUInt32(p.flags());
tfarina10a5c062015-09-04 18:47:57945 m->WriteData(p.payload(), static_cast<uint32_t>(p.payload_size()));
[email protected]bf5aedf02012-06-04 21:18:25946}
947
brettwbd4d7112015-06-03 04:29:25948bool ParamTraits<Message>::Read(const Message* m,
949 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25950 Message* r) {
tfarina10a5c062015-09-04 18:47:57951 uint32_t routing_id, type, flags;
avi48fc13b2014-12-28 23:31:48952 if (!iter->ReadUInt32(&routing_id) ||
953 !iter->ReadUInt32(&type) ||
954 !iter->ReadUInt32(&flags))
[email protected]bf5aedf02012-06-04 21:18:25955 return false;
[email protected]34d48612012-06-29 00:05:04956
957 int payload_size;
958 const char* payload;
avi48fc13b2014-12-28 23:31:48959 if (!iter->ReadData(&payload, &payload_size))
[email protected]bf5aedf02012-06-04 21:18:25960 return false;
[email protected]34d48612012-06-29 00:05:04961
tfarina10a5c062015-09-04 18:47:57962 r->SetHeaderValues(static_cast<int32_t>(routing_id), type, flags);
[email protected]34d48612012-06-29 00:05:04963 return r->WriteBytes(payload, payload_size);
[email protected]bf5aedf02012-06-04 21:18:25964}
965
966void ParamTraits<Message>::Log(const Message& p, std::string* l) {
967 l->append("<IPC::Message>");
968}
969
970#if defined(OS_WIN)
971// Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
[email protected]4a635b72013-03-04 02:29:03972// bit systems. That's why we use the Windows macros to convert to 32 bits.
[email protected]bf5aedf02012-06-04 21:18:25973void ParamTraits<HANDLE>::Write(Message* m, const param_type& p) {
[email protected]4a635b72013-03-04 02:29:03974 m->WriteInt(HandleToLong(p));
[email protected]bf5aedf02012-06-04 21:18:25975}
976
brettwbd4d7112015-06-03 04:29:25977bool ParamTraits<HANDLE>::Read(const Message* m,
978 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25979 param_type* r) {
tfarina10a5c062015-09-04 18:47:57980 int32_t temp;
avi48fc13b2014-12-28 23:31:48981 if (!iter->ReadInt(&temp))
[email protected]bf5aedf02012-06-04 21:18:25982 return false;
[email protected]4a635b72013-03-04 02:29:03983 *r = LongToHandle(temp);
[email protected]bf5aedf02012-06-04 21:18:25984 return true;
985}
986
987void ParamTraits<HANDLE>::Log(const param_type& p, std::string* l) {
brucedawson5604a11d2015-10-06 19:22:00988 l->append(base::StringPrintf("0x%p", p));
[email protected]bf5aedf02012-06-04 21:18:25989}
990
991void ParamTraits<LOGFONT>::Write(Message* m, const param_type& p) {
992 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
993}
994
brettwbd4d7112015-06-03 04:29:25995bool ParamTraits<LOGFONT>::Read(const Message* m,
996 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25997 param_type* r) {
998 const char *data;
999 int data_size = 0;
avi48fc13b2014-12-28 23:31:481000 if (iter->ReadData(&data, &data_size) && data_size == sizeof(LOGFONT)) {
[email protected]2e02cfe82012-11-21 00:58:001001 const LOGFONT *font = reinterpret_cast<LOGFONT*>(const_cast<char*>(data));
1002 if (_tcsnlen(font->lfFaceName, LF_FACESIZE) < LF_FACESIZE) {
1003 memcpy(r, data, sizeof(LOGFONT));
1004 return true;
1005 }
[email protected]bf5aedf02012-06-04 21:18:251006 }
1007
[email protected]2e02cfe82012-11-21 00:58:001008 NOTREACHED();
1009 return false;
[email protected]bf5aedf02012-06-04 21:18:251010}
1011
1012void ParamTraits<LOGFONT>::Log(const param_type& p, std::string* l) {
[email protected]7d3cbc92013-03-18 22:33:041013 l->append(base::StringPrintf("<LOGFONT>"));
[email protected]bf5aedf02012-06-04 21:18:251014}
1015
1016void ParamTraits<MSG>::Write(Message* m, const param_type& p) {
1017 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
1018}
1019
brettwbd4d7112015-06-03 04:29:251020bool ParamTraits<MSG>::Read(const Message* m,
1021 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:251022 param_type* r) {
1023 const char *data;
1024 int data_size = 0;
avi48fc13b2014-12-28 23:31:481025 bool result = iter->ReadData(&data, &data_size);
[email protected]bf5aedf02012-06-04 21:18:251026 if (result && data_size == sizeof(MSG)) {
1027 memcpy(r, data, sizeof(MSG));
1028 } else {
1029 result = false;
1030 NOTREACHED();
1031 }
1032
1033 return result;
1034}
1035
1036void ParamTraits<MSG>::Log(const param_type& p, std::string* l) {
1037 l->append("<MSG>");
1038}
1039
1040#endif // OS_WIN
1041
[email protected]946d1b22009-07-22 23:57:211042} // namespace IPC