blob: fc72210059e2f939f0510251f3569715f4ec96f6 [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 NullableString16;
49
50namespace base {
[email protected]f3a1c642011-07-12 19:15:0351class DictionaryValue;
[email protected]a3ef4832013-02-02 05:12:3352class FilePath;
[email protected]f3a1c642011-07-12 19:15:0353class 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
[email protected]bf5aedf02012-06-04 21:18:2564// -----------------------------------------------------------------------------
65// How we send IPC message logs across channels.
66struct IPC_EXPORT LogData {
67 LogData();
68 ~LogData();
69
70 std::string channel;
71 int32 routing_id;
72 uint32 type; // "User-defined" message type, from ipc_message.h.
73 std::string flags;
74 int64 sent; // Time that the message was sent (i.e. at Send()).
75 int64 receive; // Time before it was dispatched (i.e. before calling
76 // OnMessageReceived).
77 int64 dispatch; // Time after it was dispatched (i.e. after calling
78 // OnMessageReceived).
79 std::string message_name;
80 std::string params;
81};
82
initial.commit09911bf2008-07-26 23:55:2983//-----------------------------------------------------------------------------
[email protected]7edae3d02012-12-17 20:23:4784
[email protected]6476c72c2011-02-11 18:46:1985// A dummy struct to place first just to allow leading commas for all
86// members in the macro-generated constructor initializer lists.
87struct NoParams {
88};
89
[email protected]7d5c3ac2009-02-04 08:58:1990template <class P>
91static inline void WriteParam(Message* m, const P& p) {
[email protected]7b291f92009-08-14 05:43:5392 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:5393 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
[email protected]7d5c3ac2009-02-04 08:58:1994}
95
96template <class P>
[email protected]ce208f872012-03-07 20:42:5697static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m,
98 PickleIterator* iter,
[email protected]1e86aa62009-04-24 21:22:3399 P* p) {
[email protected]7b291f92009-08-14 05:43:53100 typedef typename SimilarTypeTraits<P>::Type Type;
101 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
[email protected]7d5c3ac2009-02-04 08:58:19102}
103
104template <class P>
[email protected]252cad62010-08-18 18:33:57105static inline void LogParam(const P& p, std::string* l) {
[email protected]7b291f92009-08-14 05:43:53106 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53107 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19108}
109
[email protected]bf5aedf02012-06-04 21:18:25110// Primitive ParamTraits -------------------------------------------------------
111
[email protected]7d5c3ac2009-02-04 08:58:19112template <>
113struct ParamTraits<bool> {
114 typedef bool param_type;
115 static void Write(Message* m, const param_type& p) {
116 m->WriteBool(p);
117 }
[email protected]bf5aedf02012-06-04 21:18:25118 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19119 return m->ReadBool(iter, r);
120 }
[email protected]bf5aedf02012-06-04 21:18:25121 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19122};
123
124template <>
125struct ParamTraits<int> {
126 typedef int param_type;
127 static void Write(Message* m, const param_type& p) {
128 m->WriteInt(p);
129 }
[email protected]bf5aedf02012-06-04 21:18:25130 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19131 return m->ReadInt(iter, r);
132 }
[email protected]7c854372011-08-15 20:41:46133 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19134};
135
136template <>
[email protected]63263f92009-07-28 19:35:08137struct ParamTraits<unsigned int> {
138 typedef unsigned int param_type;
139 static void Write(Message* m, const param_type& p) {
140 m->WriteInt(p);
141 }
[email protected]bf5aedf02012-06-04 21:18:25142 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]63263f92009-07-28 19:35:08143 return m->ReadInt(iter, reinterpret_cast<int*>(r));
144 }
[email protected]7c854372011-08-15 20:41:46145 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08146};
147
148template <>
[email protected]7d5c3ac2009-02-04 08:58:19149struct ParamTraits<long> {
150 typedef long param_type;
151 static void Write(Message* m, const param_type& p) {
[email protected]c272d082012-03-23 00:03:10152 m->WriteLongUsingDangerousNonPortableLessPersistableForm(p);
[email protected]7d5c3ac2009-02-04 08:58:19153 }
[email protected]bf5aedf02012-06-04 21:18:25154 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19155 return m->ReadLong(iter, r);
156 }
[email protected]7c854372011-08-15 20:41:46157 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19158};
159
[email protected]140c3032009-06-26 18:22:54160template <>
161struct ParamTraits<unsigned long> {
162 typedef unsigned long param_type;
163 static void Write(Message* m, const param_type& p) {
[email protected]c272d082012-03-23 00:03:10164 m->WriteLongUsingDangerousNonPortableLessPersistableForm(p);
[email protected]140c3032009-06-26 18:22:54165 }
[email protected]bf5aedf02012-06-04 21:18:25166 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]63263f92009-07-28 19:35:08167 return m->ReadLong(iter, reinterpret_cast<long*>(r));
[email protected]140c3032009-06-26 18:22:54168 }
[email protected]7c854372011-08-15 20:41:46169 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19170};
171
172template <>
[email protected]63263f92009-07-28 19:35:08173struct ParamTraits<long long> {
174 typedef long long param_type;
[email protected]7d5c3ac2009-02-04 08:58:19175 static void Write(Message* m, const param_type& p) {
176 m->WriteInt64(static_cast<int64>(p));
177 }
[email protected]ce208f872012-03-07 20:42:56178 static bool Read(const Message* m, PickleIterator* iter,
179 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19180 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
181 }
[email protected]7c854372011-08-15 20:41:46182 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08183};
184
185template <>
186struct ParamTraits<unsigned long long> {
187 typedef unsigned long long param_type;
188 static void Write(Message* m, const param_type& p) {
189 m->WriteInt64(p);
190 }
[email protected]ce208f872012-03-07 20:42:56191 static bool Read(const Message* m, PickleIterator* iter,
192 param_type* r) {
[email protected]63263f92009-07-28 19:35:08193 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]7d5c3ac2009-02-04 08:58:19196};
197
[email protected]43a40202010-11-12 16:25:01198template <>
[email protected]7c854372011-08-15 20:41:46199struct IPC_EXPORT ParamTraits<unsigned short> {
[email protected]43a40202010-11-12 16:25:01200 typedef unsigned short param_type;
201 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56202 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]43a40202010-11-12 16:25:01203 static void Log(const param_type& p, std::string* l);
204};
205
[email protected]20199662010-06-17 03:29:26206// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
207// should be sure to check the sanity of these values after receiving them over
208// IPC.
209template <>
[email protected]bf5aedf02012-06-04 21:18:25210struct IPC_EXPORT ParamTraits<float> {
[email protected]20199662010-06-17 03:29:26211 typedef float param_type;
[email protected]bf5aedf02012-06-04 21:18:25212 static void Write(Message* m, const param_type& p);
213 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
214 static void Log(const param_type& p, std::string* l);
[email protected]20199662010-06-17 03:29:26215};
216
[email protected]7d5c3ac2009-02-04 08:58:19217template <>
[email protected]bf5aedf02012-06-04 21:18:25218struct IPC_EXPORT ParamTraits<double> {
[email protected]7d5c3ac2009-02-04 08:58:19219 typedef double param_type;
[email protected]c410e022012-05-30 21:15:57220 static void Write(Message* m, const param_type& p);
221 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
222 static void Log(const param_type& p, std::string* l);
223};
224
[email protected]bf5aedf02012-06-04 21:18:25225// STL ParamTraits -------------------------------------------------------------
[email protected]584f2b22009-05-21 01:01:59226
227template <>
[email protected]7d5c3ac2009-02-04 08:58:19228struct ParamTraits<std::string> {
229 typedef std::string param_type;
230 static void Write(Message* m, const param_type& p) {
231 m->WriteString(p);
232 }
[email protected]ce208f872012-03-07 20:42:56233 static bool Read(const Message* m, PickleIterator* iter,
234 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19235 return m->ReadString(iter, r);
236 }
[email protected]bf5aedf02012-06-04 21:18:25237 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19238};
239
[email protected]bf5aedf02012-06-04 21:18:25240template <>
241struct ParamTraits<std::wstring> {
242 typedef std::wstring param_type;
243 static void Write(Message* m, const param_type& p) {
244 m->WriteWString(p);
[email protected]3dd7a7a2009-07-27 21:09:07245 }
[email protected]bf5aedf02012-06-04 21:18:25246 static bool Read(const Message* m, PickleIterator* iter,
247 param_type* r) {
248 return m->ReadWString(iter, r);
[email protected]3dd7a7a2009-07-27 21:09:07249 }
[email protected]bf5aedf02012-06-04 21:18:25250 IPC_EXPORT static void Log(const param_type& p, std::string* l);
251};
252
253// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
254// need this trait.
255#if !defined(WCHAR_T_IS_UTF16)
256template <>
257struct ParamTraits<string16> {
258 typedef string16 param_type;
259 static void Write(Message* m, const param_type& p) {
260 m->WriteString16(p);
261 }
262 static bool Read(const Message* m, PickleIterator* iter,
263 param_type* r) {
264 return m->ReadString16(iter, r);
265 }
266 IPC_EXPORT static void Log(const param_type& p, std::string* l);
267};
[email protected]3dd7a7a2009-07-27 21:09:07268#endif
[email protected]3dd7a7a2009-07-27 21:09:07269
[email protected]7d5c3ac2009-02-04 08:58:19270template <>
[email protected]bf5aedf02012-06-04 21:18:25271struct IPC_EXPORT ParamTraits<std::vector<char> > {
[email protected]7d5c3ac2009-02-04 08:58:19272 typedef std::vector<char> param_type;
[email protected]bf5aedf02012-06-04 21:18:25273 static void Write(Message* m, const param_type& p);
274 static bool Read(const Message*, PickleIterator* iter, param_type* r);
275 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19276};
277
[email protected]51b63f62011-10-05 18:55:42278template <>
[email protected]bf5aedf02012-06-04 21:18:25279struct IPC_EXPORT ParamTraits<std::vector<unsigned char> > {
280 typedef std::vector<unsigned char> param_type;
281 static void Write(Message* m, const param_type& p);
282 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
283 static void Log(const param_type& p, std::string* l);
284};
285
286template <>
287struct IPC_EXPORT ParamTraits<std::vector<bool> > {
[email protected]51b63f62011-10-05 18:55:42288 typedef std::vector<bool> param_type;
[email protected]bf5aedf02012-06-04 21:18:25289 static void Write(Message* m, const param_type& p);
290 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
291 static void Log(const param_type& p, std::string* l);
[email protected]51b63f62011-10-05 18:55:42292};
293
[email protected]7d5c3ac2009-02-04 08:58:19294template <class P>
295struct ParamTraits<std::vector<P> > {
296 typedef std::vector<P> param_type;
297 static void Write(Message* m, const param_type& p) {
298 WriteParam(m, static_cast<int>(p.size()));
299 for (size_t i = 0; i < p.size(); i++)
300 WriteParam(m, p[i]);
301 }
[email protected]ce208f872012-03-07 20:42:56302 static bool Read(const Message* m, PickleIterator* iter,
303 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19304 int size;
[email protected]86440f52009-12-31 05:17:23305 // ReadLength() checks for < 0 itself.
[email protected]7d5c3ac2009-02-04 08:58:19306 if (!m->ReadLength(iter, &size))
307 return false;
308 // Resizing beforehand is not safe, see BUG 1006367 for details.
[email protected]86440f52009-12-31 05:17:23309 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
310 return false;
311 r->resize(size);
312 for (int i = 0; i < size; i++) {
313 if (!ReadParam(m, iter, &(*r)[i]))
314 return false;
[email protected]7d5c3ac2009-02-04 08:58:19315 }
316 return true;
317 }
[email protected]252cad62010-08-18 18:33:57318 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19319 for (size_t i = 0; i < p.size(); ++i) {
320 if (i != 0)
[email protected]252cad62010-08-18 18:33:57321 l->append(" ");
[email protected]7d5c3ac2009-02-04 08:58:19322 LogParam((p[i]), l);
323 }
324 }
325};
326
[email protected]96da6962010-05-13 19:10:34327template <class P>
328struct ParamTraits<std::set<P> > {
329 typedef std::set<P> param_type;
330 static void Write(Message* m, const param_type& p) {
331 WriteParam(m, static_cast<int>(p.size()));
332 typename param_type::const_iterator iter;
333 for (iter = p.begin(); iter != p.end(); ++iter)
334 WriteParam(m, *iter);
335 }
[email protected]ce208f872012-03-07 20:42:56336 static bool Read(const Message* m, PickleIterator* iter,
337 param_type* r) {
[email protected]96da6962010-05-13 19:10:34338 int size;
339 if (!m->ReadLength(iter, &size))
340 return false;
341 for (int i = 0; i < size; ++i) {
342 P item;
343 if (!ReadParam(m, iter, &item))
344 return false;
345 r->insert(item);
346 }
347 return true;
348 }
[email protected]252cad62010-08-18 18:33:57349 static void Log(const param_type& p, std::string* l) {
350 l->append("<std::set>");
[email protected]96da6962010-05-13 19:10:34351 }
352};
353
[email protected]7d5c3ac2009-02-04 08:58:19354template <class K, class V>
355struct ParamTraits<std::map<K, V> > {
356 typedef std::map<K, V> param_type;
357 static void Write(Message* m, const param_type& p) {
358 WriteParam(m, static_cast<int>(p.size()));
359 typename param_type::const_iterator iter;
360 for (iter = p.begin(); iter != p.end(); ++iter) {
361 WriteParam(m, iter->first);
362 WriteParam(m, iter->second);
363 }
364 }
[email protected]ce208f872012-03-07 20:42:56365 static bool Read(const Message* m, PickleIterator* iter,
366 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19367 int size;
368 if (!ReadParam(m, iter, &size) || size < 0)
369 return false;
370 for (int i = 0; i < size; ++i) {
371 K k;
372 if (!ReadParam(m, iter, &k))
373 return false;
374 V& value = (*r)[k];
375 if (!ReadParam(m, iter, &value))
376 return false;
377 }
378 return true;
379 }
[email protected]252cad62010-08-18 18:33:57380 static void Log(const param_type& p, std::string* l) {
381 l->append("<std::map>");
[email protected]7d5c3ac2009-02-04 08:58:19382 }
383};
384
[email protected]a5da6d612009-08-04 02:00:56385template <class A, class B>
386struct ParamTraits<std::pair<A, B> > {
387 typedef std::pair<A, B> param_type;
388 static void Write(Message* m, const param_type& p) {
389 WriteParam(m, p.first);
390 WriteParam(m, p.second);
391 }
[email protected]ce208f872012-03-07 20:42:56392 static bool Read(const Message* m, PickleIterator* iter,
393 param_type* r) {
[email protected]a5da6d612009-08-04 02:00:56394 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
395 }
[email protected]252cad62010-08-18 18:33:57396 static void Log(const param_type& p, std::string* l) {
397 l->append("(");
[email protected]a5da6d612009-08-04 02:00:56398 LogParam(p.first, l);
[email protected]252cad62010-08-18 18:33:57399 l->append(", ");
[email protected]a5da6d612009-08-04 02:00:56400 LogParam(p.second, l);
[email protected]252cad62010-08-18 18:33:57401 l->append(")");
[email protected]a5da6d612009-08-04 02:00:56402 }
403};
404
[email protected]bf5aedf02012-06-04 21:18:25405// Base ParamTraits ------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19406
407template <>
[email protected]bf5aedf02012-06-04 21:18:25408struct IPC_EXPORT ParamTraits<base::DictionaryValue> {
409 typedef base::DictionaryValue param_type;
[email protected]7a4de7a62010-08-17 18:38:24410 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56411 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57412 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19413};
414
[email protected]526776c2009-02-07 00:39:26415#if defined(OS_POSIX)
[email protected]2749885f2009-03-05 21:40:11416// FileDescriptors may be serialised over IPC channels on POSIX. On the
417// receiving side, the FileDescriptor is a valid duplicate of the file
418// descriptor which was transmitted: *it is not just a copy of the integer like
419// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
420// this case, the receiving end will see a value of -1. *Zero is a valid file
421// descriptor*.
422//
423// The received file descriptor will have the |auto_close| flag set to true. The
424// code which handles the message is responsible for taking ownership of it.
425// File descriptors are OS resources and must be closed when no longer needed.
426//
427// When sending a file descriptor, the file descriptor must be valid at the time
428// of transmission. Since transmission is not synchronous, one should consider
429// dup()ing any file descriptors to be transmitted and setting the |auto_close|
430// flag, which causes the file descriptor to be closed after writing.
[email protected]526776c2009-02-07 00:39:26431template<>
[email protected]7c854372011-08-15 20:41:46432struct IPC_EXPORT ParamTraits<base::FileDescriptor> {
[email protected]5fe733de2009-02-11 18:59:20433 typedef base::FileDescriptor param_type;
[email protected]7a4de7a62010-08-17 18:38:24434 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56435 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57436 static void Log(const param_type& p, std::string* l);
[email protected]526776c2009-02-07 00:39:26437};
[email protected]379e7a52010-03-09 00:38:41438#endif // defined(OS_POSIX)
[email protected]526776c2009-02-07 00:39:26439
[email protected]bf5aedf02012-06-04 21:18:25440template <>
[email protected]a3ef4832013-02-02 05:12:33441struct IPC_EXPORT ParamTraits<base::FilePath> {
442 typedef base::FilePath param_type;
[email protected]7a4de7a62010-08-17 18:38:24443 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56444 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57445 static void Log(const param_type& p, std::string* l);
[email protected]d2e884d2009-06-22 20:37:52446};
447
[email protected]7d5c3ac2009-02-04 08:58:19448template <>
[email protected]bf5aedf02012-06-04 21:18:25449struct IPC_EXPORT ParamTraits<base::ListValue> {
450 typedef base::ListValue param_type;
[email protected]20f0487a2010-09-30 20:06:30451 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56452 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25453 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19454};
455
[email protected]eb47a132009-03-04 00:39:56456template <>
[email protected]bf5aedf02012-06-04 21:18:25457struct IPC_EXPORT ParamTraits<NullableString16> {
458 typedef NullableString16 param_type;
459 static void Write(Message* m, const param_type& p);
460 static bool Read(const Message* m, PickleIterator* iter,
461 param_type* r);
462 static void Log(const param_type& p, std::string* l);
463};
464
465template <>
466struct IPC_EXPORT ParamTraits<base::PlatformFileInfo> {
467 typedef base::PlatformFileInfo param_type;
468 static void Write(Message* m, const param_type& p);
469 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
470 static void Log(const param_type& p, std::string* l);
471};
472
473template <>
474struct SimilarTypeTraits<base::PlatformFileError> {
475 typedef int Type;
476};
477
478template <>
479struct IPC_EXPORT ParamTraits<base::Time> {
480 typedef base::Time 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 IPC_EXPORT ParamTraits<base::TimeDelta> {
488 typedef base::TimeDelta param_type;
489 static void Write(Message* m, const param_type& p);
490 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
491 static void Log(const param_type& p, std::string* l);
492};
493
494template <>
495struct IPC_EXPORT ParamTraits<base::TimeTicks> {
496 typedef base::TimeTicks param_type;
497 static void Write(Message* m, const param_type& p);
498 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
499 static void Log(const param_type& p, std::string* l);
[email protected]503683f2009-02-26 09:13:01500};
501
502template <>
[email protected]7d5c3ac2009-02-04 08:58:19503struct ParamTraits<Tuple0> {
504 typedef Tuple0 param_type;
505 static void Write(Message* m, const param_type& p) {
506 }
[email protected]ce208f872012-03-07 20:42:56507 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19508 return true;
509 }
[email protected]252cad62010-08-18 18:33:57510 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19511 }
512};
513
514template <class A>
515struct ParamTraits< Tuple1<A> > {
516 typedef Tuple1<A> param_type;
517 static void Write(Message* m, const param_type& p) {
518 WriteParam(m, p.a);
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 ReadParam(m, iter, &r->a);
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 LogParam(p.a, l);
525 }
526};
527
528template <class A, class B>
529struct ParamTraits< Tuple2<A, B> > {
530 typedef Tuple2<A, B> param_type;
531 static void Write(Message* m, const param_type& p) {
532 WriteParam(m, p.a);
533 WriteParam(m, p.b);
534 }
[email protected]ce208f872012-03-07 20:42:56535 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19536 return (ReadParam(m, iter, &r->a) &&
537 ReadParam(m, iter, &r->b));
538 }
[email protected]252cad62010-08-18 18:33:57539 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19540 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57541 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19542 LogParam(p.b, l);
543 }
544};
545
546template <class A, class B, class C>
547struct ParamTraits< Tuple3<A, B, C> > {
548 typedef Tuple3<A, B, C> param_type;
549 static void Write(Message* m, const param_type& p) {
550 WriteParam(m, p.a);
551 WriteParam(m, p.b);
552 WriteParam(m, p.c);
553 }
[email protected]ce208f872012-03-07 20:42:56554 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19555 return (ReadParam(m, iter, &r->a) &&
556 ReadParam(m, iter, &r->b) &&
557 ReadParam(m, iter, &r->c));
558 }
[email protected]252cad62010-08-18 18:33:57559 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19560 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57561 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19562 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57563 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19564 LogParam(p.c, l);
565 }
566};
567
568template <class A, class B, class C, class D>
569struct ParamTraits< Tuple4<A, B, C, D> > {
570 typedef Tuple4<A, B, C, D> param_type;
571 static void Write(Message* m, const param_type& p) {
572 WriteParam(m, p.a);
573 WriteParam(m, p.b);
574 WriteParam(m, p.c);
575 WriteParam(m, p.d);
576 }
[email protected]ce208f872012-03-07 20:42:56577 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19578 return (ReadParam(m, iter, &r->a) &&
579 ReadParam(m, iter, &r->b) &&
580 ReadParam(m, iter, &r->c) &&
581 ReadParam(m, iter, &r->d));
582 }
[email protected]252cad62010-08-18 18:33:57583 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19584 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57585 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19586 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57587 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19588 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57589 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19590 LogParam(p.d, l);
591 }
592};
593
594template <class A, class B, class C, class D, class E>
595struct ParamTraits< Tuple5<A, B, C, D, E> > {
596 typedef Tuple5<A, B, C, D, E> param_type;
597 static void Write(Message* m, const param_type& p) {
598 WriteParam(m, p.a);
599 WriteParam(m, p.b);
600 WriteParam(m, p.c);
601 WriteParam(m, p.d);
602 WriteParam(m, p.e);
603 }
[email protected]ce208f872012-03-07 20:42:56604 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19605 return (ReadParam(m, iter, &r->a) &&
606 ReadParam(m, iter, &r->b) &&
607 ReadParam(m, iter, &r->c) &&
608 ReadParam(m, iter, &r->d) &&
609 ReadParam(m, iter, &r->e));
610 }
[email protected]252cad62010-08-18 18:33:57611 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19612 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57613 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19614 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57615 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19616 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57617 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19618 LogParam(p.d, l);
[email protected]252cad62010-08-18 18:33:57619 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19620 LogParam(p.e, l);
621 }
622};
623
[email protected]b1064d62012-11-14 06:35:52624template<class P>
625struct ParamTraits<ScopedVector<P> > {
626 typedef ScopedVector<P> param_type;
627 static void Write(Message* m, const param_type& p) {
628 WriteParam(m, static_cast<int>(p.size()));
629 for (size_t i = 0; i < p.size(); i++)
630 WriteParam(m, *p[i]);
631 }
632 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
633 int size = 0;
634 if (!m->ReadLength(iter, &size))
635 return false;
636 if (INT_MAX/sizeof(P) <= static_cast<size_t>(size))
637 return false;
638 r->resize(size);
639 for (int i = 0; i < size; i++) {
640 (*r)[i] = new P();
641 if (!ReadParam(m, iter, (*r)[i]))
642 return false;
643 }
644 return true;
645 }
646 static void Log(const param_type& p, std::string* l) {
647 for (size_t i = 0; i < p.size(); ++i) {
648 if (i != 0)
649 l->append(" ");
650 LogParam(*p[i], l);
651 }
652 }
653};
654
[email protected]bf5aedf02012-06-04 21:18:25655// IPC types ParamTraits -------------------------------------------------------
656
657// A ChannelHandle is basically a platform-inspecific wrapper around the
658// fact that IPC endpoints are handled specially on POSIX. See above comments
659// on FileDescriptor for more background.
660template<>
661struct IPC_EXPORT ParamTraits<IPC::ChannelHandle> {
662 typedef ChannelHandle param_type;
663 static void Write(Message* m, const param_type& p);
664 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
665 static void Log(const param_type& p, std::string* l);
666};
667
668template <>
669struct IPC_EXPORT ParamTraits<LogData> {
670 typedef LogData param_type;
671 static void Write(Message* m, const param_type& p);
672 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
673 static void Log(const param_type& p, std::string* l);
674};
675
676template <>
677struct IPC_EXPORT ParamTraits<Message> {
678 static void Write(Message* m, const Message& p);
679 static bool Read(const Message* m, PickleIterator* iter, Message* r);
680 static void Log(const Message& p, std::string* l);
681};
682
683// Windows ParamTraits ---------------------------------------------------------
684
685#if defined(OS_WIN)
686template <>
687struct IPC_EXPORT ParamTraits<HANDLE> {
688 typedef HANDLE param_type;
689 static void Write(Message* m, const param_type& p);
690 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
691 static void Log(const param_type& p, std::string* l);
692};
693
694template <>
695struct IPC_EXPORT ParamTraits<LOGFONT> {
696 typedef LOGFONT param_type;
697 static void Write(Message* m, const param_type& p);
698 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
699 static void Log(const param_type& p, std::string* l);
700};
701
702template <>
703struct IPC_EXPORT ParamTraits<MSG> {
704 typedef MSG param_type;
705 static void Write(Message* m, const param_type& p);
706 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
707 static void Log(const param_type& p, std::string* l);
708};
709#endif // defined(OS_WIN)
710
[email protected]7d5c3ac2009-02-04 08:58:19711//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:29712// Generic message subclasses
713
714// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:24715template <class ParamType>
[email protected]1d4ecf42011-08-26 21:27:30716class MessageSchema {
initial.commit09911bf2008-07-26 23:55:29717 public:
[email protected]81a34412009-01-05 19:17:24718 typedef ParamType Param;
[email protected]7a4de7a62010-08-17 18:38:24719 typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
[email protected]81a34412009-01-05 19:17:24720
[email protected]1d4ecf42011-08-26 21:27:30721 static void Write(Message* msg, const RefParam& p) IPC_MSG_NOINLINE;
[email protected]7a4de7a62010-08-17 18:38:24722 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:29723};
724
[email protected]7a4de7a62010-08-17 18:38:24725// defined in ipc_logging.cc
[email protected]7c854372011-08-15 20:41:46726IPC_EXPORT void GenerateLogData(const std::string& channel,
727 const Message& message,
[email protected]ea7744a2011-10-20 19:34:43728 LogData* data, bool get_params);
[email protected]7a4de7a62010-08-17 18:38:24729
730
731#if defined(IPC_MESSAGE_LOG_ENABLED)
[email protected]252cad62010-08-18 18:33:57732inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
733 const std::string& output_params = msg->output_params();
[email protected]7a4de7a62010-08-17 18:38:24734 if (!l->empty() && !output_params.empty())
[email protected]252cad62010-08-18 18:33:57735 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:24736
737 l->append(output_params);
738}
739
740template <class ReplyParamType>
741inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
742 const Message* msg) {
743 if (msg->received_time() != 0) {
[email protected]252cad62010-08-18 18:33:57744 std::string output_params;
[email protected]7a4de7a62010-08-17 18:38:24745 LogParam(reply_params, &output_params);
746 msg->set_output_params(output_params);
747 }
748}
749
750inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
751 if (msg->sent_time()) {
752 // Don't log the sync message after dispatch, as we don't have the
753 // output parameters at that point. Instead, save its data and log it
754 // with the outgoing reply message when it's sent.
755 LogData* data = new LogData;
[email protected]ea7744a2011-10-20 19:34:43756 GenerateLogData("", *msg, data, true);
[email protected]7a4de7a62010-08-17 18:38:24757 msg->set_dont_log();
758 reply->set_sync_log_data(data);
759 }
760}
761#else
[email protected]252cad62010-08-18 18:33:57762inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
[email protected]7a4de7a62010-08-17 18:38:24763
764template <class ReplyParamType>
765inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
766 const Message* msg) {}
767
768inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
769#endif
770
initial.commit09911bf2008-07-26 23:55:29771// This class assumes that its template argument is a RefTuple (a Tuple with
[email protected]7a4de7a62010-08-17 18:38:24772// reference elements). This would go into ipc_message_utils_impl.h, but it is
773// also used by chrome_frame.
initial.commit09911bf2008-07-26 23:55:29774template <class RefTuple>
775class ParamDeserializer : public MessageReplyDeserializer {
776 public:
[email protected]e1981f432008-08-12 15:22:13777 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:29778
[email protected]ce208f872012-03-07 20:42:56779 bool SerializeOutputParameters(const IPC::Message& msg, PickleIterator iter) {
initial.commit09911bf2008-07-26 23:55:29780 return ReadParam(&msg, &iter, &out_);
781 }
782
783 RefTuple out_;
784};
785
initial.commit09911bf2008-07-26 23:55:29786// Used for synchronous messages.
[email protected]75e5a872009-04-02 23:56:11787template <class SendParamType, class ReplyParamType>
[email protected]1d4ecf42011-08-26 21:27:30788class SyncMessageSchema {
initial.commit09911bf2008-07-26 23:55:29789 public:
[email protected]75e5a872009-04-02 23:56:11790 typedef SendParamType SendParam;
[email protected]7a4de7a62010-08-17 18:38:24791 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
[email protected]75e5a872009-04-02 23:56:11792 typedef ReplyParamType ReplyParam;
793
[email protected]1d4ecf42011-08-26 21:27:30794 static void Write(Message* msg, const RefSendParam& send) IPC_MSG_NOINLINE;
[email protected]7a4de7a62010-08-17 18:38:24795 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
796 static bool ReadReplyParam(
797 const Message* msg,
798 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:29799
[email protected]65412272010-12-21 20:03:24800 template<class T, class S, class Method>
[email protected]1d4ecf42011-08-26 21:27:30801 static bool DispatchWithSendParams(bool ok, const SendParam& send_params,
802 const Message* msg, T* obj, S* sender,
803 Method func) {
804 Message* reply = SyncMessage::GenerateReply(msg);
805 if (ok) {
[email protected]7a4de7a62010-08-17 18:38:24806 typename TupleTypes<ReplyParam>::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:29807 DispatchToMethod(obj, func, send_params, &reply_params);
808 WriteParam(reply, reply_params);
[email protected]7a4de7a62010-08-17 18:38:24809 LogReplyParamsToMessage(reply_params, msg);
initial.commit09911bf2008-07-26 23:55:29810 } else {
811 NOTREACHED() << "Error deserializing message " << msg->type();
812 reply->set_reply_error();
initial.commit09911bf2008-07-26 23:55:29813 }
[email protected]65412272010-12-21 20:03:24814 sender->Send(reply);
[email protected]1d4ecf42011-08-26 21:27:30815 return ok;
initial.commit09911bf2008-07-26 23:55:29816 }
817
818 template<class T, class Method>
[email protected]1d4ecf42011-08-26 21:27:30819 static bool DispatchDelayReplyWithSendParams(bool ok,
820 const SendParam& send_params,
821 const Message* msg, T* obj,
822 Method func) {
823 Message* reply = SyncMessage::GenerateReply(msg);
824 if (ok) {
initial.commit09911bf2008-07-26 23:55:29825 Tuple1<Message&> t = MakeRefTuple(*reply);
[email protected]7a4de7a62010-08-17 18:38:24826 ConnectMessageAndReply(msg, reply);
initial.commit09911bf2008-07-26 23:55:29827 DispatchToMethod(obj, func, send_params, &t);
initial.commit09911bf2008-07-26 23:55:29828 } else {
829 NOTREACHED() << "Error deserializing message " << msg->type();
830 reply->set_reply_error();
831 obj->Send(reply);
initial.commit09911bf2008-07-26 23:55:29832 }
[email protected]1d4ecf42011-08-26 21:27:30833 return ok;
initial.commit09911bf2008-07-26 23:55:29834 }
835
836 template<typename TA>
837 static void WriteReplyParams(Message* reply, TA a) {
838 ReplyParam p(a);
839 WriteParam(reply, p);
840 }
841
842 template<typename TA, typename TB>
843 static void WriteReplyParams(Message* reply, TA a, TB b) {
844 ReplyParam p(a, b);
845 WriteParam(reply, p);
846 }
847
848 template<typename TA, typename TB, typename TC>
849 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
850 ReplyParam p(a, b, c);
851 WriteParam(reply, p);
852 }
853
854 template<typename TA, typename TB, typename TC, typename TD>
855 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
856 ReplyParam p(a, b, c, d);
857 WriteParam(reply, p);
858 }
859
860 template<typename TA, typename TB, typename TC, typename TD, typename TE>
861 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
862 ReplyParam p(a, b, c, d, e);
863 WriteParam(reply, p);
864 }
865};
866
[email protected]3178f4e22008-08-05 21:20:41867} // namespace IPC
initial.commit09911bf2008-07-26 23:55:29868
[email protected]946d1b22009-07-22 23:57:21869#endif // IPC_IPC_MESSAGE_UTILS_H_