blob: 718e759ca39f15c3d639cd706a60365d08df49b4 [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
[email protected]57999812013-02-24 05:40:527#include "base/files/file_path.h"
[email protected]93d49d72009-10-23 20:00:208#include "base/json/json_writer.h"
[email protected]3b63f8f42011-03-28 01:54:159#include "base/memory/scoped_ptr.h"
[email protected]7a4de7a62010-08-17 18:38:2410#include "base/nullable_string16.h"
[email protected]252cad62010-08-18 18:33:5711#include "base/string_number_conversions.h"
[email protected]946d1b22009-07-22 23:57:2112#include "base/time.h"
[email protected]252cad62010-08-18 18:33:5713#include "base/utf_string_conversions.h"
[email protected]946d1b22009-07-22 23:57:2114#include "base/values.h"
[email protected]bf5aedf02012-06-04 21:18:2515#include "ipc/ipc_channel_handle.h"
16
[email protected]7a4de7a62010-08-17 18:38:2417#if defined(OS_POSIX)
18#include "ipc/file_descriptor_set_posix.h"
[email protected]2e02cfe82012-11-21 00:58:0019#elif defined(OS_WIN)
20#include <tchar.h>
[email protected]7a4de7a62010-08-17 18:38:2421#endif
[email protected]946d1b22009-07-22 23:57:2122
23namespace IPC {
24
[email protected]bf5aedf02012-06-04 21:18:2525namespace {
26
[email protected]946d1b22009-07-22 23:57:2127const int kMaxRecursionDepth = 100;
28
[email protected]bf5aedf02012-06-04 21:18:2529template<typename CharType>
30void LogBytes(const std::vector<CharType>& data, std::string* out) {
31#if defined(OS_WIN)
32 // Windows has a GUI for logging, which can handle arbitrary binary data.
33 for (size_t i = 0; i < data.size(); ++i)
34 out->push_back(data[i]);
35#else
36 // On POSIX, we log to stdout, which we assume can display ASCII.
37 static const size_t kMaxBytesToLog = 100;
38 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
39 if (isprint(data[i]))
40 out->push_back(data[i]);
41 else
42 out->append(StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
43 }
44 if (data.size() > kMaxBytesToLog) {
45 out->append(
46 StringPrintf(" and %u more bytes",
47 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
48 }
49#endif
50}
[email protected]946d1b22009-07-22 23:57:2151
[email protected]bf5aedf02012-06-04 21:18:2552bool ReadValue(const Message* m, PickleIterator* iter, Value** value,
53 int recursion);
[email protected]946d1b22009-07-22 23:57:2154
[email protected]bf5aedf02012-06-04 21:18:2555void WriteValue(Message* m, const Value* value, int recursion) {
[email protected]dbc761a2012-07-26 01:29:2156 bool result;
[email protected]946d1b22009-07-22 23:57:2157 if (recursion > kMaxRecursionDepth) {
58 LOG(WARNING) << "Max recursion depth hit in WriteValue.";
59 return;
60 }
61
62 m->WriteInt(value->GetType());
63
64 switch (value->GetType()) {
[email protected]e4dad9fb2009-10-06 18:15:5865 case Value::TYPE_NULL:
[email protected]946d1b22009-07-22 23:57:2166 break;
[email protected]e4dad9fb2009-10-06 18:15:5867 case Value::TYPE_BOOLEAN: {
[email protected]946d1b22009-07-22 23:57:2168 bool val;
[email protected]dbc761a2012-07-26 01:29:2169 result = value->GetAsBoolean(&val);
70 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:2171 WriteParam(m, val);
72 break;
73 }
[email protected]e4dad9fb2009-10-06 18:15:5874 case Value::TYPE_INTEGER: {
[email protected]946d1b22009-07-22 23:57:2175 int val;
[email protected]dbc761a2012-07-26 01:29:2176 result = value->GetAsInteger(&val);
77 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:2178 WriteParam(m, val);
79 break;
80 }
[email protected]fb534c92011-02-01 01:02:0781 case Value::TYPE_DOUBLE: {
[email protected]946d1b22009-07-22 23:57:2182 double val;
[email protected]dbc761a2012-07-26 01:29:2183 result = value->GetAsDouble(&val);
84 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:2185 WriteParam(m, val);
86 break;
87 }
[email protected]e4dad9fb2009-10-06 18:15:5888 case Value::TYPE_STRING: {
[email protected]946d1b22009-07-22 23:57:2189 std::string val;
[email protected]dbc761a2012-07-26 01:29:2190 result = value->GetAsString(&val);
91 DCHECK(result);
[email protected]946d1b22009-07-22 23:57:2192 WriteParam(m, val);
93 break;
94 }
[email protected]e4dad9fb2009-10-06 18:15:5895 case Value::TYPE_BINARY: {
[email protected]b59ea312011-08-05 18:20:0596 const base::BinaryValue* binary =
97 static_cast<const base::BinaryValue*>(value);
[email protected]7ee1a44c2010-07-23 14:18:5998 m->WriteData(binary->GetBuffer(), static_cast<int>(binary->GetSize()));
[email protected]e4dad9fb2009-10-06 18:15:5899 break;
[email protected]946d1b22009-07-22 23:57:21100 }
[email protected]e4dad9fb2009-10-06 18:15:58101 case Value::TYPE_DICTIONARY: {
[email protected]946d1b22009-07-22 23:57:21102 const DictionaryValue* dict = static_cast<const DictionaryValue*>(value);
103
[email protected]4dad9ad82009-11-25 20:47:52104 WriteParam(m, static_cast<int>(dict->size()));
[email protected]946d1b22009-07-22 23:57:21105
[email protected]a899c0b02013-01-18 14:43:27106 for (DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
107 WriteParam(m, it.key());
108 WriteValue(m, &it.value(), recursion + 1);
[email protected]946d1b22009-07-22 23:57:21109 }
110 break;
111 }
[email protected]e4dad9fb2009-10-06 18:15:58112 case Value::TYPE_LIST: {
[email protected]946d1b22009-07-22 23:57:21113 const ListValue* list = static_cast<const ListValue*>(value);
114 WriteParam(m, static_cast<int>(list->GetSize()));
[email protected]a899c0b02013-01-18 14:43:27115 for (ListValue::const_iterator it = list->begin(); it != list->end();
116 ++it) {
117 WriteValue(m, *it, recursion + 1);
[email protected]946d1b22009-07-22 23:57:21118 }
119 break;
120 }
121 }
122}
123
124// Helper for ReadValue that reads a DictionaryValue into a pre-allocated
125// object.
[email protected]bf5aedf02012-06-04 21:18:25126bool ReadDictionaryValue(const Message* m, PickleIterator* iter,
127 DictionaryValue* value, int recursion) {
[email protected]946d1b22009-07-22 23:57:21128 int size;
129 if (!ReadParam(m, iter, &size))
130 return false;
131
132 for (int i = 0; i < size; ++i) {
[email protected]e7b418b2010-07-30 19:47:47133 std::string key;
[email protected]946d1b22009-07-22 23:57:21134 Value* subval;
135 if (!ReadParam(m, iter, &key) ||
136 !ReadValue(m, iter, &subval, recursion + 1))
137 return false;
[email protected]d8b4aa42011-08-19 05:59:57138 value->SetWithoutPathExpansion(key, subval);
[email protected]946d1b22009-07-22 23:57:21139 }
140
141 return true;
142}
143
144// Helper for ReadValue that reads a ReadListValue into a pre-allocated
145// object.
[email protected]bf5aedf02012-06-04 21:18:25146bool ReadListValue(const Message* m, PickleIterator* iter,
147 ListValue* value, int recursion) {
[email protected]946d1b22009-07-22 23:57:21148 int size;
149 if (!ReadParam(m, iter, &size))
150 return false;
151
152 for (int i = 0; i < size; ++i) {
153 Value* subval;
154 if (!ReadValue(m, iter, &subval, recursion + 1))
155 return false;
156 value->Set(i, subval);
157 }
158
159 return true;
160}
161
[email protected]bf5aedf02012-06-04 21:18:25162bool ReadValue(const Message* m, PickleIterator* iter, Value** value,
163 int recursion) {
[email protected]946d1b22009-07-22 23:57:21164 if (recursion > kMaxRecursionDepth) {
165 LOG(WARNING) << "Max recursion depth hit in ReadValue.";
166 return false;
167 }
168
169 int type;
170 if (!ReadParam(m, iter, &type))
171 return false;
172
173 switch (type) {
[email protected]e4dad9fb2009-10-06 18:15:58174 case Value::TYPE_NULL:
[email protected]946d1b22009-07-22 23:57:21175 *value = Value::CreateNullValue();
176 break;
[email protected]e4dad9fb2009-10-06 18:15:58177 case Value::TYPE_BOOLEAN: {
[email protected]946d1b22009-07-22 23:57:21178 bool val;
179 if (!ReadParam(m, iter, &val))
180 return false;
[email protected]4038a132013-01-30 05:24:07181 *value = new base::FundamentalValue(val);
[email protected]946d1b22009-07-22 23:57:21182 break;
183 }
[email protected]e4dad9fb2009-10-06 18:15:58184 case Value::TYPE_INTEGER: {
[email protected]946d1b22009-07-22 23:57:21185 int val;
186 if (!ReadParam(m, iter, &val))
187 return false;
[email protected]4038a132013-01-30 05:24:07188 *value = new base::FundamentalValue(val);
[email protected]946d1b22009-07-22 23:57:21189 break;
190 }
[email protected]fb534c92011-02-01 01:02:07191 case Value::TYPE_DOUBLE: {
[email protected]946d1b22009-07-22 23:57:21192 double val;
193 if (!ReadParam(m, iter, &val))
194 return false;
[email protected]4038a132013-01-30 05:24:07195 *value = new base::FundamentalValue(val);
[email protected]946d1b22009-07-22 23:57:21196 break;
197 }
[email protected]e4dad9fb2009-10-06 18:15:58198 case Value::TYPE_STRING: {
[email protected]946d1b22009-07-22 23:57:21199 std::string val;
200 if (!ReadParam(m, iter, &val))
201 return false;
[email protected]4038a132013-01-30 05:24:07202 *value = new base::StringValue(val);
[email protected]946d1b22009-07-22 23:57:21203 break;
204 }
[email protected]e4dad9fb2009-10-06 18:15:58205 case Value::TYPE_BINARY: {
206 const char* data;
207 int length;
208 if (!m->ReadData(iter, &data, &length))
209 return false;
[email protected]b59ea312011-08-05 18:20:05210 *value = base::BinaryValue::CreateWithCopiedBuffer(data, length);
[email protected]946d1b22009-07-22 23:57:21211 break;
212 }
[email protected]e4dad9fb2009-10-06 18:15:58213 case Value::TYPE_DICTIONARY: {
[email protected]946d1b22009-07-22 23:57:21214 scoped_ptr<DictionaryValue> val(new DictionaryValue());
215 if (!ReadDictionaryValue(m, iter, val.get(), recursion))
216 return false;
217 *value = val.release();
218 break;
219 }
[email protected]e4dad9fb2009-10-06 18:15:58220 case Value::TYPE_LIST: {
[email protected]946d1b22009-07-22 23:57:21221 scoped_ptr<ListValue> val(new ListValue());
222 if (!ReadListValue(m, iter, val.get(), recursion))
223 return false;
224 *value = val.release();
225 break;
226 }
[email protected]e4dad9fb2009-10-06 18:15:58227 default:
[email protected]946d1b22009-07-22 23:57:21228 return false;
229 }
230
231 return true;
232}
233
[email protected]bf5aedf02012-06-04 21:18:25234} // namespace
235
236// -----------------------------------------------------------------------------
237
238LogData::LogData()
239 : routing_id(0),
240 type(0),
241 sent(0),
242 receive(0),
243 dispatch(0) {
244}
245
246LogData::~LogData() {
247}
248
[email protected]bf5aedf02012-06-04 21:18:25249void ParamTraits<bool>::Log(const param_type& p, std::string* l) {
250 l->append(p ? "true" : "false");
251}
252
[email protected]252cad62010-08-18 18:33:57253void ParamTraits<int>::Log(const param_type& p, std::string* l) {
254 l->append(base::IntToString(p));
255}
256
257void ParamTraits<unsigned int>::Log(const param_type& p, std::string* l) {
258 l->append(base::UintToString(p));
259}
260
261void ParamTraits<long>::Log(const param_type& p, std::string* l) {
262 l->append(base::Int64ToString(static_cast<int64>(p)));
263}
264
265void ParamTraits<unsigned long>::Log(const param_type& p, std::string* l) {
266 l->append(base::Uint64ToString(static_cast<uint64>(p)));
267}
268
269void ParamTraits<long long>::Log(const param_type& p, std::string* l) {
270 l->append(base::Int64ToString(static_cast<int64>(p)));
271}
272
273void ParamTraits<unsigned long long>::Log(const param_type& p, std::string* l) {
274 l->append(base::Uint64ToString(p));
275}
[email protected]7a4de7a62010-08-17 18:38:24276
[email protected]43a40202010-11-12 16:25:01277void ParamTraits<unsigned short>::Write(Message* m, const param_type& p) {
278 m->WriteBytes(&p, sizeof(param_type));
279}
280
[email protected]ce208f872012-03-07 20:42:56281bool ParamTraits<unsigned short>::Read(const Message* m, PickleIterator* iter,
[email protected]43a40202010-11-12 16:25:01282 param_type* r) {
283 const char* data;
284 if (!m->ReadBytes(iter, &data, sizeof(param_type)))
285 return false;
286 memcpy(r, data, sizeof(param_type));
287 return true;
288}
289
290void ParamTraits<unsigned short>::Log(const param_type& p, std::string* l) {
291 l->append(base::UintToString(p));
292}
293
[email protected]bf5aedf02012-06-04 21:18:25294void ParamTraits<float>::Write(Message* m, const param_type& p) {
295 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
[email protected]c410e022012-05-30 21:15:57296}
297
[email protected]bf5aedf02012-06-04 21:18:25298bool ParamTraits<float>::Read(const Message* m, PickleIterator* iter,
299 param_type* r) {
300 const char *data;
301 int data_size;
302 if (!m->ReadData(iter, &data, &data_size) ||
303 data_size != sizeof(param_type)) {
304 NOTREACHED();
[email protected]7a4de7a62010-08-17 18:38:24305 return false;
[email protected]bf5aedf02012-06-04 21:18:25306 }
307 memcpy(r, data, sizeof(param_type));
[email protected]7a4de7a62010-08-17 18:38:24308 return true;
309}
310
[email protected]bf5aedf02012-06-04 21:18:25311void ParamTraits<float>::Log(const param_type& p, std::string* l) {
312 l->append(StringPrintf("%e", p));
[email protected]7a4de7a62010-08-17 18:38:24313}
314
[email protected]bf5aedf02012-06-04 21:18:25315void ParamTraits<double>::Write(Message* m, const param_type& p) {
316 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
[email protected]d84e48b2010-10-21 22:04:52317}
318
[email protected]bf5aedf02012-06-04 21:18:25319bool ParamTraits<double>::Read(const Message* m, PickleIterator* iter,
320 param_type* r) {
321 const char *data;
322 int data_size;
323 if (!m->ReadData(iter, &data, &data_size) ||
324 data_size != sizeof(param_type)) {
325 NOTREACHED();
326 return false;
327 }
328 memcpy(r, data, sizeof(param_type));
329 return true;
[email protected]d84e48b2010-10-21 22:04:52330}
331
[email protected]bf5aedf02012-06-04 21:18:25332void ParamTraits<double>::Log(const param_type& p, std::string* l) {
333 l->append(StringPrintf("%e", p));
[email protected]1d14f582011-09-02 20:42:04334}
335
[email protected]bf5aedf02012-06-04 21:18:25336
337void ParamTraits<std::string>::Log(const param_type& p, std::string* l) {
338 l->append(p);
[email protected]1d14f582011-09-02 20:42:04339}
340
[email protected]bf5aedf02012-06-04 21:18:25341void ParamTraits<std::wstring>::Log(const param_type& p, std::string* l) {
342 l->append(WideToUTF8(p));
[email protected]1d14f582011-09-02 20:42:04343}
344
[email protected]bf5aedf02012-06-04 21:18:25345#if !defined(WCHAR_T_IS_UTF16)
346void ParamTraits<string16>::Log(const param_type& p, std::string* l) {
347 l->append(UTF16ToUTF8(p));
348}
349#endif
350
351void ParamTraits<std::vector<char> >::Write(Message* m, const param_type& p) {
352 if (p.empty()) {
353 m->WriteData(NULL, 0);
354 } else {
355 m->WriteData(&p.front(), static_cast<int>(p.size()));
356 }
357}
358
359bool ParamTraits<std::vector<char> >::Read(const Message* m,
360 PickleIterator* iter,
361 param_type* r) {
362 const char *data;
363 int data_size = 0;
364 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
365 return false;
366 r->resize(data_size);
367 if (data_size)
368 memcpy(&r->front(), data, data_size);
369 return true;
370}
371
372void ParamTraits<std::vector<char> >::Log(const param_type& p, std::string* l) {
373 LogBytes(p, l);
374}
375
376void ParamTraits<std::vector<unsigned char> >::Write(Message* m,
377 const param_type& p) {
378 if (p.empty()) {
379 m->WriteData(NULL, 0);
380 } else {
381 m->WriteData(reinterpret_cast<const char*>(&p.front()),
382 static_cast<int>(p.size()));
383 }
384}
385
386bool ParamTraits<std::vector<unsigned char> >::Read(const Message* m,
387 PickleIterator* iter,
388 param_type* r) {
389 const char *data;
390 int data_size = 0;
391 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
392 return false;
393 r->resize(data_size);
394 if (data_size)
395 memcpy(&r->front(), data, data_size);
396 return true;
397}
398
399void ParamTraits<std::vector<unsigned char> >::Log(const param_type& p,
400 std::string* l) {
401 LogBytes(p, l);
402}
403
404void ParamTraits<std::vector<bool> >::Write(Message* m, const param_type& p) {
405 WriteParam(m, static_cast<int>(p.size()));
406 for (size_t i = 0; i < p.size(); i++)
407 WriteParam(m, p[i]);
408}
409
410bool ParamTraits<std::vector<bool> >::Read(const Message* m,
411 PickleIterator* iter,
412 param_type* r) {
413 int size;
414 // ReadLength() checks for < 0 itself.
415 if (!m->ReadLength(iter, &size))
416 return false;
417 r->resize(size);
418 for (int i = 0; i < size; i++) {
419 bool value;
420 if (!ReadParam(m, iter, &value))
421 return false;
422 (*r)[i] = value;
423 }
424 return true;
425}
426
427void ParamTraits<std::vector<bool> >::Log(const param_type& p, std::string* l) {
428 for (size_t i = 0; i < p.size(); ++i) {
429 if (i != 0)
430 l->push_back(' ');
431 LogParam((p[i]), l);
432 }
[email protected]d84e48b2010-10-21 22:04:52433}
434
[email protected]946d1b22009-07-22 23:57:21435void ParamTraits<DictionaryValue>::Write(Message* m, const param_type& p) {
436 WriteValue(m, &p, 0);
437}
438
439bool ParamTraits<DictionaryValue>::Read(
[email protected]ce208f872012-03-07 20:42:56440 const Message* m, PickleIterator* iter, param_type* r) {
[email protected]946d1b22009-07-22 23:57:21441 int type;
442 if (!ReadParam(m, iter, &type) || type != Value::TYPE_DICTIONARY)
443 return false;
444
445 return ReadDictionaryValue(m, iter, r, 0);
446}
447
[email protected]252cad62010-08-18 18:33:57448void ParamTraits<DictionaryValue>::Log(const param_type& p, std::string* l) {
[email protected]946d1b22009-07-22 23:57:21449 std::string json;
[email protected]4abb4602012-03-16 01:59:55450 base::JSONWriter::Write(&p, &json);
[email protected]252cad62010-08-18 18:33:57451 l->append(json);
[email protected]946d1b22009-07-22 23:57:21452}
453
[email protected]7a4de7a62010-08-17 18:38:24454#if defined(OS_POSIX)
455void ParamTraits<base::FileDescriptor>::Write(Message* m, const param_type& p) {
456 const bool valid = p.fd >= 0;
457 WriteParam(m, valid);
458
459 if (valid) {
460 if (!m->WriteFileDescriptor(p))
461 NOTREACHED();
462 }
463}
464
[email protected]ce208f872012-03-07 20:42:56465bool ParamTraits<base::FileDescriptor>::Read(const Message* m,
466 PickleIterator* iter,
[email protected]7a4de7a62010-08-17 18:38:24467 param_type* r) {
468 bool valid;
469 if (!ReadParam(m, iter, &valid))
470 return false;
471
472 if (!valid) {
473 r->fd = -1;
474 r->auto_close = false;
475 return true;
476 }
477
478 return m->ReadFileDescriptor(iter, r);
479}
480
481void ParamTraits<base::FileDescriptor>::Log(const param_type& p,
[email protected]252cad62010-08-18 18:33:57482 std::string* l) {
[email protected]7a4de7a62010-08-17 18:38:24483 if (p.auto_close) {
[email protected]252cad62010-08-18 18:33:57484 l->append(StringPrintf("FD(%d auto-close)", p.fd));
[email protected]7a4de7a62010-08-17 18:38:24485 } else {
[email protected]252cad62010-08-18 18:33:57486 l->append(StringPrintf("FD(%d)", p.fd));
[email protected]7a4de7a62010-08-17 18:38:24487 }
488}
489#endif // defined(OS_POSIX)
490
[email protected]6d4b67a2013-02-10 04:49:30491void ParamTraits<base::FilePath>::Write(Message* m, const param_type& p) {
[email protected]aeae59f2013-01-28 13:47:55492 p.WriteToPickle(m);
[email protected]bf5aedf02012-06-04 21:18:25493}
494
[email protected]6d4b67a2013-02-10 04:49:30495bool ParamTraits<base::FilePath>::Read(const Message* m,
496 PickleIterator* iter,
497 param_type* r) {
[email protected]aeae59f2013-01-28 13:47:55498 return r->ReadFromPickle(iter);
[email protected]bf5aedf02012-06-04 21:18:25499}
500
[email protected]6d4b67a2013-02-10 04:49:30501void ParamTraits<base::FilePath>::Log(const param_type& p, std::string* l) {
502 ParamTraits<base::FilePath::StringType>::Log(p.value(), l);
[email protected]bf5aedf02012-06-04 21:18:25503}
504
505void ParamTraits<ListValue>::Write(Message* m, const param_type& p) {
506 WriteValue(m, &p, 0);
507}
508
509bool ParamTraits<ListValue>::Read(
510 const Message* m, PickleIterator* iter, param_type* r) {
511 int type;
512 if (!ReadParam(m, iter, &type) || type != Value::TYPE_LIST)
513 return false;
514
515 return ReadListValue(m, iter, r, 0);
516}
517
518void ParamTraits<ListValue>::Log(const param_type& p, std::string* l) {
519 std::string json;
520 base::JSONWriter::Write(&p, &json);
521 l->append(json);
522}
523
524void ParamTraits<NullableString16>::Write(Message* m, const param_type& p) {
525 WriteParam(m, p.string());
526 WriteParam(m, p.is_null());
527}
528
529bool ParamTraits<NullableString16>::Read(const Message* m, PickleIterator* iter,
530 param_type* r) {
531 string16 string;
532 if (!ReadParam(m, iter, &string))
533 return false;
534 bool is_null;
535 if (!ReadParam(m, iter, &is_null))
536 return false;
537 *r = NullableString16(string, is_null);
538 return true;
539}
540
541void ParamTraits<NullableString16>::Log(const param_type& p, std::string* l) {
542 l->append("(");
543 LogParam(p.string(), l);
544 l->append(", ");
545 LogParam(p.is_null(), l);
546 l->append(")");
547}
548
549void ParamTraits<base::PlatformFileInfo>::Write(Message* m,
550 const param_type& p) {
551 WriteParam(m, p.size);
552 WriteParam(m, p.is_directory);
553 WriteParam(m, p.last_modified.ToDoubleT());
554 WriteParam(m, p.last_accessed.ToDoubleT());
555 WriteParam(m, p.creation_time.ToDoubleT());
556}
557
558bool ParamTraits<base::PlatformFileInfo>::Read(const Message* m,
559 PickleIterator* iter,
560 param_type* p) {
561 double last_modified;
562 double last_accessed;
563 double creation_time;
564 bool result =
565 ReadParam(m, iter, &p->size) &&
566 ReadParam(m, iter, &p->is_directory) &&
567 ReadParam(m, iter, &last_modified) &&
568 ReadParam(m, iter, &last_accessed) &&
569 ReadParam(m, iter, &creation_time);
570 if (result) {
571 p->last_modified = base::Time::FromDoubleT(last_modified);
572 p->last_accessed = base::Time::FromDoubleT(last_accessed);
573 p->creation_time = base::Time::FromDoubleT(creation_time);
574 }
575 return result;
576}
577
578void ParamTraits<base::PlatformFileInfo>::Log(const param_type& p,
579 std::string* l) {
580 l->append("(");
581 LogParam(p.size, l);
582 l->append(",");
583 LogParam(p.is_directory, l);
584 l->append(",");
585 LogParam(p.last_modified.ToDoubleT(), l);
586 l->append(",");
587 LogParam(p.last_accessed.ToDoubleT(), l);
588 l->append(",");
589 LogParam(p.creation_time.ToDoubleT(), l);
590 l->append(")");
591}
592
593void ParamTraits<base::Time>::Write(Message* m, const param_type& p) {
594 ParamTraits<int64>::Write(m, p.ToInternalValue());
595}
596
597bool ParamTraits<base::Time>::Read(const Message* m, PickleIterator* iter,
598 param_type* r) {
599 int64 value;
600 if (!ParamTraits<int64>::Read(m, iter, &value))
601 return false;
602 *r = base::Time::FromInternalValue(value);
603 return true;
604}
605
606void ParamTraits<base::Time>::Log(const param_type& p, std::string* l) {
607 ParamTraits<int64>::Log(p.ToInternalValue(), l);
608}
609
610void ParamTraits<base::TimeDelta>::Write(Message* m, const param_type& p) {
611 ParamTraits<int64>::Write(m, p.ToInternalValue());
612}
613
614bool ParamTraits<base::TimeDelta>::Read(const Message* m,
615 PickleIterator* iter,
616 param_type* r) {
617 int64 value;
618 bool ret = ParamTraits<int64>::Read(m, iter, &value);
619 if (ret)
620 *r = base::TimeDelta::FromInternalValue(value);
621
622 return ret;
623}
624
625void ParamTraits<base::TimeDelta>::Log(const param_type& p, std::string* l) {
626 ParamTraits<int64>::Log(p.ToInternalValue(), l);
627}
628
629void ParamTraits<base::TimeTicks>::Write(Message* m, const param_type& p) {
630 ParamTraits<int64>::Write(m, p.ToInternalValue());
631}
632
633bool ParamTraits<base::TimeTicks>::Read(const Message* m,
634 PickleIterator* iter,
635 param_type* r) {
636 int64 value;
637 bool ret = ParamTraits<int64>::Read(m, iter, &value);
638 if (ret)
639 *r = base::TimeTicks::FromInternalValue(value);
640
641 return ret;
642}
643
644void ParamTraits<base::TimeTicks>::Log(const param_type& p, std::string* l) {
645 ParamTraits<int64>::Log(p.ToInternalValue(), l);
646}
647
[email protected]7a4de7a62010-08-17 18:38:24648void ParamTraits<IPC::ChannelHandle>::Write(Message* m, const param_type& p) {
[email protected]a7c03d4f32012-01-24 02:36:05649#if defined(OS_WIN)
650 // On Windows marshalling pipe handle is not supported.
651 DCHECK(p.pipe.handle == NULL);
652#endif // defined (OS_WIN)
[email protected]7a4de7a62010-08-17 18:38:24653 WriteParam(m, p.name);
654#if defined(OS_POSIX)
655 WriteParam(m, p.socket);
656#endif
657}
658
[email protected]ce208f872012-03-07 20:42:56659bool ParamTraits<IPC::ChannelHandle>::Read(const Message* m,
660 PickleIterator* iter,
[email protected]7a4de7a62010-08-17 18:38:24661 param_type* r) {
662 return ReadParam(m, iter, &r->name)
663#if defined(OS_POSIX)
664 && ReadParam(m, iter, &r->socket)
665#endif
666 ;
667}
668
669void ParamTraits<IPC::ChannelHandle>::Log(const param_type& p,
[email protected]252cad62010-08-18 18:33:57670 std::string* l) {
671 l->append(StringPrintf("ChannelHandle(%s", p.name.c_str()));
[email protected]7a4de7a62010-08-17 18:38:24672#if defined(OS_POSIX)
[email protected]3cd3bce2011-09-23 10:32:19673 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:24674 ParamTraits<base::FileDescriptor>::Log(p.socket, l);
675#endif
[email protected]252cad62010-08-18 18:33:57676 l->append(")");
[email protected]7a4de7a62010-08-17 18:38:24677}
678
[email protected]20f0487a2010-09-30 20:06:30679void ParamTraits<LogData>::Write(Message* m, const param_type& p) {
680 WriteParam(m, p.channel);
681 WriteParam(m, p.routing_id);
[email protected]8bf55ca2011-10-17 22:15:27682 WriteParam(m, p.type);
[email protected]20f0487a2010-09-30 20:06:30683 WriteParam(m, p.flags);
684 WriteParam(m, p.sent);
685 WriteParam(m, p.receive);
686 WriteParam(m, p.dispatch);
[email protected]bae578e92012-11-15 03:17:45687 WriteParam(m, p.message_name);
[email protected]20f0487a2010-09-30 20:06:30688 WriteParam(m, p.params);
689}
690
[email protected]ce208f872012-03-07 20:42:56691bool ParamTraits<LogData>::Read(const Message* m,
692 PickleIterator* iter,
693 param_type* r) {
[email protected]8bf55ca2011-10-17 22:15:27694 return
[email protected]20f0487a2010-09-30 20:06:30695 ReadParam(m, iter, &r->channel) &&
696 ReadParam(m, iter, &r->routing_id) &&
[email protected]8bf55ca2011-10-17 22:15:27697 ReadParam(m, iter, &r->type) &&
[email protected]20f0487a2010-09-30 20:06:30698 ReadParam(m, iter, &r->flags) &&
699 ReadParam(m, iter, &r->sent) &&
700 ReadParam(m, iter, &r->receive) &&
701 ReadParam(m, iter, &r->dispatch) &&
[email protected]bae578e92012-11-15 03:17:45702 ReadParam(m, iter, &r->message_name) &&
[email protected]20f0487a2010-09-30 20:06:30703 ReadParam(m, iter, &r->params);
[email protected]20f0487a2010-09-30 20:06:30704}
705
[email protected]bf5aedf02012-06-04 21:18:25706void ParamTraits<LogData>::Log(const param_type& p, std::string* l) {
707 // Doesn't make sense to implement this!
708}
709
710void ParamTraits<Message>::Write(Message* m, const Message& p) {
[email protected]34d48612012-06-29 00:05:04711#if defined(OS_POSIX)
712 // We don't serialize the file descriptors in the nested message, so there
713 // better not be any.
714 DCHECK(!p.HasFileDescriptors());
715#endif
716
717 // Don't just write out the message. This is used to send messages between
718 // NaCl (Posix environment) and the browser (could be on Windows). The message
719 // header formats differ between these systems (so does handle sharing, but
720 // we already asserted we don't have any handles). So just write out the
721 // parts of the header we use.
722 //
723 // Be careful also to use only explicitly-sized types. The NaCl environment
724 // could be 64-bit and the host browser could be 32-bits. The nested message
725 // may or may not be safe to send between 32-bit and 64-bit systems, but we
726 // leave that up to the code sending the message to ensure.
727 m->WriteUInt32(static_cast<uint32>(p.routing_id()));
728 m->WriteUInt32(p.type());
729 m->WriteUInt32(p.flags());
730 m->WriteData(p.payload(), static_cast<uint32>(p.payload_size()));
[email protected]bf5aedf02012-06-04 21:18:25731}
732
733bool ParamTraits<Message>::Read(const Message* m, PickleIterator* iter,
734 Message* r) {
[email protected]34d48612012-06-29 00:05:04735 uint32 routing_id, type, flags;
736 if (!m->ReadUInt32(iter, &routing_id) ||
737 !m->ReadUInt32(iter, &type) ||
738 !m->ReadUInt32(iter, &flags))
[email protected]bf5aedf02012-06-04 21:18:25739 return false;
[email protected]34d48612012-06-29 00:05:04740
741 int payload_size;
742 const char* payload;
743 if (!m->ReadData(iter, &payload, &payload_size))
[email protected]bf5aedf02012-06-04 21:18:25744 return false;
[email protected]34d48612012-06-29 00:05:04745
746 r->SetHeaderValues(static_cast<int32>(routing_id), type, flags);
747 return r->WriteBytes(payload, payload_size);
[email protected]bf5aedf02012-06-04 21:18:25748}
749
750void ParamTraits<Message>::Log(const Message& p, std::string* l) {
751 l->append("<IPC::Message>");
752}
753
754#if defined(OS_WIN)
755// Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
[email protected]4a635b72013-03-04 02:29:03756// bit systems. That's why we use the Windows macros to convert to 32 bits.
[email protected]bf5aedf02012-06-04 21:18:25757void ParamTraits<HANDLE>::Write(Message* m, const param_type& p) {
[email protected]4a635b72013-03-04 02:29:03758 m->WriteInt(HandleToLong(p));
[email protected]bf5aedf02012-06-04 21:18:25759}
760
761bool ParamTraits<HANDLE>::Read(const Message* m, PickleIterator* iter,
762 param_type* r) {
[email protected]4a635b72013-03-04 02:29:03763 int32 temp;
764 if (!m->ReadInt(iter, &temp))
[email protected]bf5aedf02012-06-04 21:18:25765 return false;
[email protected]4a635b72013-03-04 02:29:03766 *r = LongToHandle(temp);
[email protected]bf5aedf02012-06-04 21:18:25767 return true;
768}
769
770void ParamTraits<HANDLE>::Log(const param_type& p, std::string* l) {
771 l->append(StringPrintf("0x%X", p));
772}
773
774void ParamTraits<LOGFONT>::Write(Message* m, const param_type& p) {
775 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
776}
777
778bool ParamTraits<LOGFONT>::Read(const Message* m, PickleIterator* iter,
779 param_type* r) {
780 const char *data;
781 int data_size = 0;
[email protected]2e02cfe82012-11-21 00:58:00782 if (m->ReadData(iter, &data, &data_size) && data_size == sizeof(LOGFONT)) {
783 const LOGFONT *font = reinterpret_cast<LOGFONT*>(const_cast<char*>(data));
784 if (_tcsnlen(font->lfFaceName, LF_FACESIZE) < LF_FACESIZE) {
785 memcpy(r, data, sizeof(LOGFONT));
786 return true;
787 }
[email protected]bf5aedf02012-06-04 21:18:25788 }
789
[email protected]2e02cfe82012-11-21 00:58:00790 NOTREACHED();
791 return false;
[email protected]bf5aedf02012-06-04 21:18:25792}
793
794void ParamTraits<LOGFONT>::Log(const param_type& p, std::string* l) {
795 l->append(StringPrintf("<LOGFONT>"));
796}
797
798void ParamTraits<MSG>::Write(Message* m, const param_type& p) {
799 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
800}
801
802bool ParamTraits<MSG>::Read(const Message* m, PickleIterator* iter,
803 param_type* r) {
804 const char *data;
805 int data_size = 0;
806 bool result = m->ReadData(iter, &data, &data_size);
807 if (result && data_size == sizeof(MSG)) {
808 memcpy(r, data, sizeof(MSG));
809 } else {
810 result = false;
811 NOTREACHED();
812 }
813
814 return result;
815}
816
817void ParamTraits<MSG>::Log(const param_type& p, std::string* l) {
818 l->append("<MSG>");
819}
820
821#endif // OS_WIN
822
[email protected]946d1b22009-07-22 23:57:21823} // namespace IPC