OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef IPC_IPC_MESSAGE_UTILS_H_ | 5 #ifndef IPC_IPC_MESSAGE_UTILS_H_ |
6 #define IPC_IPC_MESSAGE_UTILS_H_ | 6 #define IPC_IPC_MESSAGE_UTILS_H_ |
7 #pragma once | 7 #pragma once |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <map> | 10 #include <map> |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 class TimeTicks; | 117 class TimeTicks; |
118 struct FileDescriptor; | 118 struct FileDescriptor; |
119 } | 119 } |
120 | 120 |
121 namespace IPC { | 121 namespace IPC { |
122 | 122 |
123 struct ChannelHandle; | 123 struct ChannelHandle; |
124 | 124 |
125 //----------------------------------------------------------------------------- | 125 //----------------------------------------------------------------------------- |
126 // An iterator class for reading the fields contained within a Message. | 126 // An iterator class for reading the fields contained within a Message. |
| 127 class IPC_EXPORT MessageIterator { |
| 128 public: |
| 129 explicit MessageIterator(const Message& m); |
127 | 130 |
128 class MessageIterator { | 131 int NextInt() const; |
129 public: | 132 const std::string NextString() const; |
130 explicit MessageIterator(const Message& m) : iter_(m) { | 133 |
131 } | |
132 int NextInt() const { | |
133 int val = -1; | |
134 if (!iter_.ReadInt(&val)) | |
135 NOTREACHED(); | |
136 return val; | |
137 } | |
138 const std::string NextString() const { | |
139 std::string val; | |
140 if (!iter_.ReadString(&val)) | |
141 NOTREACHED(); | |
142 return val; | |
143 } | |
144 private: | 134 private: |
145 mutable PickleIterator iter_; | 135 mutable PickleIterator iter_; |
146 }; | 136 }; |
147 | 137 |
| 138 // ----------------------------------------------------------------------------- |
| 139 // How we send IPC message logs across channels. |
| 140 struct IPC_EXPORT LogData { |
| 141 LogData(); |
| 142 ~LogData(); |
| 143 |
| 144 std::string channel; |
| 145 int32 routing_id; |
| 146 uint32 type; // "User-defined" message type, from ipc_message.h. |
| 147 std::string flags; |
| 148 int64 sent; // Time that the message was sent (i.e. at Send()). |
| 149 int64 receive; // Time before it was dispatched (i.e. before calling |
| 150 // OnMessageReceived). |
| 151 int64 dispatch; // Time after it was dispatched (i.e. after calling |
| 152 // OnMessageReceived). |
| 153 std::string message_name; |
| 154 std::string params; |
| 155 }; |
| 156 |
| 157 |
148 //----------------------------------------------------------------------------- | 158 //----------------------------------------------------------------------------- |
149 // A dummy struct to place first just to allow leading commas for all | 159 // A dummy struct to place first just to allow leading commas for all |
150 // members in the macro-generated constructor initializer lists. | 160 // members in the macro-generated constructor initializer lists. |
151 struct NoParams { | 161 struct NoParams { |
152 }; | 162 }; |
153 | 163 |
154 //----------------------------------------------------------------------------- | |
155 // ParamTraits specializations, etc. | |
156 | |
157 template <class P> | 164 template <class P> |
158 static inline void WriteParam(Message* m, const P& p) { | 165 static inline void WriteParam(Message* m, const P& p) { |
159 typedef typename SimilarTypeTraits<P>::Type Type; | 166 typedef typename SimilarTypeTraits<P>::Type Type; |
160 ParamTraits<Type>::Write(m, static_cast<const Type& >(p)); | 167 ParamTraits<Type>::Write(m, static_cast<const Type& >(p)); |
161 } | 168 } |
162 | 169 |
163 template <class P> | 170 template <class P> |
164 static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, | 171 static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, |
165 PickleIterator* iter, | 172 PickleIterator* iter, |
166 P* p) { | 173 P* p) { |
167 typedef typename SimilarTypeTraits<P>::Type Type; | 174 typedef typename SimilarTypeTraits<P>::Type Type; |
168 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p)); | 175 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p)); |
169 } | 176 } |
170 | 177 |
171 template <class P> | 178 template <class P> |
172 static inline void LogParam(const P& p, std::string* l) { | 179 static inline void LogParam(const P& p, std::string* l) { |
173 typedef typename SimilarTypeTraits<P>::Type Type; | 180 typedef typename SimilarTypeTraits<P>::Type Type; |
174 ParamTraits<Type>::Log(static_cast<const Type& >(p), l); | 181 ParamTraits<Type>::Log(static_cast<const Type& >(p), l); |
175 } | 182 } |
176 | 183 |
| 184 // Primitive ParamTraits ------------------------------------------------------- |
| 185 |
177 template <> | 186 template <> |
178 struct ParamTraits<bool> { | 187 struct ParamTraits<bool> { |
179 typedef bool param_type; | 188 typedef bool param_type; |
180 static void Write(Message* m, const param_type& p) { | 189 static void Write(Message* m, const param_type& p) { |
181 m->WriteBool(p); | 190 m->WriteBool(p); |
182 } | 191 } |
183 static bool Read(const Message* m, PickleIterator* iter, | 192 static bool Read(const Message* m, PickleIterator* iter, param_type* r) { |
184 param_type* r) { | |
185 return m->ReadBool(iter, r); | 193 return m->ReadBool(iter, r); |
186 } | 194 } |
187 static void Log(const param_type& p, std::string* l) { | 195 IPC_EXPORT static void Log(const param_type& p, std::string* l); |
188 l->append(p ? "true" : "false"); | |
189 } | |
190 }; | 196 }; |
191 | 197 |
192 template <> | 198 template <> |
193 struct ParamTraits<int> { | 199 struct ParamTraits<int> { |
194 typedef int param_type; | 200 typedef int param_type; |
195 static void Write(Message* m, const param_type& p) { | 201 static void Write(Message* m, const param_type& p) { |
196 m->WriteInt(p); | 202 m->WriteInt(p); |
197 } | 203 } |
198 static bool Read(const Message* m, PickleIterator* iter, | 204 static bool Read(const Message* m, PickleIterator* iter, param_type* r) { |
199 param_type* r) { | |
200 return m->ReadInt(iter, r); | 205 return m->ReadInt(iter, r); |
201 } | 206 } |
202 IPC_EXPORT static void Log(const param_type& p, std::string* l); | 207 IPC_EXPORT static void Log(const param_type& p, std::string* l); |
203 }; | 208 }; |
204 | 209 |
205 template <> | 210 template <> |
206 struct ParamTraits<unsigned int> { | 211 struct ParamTraits<unsigned int> { |
207 typedef unsigned int param_type; | 212 typedef unsigned int param_type; |
208 static void Write(Message* m, const param_type& p) { | 213 static void Write(Message* m, const param_type& p) { |
209 m->WriteInt(p); | 214 m->WriteInt(p); |
210 } | 215 } |
211 static bool Read(const Message* m, PickleIterator* iter, | 216 static bool Read(const Message* m, PickleIterator* iter, param_type* r) { |
212 param_type* r) { | |
213 return m->ReadInt(iter, reinterpret_cast<int*>(r)); | 217 return m->ReadInt(iter, reinterpret_cast<int*>(r)); |
214 } | 218 } |
215 IPC_EXPORT static void Log(const param_type& p, std::string* l); | 219 IPC_EXPORT static void Log(const param_type& p, std::string* l); |
216 }; | 220 }; |
217 | 221 |
218 template <> | 222 template <> |
219 struct ParamTraits<long> { | 223 struct ParamTraits<long> { |
220 typedef long param_type; | 224 typedef long param_type; |
221 static void Write(Message* m, const param_type& p) { | 225 static void Write(Message* m, const param_type& p) { |
222 m->WriteLongUsingDangerousNonPortableLessPersistableForm(p); | 226 m->WriteLongUsingDangerousNonPortableLessPersistableForm(p); |
223 } | 227 } |
224 static bool Read(const Message* m, PickleIterator* iter, | 228 static bool Read(const Message* m, PickleIterator* iter, param_type* r) { |
225 param_type* r) { | |
226 return m->ReadLong(iter, r); | 229 return m->ReadLong(iter, r); |
227 } | 230 } |
228 IPC_EXPORT static void Log(const param_type& p, std::string* l); | 231 IPC_EXPORT static void Log(const param_type& p, std::string* l); |
229 }; | 232 }; |
230 | 233 |
231 template <> | 234 template <> |
232 struct ParamTraits<unsigned long> { | 235 struct ParamTraits<unsigned long> { |
233 typedef unsigned long param_type; | 236 typedef unsigned long param_type; |
234 static void Write(Message* m, const param_type& p) { | 237 static void Write(Message* m, const param_type& p) { |
235 m->WriteLongUsingDangerousNonPortableLessPersistableForm(p); | 238 m->WriteLongUsingDangerousNonPortableLessPersistableForm(p); |
236 } | 239 } |
237 static bool Read(const Message* m, PickleIterator* iter, | 240 static bool Read(const Message* m, PickleIterator* iter, param_type* r) { |
238 param_type* r) { | |
239 return m->ReadLong(iter, reinterpret_cast<long*>(r)); | 241 return m->ReadLong(iter, reinterpret_cast<long*>(r)); |
240 } | 242 } |
241 IPC_EXPORT static void Log(const param_type& p, std::string* l); | 243 IPC_EXPORT static void Log(const param_type& p, std::string* l); |
242 }; | 244 }; |
243 | 245 |
244 template <> | 246 template <> |
245 struct ParamTraits<long long> { | 247 struct ParamTraits<long long> { |
246 typedef long long param_type; | 248 typedef long long param_type; |
247 static void Write(Message* m, const param_type& p) { | 249 static void Write(Message* m, const param_type& p) { |
248 m->WriteInt64(static_cast<int64>(p)); | 250 m->WriteInt64(static_cast<int64>(p)); |
(...skipping 23 matching lines...) Expand all Loading... |
272 typedef unsigned short param_type; | 274 typedef unsigned short param_type; |
273 static void Write(Message* m, const param_type& p); | 275 static void Write(Message* m, const param_type& p); |
274 static bool Read(const Message* m, PickleIterator* iter, param_type* r); | 276 static bool Read(const Message* m, PickleIterator* iter, param_type* r); |
275 static void Log(const param_type& p, std::string* l); | 277 static void Log(const param_type& p, std::string* l); |
276 }; | 278 }; |
277 | 279 |
278 // Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients | 280 // Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients |
279 // should be sure to check the sanity of these values after receiving them over | 281 // should be sure to check the sanity of these values after receiving them over |
280 // IPC. | 282 // IPC. |
281 template <> | 283 template <> |
282 struct ParamTraits<float> { | 284 struct IPC_EXPORT ParamTraits<float> { |
283 typedef float param_type; | 285 typedef float param_type; |
284 static void Write(Message* m, const param_type& p) { | |
285 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type)); | |
286 } | |
287 static bool Read(const Message* m, PickleIterator* iter, | |
288 param_type* r) { | |
289 const char *data; | |
290 int data_size; | |
291 if (!m->ReadData(iter, &data, &data_size) || | |
292 data_size != sizeof(param_type)) { | |
293 NOTREACHED(); | |
294 return false; | |
295 } | |
296 memcpy(r, data, sizeof(param_type)); | |
297 return true; | |
298 } | |
299 static void Log(const param_type& p, std::string* l) { | |
300 l->append(StringPrintf("%e", p)); | |
301 } | |
302 }; | |
303 | |
304 template <> | |
305 struct ParamTraits<double> { | |
306 typedef double param_type; | |
307 static void Write(Message* m, const param_type& p) { | |
308 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type)); | |
309 } | |
310 static bool Read(const Message* m, PickleIterator* iter, | |
311 param_type* r) { | |
312 const char *data; | |
313 int data_size; | |
314 if (!m->ReadData(iter, &data, &data_size) || | |
315 data_size != sizeof(param_type)) { | |
316 NOTREACHED(); | |
317 return false; | |
318 } | |
319 memcpy(r, data, sizeof(param_type)); | |
320 return true; | |
321 } | |
322 static void Log(const param_type& p, std::string* l) { | |
323 l->append(StringPrintf("%e", p)); | |
324 } | |
325 }; | |
326 | |
327 template <> | |
328 struct IPC_EXPORT ParamTraits<base::PlatformFileInfo> { | |
329 typedef base::PlatformFileInfo param_type; | |
330 static void Write(Message* m, const param_type& p); | 286 static void Write(Message* m, const param_type& p); |
331 static bool Read(const Message* m, PickleIterator* iter, param_type* r); | 287 static bool Read(const Message* m, PickleIterator* iter, param_type* r); |
332 static void Log(const param_type& p, std::string* l); | 288 static void Log(const param_type& p, std::string* l); |
333 }; | 289 }; |
334 | 290 |
335 template <> | 291 template <> |
336 struct SimilarTypeTraits<base::PlatformFileError> { | 292 struct IPC_EXPORT ParamTraits<double> { |
337 typedef int Type; | 293 typedef double param_type; |
338 }; | |
339 | |
340 template <> | |
341 struct IPC_EXPORT ParamTraits<base::Time> { | |
342 typedef base::Time param_type; | |
343 static void Write(Message* m, const param_type& p); | 294 static void Write(Message* m, const param_type& p); |
344 static bool Read(const Message* m, PickleIterator* iter, param_type* r); | 295 static bool Read(const Message* m, PickleIterator* iter, param_type* r); |
345 static void Log(const param_type& p, std::string* l); | 296 static void Log(const param_type& p, std::string* l); |
346 }; | 297 }; |
347 | 298 |
348 template <> | 299 // STL ParamTraits ------------------------------------------------------------- |
349 struct IPC_EXPORT ParamTraits<base::TimeDelta> { | |
350 typedef base::TimeDelta param_type; | |
351 static void Write(Message* m, const param_type& p); | |
352 static bool Read(const Message* m, PickleIterator* iter, param_type* r); | |
353 static void Log(const param_type& p, std::string* l); | |
354 }; | |
355 | |
356 template <> | |
357 struct IPC_EXPORT ParamTraits<base::TimeTicks> { | |
358 typedef base::TimeTicks param_type; | |
359 static void Write(Message* m, const param_type& p); | |
360 static bool Read(const Message* m, PickleIterator* iter, param_type* r); | |
361 static void Log(const param_type& p, std::string* l); | |
362 }; | |
363 | |
364 #if defined(OS_WIN) | |
365 template <> | |
366 struct ParamTraits<LOGFONT> { | |
367 typedef LOGFONT param_type; | |
368 static void Write(Message* m, const param_type& p) { | |
369 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT)); | |
370 } | |
371 static bool Read(const Message* m, PickleIterator* iter, | |
372 param_type* r) { | |
373 const char *data; | |
374 int data_size = 0; | |
375 bool result = m->ReadData(iter, &data, &data_size); | |
376 if (result && data_size == sizeof(LOGFONT)) { | |
377 memcpy(r, data, sizeof(LOGFONT)); | |
378 } else { | |
379 result = false; | |
380 NOTREACHED(); | |
381 } | |
382 | |
383 return result; | |
384 } | |
385 static void Log(const param_type& p, std::string* l) { | |
386 l->append(StringPrintf("<LOGFONT>")); | |
387 } | |
388 }; | |
389 | |
390 template <> | |
391 struct ParamTraits<MSG> { | |
392 typedef MSG param_type; | |
393 static void Write(Message* m, const param_type& p) { | |
394 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG)); | |
395 } | |
396 static bool Read(const Message* m, PickleIterator* iter, | |
397 param_type* r) { | |
398 const char *data; | |
399 int data_size = 0; | |
400 bool result = m->ReadData(iter, &data, &data_size); | |
401 if (result && data_size == sizeof(MSG)) { | |
402 memcpy(r, data, sizeof(MSG)); | |
403 } else { | |
404 result = false; | |
405 NOTREACHED(); | |
406 } | |
407 | |
408 return result; | |
409 } | |
410 static void Log(const param_type& p, std::string* l) { | |
411 l->append("<MSG>"); | |
412 } | |
413 }; | |
414 #endif // defined(OS_WIN) | |
415 | |
416 template <> | |
417 struct IPC_EXPORT ParamTraits<base::DictionaryValue> { | |
418 typedef base::DictionaryValue param_type; | |
419 static void Write(Message* m, const param_type& p); | |
420 static bool Read(const Message* m, PickleIterator* iter, param_type* r); | |
421 static void Log(const param_type& p, std::string* l); | |
422 }; | |
423 | |
424 template <> | |
425 struct IPC_EXPORT ParamTraits<base::ListValue> { | |
426 typedef base::ListValue param_type; | |
427 static void Write(Message* m, const param_type& p); | |
428 static bool Read(const Message* m, PickleIterator* iter, param_type* r); | |
429 static void Log(const param_type& p, std::string* l); | |
430 }; | |
431 | 300 |
432 template <> | 301 template <> |
433 struct ParamTraits<std::string> { | 302 struct ParamTraits<std::string> { |
434 typedef std::string param_type; | 303 typedef std::string param_type; |
435 static void Write(Message* m, const param_type& p) { | 304 static void Write(Message* m, const param_type& p) { |
436 m->WriteString(p); | 305 m->WriteString(p); |
437 } | 306 } |
438 static bool Read(const Message* m, PickleIterator* iter, | 307 static bool Read(const Message* m, PickleIterator* iter, |
439 param_type* r) { | 308 param_type* r) { |
440 return m->ReadString(iter, r); | 309 return m->ReadString(iter, r); |
441 } | 310 } |
442 static void Log(const param_type& p, std::string* l) { | 311 IPC_EXPORT static void Log(const param_type& p, std::string* l); |
443 l->append(p); | |
444 } | |
445 }; | 312 }; |
446 | 313 |
447 template<typename CharType> | |
448 static void LogBytes(const std::vector<CharType>& data, std::string* out) { | |
449 #if defined(OS_WIN) | |
450 // Windows has a GUI for logging, which can handle arbitrary binary data. | |
451 for (size_t i = 0; i < data.size(); ++i) | |
452 out->push_back(data[i]); | |
453 #else | |
454 // On POSIX, we log to stdout, which we assume can display ASCII. | |
455 static const size_t kMaxBytesToLog = 100; | |
456 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) { | |
457 if (isprint(data[i])) | |
458 out->push_back(data[i]); | |
459 else | |
460 out->append(StringPrintf("[%02X]", static_cast<unsigned char>(data[i]))); | |
461 } | |
462 if (data.size() > kMaxBytesToLog) { | |
463 out->append( | |
464 StringPrintf(" and %u more bytes", | |
465 static_cast<unsigned>(data.size() - kMaxBytesToLog))); | |
466 } | |
467 #endif | |
468 } | |
469 | |
470 template <> | 314 template <> |
471 struct ParamTraits<std::vector<unsigned char> > { | 315 struct ParamTraits<std::wstring> { |
472 typedef std::vector<unsigned char> param_type; | 316 typedef std::wstring param_type; |
473 static void Write(Message* m, const param_type& p) { | 317 static void Write(Message* m, const param_type& p) { |
474 if (p.empty()) { | 318 m->WriteWString(p); |
475 m->WriteData(NULL, 0); | |
476 } else { | |
477 m->WriteData(reinterpret_cast<const char*>(&p.front()), | |
478 static_cast<int>(p.size())); | |
479 } | |
480 } | 319 } |
481 static bool Read(const Message* m, PickleIterator* iter, | 320 static bool Read(const Message* m, PickleIterator* iter, |
482 param_type* r) { | 321 param_type* r) { |
483 const char *data; | 322 return m->ReadWString(iter, r); |
484 int data_size = 0; | |
485 if (!m->ReadData(iter, &data, &data_size) || data_size < 0) | |
486 return false; | |
487 r->resize(data_size); | |
488 if (data_size) | |
489 memcpy(&r->front(), data, data_size); | |
490 return true; | |
491 } | 323 } |
492 static void Log(const param_type& p, std::string* l) { | 324 IPC_EXPORT static void Log(const param_type& p, std::string* l); |
493 LogBytes(p, l); | 325 }; |
| 326 |
| 327 // If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't |
| 328 // need this trait. |
| 329 #if !defined(WCHAR_T_IS_UTF16) |
| 330 template <> |
| 331 struct ParamTraits<string16> { |
| 332 typedef string16 param_type; |
| 333 static void Write(Message* m, const param_type& p) { |
| 334 m->WriteString16(p); |
494 } | 335 } |
| 336 static bool Read(const Message* m, PickleIterator* iter, |
| 337 param_type* r) { |
| 338 return m->ReadString16(iter, r); |
| 339 } |
| 340 IPC_EXPORT static void Log(const param_type& p, std::string* l); |
| 341 }; |
| 342 #endif |
| 343 |
| 344 template <> |
| 345 struct IPC_EXPORT ParamTraits<std::vector<char> > { |
| 346 typedef std::vector<char> param_type; |
| 347 static void Write(Message* m, const param_type& p); |
| 348 static bool Read(const Message*, PickleIterator* iter, param_type* r); |
| 349 static void Log(const param_type& p, std::string* l); |
495 }; | 350 }; |
496 | 351 |
497 template <> | 352 template <> |
498 struct ParamTraits<std::vector<char> > { | 353 struct IPC_EXPORT ParamTraits<std::vector<unsigned char> > { |
499 typedef std::vector<char> param_type; | 354 typedef std::vector<unsigned char> param_type; |
500 static void Write(Message* m, const param_type& p) { | 355 static void Write(Message* m, const param_type& p); |
501 if (p.empty()) { | 356 static bool Read(const Message* m, PickleIterator* iter, param_type* r); |
502 m->WriteData(NULL, 0); | 357 static void Log(const param_type& p, std::string* l); |
503 } else { | |
504 m->WriteData(&p.front(), static_cast<int>(p.size())); | |
505 } | |
506 } | |
507 static bool Read(const Message* m, PickleIterator* iter, | |
508 param_type* r) { | |
509 const char *data; | |
510 int data_size = 0; | |
511 if (!m->ReadData(iter, &data, &data_size) || data_size < 0) | |
512 return false; | |
513 r->resize(data_size); | |
514 if (data_size) | |
515 memcpy(&r->front(), data, data_size); | |
516 return true; | |
517 } | |
518 static void Log(const param_type& p, std::string* l) { | |
519 LogBytes(p, l); | |
520 } | |
521 }; | 358 }; |
522 | 359 |
523 template <> | 360 template <> |
524 struct ParamTraits<std::vector<bool> > { | 361 struct IPC_EXPORT ParamTraits<std::vector<bool> > { |
525 typedef std::vector<bool> param_type; | 362 typedef std::vector<bool> param_type; |
526 static void Write(Message* m, const param_type& p) { | 363 static void Write(Message* m, const param_type& p); |
527 WriteParam(m, static_cast<int>(p.size())); | 364 static bool Read(const Message* m, PickleIterator* iter, param_type* r); |
528 for (size_t i = 0; i < p.size(); i++) | 365 static void Log(const param_type& p, std::string* l); |
529 WriteParam(m, p[i]); | |
530 } | |
531 static bool Read(const Message* m, PickleIterator* iter, | |
532 param_type* r) { | |
533 int size; | |
534 // ReadLength() checks for < 0 itself. | |
535 if (!m->ReadLength(iter, &size)) | |
536 return false; | |
537 r->resize(size); | |
538 for (int i = 0; i < size; i++) { | |
539 bool value; | |
540 if (!ReadParam(m, iter, &value)) | |
541 return false; | |
542 (*r)[i] = value; | |
543 } | |
544 return true; | |
545 } | |
546 static void Log(const param_type& p, std::string* l) { | |
547 for (size_t i = 0; i < p.size(); ++i) { | |
548 if (i != 0) | |
549 l->append(" "); | |
550 LogParam((p[i]), l); | |
551 } | |
552 } | |
553 }; | 366 }; |
554 | 367 |
555 template <class P> | 368 template <class P> |
556 struct ParamTraits<std::vector<P> > { | 369 struct ParamTraits<std::vector<P> > { |
557 typedef std::vector<P> param_type; | 370 typedef std::vector<P> param_type; |
558 static void Write(Message* m, const param_type& p) { | 371 static void Write(Message* m, const param_type& p) { |
559 WriteParam(m, static_cast<int>(p.size())); | 372 WriteParam(m, static_cast<int>(p.size())); |
560 for (size_t i = 0; i < p.size(); i++) | 373 for (size_t i = 0; i < p.size(); i++) |
561 WriteParam(m, p[i]); | 374 WriteParam(m, p[i]); |
562 } | 375 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
605 return false; | 418 return false; |
606 r->insert(item); | 419 r->insert(item); |
607 } | 420 } |
608 return true; | 421 return true; |
609 } | 422 } |
610 static void Log(const param_type& p, std::string* l) { | 423 static void Log(const param_type& p, std::string* l) { |
611 l->append("<std::set>"); | 424 l->append("<std::set>"); |
612 } | 425 } |
613 }; | 426 }; |
614 | 427 |
615 | |
616 template <class K, class V> | 428 template <class K, class V> |
617 struct ParamTraits<std::map<K, V> > { | 429 struct ParamTraits<std::map<K, V> > { |
618 typedef std::map<K, V> param_type; | 430 typedef std::map<K, V> param_type; |
619 static void Write(Message* m, const param_type& p) { | 431 static void Write(Message* m, const param_type& p) { |
620 WriteParam(m, static_cast<int>(p.size())); | 432 WriteParam(m, static_cast<int>(p.size())); |
621 typename param_type::const_iterator iter; | 433 typename param_type::const_iterator iter; |
622 for (iter = p.begin(); iter != p.end(); ++iter) { | 434 for (iter = p.begin(); iter != p.end(); ++iter) { |
623 WriteParam(m, iter->first); | 435 WriteParam(m, iter->first); |
624 WriteParam(m, iter->second); | 436 WriteParam(m, iter->second); |
625 } | 437 } |
(...skipping 11 matching lines...) Expand all Loading... |
637 if (!ReadParam(m, iter, &value)) | 449 if (!ReadParam(m, iter, &value)) |
638 return false; | 450 return false; |
639 } | 451 } |
640 return true; | 452 return true; |
641 } | 453 } |
642 static void Log(const param_type& p, std::string* l) { | 454 static void Log(const param_type& p, std::string* l) { |
643 l->append("<std::map>"); | 455 l->append("<std::map>"); |
644 } | 456 } |
645 }; | 457 }; |
646 | 458 |
647 | |
648 template <> | |
649 struct ParamTraits<std::wstring> { | |
650 typedef std::wstring param_type; | |
651 static void Write(Message* m, const param_type& p) { | |
652 m->WriteWString(p); | |
653 } | |
654 static bool Read(const Message* m, PickleIterator* iter, | |
655 param_type* r) { | |
656 return m->ReadWString(iter, r); | |
657 } | |
658 IPC_EXPORT static void Log(const param_type& p, std::string* l); | |
659 }; | |
660 | |
661 template <class A, class B> | 459 template <class A, class B> |
662 struct ParamTraits<std::pair<A, B> > { | 460 struct ParamTraits<std::pair<A, B> > { |
663 typedef std::pair<A, B> param_type; | 461 typedef std::pair<A, B> param_type; |
664 static void Write(Message* m, const param_type& p) { | 462 static void Write(Message* m, const param_type& p) { |
665 WriteParam(m, p.first); | 463 WriteParam(m, p.first); |
666 WriteParam(m, p.second); | 464 WriteParam(m, p.second); |
667 } | 465 } |
668 static bool Read(const Message* m, PickleIterator* iter, | 466 static bool Read(const Message* m, PickleIterator* iter, |
669 param_type* r) { | 467 param_type* r) { |
670 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second); | 468 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second); |
671 } | 469 } |
672 static void Log(const param_type& p, std::string* l) { | 470 static void Log(const param_type& p, std::string* l) { |
673 l->append("("); | 471 l->append("("); |
674 LogParam(p.first, l); | 472 LogParam(p.first, l); |
675 l->append(", "); | 473 l->append(", "); |
676 LogParam(p.second, l); | 474 LogParam(p.second, l); |
677 l->append(")"); | 475 l->append(")"); |
678 } | 476 } |
679 }; | 477 }; |
680 | 478 |
681 template <> | 479 // Base ParamTraits ------------------------------------------------------------ |
682 struct IPC_EXPORT ParamTraits<NullableString16> { | |
683 typedef NullableString16 param_type; | |
684 static void Write(Message* m, const param_type& p); | |
685 static bool Read(const Message* m, PickleIterator* iter, | |
686 param_type* r); | |
687 static void Log(const param_type& p, std::string* l); | |
688 }; | |
689 | |
690 // If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't | |
691 // need this trait. | |
692 #if !defined(WCHAR_T_IS_UTF16) | |
693 template <> | |
694 struct ParamTraits<string16> { | |
695 typedef string16 param_type; | |
696 static void Write(Message* m, const param_type& p) { | |
697 m->WriteString16(p); | |
698 } | |
699 static bool Read(const Message* m, PickleIterator* iter, | |
700 param_type* r) { | |
701 return m->ReadString16(iter, r); | |
702 } | |
703 IPC_EXPORT static void Log(const param_type& p, std::string* l); | |
704 }; | |
705 #endif | |
706 | |
707 // and, a few more useful types... | |
708 #if defined(OS_WIN) | |
709 template <> | |
710 struct ParamTraits<HANDLE> { | |
711 typedef HANDLE param_type; | |
712 // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64 | |
713 // bit systems. | |
714 static void Write(Message* m, const param_type& p) { | |
715 m->WriteUInt32(reinterpret_cast<uint32>(p)); | |
716 } | |
717 static bool Read(const Message* m, PickleIterator* iter, | |
718 param_type* r) { | |
719 uint32 temp; | |
720 if (!m->ReadUInt32(iter, &temp)) | |
721 return false; | |
722 *r = reinterpret_cast<HANDLE>(temp); | |
723 return true; | |
724 } | |
725 static void Log(const param_type& p, std::string* l) { | |
726 l->append(StringPrintf("0x%X", p)); | |
727 } | |
728 }; | |
729 #endif // defined(OS_WIN) | |
730 | 480 |
731 template <> | 481 template <> |
732 struct IPC_EXPORT ParamTraits<FilePath> { | 482 struct IPC_EXPORT ParamTraits<base::DictionaryValue> { |
733 typedef FilePath param_type; | 483 typedef base::DictionaryValue param_type; |
734 static void Write(Message* m, const param_type& p); | 484 static void Write(Message* m, const param_type& p); |
735 static bool Read(const Message* m, PickleIterator* iter, param_type* r); | 485 static bool Read(const Message* m, PickleIterator* iter, param_type* r); |
736 static void Log(const param_type& p, std::string* l); | 486 static void Log(const param_type& p, std::string* l); |
737 }; | 487 }; |
738 | 488 |
739 #if defined(OS_POSIX) | 489 #if defined(OS_POSIX) |
740 // FileDescriptors may be serialised over IPC channels on POSIX. On the | 490 // FileDescriptors may be serialised over IPC channels on POSIX. On the |
741 // receiving side, the FileDescriptor is a valid duplicate of the file | 491 // receiving side, the FileDescriptor is a valid duplicate of the file |
742 // descriptor which was transmitted: *it is not just a copy of the integer like | 492 // descriptor which was transmitted: *it is not just a copy of the integer like |
743 // HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In | 493 // HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In |
(...skipping 10 matching lines...) Expand all Loading... |
754 // flag, which causes the file descriptor to be closed after writing. | 504 // flag, which causes the file descriptor to be closed after writing. |
755 template<> | 505 template<> |
756 struct IPC_EXPORT ParamTraits<base::FileDescriptor> { | 506 struct IPC_EXPORT ParamTraits<base::FileDescriptor> { |
757 typedef base::FileDescriptor param_type; | 507 typedef base::FileDescriptor param_type; |
758 static void Write(Message* m, const param_type& p); | 508 static void Write(Message* m, const param_type& p); |
759 static bool Read(const Message* m, PickleIterator* iter, param_type* r); | 509 static bool Read(const Message* m, PickleIterator* iter, param_type* r); |
760 static void Log(const param_type& p, std::string* l); | 510 static void Log(const param_type& p, std::string* l); |
761 }; | 511 }; |
762 #endif // defined(OS_POSIX) | 512 #endif // defined(OS_POSIX) |
763 | 513 |
764 // A ChannelHandle is basically a platform-inspecific wrapper around the | 514 template <> |
765 // fact that IPC endpoints are handled specially on POSIX. See above comments | 515 struct IPC_EXPORT ParamTraits<FilePath> { |
766 // on FileDescriptor for more background. | 516 typedef FilePath param_type; |
767 template<> | |
768 struct IPC_EXPORT ParamTraits<IPC::ChannelHandle> { | |
769 typedef ChannelHandle param_type; | |
770 static void Write(Message* m, const param_type& p); | 517 static void Write(Message* m, const param_type& p); |
771 static bool Read(const Message* m, PickleIterator* iter, param_type* r); | 518 static bool Read(const Message* m, PickleIterator* iter, param_type* r); |
772 static void Log(const param_type& p, std::string* l); | 519 static void Log(const param_type& p, std::string* l); |
773 }; | 520 }; |
774 | 521 |
775 struct IPC_EXPORT LogData { | 522 template <> |
776 LogData(); | 523 struct IPC_EXPORT ParamTraits<base::ListValue> { |
777 ~LogData(); | 524 typedef base::ListValue param_type; |
778 | 525 static void Write(Message* m, const param_type& p); |
779 std::string channel; | 526 static bool Read(const Message* m, PickleIterator* iter, param_type* r); |
780 int32 routing_id; | 527 static void Log(const param_type& p, std::string* l); |
781 uint32 type; // "User-defined" message type, from ipc_message.h. | |
782 std::string flags; | |
783 int64 sent; // Time that the message was sent (i.e. at Send()). | |
784 int64 receive; // Time before it was dispatched (i.e. before calling | |
785 // OnMessageReceived). | |
786 int64 dispatch; // Time after it was dispatched (i.e. after calling | |
787 // OnMessageReceived). | |
788 std::string message_name; | |
789 std::string params; | |
790 }; | 528 }; |
791 | 529 |
792 template <> | 530 template <> |
793 struct IPC_EXPORT ParamTraits<LogData> { | 531 struct IPC_EXPORT ParamTraits<NullableString16> { |
794 typedef LogData param_type; | 532 typedef NullableString16 param_type; |
795 static void Write(Message* m, const param_type& p); | 533 static void Write(Message* m, const param_type& p); |
796 static bool Read(const Message* m, PickleIterator* iter, param_type* r); | 534 static bool Read(const Message* m, PickleIterator* iter, |
797 static void Log(const param_type& p, std::string* l) { | 535 param_type* r); |
798 // Doesn't make sense to implement this! | 536 static void Log(const param_type& p, std::string* l); |
799 } | |
800 }; | 537 }; |
801 | 538 |
802 template <> | 539 template <> |
803 struct ParamTraits<Message> { | 540 struct IPC_EXPORT ParamTraits<base::PlatformFileInfo> { |
804 static void Write(Message* m, const Message& p) { | 541 typedef base::PlatformFileInfo param_type; |
805 DCHECK(p.size() <= INT_MAX); | 542 static void Write(Message* m, const param_type& p); |
806 int message_size = static_cast<int>(p.size()); | 543 static bool Read(const Message* m, PickleIterator* iter, param_type* r); |
807 m->WriteInt(message_size); | 544 static void Log(const param_type& p, std::string* l); |
808 m->WriteData(reinterpret_cast<const char*>(p.data()), message_size); | |
809 } | |
810 static bool Read(const Message* m, PickleIterator* iter, Message* r) { | |
811 int size; | |
812 if (!m->ReadInt(iter, &size)) | |
813 return false; | |
814 const char* data; | |
815 if (!m->ReadData(iter, &data, &size)) | |
816 return false; | |
817 *r = Message(data, size); | |
818 return true; | |
819 } | |
820 static void Log(const Message& p, std::string* l) { | |
821 l->append("<IPC::Message>"); | |
822 } | |
823 }; | 545 }; |
824 | 546 |
825 template <> | 547 template <> |
| 548 struct SimilarTypeTraits<base::PlatformFileError> { |
| 549 typedef int Type; |
| 550 }; |
| 551 |
| 552 template <> |
| 553 struct IPC_EXPORT ParamTraits<base::Time> { |
| 554 typedef base::Time param_type; |
| 555 static void Write(Message* m, const param_type& p); |
| 556 static bool Read(const Message* m, PickleIterator* iter, param_type* r); |
| 557 static void Log(const param_type& p, std::string* l); |
| 558 }; |
| 559 |
| 560 template <> |
| 561 struct IPC_EXPORT ParamTraits<base::TimeDelta> { |
| 562 typedef base::TimeDelta param_type; |
| 563 static void Write(Message* m, const param_type& p); |
| 564 static bool Read(const Message* m, PickleIterator* iter, param_type* r); |
| 565 static void Log(const param_type& p, std::string* l); |
| 566 }; |
| 567 |
| 568 template <> |
| 569 struct IPC_EXPORT ParamTraits<base::TimeTicks> { |
| 570 typedef base::TimeTicks param_type; |
| 571 static void Write(Message* m, const param_type& p); |
| 572 static bool Read(const Message* m, PickleIterator* iter, param_type* r); |
| 573 static void Log(const param_type& p, std::string* l); |
| 574 }; |
| 575 |
| 576 template <> |
826 struct ParamTraits<Tuple0> { | 577 struct ParamTraits<Tuple0> { |
827 typedef Tuple0 param_type; | 578 typedef Tuple0 param_type; |
828 static void Write(Message* m, const param_type& p) { | 579 static void Write(Message* m, const param_type& p) { |
829 } | 580 } |
830 static bool Read(const Message* m, PickleIterator* iter, param_type* r) { | 581 static bool Read(const Message* m, PickleIterator* iter, param_type* r) { |
831 return true; | 582 return true; |
832 } | 583 } |
833 static void Log(const param_type& p, std::string* l) { | 584 static void Log(const param_type& p, std::string* l) { |
834 } | 585 } |
835 }; | 586 }; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
937 LogParam(p.b, l); | 688 LogParam(p.b, l); |
938 l->append(", "); | 689 l->append(", "); |
939 LogParam(p.c, l); | 690 LogParam(p.c, l); |
940 l->append(", "); | 691 l->append(", "); |
941 LogParam(p.d, l); | 692 LogParam(p.d, l); |
942 l->append(", "); | 693 l->append(", "); |
943 LogParam(p.e, l); | 694 LogParam(p.e, l); |
944 } | 695 } |
945 }; | 696 }; |
946 | 697 |
| 698 // IPC types ParamTraits ------------------------------------------------------- |
| 699 |
| 700 // A ChannelHandle is basically a platform-inspecific wrapper around the |
| 701 // fact that IPC endpoints are handled specially on POSIX. See above comments |
| 702 // on FileDescriptor for more background. |
| 703 template<> |
| 704 struct IPC_EXPORT ParamTraits<IPC::ChannelHandle> { |
| 705 typedef ChannelHandle param_type; |
| 706 static void Write(Message* m, const param_type& p); |
| 707 static bool Read(const Message* m, PickleIterator* iter, param_type* r); |
| 708 static void Log(const param_type& p, std::string* l); |
| 709 }; |
| 710 |
| 711 template <> |
| 712 struct IPC_EXPORT ParamTraits<LogData> { |
| 713 typedef LogData param_type; |
| 714 static void Write(Message* m, const param_type& p); |
| 715 static bool Read(const Message* m, PickleIterator* iter, param_type* r); |
| 716 static void Log(const param_type& p, std::string* l); |
| 717 }; |
| 718 |
| 719 template <> |
| 720 struct IPC_EXPORT ParamTraits<Message> { |
| 721 static void Write(Message* m, const Message& p); |
| 722 static bool Read(const Message* m, PickleIterator* iter, Message* r); |
| 723 static void Log(const Message& p, std::string* l); |
| 724 }; |
| 725 |
| 726 // Windows ParamTraits --------------------------------------------------------- |
| 727 |
| 728 #if defined(OS_WIN) |
| 729 template <> |
| 730 struct IPC_EXPORT ParamTraits<HANDLE> { |
| 731 typedef HANDLE param_type; |
| 732 static void Write(Message* m, const param_type& p); |
| 733 static bool Read(const Message* m, PickleIterator* iter, param_type* r); |
| 734 static void Log(const param_type& p, std::string* l); |
| 735 }; |
| 736 |
| 737 template <> |
| 738 struct IPC_EXPORT ParamTraits<LOGFONT> { |
| 739 typedef LOGFONT param_type; |
| 740 static void Write(Message* m, const param_type& p); |
| 741 static bool Read(const Message* m, PickleIterator* iter, param_type* r); |
| 742 static void Log(const param_type& p, std::string* l); |
| 743 }; |
| 744 |
| 745 template <> |
| 746 struct IPC_EXPORT ParamTraits<MSG> { |
| 747 typedef MSG param_type; |
| 748 static void Write(Message* m, const param_type& p); |
| 749 static bool Read(const Message* m, PickleIterator* iter, param_type* r); |
| 750 static void Log(const param_type& p, std::string* l); |
| 751 }; |
| 752 #endif // defined(OS_WIN) |
| 753 |
947 //----------------------------------------------------------------------------- | 754 //----------------------------------------------------------------------------- |
948 // Generic message subclasses | 755 // Generic message subclasses |
949 | 756 |
950 // Used for asynchronous messages. | 757 // Used for asynchronous messages. |
951 template <class ParamType> | 758 template <class ParamType> |
952 class MessageSchema { | 759 class MessageSchema { |
953 public: | 760 public: |
954 typedef ParamType Param; | 761 typedef ParamType Param; |
955 typedef typename TupleTypes<ParamType>::ParamTuple RefParam; | 762 typedef typename TupleTypes<ParamType>::ParamTuple RefParam; |
956 | 763 |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1093 WriteParam(reply, p); | 900 WriteParam(reply, p); |
1094 } | 901 } |
1095 | 902 |
1096 template<typename TA, typename TB, typename TC, typename TD, typename TE> | 903 template<typename TA, typename TB, typename TC, typename TD, typename TE> |
1097 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) { | 904 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) { |
1098 ReplyParam p(a, b, c, d, e); | 905 ReplyParam p(a, b, c, d, e); |
1099 WriteParam(reply, p); | 906 WriteParam(reply, p); |
1100 } | 907 } |
1101 }; | 908 }; |
1102 | 909 |
1103 //----------------------------------------------------------------------------- | |
1104 | |
1105 } // namespace IPC | 910 } // namespace IPC |
1106 | 911 |
1107 #endif // IPC_IPC_MESSAGE_UTILS_H_ | 912 #endif // IPC_IPC_MESSAGE_UTILS_H_ |
OLD | NEW |