blob: b05f76dd17334c7a98385dc1114795e0bf384ec4 [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]141bcc52014-01-27 21:36:0014#include "base/files/file.h"
[email protected]dce5df52009-06-29 17:58:2515#include "base/format_macros.h"
[email protected]b1064d62012-11-14 06:35:5216#include "base/memory/scoped_vector.h"
[email protected]4aa794a12013-06-11 06:32:1817#include "base/strings/string16.h"
18#include "base/strings/string_util.h"
19#include "base/strings/stringprintf.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:2448namespace base {
[email protected]f3a1c642011-07-12 19:15:0349class DictionaryValue;
[email protected]a3ef4832013-02-02 05:12:3350class FilePath;
[email protected]f3a1c642011-07-12 19:15:0351class ListValue;
[email protected]0238a162013-06-13 13:47:4652class NullableString16;
[email protected]7a4de7a62010-08-17 18:38:2453class Time;
[email protected]d84e48b2010-10-21 22:04:5254class TimeDelta;
[email protected]1d14f582011-09-02 20:42:0455class TimeTicks;
[email protected]7a4de7a62010-08-17 18:38:2456struct FileDescriptor;
57}
58
initial.commit09911bf2008-07-26 23:55:2959namespace IPC {
60
[email protected]7a4de7a62010-08-17 18:38:2461struct ChannelHandle;
62
[email protected]bf5aedf02012-06-04 21:18:2563// -----------------------------------------------------------------------------
64// How we send IPC message logs across channels.
65struct IPC_EXPORT LogData {
66 LogData();
67 ~LogData();
68
69 std::string channel;
70 int32 routing_id;
71 uint32 type; // "User-defined" message type, from ipc_message.h.
72 std::string flags;
73 int64 sent; // Time that the message was sent (i.e. at Send()).
74 int64 receive; // Time before it was dispatched (i.e. before calling
75 // OnMessageReceived).
76 int64 dispatch; // Time after it was dispatched (i.e. after calling
77 // OnMessageReceived).
78 std::string message_name;
79 std::string params;
80};
81
initial.commit09911bf2008-07-26 23:55:2982//-----------------------------------------------------------------------------
[email protected]7edae3d02012-12-17 20:23:4783
[email protected]6476c72c2011-02-11 18:46:1984// A dummy struct to place first just to allow leading commas for all
85// members in the macro-generated constructor initializer lists.
86struct NoParams {
87};
88
[email protected]7d5c3ac2009-02-04 08:58:1989template <class P>
90static inline void WriteParam(Message* m, const P& p) {
[email protected]7b291f92009-08-14 05:43:5391 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:5392 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
[email protected]7d5c3ac2009-02-04 08:58:1993}
94
95template <class P>
[email protected]ce208f872012-03-07 20:42:5696static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m,
97 PickleIterator* iter,
[email protected]1e86aa62009-04-24 21:22:3398 P* p) {
[email protected]7b291f92009-08-14 05:43:5399 typedef typename SimilarTypeTraits<P>::Type Type;
100 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
[email protected]7d5c3ac2009-02-04 08:58:19101}
102
103template <class P>
[email protected]252cad62010-08-18 18:33:57104static inline void LogParam(const P& p, std::string* l) {
[email protected]7b291f92009-08-14 05:43:53105 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53106 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19107}
108
[email protected]bf5aedf02012-06-04 21:18:25109// Primitive ParamTraits -------------------------------------------------------
110
[email protected]7d5c3ac2009-02-04 08:58:19111template <>
112struct ParamTraits<bool> {
113 typedef bool param_type;
114 static void Write(Message* m, const param_type& p) {
115 m->WriteBool(p);
116 }
[email protected]bf5aedf02012-06-04 21:18:25117 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19118 return m->ReadBool(iter, r);
119 }
[email protected]bf5aedf02012-06-04 21:18:25120 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19121};
122
123template <>
[email protected]c1ee48d2013-07-12 23:12:28124struct IPC_EXPORT ParamTraits<unsigned char> {
[email protected]7bea7352013-07-13 04:42:10125 typedef unsigned char param_type;
[email protected]c1ee48d2013-07-12 23:12:28126 static void Write(Message* m, const param_type& p);
127 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
128 static void Log(const param_type& p, std::string* l);
129};
130
131template <>
132struct IPC_EXPORT ParamTraits<unsigned short> {
133 typedef unsigned short param_type;
134 static void Write(Message* m, const param_type& p);
135 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
136 static void Log(const param_type& p, std::string* l);
137};
138
139template <>
[email protected]7d5c3ac2009-02-04 08:58:19140struct ParamTraits<int> {
141 typedef int param_type;
142 static void Write(Message* m, const param_type& p) {
143 m->WriteInt(p);
144 }
[email protected]bf5aedf02012-06-04 21:18:25145 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19146 return m->ReadInt(iter, r);
147 }
[email protected]7c854372011-08-15 20:41:46148 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19149};
150
151template <>
[email protected]63263f92009-07-28 19:35:08152struct ParamTraits<unsigned int> {
153 typedef unsigned int param_type;
154 static void Write(Message* m, const param_type& p) {
155 m->WriteInt(p);
156 }
[email protected]bf5aedf02012-06-04 21:18:25157 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]63263f92009-07-28 19:35:08158 return m->ReadInt(iter, reinterpret_cast<int*>(r));
159 }
[email protected]7c854372011-08-15 20:41:46160 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08161};
162
163template <>
[email protected]7d5c3ac2009-02-04 08:58:19164struct ParamTraits<long> {
165 typedef long param_type;
166 static void Write(Message* m, const param_type& p) {
[email protected]c272d082012-03-23 00:03:10167 m->WriteLongUsingDangerousNonPortableLessPersistableForm(p);
[email protected]7d5c3ac2009-02-04 08:58:19168 }
[email protected]bf5aedf02012-06-04 21:18:25169 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19170 return m->ReadLong(iter, r);
171 }
[email protected]7c854372011-08-15 20:41:46172 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19173};
174
[email protected]140c3032009-06-26 18:22:54175template <>
176struct ParamTraits<unsigned long> {
177 typedef unsigned long param_type;
178 static void Write(Message* m, const param_type& p) {
[email protected]c272d082012-03-23 00:03:10179 m->WriteLongUsingDangerousNonPortableLessPersistableForm(p);
[email protected]140c3032009-06-26 18:22:54180 }
[email protected]bf5aedf02012-06-04 21:18:25181 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]63263f92009-07-28 19:35:08182 return m->ReadLong(iter, reinterpret_cast<long*>(r));
[email protected]140c3032009-06-26 18:22:54183 }
[email protected]7c854372011-08-15 20:41:46184 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19185};
186
187template <>
[email protected]63263f92009-07-28 19:35:08188struct ParamTraits<long long> {
189 typedef long long param_type;
[email protected]7d5c3ac2009-02-04 08:58:19190 static void Write(Message* m, const param_type& p) {
191 m->WriteInt64(static_cast<int64>(p));
192 }
[email protected]ce208f872012-03-07 20:42:56193 static bool Read(const Message* m, PickleIterator* iter,
194 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19195 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
196 }
[email protected]7c854372011-08-15 20:41:46197 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08198};
199
200template <>
201struct ParamTraits<unsigned long long> {
202 typedef unsigned long long param_type;
203 static void Write(Message* m, const param_type& p) {
204 m->WriteInt64(p);
205 }
[email protected]ce208f872012-03-07 20:42:56206 static bool Read(const Message* m, PickleIterator* iter,
207 param_type* r) {
[email protected]63263f92009-07-28 19:35:08208 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
209 }
[email protected]7c854372011-08-15 20:41:46210 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19211};
212
[email protected]20199662010-06-17 03:29:26213// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
214// should be sure to check the sanity of these values after receiving them over
215// IPC.
216template <>
[email protected]bf5aedf02012-06-04 21:18:25217struct IPC_EXPORT ParamTraits<float> {
[email protected]20199662010-06-17 03:29:26218 typedef float param_type;
[email protected]48328ff2013-10-31 09:27:31219 static void Write(Message* m, const param_type& p) {
220 m->WriteFloat(p);
221 }
222 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
223 return m->ReadFloat(iter, r);
224 }
[email protected]bf5aedf02012-06-04 21:18:25225 static void Log(const param_type& p, std::string* l);
[email protected]20199662010-06-17 03:29:26226};
227
[email protected]7d5c3ac2009-02-04 08:58:19228template <>
[email protected]bf5aedf02012-06-04 21:18:25229struct IPC_EXPORT ParamTraits<double> {
[email protected]7d5c3ac2009-02-04 08:58:19230 typedef double param_type;
[email protected]c410e022012-05-30 21:15:57231 static void Write(Message* m, const param_type& p);
232 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
233 static void Log(const param_type& p, std::string* l);
234};
235
[email protected]bf5aedf02012-06-04 21:18:25236// STL ParamTraits -------------------------------------------------------------
[email protected]584f2b22009-05-21 01:01:59237
238template <>
[email protected]7d5c3ac2009-02-04 08:58:19239struct ParamTraits<std::string> {
240 typedef std::string param_type;
241 static void Write(Message* m, const param_type& p) {
242 m->WriteString(p);
243 }
[email protected]ce208f872012-03-07 20:42:56244 static bool Read(const Message* m, PickleIterator* iter,
245 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19246 return m->ReadString(iter, r);
247 }
[email protected]bf5aedf02012-06-04 21:18:25248 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19249};
250
[email protected]bf5aedf02012-06-04 21:18:25251template <>
252struct ParamTraits<std::wstring> {
253 typedef std::wstring param_type;
254 static void Write(Message* m, const param_type& p) {
255 m->WriteWString(p);
[email protected]3dd7a7a2009-07-27 21:09:07256 }
[email protected]bf5aedf02012-06-04 21:18:25257 static bool Read(const Message* m, PickleIterator* iter,
258 param_type* r) {
259 return m->ReadWString(iter, r);
[email protected]3dd7a7a2009-07-27 21:09:07260 }
[email protected]bf5aedf02012-06-04 21:18:25261 IPC_EXPORT static void Log(const param_type& p, std::string* l);
262};
263
264// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
265// need this trait.
266#if !defined(WCHAR_T_IS_UTF16)
267template <>
[email protected]476dafb2013-12-03 00:39:26268struct ParamTraits<base::string16> {
269 typedef base::string16 param_type;
[email protected]bf5aedf02012-06-04 21:18:25270 static void Write(Message* m, const param_type& p) {
271 m->WriteString16(p);
272 }
273 static bool Read(const Message* m, PickleIterator* iter,
274 param_type* r) {
275 return m->ReadString16(iter, r);
276 }
277 IPC_EXPORT static void Log(const param_type& p, std::string* l);
278};
[email protected]3dd7a7a2009-07-27 21:09:07279#endif
[email protected]3dd7a7a2009-07-27 21:09:07280
[email protected]7d5c3ac2009-02-04 08:58:19281template <>
[email protected]bf5aedf02012-06-04 21:18:25282struct IPC_EXPORT ParamTraits<std::vector<char> > {
[email protected]7d5c3ac2009-02-04 08:58:19283 typedef std::vector<char> param_type;
[email protected]bf5aedf02012-06-04 21:18:25284 static void Write(Message* m, const param_type& p);
285 static bool Read(const Message*, PickleIterator* iter, param_type* r);
286 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19287};
288
[email protected]51b63f62011-10-05 18:55:42289template <>
[email protected]bf5aedf02012-06-04 21:18:25290struct IPC_EXPORT ParamTraits<std::vector<unsigned char> > {
291 typedef std::vector<unsigned char> param_type;
292 static void Write(Message* m, const param_type& p);
293 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
294 static void Log(const param_type& p, std::string* l);
295};
296
297template <>
298struct IPC_EXPORT ParamTraits<std::vector<bool> > {
[email protected]51b63f62011-10-05 18:55:42299 typedef std::vector<bool> param_type;
[email protected]bf5aedf02012-06-04 21:18:25300 static void Write(Message* m, const param_type& p);
301 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
302 static void Log(const param_type& p, std::string* l);
[email protected]51b63f62011-10-05 18:55:42303};
304
[email protected]7d5c3ac2009-02-04 08:58:19305template <class P>
306struct ParamTraits<std::vector<P> > {
307 typedef std::vector<P> param_type;
308 static void Write(Message* m, const param_type& p) {
309 WriteParam(m, static_cast<int>(p.size()));
310 for (size_t i = 0; i < p.size(); i++)
311 WriteParam(m, p[i]);
312 }
[email protected]ce208f872012-03-07 20:42:56313 static bool Read(const Message* m, PickleIterator* iter,
314 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19315 int size;
[email protected]86440f52009-12-31 05:17:23316 // ReadLength() checks for < 0 itself.
[email protected]7d5c3ac2009-02-04 08:58:19317 if (!m->ReadLength(iter, &size))
318 return false;
319 // Resizing beforehand is not safe, see BUG 1006367 for details.
[email protected]86440f52009-12-31 05:17:23320 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
321 return false;
322 r->resize(size);
323 for (int i = 0; i < size; i++) {
324 if (!ReadParam(m, iter, &(*r)[i]))
325 return false;
[email protected]7d5c3ac2009-02-04 08:58:19326 }
327 return true;
328 }
[email protected]252cad62010-08-18 18:33:57329 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19330 for (size_t i = 0; i < p.size(); ++i) {
331 if (i != 0)
[email protected]252cad62010-08-18 18:33:57332 l->append(" ");
[email protected]7d5c3ac2009-02-04 08:58:19333 LogParam((p[i]), l);
334 }
335 }
336};
337
[email protected]96da6962010-05-13 19:10:34338template <class P>
339struct ParamTraits<std::set<P> > {
340 typedef std::set<P> param_type;
341 static void Write(Message* m, const param_type& p) {
342 WriteParam(m, static_cast<int>(p.size()));
343 typename param_type::const_iterator iter;
344 for (iter = p.begin(); iter != p.end(); ++iter)
345 WriteParam(m, *iter);
346 }
[email protected]ce208f872012-03-07 20:42:56347 static bool Read(const Message* m, PickleIterator* iter,
348 param_type* r) {
[email protected]96da6962010-05-13 19:10:34349 int size;
350 if (!m->ReadLength(iter, &size))
351 return false;
352 for (int i = 0; i < size; ++i) {
353 P item;
354 if (!ReadParam(m, iter, &item))
355 return false;
356 r->insert(item);
357 }
358 return true;
359 }
[email protected]252cad62010-08-18 18:33:57360 static void Log(const param_type& p, std::string* l) {
361 l->append("<std::set>");
[email protected]96da6962010-05-13 19:10:34362 }
363};
364
[email protected]7d5c3ac2009-02-04 08:58:19365template <class K, class V>
366struct ParamTraits<std::map<K, V> > {
367 typedef std::map<K, V> param_type;
368 static void Write(Message* m, const param_type& p) {
369 WriteParam(m, static_cast<int>(p.size()));
370 typename param_type::const_iterator iter;
371 for (iter = p.begin(); iter != p.end(); ++iter) {
372 WriteParam(m, iter->first);
373 WriteParam(m, iter->second);
374 }
375 }
[email protected]ce208f872012-03-07 20:42:56376 static bool Read(const Message* m, PickleIterator* iter,
377 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19378 int size;
379 if (!ReadParam(m, iter, &size) || size < 0)
380 return false;
381 for (int i = 0; i < size; ++i) {
382 K k;
383 if (!ReadParam(m, iter, &k))
384 return false;
385 V& value = (*r)[k];
386 if (!ReadParam(m, iter, &value))
387 return false;
388 }
389 return true;
390 }
[email protected]252cad62010-08-18 18:33:57391 static void Log(const param_type& p, std::string* l) {
392 l->append("<std::map>");
[email protected]7d5c3ac2009-02-04 08:58:19393 }
394};
395
[email protected]a5da6d612009-08-04 02:00:56396template <class A, class B>
397struct ParamTraits<std::pair<A, B> > {
398 typedef std::pair<A, B> param_type;
399 static void Write(Message* m, const param_type& p) {
400 WriteParam(m, p.first);
401 WriteParam(m, p.second);
402 }
[email protected]ce208f872012-03-07 20:42:56403 static bool Read(const Message* m, PickleIterator* iter,
404 param_type* r) {
[email protected]a5da6d612009-08-04 02:00:56405 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
406 }
[email protected]252cad62010-08-18 18:33:57407 static void Log(const param_type& p, std::string* l) {
408 l->append("(");
[email protected]a5da6d612009-08-04 02:00:56409 LogParam(p.first, l);
[email protected]252cad62010-08-18 18:33:57410 l->append(", ");
[email protected]a5da6d612009-08-04 02:00:56411 LogParam(p.second, l);
[email protected]252cad62010-08-18 18:33:57412 l->append(")");
[email protected]a5da6d612009-08-04 02:00:56413 }
414};
415
[email protected]bf5aedf02012-06-04 21:18:25416// Base ParamTraits ------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19417
418template <>
[email protected]bf5aedf02012-06-04 21:18:25419struct IPC_EXPORT ParamTraits<base::DictionaryValue> {
420 typedef base::DictionaryValue param_type;
[email protected]7a4de7a62010-08-17 18:38:24421 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56422 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57423 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19424};
425
[email protected]526776c2009-02-07 00:39:26426#if defined(OS_POSIX)
[email protected]2749885f2009-03-05 21:40:11427// FileDescriptors may be serialised over IPC channels on POSIX. On the
428// receiving side, the FileDescriptor is a valid duplicate of the file
429// descriptor which was transmitted: *it is not just a copy of the integer like
430// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
431// this case, the receiving end will see a value of -1. *Zero is a valid file
432// descriptor*.
433//
434// The received file descriptor will have the |auto_close| flag set to true. The
435// code which handles the message is responsible for taking ownership of it.
436// File descriptors are OS resources and must be closed when no longer needed.
437//
438// When sending a file descriptor, the file descriptor must be valid at the time
439// of transmission. Since transmission is not synchronous, one should consider
440// dup()ing any file descriptors to be transmitted and setting the |auto_close|
441// flag, which causes the file descriptor to be closed after writing.
[email protected]526776c2009-02-07 00:39:26442template<>
[email protected]7c854372011-08-15 20:41:46443struct IPC_EXPORT ParamTraits<base::FileDescriptor> {
[email protected]5fe733de2009-02-11 18:59:20444 typedef base::FileDescriptor param_type;
[email protected]7a4de7a62010-08-17 18:38:24445 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56446 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57447 static void Log(const param_type& p, std::string* l);
[email protected]526776c2009-02-07 00:39:26448};
[email protected]379e7a52010-03-09 00:38:41449#endif // defined(OS_POSIX)
[email protected]526776c2009-02-07 00:39:26450
[email protected]bf5aedf02012-06-04 21:18:25451template <>
[email protected]a3ef4832013-02-02 05:12:33452struct IPC_EXPORT ParamTraits<base::FilePath> {
453 typedef base::FilePath param_type;
[email protected]7a4de7a62010-08-17 18:38:24454 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56455 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57456 static void Log(const param_type& p, std::string* l);
[email protected]d2e884d2009-06-22 20:37:52457};
458
[email protected]7d5c3ac2009-02-04 08:58:19459template <>
[email protected]bf5aedf02012-06-04 21:18:25460struct IPC_EXPORT ParamTraits<base::ListValue> {
461 typedef base::ListValue param_type;
[email protected]20f0487a2010-09-30 20:06:30462 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56463 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25464 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19465};
466
[email protected]eb47a132009-03-04 00:39:56467template <>
[email protected]0238a162013-06-13 13:47:46468struct IPC_EXPORT ParamTraits<base::NullableString16> {
469 typedef base::NullableString16 param_type;
[email protected]bf5aedf02012-06-04 21:18:25470 static void Write(Message* m, const param_type& p);
471 static bool Read(const Message* m, PickleIterator* iter,
472 param_type* r);
473 static void Log(const param_type& p, std::string* l);
474};
475
476template <>
[email protected]141bcc52014-01-27 21:36:00477struct IPC_EXPORT ParamTraits<base::File::Info> {
478 typedef base::File::Info param_type;
[email protected]bf5aedf02012-06-04 21:18:25479 static void Write(Message* m, const param_type& p);
480 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
481 static void Log(const param_type& p, std::string* l);
482};
483
484template <>
[email protected]141bcc52014-01-27 21:36:00485struct SimilarTypeTraits<base::File::Error> {
[email protected]bf5aedf02012-06-04 21:18:25486 typedef int Type;
487};
488
[email protected]ecf59c72013-02-28 21:46:11489#if defined(OS_WIN)
490template <>
491struct SimilarTypeTraits<HWND> {
492 typedef HANDLE Type;
493};
494#endif // defined(OS_WIN)
495
[email protected]bf5aedf02012-06-04 21:18:25496template <>
497struct IPC_EXPORT ParamTraits<base::Time> {
498 typedef base::Time param_type;
499 static void Write(Message* m, const param_type& p);
500 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
501 static void Log(const param_type& p, std::string* l);
502};
503
504template <>
505struct IPC_EXPORT ParamTraits<base::TimeDelta> {
506 typedef base::TimeDelta param_type;
507 static void Write(Message* m, const param_type& p);
508 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
509 static void Log(const param_type& p, std::string* l);
510};
511
512template <>
513struct IPC_EXPORT ParamTraits<base::TimeTicks> {
514 typedef base::TimeTicks param_type;
515 static void Write(Message* m, const param_type& p);
516 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
517 static void Log(const param_type& p, std::string* l);
[email protected]503683f2009-02-26 09:13:01518};
519
520template <>
[email protected]7d5c3ac2009-02-04 08:58:19521struct ParamTraits<Tuple0> {
522 typedef Tuple0 param_type;
523 static void Write(Message* m, const param_type& p) {
524 }
[email protected]ce208f872012-03-07 20:42:56525 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19526 return true;
527 }
[email protected]252cad62010-08-18 18:33:57528 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19529 }
530};
531
532template <class A>
533struct ParamTraits< Tuple1<A> > {
534 typedef Tuple1<A> param_type;
535 static void Write(Message* m, const param_type& p) {
536 WriteParam(m, p.a);
537 }
[email protected]ce208f872012-03-07 20:42:56538 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19539 return ReadParam(m, iter, &r->a);
540 }
[email protected]252cad62010-08-18 18:33:57541 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19542 LogParam(p.a, l);
543 }
544};
545
546template <class A, class B>
547struct ParamTraits< Tuple2<A, B> > {
548 typedef Tuple2<A, B> param_type;
549 static void Write(Message* m, const param_type& p) {
550 WriteParam(m, p.a);
551 WriteParam(m, p.b);
552 }
[email protected]ce208f872012-03-07 20:42:56553 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19554 return (ReadParam(m, iter, &r->a) &&
555 ReadParam(m, iter, &r->b));
556 }
[email protected]252cad62010-08-18 18:33:57557 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19558 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57559 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19560 LogParam(p.b, l);
561 }
562};
563
564template <class A, class B, class C>
565struct ParamTraits< Tuple3<A, B, C> > {
566 typedef Tuple3<A, B, C> param_type;
567 static void Write(Message* m, const param_type& p) {
568 WriteParam(m, p.a);
569 WriteParam(m, p.b);
570 WriteParam(m, p.c);
571 }
[email protected]ce208f872012-03-07 20:42:56572 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19573 return (ReadParam(m, iter, &r->a) &&
574 ReadParam(m, iter, &r->b) &&
575 ReadParam(m, iter, &r->c));
576 }
[email protected]252cad62010-08-18 18:33:57577 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19578 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57579 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19580 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57581 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19582 LogParam(p.c, l);
583 }
584};
585
586template <class A, class B, class C, class D>
587struct ParamTraits< Tuple4<A, B, C, D> > {
588 typedef Tuple4<A, B, C, D> param_type;
589 static void Write(Message* m, const param_type& p) {
590 WriteParam(m, p.a);
591 WriteParam(m, p.b);
592 WriteParam(m, p.c);
593 WriteParam(m, p.d);
594 }
[email protected]ce208f872012-03-07 20:42:56595 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19596 return (ReadParam(m, iter, &r->a) &&
597 ReadParam(m, iter, &r->b) &&
598 ReadParam(m, iter, &r->c) &&
599 ReadParam(m, iter, &r->d));
600 }
[email protected]252cad62010-08-18 18:33:57601 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19602 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57603 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19604 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57605 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19606 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57607 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19608 LogParam(p.d, l);
609 }
610};
611
612template <class A, class B, class C, class D, class E>
613struct ParamTraits< Tuple5<A, B, C, D, E> > {
614 typedef Tuple5<A, B, C, D, E> param_type;
615 static void Write(Message* m, const param_type& p) {
616 WriteParam(m, p.a);
617 WriteParam(m, p.b);
618 WriteParam(m, p.c);
619 WriteParam(m, p.d);
620 WriteParam(m, p.e);
621 }
[email protected]ce208f872012-03-07 20:42:56622 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19623 return (ReadParam(m, iter, &r->a) &&
624 ReadParam(m, iter, &r->b) &&
625 ReadParam(m, iter, &r->c) &&
626 ReadParam(m, iter, &r->d) &&
627 ReadParam(m, iter, &r->e));
628 }
[email protected]252cad62010-08-18 18:33:57629 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19630 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57631 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19632 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57633 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19634 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57635 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19636 LogParam(p.d, l);
[email protected]252cad62010-08-18 18:33:57637 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19638 LogParam(p.e, l);
639 }
640};
641
[email protected]b1064d62012-11-14 06:35:52642template<class P>
643struct ParamTraits<ScopedVector<P> > {
644 typedef ScopedVector<P> param_type;
645 static void Write(Message* m, const param_type& p) {
646 WriteParam(m, static_cast<int>(p.size()));
647 for (size_t i = 0; i < p.size(); i++)
648 WriteParam(m, *p[i]);
649 }
650 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
651 int size = 0;
652 if (!m->ReadLength(iter, &size))
653 return false;
654 if (INT_MAX/sizeof(P) <= static_cast<size_t>(size))
655 return false;
656 r->resize(size);
657 for (int i = 0; i < size; i++) {
658 (*r)[i] = new P();
659 if (!ReadParam(m, iter, (*r)[i]))
660 return false;
661 }
662 return true;
663 }
664 static void Log(const param_type& p, std::string* l) {
665 for (size_t i = 0; i < p.size(); ++i) {
666 if (i != 0)
667 l->append(" ");
668 LogParam(*p[i], l);
669 }
670 }
671};
672
[email protected]bf5aedf02012-06-04 21:18:25673// IPC types ParamTraits -------------------------------------------------------
674
675// A ChannelHandle is basically a platform-inspecific wrapper around the
676// fact that IPC endpoints are handled specially on POSIX. See above comments
677// on FileDescriptor for more background.
678template<>
679struct IPC_EXPORT ParamTraits<IPC::ChannelHandle> {
680 typedef ChannelHandle param_type;
681 static void Write(Message* m, const param_type& p);
682 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
683 static void Log(const param_type& p, std::string* l);
684};
685
686template <>
687struct IPC_EXPORT ParamTraits<LogData> {
688 typedef LogData 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<Message> {
696 static void Write(Message* m, const Message& p);
697 static bool Read(const Message* m, PickleIterator* iter, Message* r);
698 static void Log(const Message& p, std::string* l);
699};
700
701// Windows ParamTraits ---------------------------------------------------------
702
703#if defined(OS_WIN)
704template <>
705struct IPC_EXPORT ParamTraits<HANDLE> {
706 typedef HANDLE param_type;
707 static void Write(Message* m, const param_type& p);
708 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
709 static void Log(const param_type& p, std::string* l);
710};
711
712template <>
713struct IPC_EXPORT ParamTraits<LOGFONT> {
714 typedef LOGFONT param_type;
715 static void Write(Message* m, const param_type& p);
716 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
717 static void Log(const param_type& p, std::string* l);
718};
719
720template <>
721struct IPC_EXPORT ParamTraits<MSG> {
722 typedef MSG param_type;
723 static void Write(Message* m, const param_type& p);
724 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
725 static void Log(const param_type& p, std::string* l);
726};
727#endif // defined(OS_WIN)
728
[email protected]7d5c3ac2009-02-04 08:58:19729//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:29730// Generic message subclasses
731
732// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:24733template <class ParamType>
[email protected]1d4ecf42011-08-26 21:27:30734class MessageSchema {
initial.commit09911bf2008-07-26 23:55:29735 public:
[email protected]81a34412009-01-05 19:17:24736 typedef ParamType Param;
[email protected]7a4de7a62010-08-17 18:38:24737 typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
[email protected]81a34412009-01-05 19:17:24738
[email protected]1d4ecf42011-08-26 21:27:30739 static void Write(Message* msg, const RefParam& p) IPC_MSG_NOINLINE;
[email protected]7a4de7a62010-08-17 18:38:24740 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:29741};
742
[email protected]7a4de7a62010-08-17 18:38:24743// defined in ipc_logging.cc
[email protected]7c854372011-08-15 20:41:46744IPC_EXPORT void GenerateLogData(const std::string& channel,
745 const Message& message,
[email protected]ea7744a2011-10-20 19:34:43746 LogData* data, bool get_params);
[email protected]7a4de7a62010-08-17 18:38:24747
748
749#if defined(IPC_MESSAGE_LOG_ENABLED)
[email protected]252cad62010-08-18 18:33:57750inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
751 const std::string& output_params = msg->output_params();
[email protected]7a4de7a62010-08-17 18:38:24752 if (!l->empty() && !output_params.empty())
[email protected]252cad62010-08-18 18:33:57753 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:24754
755 l->append(output_params);
756}
757
758template <class ReplyParamType>
759inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
760 const Message* msg) {
761 if (msg->received_time() != 0) {
[email protected]252cad62010-08-18 18:33:57762 std::string output_params;
[email protected]7a4de7a62010-08-17 18:38:24763 LogParam(reply_params, &output_params);
764 msg->set_output_params(output_params);
765 }
766}
767
768inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
769 if (msg->sent_time()) {
770 // Don't log the sync message after dispatch, as we don't have the
771 // output parameters at that point. Instead, save its data and log it
772 // with the outgoing reply message when it's sent.
773 LogData* data = new LogData;
[email protected]ea7744a2011-10-20 19:34:43774 GenerateLogData("", *msg, data, true);
[email protected]7a4de7a62010-08-17 18:38:24775 msg->set_dont_log();
776 reply->set_sync_log_data(data);
777 }
778}
779#else
[email protected]252cad62010-08-18 18:33:57780inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
[email protected]7a4de7a62010-08-17 18:38:24781
782template <class ReplyParamType>
783inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
784 const Message* msg) {}
785
786inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
787#endif
788
initial.commit09911bf2008-07-26 23:55:29789// This class assumes that its template argument is a RefTuple (a Tuple with
[email protected]7a4de7a62010-08-17 18:38:24790// reference elements). This would go into ipc_message_utils_impl.h, but it is
791// also used by chrome_frame.
initial.commit09911bf2008-07-26 23:55:29792template <class RefTuple>
793class ParamDeserializer : public MessageReplyDeserializer {
794 public:
[email protected]e1981f432008-08-12 15:22:13795 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:29796
[email protected]ce208f872012-03-07 20:42:56797 bool SerializeOutputParameters(const IPC::Message& msg, PickleIterator iter) {
initial.commit09911bf2008-07-26 23:55:29798 return ReadParam(&msg, &iter, &out_);
799 }
800
801 RefTuple out_;
802};
803
initial.commit09911bf2008-07-26 23:55:29804// Used for synchronous messages.
[email protected]75e5a872009-04-02 23:56:11805template <class SendParamType, class ReplyParamType>
[email protected]1d4ecf42011-08-26 21:27:30806class SyncMessageSchema {
initial.commit09911bf2008-07-26 23:55:29807 public:
[email protected]75e5a872009-04-02 23:56:11808 typedef SendParamType SendParam;
[email protected]7a4de7a62010-08-17 18:38:24809 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
[email protected]75e5a872009-04-02 23:56:11810 typedef ReplyParamType ReplyParam;
811
[email protected]1d4ecf42011-08-26 21:27:30812 static void Write(Message* msg, const RefSendParam& send) IPC_MSG_NOINLINE;
[email protected]7a4de7a62010-08-17 18:38:24813 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
814 static bool ReadReplyParam(
815 const Message* msg,
816 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:29817
[email protected]65412272010-12-21 20:03:24818 template<class T, class S, class Method>
[email protected]1d4ecf42011-08-26 21:27:30819 static bool DispatchWithSendParams(bool ok, const SendParam& send_params,
820 const Message* msg, T* obj, S* sender,
821 Method func) {
822 Message* reply = SyncMessage::GenerateReply(msg);
823 if (ok) {
[email protected]7a4de7a62010-08-17 18:38:24824 typename TupleTypes<ReplyParam>::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:29825 DispatchToMethod(obj, func, send_params, &reply_params);
826 WriteParam(reply, reply_params);
[email protected]7a4de7a62010-08-17 18:38:24827 LogReplyParamsToMessage(reply_params, msg);
initial.commit09911bf2008-07-26 23:55:29828 } else {
829 NOTREACHED() << "Error deserializing message " << msg->type();
830 reply->set_reply_error();
initial.commit09911bf2008-07-26 23:55:29831 }
[email protected]65412272010-12-21 20:03:24832 sender->Send(reply);
[email protected]1d4ecf42011-08-26 21:27:30833 return ok;
initial.commit09911bf2008-07-26 23:55:29834 }
835
836 template<class T, class Method>
[email protected]1d4ecf42011-08-26 21:27:30837 static bool DispatchDelayReplyWithSendParams(bool ok,
838 const SendParam& send_params,
839 const Message* msg, T* obj,
840 Method func) {
841 Message* reply = SyncMessage::GenerateReply(msg);
842 if (ok) {
initial.commit09911bf2008-07-26 23:55:29843 Tuple1<Message&> t = MakeRefTuple(*reply);
[email protected]7a4de7a62010-08-17 18:38:24844 ConnectMessageAndReply(msg, reply);
initial.commit09911bf2008-07-26 23:55:29845 DispatchToMethod(obj, func, send_params, &t);
initial.commit09911bf2008-07-26 23:55:29846 } else {
847 NOTREACHED() << "Error deserializing message " << msg->type();
848 reply->set_reply_error();
849 obj->Send(reply);
initial.commit09911bf2008-07-26 23:55:29850 }
[email protected]1d4ecf42011-08-26 21:27:30851 return ok;
initial.commit09911bf2008-07-26 23:55:29852 }
853
854 template<typename TA>
855 static void WriteReplyParams(Message* reply, TA a) {
856 ReplyParam p(a);
857 WriteParam(reply, p);
858 }
859
860 template<typename TA, typename TB>
861 static void WriteReplyParams(Message* reply, TA a, TB b) {
862 ReplyParam p(a, b);
863 WriteParam(reply, p);
864 }
865
866 template<typename TA, typename TB, typename TC>
867 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
868 ReplyParam p(a, b, c);
869 WriteParam(reply, p);
870 }
871
872 template<typename TA, typename TB, typename TC, typename TD>
873 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
874 ReplyParam p(a, b, c, d);
875 WriteParam(reply, p);
876 }
877
878 template<typename TA, typename TB, typename TC, typename TD, typename TE>
879 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
880 ReplyParam p(a, b, c, d, e);
881 WriteParam(reply, p);
882 }
883};
884
[email protected]3178f4e22008-08-05 21:20:41885} // namespace IPC
initial.commit09911bf2008-07-26 23:55:29886
[email protected]946d1b22009-07-22 23:57:21887#endif // IPC_IPC_MESSAGE_UTILS_H_