blob: 19622b26885093f74f2cbac284ab129defd12dd0 [file] [log] [blame]
[email protected]efb5f572012-01-29 10:57:331// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]946d1b22009-07-22 23:57:215#ifndef IPC_IPC_MESSAGE_UTILS_H_
6#define IPC_IPC_MESSAGE_UTILS_H_
initial.commit09911bf2008-07-26 23:55:297
[email protected]379e7a52010-03-09 00:38:418#include <algorithm>
initial.commit09911bf2008-07-26 23:55:299#include <map>
[email protected]96da6962010-05-13 19:10:3410#include <set>
[email protected]663bd9e2011-03-21 01:07:0111#include <string>
12#include <vector>
initial.commit09911bf2008-07-26 23:55:2913
[email protected]dce5df52009-06-29 17:58:2514#include "base/format_macros.h"
[email protected]b1064d62012-11-14 06:35:5215#include "base/memory/scoped_vector.h"
[email protected]c410e022012-05-30 21:15:5716#include "base/platform_file.h"
[email protected]eb47a132009-03-04 00:39:5617#include "base/string16.h"
[email protected]6782f832011-05-10 04:06:0018#include "base/stringprintf.h"
[email protected]dce5df52009-06-29 17:58:2519#include "base/string_util.h"
initial.commit09911bf2008-07-26 23:55:2920#include "base/tuple.h"
[email protected]f9509812012-10-23 23:03:3521#include "ipc/ipc_message_start.h"
[email protected]939856a2010-08-24 20:29:0222#include "ipc/ipc_param_traits.h"
[email protected]0cfe5dae2010-08-17 00:24:5423#include "ipc/ipc_sync_message.h"
[email protected]55b4e212010-08-13 20:43:5824
[email protected]7a4de7a62010-08-17 18:38:2425#if defined(COMPILER_GCC)
26// GCC "helpfully" tries to inline template methods in release mode. Except we
27// want the majority of the template junk being expanded once in the
28// implementation file (and only provide the definitions in
29// ipc_message_utils_impl.h in those files) and exported, instead of expanded
30// at every call site. Special note: GCC happily accepts the attribute before
31// the method declaration, but only acts on it if it is after.
[email protected]efafbbd2010-08-19 20:23:2532#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 40500
33// Starting in gcc 4.5, the noinline no longer implies the concept covered by
34// the introduced noclone attribute, which will create specialized versions of
35// functions/methods when certain types are constant.
36// www.gnu.org/software/gcc/gcc-4.5/changes.html
37#define IPC_MSG_NOINLINE __attribute__((noinline, noclone));
38#else
[email protected]7a4de7a62010-08-17 18:38:2439#define IPC_MSG_NOINLINE __attribute__((noinline));
[email protected]efafbbd2010-08-19 20:23:2540#endif
[email protected]7a4de7a62010-08-17 18:38:2441#elif defined(COMPILER_MSVC)
42// MSVC++ doesn't do this.
43#define IPC_MSG_NOINLINE
44#else
45#error "Please add the noinline property for your new compiler here."
46#endif
47
[email protected]7a4de7a62010-08-17 18:38:2448class FilePath;
[email protected]7a4de7a62010-08-17 18:38:2449class NullableString16;
50
51namespace base {
[email protected]f3a1c642011-07-12 19:15:0352class DictionaryValue;
53class ListValue;
[email protected]7a4de7a62010-08-17 18:38:2454class Time;
[email protected]d84e48b2010-10-21 22:04:5255class TimeDelta;
[email protected]1d14f582011-09-02 20:42:0456class TimeTicks;
[email protected]7a4de7a62010-08-17 18:38:2457struct FileDescriptor;
58}
59
initial.commit09911bf2008-07-26 23:55:2960namespace IPC {
61
[email protected]7a4de7a62010-08-17 18:38:2462struct ChannelHandle;
63
initial.commit09911bf2008-07-26 23:55:2964//-----------------------------------------------------------------------------
65// An iterator class for reading the fields contained within a Message.
[email protected]bf5aedf02012-06-04 21:18:2566class IPC_EXPORT MessageIterator {
initial.commit09911bf2008-07-26 23:55:2967 public:
[email protected]bf5aedf02012-06-04 21:18:2568 explicit MessageIterator(const Message& m);
69
70 int NextInt() const;
71 const std::string NextString() const;
72
initial.commit09911bf2008-07-26 23:55:2973 private:
[email protected]ce208f872012-03-07 20:42:5674 mutable PickleIterator iter_;
initial.commit09911bf2008-07-26 23:55:2975};
76
[email protected]bf5aedf02012-06-04 21:18:2577// -----------------------------------------------------------------------------
78// How we send IPC message logs across channels.
79struct IPC_EXPORT LogData {
80 LogData();
81 ~LogData();
82
83 std::string channel;
84 int32 routing_id;
85 uint32 type; // "User-defined" message type, from ipc_message.h.
86 std::string flags;
87 int64 sent; // Time that the message was sent (i.e. at Send()).
88 int64 receive; // Time before it was dispatched (i.e. before calling
89 // OnMessageReceived).
90 int64 dispatch; // Time after it was dispatched (i.e. after calling
91 // OnMessageReceived).
92 std::string message_name;
93 std::string params;
94};
95
96
initial.commit09911bf2008-07-26 23:55:2997//-----------------------------------------------------------------------------
[email protected]6476c72c2011-02-11 18:46:1998// A dummy struct to place first just to allow leading commas for all
99// members in the macro-generated constructor initializer lists.
100struct NoParams {
101};
102
[email protected]7d5c3ac2009-02-04 08:58:19103template <class P>
104static inline void WriteParam(Message* m, const P& p) {
[email protected]7b291f92009-08-14 05:43:53105 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53106 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
[email protected]7d5c3ac2009-02-04 08:58:19107}
108
109template <class P>
[email protected]ce208f872012-03-07 20:42:56110static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m,
111 PickleIterator* iter,
[email protected]1e86aa62009-04-24 21:22:33112 P* p) {
[email protected]7b291f92009-08-14 05:43:53113 typedef typename SimilarTypeTraits<P>::Type Type;
114 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
[email protected]7d5c3ac2009-02-04 08:58:19115}
116
117template <class P>
[email protected]252cad62010-08-18 18:33:57118static inline void LogParam(const P& p, std::string* l) {
[email protected]7b291f92009-08-14 05:43:53119 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53120 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19121}
122
[email protected]bf5aedf02012-06-04 21:18:25123// Primitive ParamTraits -------------------------------------------------------
124
[email protected]7d5c3ac2009-02-04 08:58:19125template <>
126struct ParamTraits<bool> {
127 typedef bool param_type;
128 static void Write(Message* m, const param_type& p) {
129 m->WriteBool(p);
130 }
[email protected]bf5aedf02012-06-04 21:18:25131 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19132 return m->ReadBool(iter, r);
133 }
[email protected]bf5aedf02012-06-04 21:18:25134 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19135};
136
137template <>
138struct ParamTraits<int> {
139 typedef int param_type;
140 static void Write(Message* m, const param_type& p) {
141 m->WriteInt(p);
142 }
[email protected]bf5aedf02012-06-04 21:18:25143 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19144 return m->ReadInt(iter, r);
145 }
[email protected]7c854372011-08-15 20:41:46146 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19147};
148
149template <>
[email protected]63263f92009-07-28 19:35:08150struct ParamTraits<unsigned int> {
151 typedef unsigned int param_type;
152 static void Write(Message* m, const param_type& p) {
153 m->WriteInt(p);
154 }
[email protected]bf5aedf02012-06-04 21:18:25155 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]63263f92009-07-28 19:35:08156 return m->ReadInt(iter, reinterpret_cast<int*>(r));
157 }
[email protected]7c854372011-08-15 20:41:46158 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08159};
160
161template <>
[email protected]7d5c3ac2009-02-04 08:58:19162struct ParamTraits<long> {
163 typedef long param_type;
164 static void Write(Message* m, const param_type& p) {
[email protected]c272d082012-03-23 00:03:10165 m->WriteLongUsingDangerousNonPortableLessPersistableForm(p);
[email protected]7d5c3ac2009-02-04 08:58:19166 }
[email protected]bf5aedf02012-06-04 21:18:25167 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19168 return m->ReadLong(iter, r);
169 }
[email protected]7c854372011-08-15 20:41:46170 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19171};
172
[email protected]140c3032009-06-26 18:22:54173template <>
174struct ParamTraits<unsigned long> {
175 typedef unsigned long param_type;
176 static void Write(Message* m, const param_type& p) {
[email protected]c272d082012-03-23 00:03:10177 m->WriteLongUsingDangerousNonPortableLessPersistableForm(p);
[email protected]140c3032009-06-26 18:22:54178 }
[email protected]bf5aedf02012-06-04 21:18:25179 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]63263f92009-07-28 19:35:08180 return m->ReadLong(iter, reinterpret_cast<long*>(r));
[email protected]140c3032009-06-26 18:22:54181 }
[email protected]7c854372011-08-15 20:41:46182 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19183};
184
185template <>
[email protected]63263f92009-07-28 19:35:08186struct ParamTraits<long long> {
187 typedef long long param_type;
[email protected]7d5c3ac2009-02-04 08:58:19188 static void Write(Message* m, const param_type& p) {
189 m->WriteInt64(static_cast<int64>(p));
190 }
[email protected]ce208f872012-03-07 20:42:56191 static bool Read(const Message* m, PickleIterator* iter,
192 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19193 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
194 }
[email protected]7c854372011-08-15 20:41:46195 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08196};
197
198template <>
199struct ParamTraits<unsigned long long> {
200 typedef unsigned long long param_type;
201 static void Write(Message* m, const param_type& p) {
202 m->WriteInt64(p);
203 }
[email protected]ce208f872012-03-07 20:42:56204 static bool Read(const Message* m, PickleIterator* iter,
205 param_type* r) {
[email protected]63263f92009-07-28 19:35:08206 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
207 }
[email protected]7c854372011-08-15 20:41:46208 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19209};
210
[email protected]43a40202010-11-12 16:25:01211template <>
[email protected]7c854372011-08-15 20:41:46212struct IPC_EXPORT ParamTraits<unsigned short> {
[email protected]43a40202010-11-12 16:25:01213 typedef unsigned short param_type;
214 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56215 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]43a40202010-11-12 16:25:01216 static void Log(const param_type& p, std::string* l);
217};
218
[email protected]20199662010-06-17 03:29:26219// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
220// should be sure to check the sanity of these values after receiving them over
221// IPC.
222template <>
[email protected]bf5aedf02012-06-04 21:18:25223struct IPC_EXPORT ParamTraits<float> {
[email protected]20199662010-06-17 03:29:26224 typedef float param_type;
[email protected]bf5aedf02012-06-04 21:18:25225 static void Write(Message* m, const param_type& p);
226 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
227 static void Log(const param_type& p, std::string* l);
[email protected]20199662010-06-17 03:29:26228};
229
[email protected]7d5c3ac2009-02-04 08:58:19230template <>
[email protected]bf5aedf02012-06-04 21:18:25231struct IPC_EXPORT ParamTraits<double> {
[email protected]7d5c3ac2009-02-04 08:58:19232 typedef double param_type;
[email protected]c410e022012-05-30 21:15:57233 static void Write(Message* m, const param_type& p);
234 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
235 static void Log(const param_type& p, std::string* l);
236};
237
[email protected]bf5aedf02012-06-04 21:18:25238// STL ParamTraits -------------------------------------------------------------
[email protected]584f2b22009-05-21 01:01:59239
240template <>
[email protected]7d5c3ac2009-02-04 08:58:19241struct ParamTraits<std::string> {
242 typedef std::string param_type;
243 static void Write(Message* m, const param_type& p) {
244 m->WriteString(p);
245 }
[email protected]ce208f872012-03-07 20:42:56246 static bool Read(const Message* m, PickleIterator* iter,
247 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19248 return m->ReadString(iter, r);
249 }
[email protected]bf5aedf02012-06-04 21:18:25250 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19251};
252
[email protected]bf5aedf02012-06-04 21:18:25253template <>
254struct ParamTraits<std::wstring> {
255 typedef std::wstring param_type;
256 static void Write(Message* m, const param_type& p) {
257 m->WriteWString(p);
[email protected]3dd7a7a2009-07-27 21:09:07258 }
[email protected]bf5aedf02012-06-04 21:18:25259 static bool Read(const Message* m, PickleIterator* iter,
260 param_type* r) {
261 return m->ReadWString(iter, r);
[email protected]3dd7a7a2009-07-27 21:09:07262 }
[email protected]bf5aedf02012-06-04 21:18:25263 IPC_EXPORT static void Log(const param_type& p, std::string* l);
264};
265
266// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
267// need this trait.
268#if !defined(WCHAR_T_IS_UTF16)
269template <>
270struct ParamTraits<string16> {
271 typedef string16 param_type;
272 static void Write(Message* m, const param_type& p) {
273 m->WriteString16(p);
274 }
275 static bool Read(const Message* m, PickleIterator* iter,
276 param_type* r) {
277 return m->ReadString16(iter, r);
278 }
279 IPC_EXPORT static void Log(const param_type& p, std::string* l);
280};
[email protected]3dd7a7a2009-07-27 21:09:07281#endif
[email protected]3dd7a7a2009-07-27 21:09:07282
[email protected]7d5c3ac2009-02-04 08:58:19283template <>
[email protected]bf5aedf02012-06-04 21:18:25284struct IPC_EXPORT ParamTraits<std::vector<char> > {
[email protected]7d5c3ac2009-02-04 08:58:19285 typedef std::vector<char> param_type;
[email protected]bf5aedf02012-06-04 21:18:25286 static void Write(Message* m, const param_type& p);
287 static bool Read(const Message*, PickleIterator* iter, param_type* r);
288 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19289};
290
[email protected]51b63f62011-10-05 18:55:42291template <>
[email protected]bf5aedf02012-06-04 21:18:25292struct IPC_EXPORT ParamTraits<std::vector<unsigned char> > {
293 typedef std::vector<unsigned char> param_type;
294 static void Write(Message* m, const param_type& p);
295 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
296 static void Log(const param_type& p, std::string* l);
297};
298
299template <>
300struct IPC_EXPORT ParamTraits<std::vector<bool> > {
[email protected]51b63f62011-10-05 18:55:42301 typedef std::vector<bool> param_type;
[email protected]bf5aedf02012-06-04 21:18:25302 static void Write(Message* m, const param_type& p);
303 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
304 static void Log(const param_type& p, std::string* l);
[email protected]51b63f62011-10-05 18:55:42305};
306
[email protected]7d5c3ac2009-02-04 08:58:19307template <class P>
308struct ParamTraits<std::vector<P> > {
309 typedef std::vector<P> param_type;
310 static void Write(Message* m, const param_type& p) {
311 WriteParam(m, static_cast<int>(p.size()));
312 for (size_t i = 0; i < p.size(); i++)
313 WriteParam(m, p[i]);
314 }
[email protected]ce208f872012-03-07 20:42:56315 static bool Read(const Message* m, PickleIterator* iter,
316 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19317 int size;
[email protected]86440f52009-12-31 05:17:23318 // ReadLength() checks for < 0 itself.
[email protected]7d5c3ac2009-02-04 08:58:19319 if (!m->ReadLength(iter, &size))
320 return false;
321 // Resizing beforehand is not safe, see BUG 1006367 for details.
[email protected]86440f52009-12-31 05:17:23322 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
323 return false;
324 r->resize(size);
325 for (int i = 0; i < size; i++) {
326 if (!ReadParam(m, iter, &(*r)[i]))
327 return false;
[email protected]7d5c3ac2009-02-04 08:58:19328 }
329 return true;
330 }
[email protected]252cad62010-08-18 18:33:57331 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19332 for (size_t i = 0; i < p.size(); ++i) {
333 if (i != 0)
[email protected]252cad62010-08-18 18:33:57334 l->append(" ");
[email protected]7d5c3ac2009-02-04 08:58:19335 LogParam((p[i]), l);
336 }
337 }
338};
339
[email protected]96da6962010-05-13 19:10:34340template <class P>
341struct ParamTraits<std::set<P> > {
342 typedef std::set<P> param_type;
343 static void Write(Message* m, const param_type& p) {
344 WriteParam(m, static_cast<int>(p.size()));
345 typename param_type::const_iterator iter;
346 for (iter = p.begin(); iter != p.end(); ++iter)
347 WriteParam(m, *iter);
348 }
[email protected]ce208f872012-03-07 20:42:56349 static bool Read(const Message* m, PickleIterator* iter,
350 param_type* r) {
[email protected]96da6962010-05-13 19:10:34351 int size;
352 if (!m->ReadLength(iter, &size))
353 return false;
354 for (int i = 0; i < size; ++i) {
355 P item;
356 if (!ReadParam(m, iter, &item))
357 return false;
358 r->insert(item);
359 }
360 return true;
361 }
[email protected]252cad62010-08-18 18:33:57362 static void Log(const param_type& p, std::string* l) {
363 l->append("<std::set>");
[email protected]96da6962010-05-13 19:10:34364 }
365};
366
[email protected]7d5c3ac2009-02-04 08:58:19367template <class K, class V>
368struct ParamTraits<std::map<K, V> > {
369 typedef std::map<K, V> param_type;
370 static void Write(Message* m, const param_type& p) {
371 WriteParam(m, static_cast<int>(p.size()));
372 typename param_type::const_iterator iter;
373 for (iter = p.begin(); iter != p.end(); ++iter) {
374 WriteParam(m, iter->first);
375 WriteParam(m, iter->second);
376 }
377 }
[email protected]ce208f872012-03-07 20:42:56378 static bool Read(const Message* m, PickleIterator* iter,
379 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19380 int size;
381 if (!ReadParam(m, iter, &size) || size < 0)
382 return false;
383 for (int i = 0; i < size; ++i) {
384 K k;
385 if (!ReadParam(m, iter, &k))
386 return false;
387 V& value = (*r)[k];
388 if (!ReadParam(m, iter, &value))
389 return false;
390 }
391 return true;
392 }
[email protected]252cad62010-08-18 18:33:57393 static void Log(const param_type& p, std::string* l) {
394 l->append("<std::map>");
[email protected]7d5c3ac2009-02-04 08:58:19395 }
396};
397
[email protected]a5da6d612009-08-04 02:00:56398template <class A, class B>
399struct ParamTraits<std::pair<A, B> > {
400 typedef std::pair<A, B> param_type;
401 static void Write(Message* m, const param_type& p) {
402 WriteParam(m, p.first);
403 WriteParam(m, p.second);
404 }
[email protected]ce208f872012-03-07 20:42:56405 static bool Read(const Message* m, PickleIterator* iter,
406 param_type* r) {
[email protected]a5da6d612009-08-04 02:00:56407 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
408 }
[email protected]252cad62010-08-18 18:33:57409 static void Log(const param_type& p, std::string* l) {
410 l->append("(");
[email protected]a5da6d612009-08-04 02:00:56411 LogParam(p.first, l);
[email protected]252cad62010-08-18 18:33:57412 l->append(", ");
[email protected]a5da6d612009-08-04 02:00:56413 LogParam(p.second, l);
[email protected]252cad62010-08-18 18:33:57414 l->append(")");
[email protected]a5da6d612009-08-04 02:00:56415 }
416};
417
[email protected]bf5aedf02012-06-04 21:18:25418// Base ParamTraits ------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19419
420template <>
[email protected]bf5aedf02012-06-04 21:18:25421struct IPC_EXPORT ParamTraits<base::DictionaryValue> {
422 typedef base::DictionaryValue param_type;
[email protected]7a4de7a62010-08-17 18:38:24423 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56424 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57425 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19426};
427
[email protected]526776c2009-02-07 00:39:26428#if defined(OS_POSIX)
[email protected]2749885f2009-03-05 21:40:11429// FileDescriptors may be serialised over IPC channels on POSIX. On the
430// receiving side, the FileDescriptor is a valid duplicate of the file
431// descriptor which was transmitted: *it is not just a copy of the integer like
432// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
433// this case, the receiving end will see a value of -1. *Zero is a valid file
434// descriptor*.
435//
436// The received file descriptor will have the |auto_close| flag set to true. The
437// code which handles the message is responsible for taking ownership of it.
438// File descriptors are OS resources and must be closed when no longer needed.
439//
440// When sending a file descriptor, the file descriptor must be valid at the time
441// of transmission. Since transmission is not synchronous, one should consider
442// dup()ing any file descriptors to be transmitted and setting the |auto_close|
443// flag, which causes the file descriptor to be closed after writing.
[email protected]526776c2009-02-07 00:39:26444template<>
[email protected]7c854372011-08-15 20:41:46445struct IPC_EXPORT ParamTraits<base::FileDescriptor> {
[email protected]5fe733de2009-02-11 18:59:20446 typedef base::FileDescriptor param_type;
[email protected]7a4de7a62010-08-17 18:38:24447 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56448 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57449 static void Log(const param_type& p, std::string* l);
[email protected]526776c2009-02-07 00:39:26450};
[email protected]379e7a52010-03-09 00:38:41451#endif // defined(OS_POSIX)
[email protected]526776c2009-02-07 00:39:26452
[email protected]bf5aedf02012-06-04 21:18:25453template <>
454struct IPC_EXPORT ParamTraits<FilePath> {
455 typedef FilePath param_type;
[email protected]7a4de7a62010-08-17 18:38:24456 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56457 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57458 static void Log(const param_type& p, std::string* l);
[email protected]d2e884d2009-06-22 20:37:52459};
460
[email protected]7d5c3ac2009-02-04 08:58:19461template <>
[email protected]bf5aedf02012-06-04 21:18:25462struct IPC_EXPORT ParamTraits<base::ListValue> {
463 typedef base::ListValue param_type;
[email protected]20f0487a2010-09-30 20:06:30464 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56465 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25466 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19467};
468
[email protected]eb47a132009-03-04 00:39:56469template <>
[email protected]bf5aedf02012-06-04 21:18:25470struct IPC_EXPORT ParamTraits<NullableString16> {
471 typedef NullableString16 param_type;
472 static void Write(Message* m, const param_type& p);
473 static bool Read(const Message* m, PickleIterator* iter,
474 param_type* r);
475 static void Log(const param_type& p, std::string* l);
476};
477
478template <>
479struct IPC_EXPORT ParamTraits<base::PlatformFileInfo> {
480 typedef base::PlatformFileInfo param_type;
481 static void Write(Message* m, const param_type& p);
482 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
483 static void Log(const param_type& p, std::string* l);
484};
485
486template <>
487struct SimilarTypeTraits<base::PlatformFileError> {
488 typedef int Type;
489};
490
491template <>
492struct IPC_EXPORT ParamTraits<base::Time> {
493 typedef base::Time param_type;
494 static void Write(Message* m, const param_type& p);
495 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
496 static void Log(const param_type& p, std::string* l);
497};
498
499template <>
500struct IPC_EXPORT ParamTraits<base::TimeDelta> {
501 typedef base::TimeDelta param_type;
502 static void Write(Message* m, const param_type& p);
503 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
504 static void Log(const param_type& p, std::string* l);
505};
506
507template <>
508struct IPC_EXPORT ParamTraits<base::TimeTicks> {
509 typedef base::TimeTicks param_type;
510 static void Write(Message* m, const param_type& p);
511 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
512 static void Log(const param_type& p, std::string* l);
[email protected]503683f2009-02-26 09:13:01513};
514
515template <>
[email protected]7d5c3ac2009-02-04 08:58:19516struct ParamTraits<Tuple0> {
517 typedef Tuple0 param_type;
518 static void Write(Message* m, const param_type& p) {
519 }
[email protected]ce208f872012-03-07 20:42:56520 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19521 return true;
522 }
[email protected]252cad62010-08-18 18:33:57523 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19524 }
525};
526
527template <class A>
528struct ParamTraits< Tuple1<A> > {
529 typedef Tuple1<A> param_type;
530 static void Write(Message* m, const param_type& p) {
531 WriteParam(m, p.a);
532 }
[email protected]ce208f872012-03-07 20:42:56533 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19534 return ReadParam(m, iter, &r->a);
535 }
[email protected]252cad62010-08-18 18:33:57536 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19537 LogParam(p.a, l);
538 }
539};
540
541template <class A, class B>
542struct ParamTraits< Tuple2<A, B> > {
543 typedef Tuple2<A, B> param_type;
544 static void Write(Message* m, const param_type& p) {
545 WriteParam(m, p.a);
546 WriteParam(m, p.b);
547 }
[email protected]ce208f872012-03-07 20:42:56548 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19549 return (ReadParam(m, iter, &r->a) &&
550 ReadParam(m, iter, &r->b));
551 }
[email protected]252cad62010-08-18 18:33:57552 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19553 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57554 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19555 LogParam(p.b, l);
556 }
557};
558
559template <class A, class B, class C>
560struct ParamTraits< Tuple3<A, B, C> > {
561 typedef Tuple3<A, B, C> param_type;
562 static void Write(Message* m, const param_type& p) {
563 WriteParam(m, p.a);
564 WriteParam(m, p.b);
565 WriteParam(m, p.c);
566 }
[email protected]ce208f872012-03-07 20:42:56567 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19568 return (ReadParam(m, iter, &r->a) &&
569 ReadParam(m, iter, &r->b) &&
570 ReadParam(m, iter, &r->c));
571 }
[email protected]252cad62010-08-18 18:33:57572 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19573 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57574 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19575 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57576 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19577 LogParam(p.c, l);
578 }
579};
580
581template <class A, class B, class C, class D>
582struct ParamTraits< Tuple4<A, B, C, D> > {
583 typedef Tuple4<A, B, C, D> param_type;
584 static void Write(Message* m, const param_type& p) {
585 WriteParam(m, p.a);
586 WriteParam(m, p.b);
587 WriteParam(m, p.c);
588 WriteParam(m, p.d);
589 }
[email protected]ce208f872012-03-07 20:42:56590 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19591 return (ReadParam(m, iter, &r->a) &&
592 ReadParam(m, iter, &r->b) &&
593 ReadParam(m, iter, &r->c) &&
594 ReadParam(m, iter, &r->d));
595 }
[email protected]252cad62010-08-18 18:33:57596 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19597 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57598 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19599 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57600 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19601 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57602 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19603 LogParam(p.d, l);
604 }
605};
606
607template <class A, class B, class C, class D, class E>
608struct ParamTraits< Tuple5<A, B, C, D, E> > {
609 typedef Tuple5<A, B, C, D, E> param_type;
610 static void Write(Message* m, const param_type& p) {
611 WriteParam(m, p.a);
612 WriteParam(m, p.b);
613 WriteParam(m, p.c);
614 WriteParam(m, p.d);
615 WriteParam(m, p.e);
616 }
[email protected]ce208f872012-03-07 20:42:56617 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19618 return (ReadParam(m, iter, &r->a) &&
619 ReadParam(m, iter, &r->b) &&
620 ReadParam(m, iter, &r->c) &&
621 ReadParam(m, iter, &r->d) &&
622 ReadParam(m, iter, &r->e));
623 }
[email protected]252cad62010-08-18 18:33:57624 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19625 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57626 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19627 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57628 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19629 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57630 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19631 LogParam(p.d, l);
[email protected]252cad62010-08-18 18:33:57632 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19633 LogParam(p.e, l);
634 }
635};
636
[email protected]b1064d62012-11-14 06:35:52637template<class P>
638struct ParamTraits<ScopedVector<P> > {
639 typedef ScopedVector<P> param_type;
640 static void Write(Message* m, const param_type& p) {
641 WriteParam(m, static_cast<int>(p.size()));
642 for (size_t i = 0; i < p.size(); i++)
643 WriteParam(m, *p[i]);
644 }
645 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
646 int size = 0;
647 if (!m->ReadLength(iter, &size))
648 return false;
649 if (INT_MAX/sizeof(P) <= static_cast<size_t>(size))
650 return false;
651 r->resize(size);
652 for (int i = 0; i < size; i++) {
653 (*r)[i] = new P();
654 if (!ReadParam(m, iter, (*r)[i]))
655 return false;
656 }
657 return true;
658 }
659 static void Log(const param_type& p, std::string* l) {
660 for (size_t i = 0; i < p.size(); ++i) {
661 if (i != 0)
662 l->append(" ");
663 LogParam(*p[i], l);
664 }
665 }
666};
667
[email protected]bf5aedf02012-06-04 21:18:25668// IPC types ParamTraits -------------------------------------------------------
669
670// A ChannelHandle is basically a platform-inspecific wrapper around the
671// fact that IPC endpoints are handled specially on POSIX. See above comments
672// on FileDescriptor for more background.
673template<>
674struct IPC_EXPORT ParamTraits<IPC::ChannelHandle> {
675 typedef ChannelHandle param_type;
676 static void Write(Message* m, const param_type& p);
677 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
678 static void Log(const param_type& p, std::string* l);
679};
680
681template <>
682struct IPC_EXPORT ParamTraits<LogData> {
683 typedef LogData param_type;
684 static void Write(Message* m, const param_type& p);
685 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
686 static void Log(const param_type& p, std::string* l);
687};
688
689template <>
690struct IPC_EXPORT ParamTraits<Message> {
691 static void Write(Message* m, const Message& p);
692 static bool Read(const Message* m, PickleIterator* iter, Message* r);
693 static void Log(const Message& p, std::string* l);
694};
695
696// Windows ParamTraits ---------------------------------------------------------
697
698#if defined(OS_WIN)
699template <>
700struct IPC_EXPORT ParamTraits<HANDLE> {
701 typedef HANDLE param_type;
702 static void Write(Message* m, const param_type& p);
703 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
704 static void Log(const param_type& p, std::string* l);
705};
706
707template <>
708struct IPC_EXPORT ParamTraits<LOGFONT> {
709 typedef LOGFONT param_type;
710 static void Write(Message* m, const param_type& p);
711 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
712 static void Log(const param_type& p, std::string* l);
713};
714
715template <>
716struct IPC_EXPORT ParamTraits<MSG> {
717 typedef MSG param_type;
718 static void Write(Message* m, const param_type& p);
719 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
720 static void Log(const param_type& p, std::string* l);
721};
722#endif // defined(OS_WIN)
723
[email protected]7d5c3ac2009-02-04 08:58:19724//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:29725// Generic message subclasses
726
727// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:24728template <class ParamType>
[email protected]1d4ecf42011-08-26 21:27:30729class MessageSchema {
initial.commit09911bf2008-07-26 23:55:29730 public:
[email protected]81a34412009-01-05 19:17:24731 typedef ParamType Param;
[email protected]7a4de7a62010-08-17 18:38:24732 typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
[email protected]81a34412009-01-05 19:17:24733
[email protected]1d4ecf42011-08-26 21:27:30734 static void Write(Message* msg, const RefParam& p) IPC_MSG_NOINLINE;
[email protected]7a4de7a62010-08-17 18:38:24735 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:29736};
737
[email protected]7a4de7a62010-08-17 18:38:24738// defined in ipc_logging.cc
[email protected]7c854372011-08-15 20:41:46739IPC_EXPORT void GenerateLogData(const std::string& channel,
740 const Message& message,
[email protected]ea7744a2011-10-20 19:34:43741 LogData* data, bool get_params);
[email protected]7a4de7a62010-08-17 18:38:24742
743
744#if defined(IPC_MESSAGE_LOG_ENABLED)
[email protected]252cad62010-08-18 18:33:57745inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
746 const std::string& output_params = msg->output_params();
[email protected]7a4de7a62010-08-17 18:38:24747 if (!l->empty() && !output_params.empty())
[email protected]252cad62010-08-18 18:33:57748 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:24749
750 l->append(output_params);
751}
752
753template <class ReplyParamType>
754inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
755 const Message* msg) {
756 if (msg->received_time() != 0) {
[email protected]252cad62010-08-18 18:33:57757 std::string output_params;
[email protected]7a4de7a62010-08-17 18:38:24758 LogParam(reply_params, &output_params);
759 msg->set_output_params(output_params);
760 }
761}
762
763inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
764 if (msg->sent_time()) {
765 // Don't log the sync message after dispatch, as we don't have the
766 // output parameters at that point. Instead, save its data and log it
767 // with the outgoing reply message when it's sent.
768 LogData* data = new LogData;
[email protected]ea7744a2011-10-20 19:34:43769 GenerateLogData("", *msg, data, true);
[email protected]7a4de7a62010-08-17 18:38:24770 msg->set_dont_log();
771 reply->set_sync_log_data(data);
772 }
773}
774#else
[email protected]252cad62010-08-18 18:33:57775inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
[email protected]7a4de7a62010-08-17 18:38:24776
777template <class ReplyParamType>
778inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
779 const Message* msg) {}
780
781inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
782#endif
783
initial.commit09911bf2008-07-26 23:55:29784// This class assumes that its template argument is a RefTuple (a Tuple with
[email protected]7a4de7a62010-08-17 18:38:24785// reference elements). This would go into ipc_message_utils_impl.h, but it is
786// also used by chrome_frame.
initial.commit09911bf2008-07-26 23:55:29787template <class RefTuple>
788class ParamDeserializer : public MessageReplyDeserializer {
789 public:
[email protected]e1981f432008-08-12 15:22:13790 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:29791
[email protected]ce208f872012-03-07 20:42:56792 bool SerializeOutputParameters(const IPC::Message& msg, PickleIterator iter) {
initial.commit09911bf2008-07-26 23:55:29793 return ReadParam(&msg, &iter, &out_);
794 }
795
796 RefTuple out_;
797};
798
initial.commit09911bf2008-07-26 23:55:29799// Used for synchronous messages.
[email protected]75e5a872009-04-02 23:56:11800template <class SendParamType, class ReplyParamType>
[email protected]1d4ecf42011-08-26 21:27:30801class SyncMessageSchema {
initial.commit09911bf2008-07-26 23:55:29802 public:
[email protected]75e5a872009-04-02 23:56:11803 typedef SendParamType SendParam;
[email protected]7a4de7a62010-08-17 18:38:24804 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
[email protected]75e5a872009-04-02 23:56:11805 typedef ReplyParamType ReplyParam;
806
[email protected]1d4ecf42011-08-26 21:27:30807 static void Write(Message* msg, const RefSendParam& send) IPC_MSG_NOINLINE;
[email protected]7a4de7a62010-08-17 18:38:24808 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
809 static bool ReadReplyParam(
810 const Message* msg,
811 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:29812
[email protected]65412272010-12-21 20:03:24813 template<class T, class S, class Method>
[email protected]1d4ecf42011-08-26 21:27:30814 static bool DispatchWithSendParams(bool ok, const SendParam& send_params,
815 const Message* msg, T* obj, S* sender,
816 Method func) {
817 Message* reply = SyncMessage::GenerateReply(msg);
818 if (ok) {
[email protected]7a4de7a62010-08-17 18:38:24819 typename TupleTypes<ReplyParam>::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:29820 DispatchToMethod(obj, func, send_params, &reply_params);
821 WriteParam(reply, reply_params);
[email protected]7a4de7a62010-08-17 18:38:24822 LogReplyParamsToMessage(reply_params, msg);
initial.commit09911bf2008-07-26 23:55:29823 } else {
824 NOTREACHED() << "Error deserializing message " << msg->type();
825 reply->set_reply_error();
initial.commit09911bf2008-07-26 23:55:29826 }
[email protected]65412272010-12-21 20:03:24827 sender->Send(reply);
[email protected]1d4ecf42011-08-26 21:27:30828 return ok;
initial.commit09911bf2008-07-26 23:55:29829 }
830
831 template<class T, class Method>
[email protected]1d4ecf42011-08-26 21:27:30832 static bool DispatchDelayReplyWithSendParams(bool ok,
833 const SendParam& send_params,
834 const Message* msg, T* obj,
835 Method func) {
836 Message* reply = SyncMessage::GenerateReply(msg);
837 if (ok) {
initial.commit09911bf2008-07-26 23:55:29838 Tuple1<Message&> t = MakeRefTuple(*reply);
[email protected]7a4de7a62010-08-17 18:38:24839 ConnectMessageAndReply(msg, reply);
initial.commit09911bf2008-07-26 23:55:29840 DispatchToMethod(obj, func, send_params, &t);
initial.commit09911bf2008-07-26 23:55:29841 } else {
842 NOTREACHED() << "Error deserializing message " << msg->type();
843 reply->set_reply_error();
844 obj->Send(reply);
initial.commit09911bf2008-07-26 23:55:29845 }
[email protected]1d4ecf42011-08-26 21:27:30846 return ok;
initial.commit09911bf2008-07-26 23:55:29847 }
848
849 template<typename TA>
850 static void WriteReplyParams(Message* reply, TA a) {
851 ReplyParam p(a);
852 WriteParam(reply, p);
853 }
854
855 template<typename TA, typename TB>
856 static void WriteReplyParams(Message* reply, TA a, TB b) {
857 ReplyParam p(a, b);
858 WriteParam(reply, p);
859 }
860
861 template<typename TA, typename TB, typename TC>
862 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
863 ReplyParam p(a, b, c);
864 WriteParam(reply, p);
865 }
866
867 template<typename TA, typename TB, typename TC, typename TD>
868 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
869 ReplyParam p(a, b, c, d);
870 WriteParam(reply, p);
871 }
872
873 template<typename TA, typename TB, typename TC, typename TD, typename TE>
874 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
875 ReplyParam p(a, b, c, d, e);
876 WriteParam(reply, p);
877 }
878};
879
[email protected]3178f4e22008-08-05 21:20:41880} // namespace IPC
initial.commit09911bf2008-07-26 23:55:29881
[email protected]946d1b22009-07-22 23:57:21882#endif // IPC_IPC_MESSAGE_UTILS_H_