blob: 942a4b79a000032a3382dce4968f7612724de3e4 [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
avi51ba3e692015-12-26 17:30:508#include <limits.h>
avi246998d82015-12-22 02:39:049#include <stddef.h>
tfarina10a5c062015-09-04 18:47:5710#include <stdint.h>
11
[email protected]379e7a52010-03-09 00:38:4112#include <algorithm>
initial.commit09911bf2008-07-26 23:55:2913#include <map>
[email protected]96da6962010-05-13 19:10:3414#include <set>
[email protected]663bd9e2011-03-21 01:07:0115#include <string>
16#include <vector>
initial.commit09911bf2008-07-26 23:55:2917
[email protected]205294b2014-03-18 20:48:3518#include "base/containers/small_map.h"
miletus1edf97f92015-07-23 19:42:3619#include "base/containers/stack_container.h"
[email protected]141bcc52014-01-27 21:36:0020#include "base/files/file.h"
[email protected]dce5df52009-06-29 17:58:2521#include "base/format_macros.h"
[email protected]8e431f2032014-05-20 02:34:5622#include "base/memory/scoped_ptr.h"
[email protected]b1064d62012-11-14 06:35:5223#include "base/memory/scoped_vector.h"
[email protected]4aa794a12013-06-11 06:32:1824#include "base/strings/string16.h"
25#include "base/strings/string_util.h"
26#include "base/strings/stringprintf.h"
initial.commit09911bf2008-07-26 23:55:2927#include "base/tuple.h"
avi246998d82015-12-22 02:39:0428#include "build/build_config.h"
erikcheneece6c32015-07-07 22:13:1129#include "ipc/brokerable_attachment.h"
[email protected]f9509812012-10-23 23:03:3530#include "ipc/ipc_message_start.h"
[email protected]939856a2010-08-24 20:29:0231#include "ipc/ipc_param_traits.h"
[email protected]0cfe5dae2010-08-17 00:24:5432#include "ipc/ipc_sync_message.h"
[email protected]55b4e212010-08-13 20:43:5833
[email protected]7a4de7a62010-08-17 18:38:2434namespace base {
[email protected]f3a1c642011-07-12 19:15:0335class DictionaryValue;
[email protected]a3ef4832013-02-02 05:12:3336class FilePath;
[email protected]f3a1c642011-07-12 19:15:0337class ListValue;
[email protected]0238a162013-06-13 13:47:4638class NullableString16;
[email protected]7a4de7a62010-08-17 18:38:2439class Time;
[email protected]d84e48b2010-10-21 22:04:5240class TimeDelta;
[email protected]1d14f582011-09-02 20:42:0441class TimeTicks;
[email protected]7a4de7a62010-08-17 18:38:2442struct FileDescriptor;
scottmgd19b4f72015-06-19 22:51:0043
erikchen5ea2ab72015-09-25 22:34:3144#if (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
scottmgd19b4f72015-06-19 22:51:0045class SharedMemoryHandle;
erikchen5ea2ab72015-09-25 22:34:3146#endif // (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
[email protected]7a4de7a62010-08-17 18:38:2447}
48
initial.commit09911bf2008-07-26 23:55:2949namespace IPC {
50
[email protected]7a4de7a62010-08-17 18:38:2451struct ChannelHandle;
52
[email protected]bf5aedf02012-06-04 21:18:2553// -----------------------------------------------------------------------------
54// How we send IPC message logs across channels.
55struct IPC_EXPORT LogData {
56 LogData();
57 ~LogData();
58
59 std::string channel;
tfarina10a5c062015-09-04 18:47:5760 int32_t routing_id;
61 uint32_t type; // "User-defined" message type, from ipc_message.h.
[email protected]bf5aedf02012-06-04 21:18:2562 std::string flags;
tfarina10a5c062015-09-04 18:47:5763 int64_t sent; // Time that the message was sent (i.e. at Send()).
64 int64_t receive; // Time before it was dispatched (i.e. before calling
65 // OnMessageReceived).
66 int64_t dispatch; // Time after it was dispatched (i.e. after calling
67 // OnMessageReceived).
[email protected]bf5aedf02012-06-04 21:18:2568 std::string message_name;
69 std::string params;
70};
71
initial.commit09911bf2008-07-26 23:55:2972//-----------------------------------------------------------------------------
[email protected]7edae3d02012-12-17 20:23:4773
[email protected]6476c72c2011-02-11 18:46:1974// A dummy struct to place first just to allow leading commas for all
75// members in the macro-generated constructor initializer lists.
76struct NoParams {
77};
78
[email protected]7d5c3ac2009-02-04 08:58:1979template <class P>
rockot0457af102016-02-05 02:12:3280static inline void GetParamSize(base::PickleSizer* sizer, const P& p) {
81 typedef typename SimilarTypeTraits<P>::Type Type;
82 ParamTraits<Type>::GetSize(sizer, static_cast<const Type&>(p));
83}
84
85template <class P>
rockot502c94f2016-02-03 20:20:1686static inline void WriteParam(base::Pickle* m, const P& p) {
[email protected]7b291f92009-08-14 05:43:5387 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:5388 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
[email protected]7d5c3ac2009-02-04 08:58:1989}
90
91template <class P>
rockot502c94f2016-02-03 20:20:1692static inline bool WARN_UNUSED_RESULT ReadParam(const base::Pickle* m,
93 base::PickleIterator* iter,
94 P* p) {
[email protected]7b291f92009-08-14 05:43:5395 typedef typename SimilarTypeTraits<P>::Type Type;
96 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
[email protected]7d5c3ac2009-02-04 08:58:1997}
98
99template <class P>
[email protected]252cad62010-08-18 18:33:57100static inline void LogParam(const P& p, std::string* l) {
[email protected]7b291f92009-08-14 05:43:53101 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53102 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19103}
104
[email protected]bf5aedf02012-06-04 21:18:25105// Primitive ParamTraits -------------------------------------------------------
106
[email protected]7d5c3ac2009-02-04 08:58:19107template <>
108struct ParamTraits<bool> {
109 typedef bool param_type;
rockot0457af102016-02-05 02:12:32110 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
111 sizer->AddBool();
112 }
rockot502c94f2016-02-03 20:20:16113 static void Write(base::Pickle* m, const param_type& p) { m->WriteBool(p); }
114 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25115 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47116 param_type* r) {
avi48fc13b2014-12-28 23:31:48117 return iter->ReadBool(r);
[email protected]7d5c3ac2009-02-04 08:58:19118 }
[email protected]bf5aedf02012-06-04 21:18:25119 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19120};
121
122template <>
ortuno19ecf1842015-10-30 00:46:20123struct IPC_EXPORT ParamTraits<signed char> {
124 typedef signed char param_type;
rockot0457af102016-02-05 02:12:32125 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16126 static void Write(base::Pickle* m, const param_type& p);
127 static bool Read(const base::Pickle* m,
128 base::PickleIterator* iter,
129 param_type* r);
ortuno19ecf1842015-10-30 00:46:20130 static void Log(const param_type& p, std::string* l);
131};
132
133template <>
[email protected]c1ee48d2013-07-12 23:12:28134struct IPC_EXPORT ParamTraits<unsigned char> {
[email protected]7bea7352013-07-13 04:42:10135 typedef unsigned char param_type;
rockot0457af102016-02-05 02:12:32136 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16137 static void Write(base::Pickle* m, const param_type& p);
138 static bool Read(const base::Pickle* m,
139 base::PickleIterator* iter,
140 param_type* r);
[email protected]c1ee48d2013-07-12 23:12:28141 static void Log(const param_type& p, std::string* l);
142};
143
144template <>
145struct IPC_EXPORT ParamTraits<unsigned short> {
146 typedef unsigned short param_type;
rockot0457af102016-02-05 02:12:32147 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16148 static void Write(base::Pickle* m, const param_type& p);
149 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25150 base::PickleIterator* iter,
151 param_type* r);
[email protected]c1ee48d2013-07-12 23:12:28152 static void Log(const param_type& p, std::string* l);
153};
154
155template <>
[email protected]7d5c3ac2009-02-04 08:58:19156struct ParamTraits<int> {
157 typedef int param_type;
rockot0457af102016-02-05 02:12:32158 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
159 sizer->AddInt();
160 }
rockot502c94f2016-02-03 20:20:16161 static void Write(base::Pickle* m, const param_type& p) { m->WriteInt(p); }
162 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25163 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47164 param_type* r) {
avi48fc13b2014-12-28 23:31:48165 return iter->ReadInt(r);
[email protected]7d5c3ac2009-02-04 08:58:19166 }
[email protected]7c854372011-08-15 20:41:46167 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19168};
169
170template <>
[email protected]63263f92009-07-28 19:35:08171struct ParamTraits<unsigned int> {
172 typedef unsigned int param_type;
rockot0457af102016-02-05 02:12:32173 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
174 sizer->AddInt();
175 }
rockot502c94f2016-02-03 20:20:16176 static void Write(base::Pickle* m, const param_type& p) { m->WriteInt(p); }
177 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25178 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47179 param_type* r) {
avi48fc13b2014-12-28 23:31:48180 return iter->ReadInt(reinterpret_cast<int*>(r));
[email protected]63263f92009-07-28 19:35:08181 }
[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
jam03d8a782016-02-10 20:13:39185// long isn't safe to send over IPC because it's 4 bytes on 32 bit builds but
186// 8 bytes on 64 bit builds. So if a 32 bit and 64 bit process have a channel
187// that would cause problem.
188// We need to keep this on for a few configs:
189// 1) Windows because DWORD is typedef'd to it, which is fine because we have
190// very few IPCs that cross this boundary.
191// 2) We also need to keep it for Linux for two reasons: int64_t is typedef'd
192// to long, and gfx::PluginWindow is long and is used in one GPU IPC.
193// 3) Android 64 bit also has int64_t typedef'd to long.
194// Since we want to support Android 32<>64 bit IPC, as long as we don't have
195// these traits for 32 bit ARM then that'll catch any errors.
jamac78d7d82016-02-11 00:50:28196#if defined(OS_WIN) || defined(OS_LINUX) || \
197 (defined(OS_ANDROID) && defined(ARCH_CPU_64_BITS))
[email protected]63263f92009-07-28 19:35:08198template <>
[email protected]7d5c3ac2009-02-04 08:58:19199struct ParamTraits<long> {
200 typedef long param_type;
rockot0457af102016-02-05 02:12:32201 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
jam03d8a782016-02-10 20:13:39202 sizer->AddLong();
rockot0457af102016-02-05 02:12:32203 }
rockot502c94f2016-02-03 20:20:16204 static void Write(base::Pickle* m, const param_type& p) {
jam03d8a782016-02-10 20:13:39205 m->WriteLong(p);
[email protected]7d5c3ac2009-02-04 08:58:19206 }
rockot502c94f2016-02-03 20:20:16207 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25208 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47209 param_type* r) {
avi48fc13b2014-12-28 23:31:48210 return iter->ReadLong(r);
[email protected]7d5c3ac2009-02-04 08:58:19211 }
[email protected]7c854372011-08-15 20:41:46212 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19213};
214
[email protected]140c3032009-06-26 18:22:54215template <>
216struct ParamTraits<unsigned long> {
217 typedef unsigned long param_type;
rockot0457af102016-02-05 02:12:32218 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
jam03d8a782016-02-10 20:13:39219 sizer->AddLong();
rockot0457af102016-02-05 02:12:32220 }
rockot502c94f2016-02-03 20:20:16221 static void Write(base::Pickle* m, const param_type& p) {
jam03d8a782016-02-10 20:13:39222 m->WriteLong(p);
[email protected]140c3032009-06-26 18:22:54223 }
rockot502c94f2016-02-03 20:20:16224 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25225 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47226 param_type* r) {
avi48fc13b2014-12-28 23:31:48227 return iter->ReadLong(reinterpret_cast<long*>(r));
[email protected]140c3032009-06-26 18:22:54228 }
[email protected]7c854372011-08-15 20:41:46229 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19230};
jam03d8a782016-02-10 20:13:39231#endif
[email protected]7d5c3ac2009-02-04 08:58:19232
233template <>
[email protected]63263f92009-07-28 19:35:08234struct ParamTraits<long long> {
235 typedef long long param_type;
rockot0457af102016-02-05 02:12:32236 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
237 sizer->AddInt64();
238 }
rockot502c94f2016-02-03 20:20:16239 static void Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:57240 m->WriteInt64(static_cast<int64_t>(p));
[email protected]7d5c3ac2009-02-04 08:58:19241 }
rockot502c94f2016-02-03 20:20:16242 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25243 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:56244 param_type* r) {
tfarina10a5c062015-09-04 18:47:57245 return iter->ReadInt64(reinterpret_cast<int64_t*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19246 }
[email protected]7c854372011-08-15 20:41:46247 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08248};
249
250template <>
251struct ParamTraits<unsigned long long> {
252 typedef unsigned long long param_type;
rockot0457af102016-02-05 02:12:32253 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
254 sizer->AddInt64();
255 }
rockot502c94f2016-02-03 20:20:16256 static void Write(base::Pickle* m, const param_type& p) { m->WriteInt64(p); }
257 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25258 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:56259 param_type* r) {
tfarina10a5c062015-09-04 18:47:57260 return iter->ReadInt64(reinterpret_cast<int64_t*>(r));
[email protected]63263f92009-07-28 19:35:08261 }
[email protected]7c854372011-08-15 20:41:46262 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19263};
264
[email protected]20199662010-06-17 03:29:26265// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
266// should be sure to check the sanity of these values after receiving them over
267// IPC.
268template <>
[email protected]bf5aedf02012-06-04 21:18:25269struct IPC_EXPORT ParamTraits<float> {
[email protected]20199662010-06-17 03:29:26270 typedef float param_type;
rockot0457af102016-02-05 02:12:32271 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
272 sizer->AddFloat();
273 }
rockot502c94f2016-02-03 20:20:16274 static void Write(base::Pickle* m, const param_type& p) { m->WriteFloat(p); }
275 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25276 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47277 param_type* r) {
avi48fc13b2014-12-28 23:31:48278 return iter->ReadFloat(r);
[email protected]48328ff2013-10-31 09:27:31279 }
[email protected]bf5aedf02012-06-04 21:18:25280 static void Log(const param_type& p, std::string* l);
[email protected]20199662010-06-17 03:29:26281};
282
[email protected]7d5c3ac2009-02-04 08:58:19283template <>
[email protected]bf5aedf02012-06-04 21:18:25284struct IPC_EXPORT ParamTraits<double> {
[email protected]7d5c3ac2009-02-04 08:58:19285 typedef double param_type;
rockot0457af102016-02-05 02:12:32286 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16287 static void Write(base::Pickle* m, const param_type& p);
288 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25289 base::PickleIterator* iter,
290 param_type* r);
[email protected]c410e022012-05-30 21:15:57291 static void Log(const param_type& p, std::string* l);
292};
293
[email protected]bf5aedf02012-06-04 21:18:25294// STL ParamTraits -------------------------------------------------------------
[email protected]584f2b22009-05-21 01:01:59295
296template <>
[email protected]7d5c3ac2009-02-04 08:58:19297struct ParamTraits<std::string> {
298 typedef std::string param_type;
rockot0457af102016-02-05 02:12:32299 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
300 sizer->AddString(p);
301 }
rockot502c94f2016-02-03 20:20:16302 static void Write(base::Pickle* m, const param_type& p) { m->WriteString(p); }
303 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25304 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:56305 param_type* r) {
avi48fc13b2014-12-28 23:31:48306 return iter->ReadString(r);
[email protected]7d5c3ac2009-02-04 08:58:19307 }
[email protected]bf5aedf02012-06-04 21:18:25308 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19309};
310
[email protected]bf5aedf02012-06-04 21:18:25311template <>
[email protected]476dafb2013-12-03 00:39:26312struct ParamTraits<base::string16> {
313 typedef base::string16 param_type;
rockot0457af102016-02-05 02:12:32314 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
315 sizer->AddString16(p);
316 }
rockot502c94f2016-02-03 20:20:16317 static void Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25318 m->WriteString16(p);
319 }
rockot502c94f2016-02-03 20:20:16320 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25321 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25322 param_type* r) {
avi48fc13b2014-12-28 23:31:48323 return iter->ReadString16(r);
[email protected]bf5aedf02012-06-04 21:18:25324 }
325 IPC_EXPORT static void Log(const param_type& p, std::string* l);
326};
[email protected]3dd7a7a2009-07-27 21:09:07327
[email protected]7d5c3ac2009-02-04 08:58:19328template <>
[email protected]bf5aedf02012-06-04 21:18:25329struct IPC_EXPORT ParamTraits<std::vector<char> > {
[email protected]7d5c3ac2009-02-04 08:58:19330 typedef std::vector<char> param_type;
rockot0457af102016-02-05 02:12:32331 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16332 static void Write(base::Pickle* m, const param_type& p);
333 static bool Read(const base::Pickle*,
brettwbd4d7112015-06-03 04:29:25334 base::PickleIterator* iter,
335 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25336 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19337};
338
[email protected]51b63f62011-10-05 18:55:42339template <>
[email protected]bf5aedf02012-06-04 21:18:25340struct IPC_EXPORT ParamTraits<std::vector<unsigned char> > {
341 typedef std::vector<unsigned char> param_type;
rockot0457af102016-02-05 02:12:32342 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16343 static void Write(base::Pickle* m, const param_type& p);
344 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25345 base::PickleIterator* iter,
346 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25347 static void Log(const param_type& p, std::string* l);
348};
349
350template <>
351struct IPC_EXPORT ParamTraits<std::vector<bool> > {
[email protected]51b63f62011-10-05 18:55:42352 typedef std::vector<bool> param_type;
rockot0457af102016-02-05 02:12:32353 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16354 static void Write(base::Pickle* m, const param_type& p);
355 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25356 base::PickleIterator* iter,
357 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25358 static void Log(const param_type& p, std::string* l);
[email protected]51b63f62011-10-05 18:55:42359};
360
[email protected]7d5c3ac2009-02-04 08:58:19361template <class P>
362struct ParamTraits<std::vector<P> > {
363 typedef std::vector<P> param_type;
rockot0457af102016-02-05 02:12:32364 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
365 GetParamSize(sizer, static_cast<int>(p.size()));
366 for (size_t i = 0; i < p.size(); i++)
367 GetParamSize(sizer, p[i]);
368 }
rockot502c94f2016-02-03 20:20:16369 static void Write(base::Pickle* m, const param_type& p) {
[email protected]7d5c3ac2009-02-04 08:58:19370 WriteParam(m, static_cast<int>(p.size()));
371 for (size_t i = 0; i < p.size(); i++)
372 WriteParam(m, p[i]);
373 }
rockot502c94f2016-02-03 20:20:16374 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25375 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:56376 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19377 int size;
[email protected]86440f52009-12-31 05:17:23378 // ReadLength() checks for < 0 itself.
avi48fc13b2014-12-28 23:31:48379 if (!iter->ReadLength(&size))
[email protected]7d5c3ac2009-02-04 08:58:19380 return false;
381 // Resizing beforehand is not safe, see BUG 1006367 for details.
[email protected]86440f52009-12-31 05:17:23382 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
383 return false;
384 r->resize(size);
385 for (int i = 0; i < size; i++) {
386 if (!ReadParam(m, iter, &(*r)[i]))
387 return false;
[email protected]7d5c3ac2009-02-04 08:58:19388 }
389 return true;
390 }
[email protected]252cad62010-08-18 18:33:57391 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19392 for (size_t i = 0; i < p.size(); ++i) {
393 if (i != 0)
[email protected]252cad62010-08-18 18:33:57394 l->append(" ");
[email protected]7d5c3ac2009-02-04 08:58:19395 LogParam((p[i]), l);
396 }
397 }
398};
399
[email protected]96da6962010-05-13 19:10:34400template <class P>
401struct ParamTraits<std::set<P> > {
402 typedef std::set<P> param_type;
rockot0457af102016-02-05 02:12:32403 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
404 GetParamSize(sizer, static_cast<int>(p.size()));
405 typename param_type::const_iterator iter;
406 for (iter = p.begin(); iter != p.end(); ++iter)
407 GetParamSize(sizer, *iter);
408 }
rockot502c94f2016-02-03 20:20:16409 static void Write(base::Pickle* m, const param_type& p) {
[email protected]96da6962010-05-13 19:10:34410 WriteParam(m, static_cast<int>(p.size()));
411 typename param_type::const_iterator iter;
412 for (iter = p.begin(); iter != p.end(); ++iter)
413 WriteParam(m, *iter);
414 }
rockot502c94f2016-02-03 20:20:16415 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25416 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:56417 param_type* r) {
[email protected]96da6962010-05-13 19:10:34418 int size;
avi48fc13b2014-12-28 23:31:48419 if (!iter->ReadLength(&size))
[email protected]96da6962010-05-13 19:10:34420 return false;
421 for (int i = 0; i < size; ++i) {
422 P item;
423 if (!ReadParam(m, iter, &item))
424 return false;
425 r->insert(item);
426 }
427 return true;
428 }
[email protected]252cad62010-08-18 18:33:57429 static void Log(const param_type& p, std::string* l) {
430 l->append("<std::set>");
[email protected]96da6962010-05-13 19:10:34431 }
432};
433
jkarlinf96d19ba2014-09-24 11:42:37434template <class K, class V, class C, class A>
435struct ParamTraits<std::map<K, V, C, A> > {
436 typedef std::map<K, V, C, A> param_type;
rockot0457af102016-02-05 02:12:32437 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
438 GetParamSize(sizer, static_cast<int>(p.size()));
439 typename param_type::const_iterator iter;
440 for (iter = p.begin(); iter != p.end(); ++iter) {
441 GetParamSize(sizer, iter->first);
442 GetParamSize(sizer, iter->second);
443 }
444 }
rockot502c94f2016-02-03 20:20:16445 static void Write(base::Pickle* m, const param_type& p) {
[email protected]7d5c3ac2009-02-04 08:58:19446 WriteParam(m, static_cast<int>(p.size()));
447 typename param_type::const_iterator iter;
448 for (iter = p.begin(); iter != p.end(); ++iter) {
449 WriteParam(m, iter->first);
450 WriteParam(m, iter->second);
451 }
452 }
rockot502c94f2016-02-03 20:20:16453 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25454 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:56455 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19456 int size;
457 if (!ReadParam(m, iter, &size) || size < 0)
458 return false;
459 for (int i = 0; i < size; ++i) {
460 K k;
461 if (!ReadParam(m, iter, &k))
462 return false;
463 V& value = (*r)[k];
464 if (!ReadParam(m, iter, &value))
465 return false;
466 }
467 return true;
468 }
[email protected]252cad62010-08-18 18:33:57469 static void Log(const param_type& p, std::string* l) {
470 l->append("<std::map>");
[email protected]7d5c3ac2009-02-04 08:58:19471 }
472};
473
[email protected]a5da6d612009-08-04 02:00:56474template <class A, class B>
475struct ParamTraits<std::pair<A, B> > {
476 typedef std::pair<A, B> param_type;
rockot0457af102016-02-05 02:12:32477 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
478 GetParamSize(sizer, p.first);
479 GetParamSize(sizer, p.second);
480 }
rockot502c94f2016-02-03 20:20:16481 static void Write(base::Pickle* m, const param_type& p) {
[email protected]a5da6d612009-08-04 02:00:56482 WriteParam(m, p.first);
483 WriteParam(m, p.second);
484 }
rockot502c94f2016-02-03 20:20:16485 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25486 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:56487 param_type* r) {
[email protected]a5da6d612009-08-04 02:00:56488 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
489 }
[email protected]252cad62010-08-18 18:33:57490 static void Log(const param_type& p, std::string* l) {
491 l->append("(");
[email protected]a5da6d612009-08-04 02:00:56492 LogParam(p.first, l);
[email protected]252cad62010-08-18 18:33:57493 l->append(", ");
[email protected]a5da6d612009-08-04 02:00:56494 LogParam(p.second, l);
[email protected]252cad62010-08-18 18:33:57495 l->append(")");
[email protected]a5da6d612009-08-04 02:00:56496 }
497};
498
erikcheneece6c32015-07-07 22:13:11499// IPC ParamTraits -------------------------------------------------------------
500template <>
501struct IPC_EXPORT ParamTraits<BrokerableAttachment::AttachmentId> {
502 typedef BrokerableAttachment::AttachmentId param_type;
rockot502c94f2016-02-03 20:20:16503 static void Write(base::Pickle* m, const param_type& p);
504 static bool Read(const base::Pickle* m,
505 base::PickleIterator* iter,
506 param_type* r);
erikcheneece6c32015-07-07 22:13:11507 static void Log(const param_type& p, std::string* l);
508};
509
[email protected]bf5aedf02012-06-04 21:18:25510// Base ParamTraits ------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19511
512template <>
[email protected]bf5aedf02012-06-04 21:18:25513struct IPC_EXPORT ParamTraits<base::DictionaryValue> {
514 typedef base::DictionaryValue param_type;
rockot0457af102016-02-05 02:12:32515 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16516 static void Write(base::Pickle* m, const param_type& p);
517 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25518 base::PickleIterator* iter,
519 param_type* r);
[email protected]252cad62010-08-18 18:33:57520 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19521};
522
[email protected]526776c2009-02-07 00:39:26523#if defined(OS_POSIX)
[email protected]2749885f2009-03-05 21:40:11524// FileDescriptors may be serialised over IPC channels on POSIX. On the
525// receiving side, the FileDescriptor is a valid duplicate of the file
526// descriptor which was transmitted: *it is not just a copy of the integer like
527// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
528// this case, the receiving end will see a value of -1. *Zero is a valid file
529// descriptor*.
530//
531// The received file descriptor will have the |auto_close| flag set to true. The
532// code which handles the message is responsible for taking ownership of it.
533// File descriptors are OS resources and must be closed when no longer needed.
534//
535// When sending a file descriptor, the file descriptor must be valid at the time
536// of transmission. Since transmission is not synchronous, one should consider
537// dup()ing any file descriptors to be transmitted and setting the |auto_close|
538// flag, which causes the file descriptor to be closed after writing.
[email protected]526776c2009-02-07 00:39:26539template<>
[email protected]7c854372011-08-15 20:41:46540struct IPC_EXPORT ParamTraits<base::FileDescriptor> {
[email protected]5fe733de2009-02-11 18:59:20541 typedef base::FileDescriptor param_type;
rockot502c94f2016-02-03 20:20:16542 static void Write(base::Pickle* m, const param_type& p);
543 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25544 base::PickleIterator* iter,
545 param_type* r);
[email protected]252cad62010-08-18 18:33:57546 static void Log(const param_type& p, std::string* l);
[email protected]526776c2009-02-07 00:39:26547};
[email protected]379e7a52010-03-09 00:38:41548#endif // defined(OS_POSIX)
[email protected]526776c2009-02-07 00:39:26549
erikchen5ea2ab72015-09-25 22:34:31550#if (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
scottmgd19b4f72015-06-19 22:51:00551template <>
552struct IPC_EXPORT ParamTraits<base::SharedMemoryHandle> {
553 typedef base::SharedMemoryHandle param_type;
rockot502c94f2016-02-03 20:20:16554 static void Write(base::Pickle* m, const param_type& p);
555 static bool Read(const base::Pickle* m,
556 base::PickleIterator* iter,
557 param_type* r);
scottmgd19b4f72015-06-19 22:51:00558 static void Log(const param_type& p, std::string* l);
559};
erikchen5ea2ab72015-09-25 22:34:31560#endif // (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
scottmgd19b4f72015-06-19 22:51:00561
[email protected]bf5aedf02012-06-04 21:18:25562template <>
[email protected]a3ef4832013-02-02 05:12:33563struct IPC_EXPORT ParamTraits<base::FilePath> {
564 typedef base::FilePath param_type;
rockot0457af102016-02-05 02:12:32565 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16566 static void Write(base::Pickle* m, const param_type& p);
567 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25568 base::PickleIterator* iter,
569 param_type* r);
[email protected]252cad62010-08-18 18:33:57570 static void Log(const param_type& p, std::string* l);
[email protected]d2e884d2009-06-22 20:37:52571};
572
[email protected]7d5c3ac2009-02-04 08:58:19573template <>
[email protected]bf5aedf02012-06-04 21:18:25574struct IPC_EXPORT ParamTraits<base::ListValue> {
575 typedef base::ListValue param_type;
rockot0457af102016-02-05 02:12:32576 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16577 static void Write(base::Pickle* m, const param_type& p);
578 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25579 base::PickleIterator* iter,
580 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25581 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19582};
583
[email protected]eb47a132009-03-04 00:39:56584template <>
[email protected]0238a162013-06-13 13:47:46585struct IPC_EXPORT ParamTraits<base::NullableString16> {
586 typedef base::NullableString16 param_type;
rockot0457af102016-02-05 02:12:32587 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16588 static void Write(base::Pickle* m, const param_type& p);
589 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25590 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25591 param_type* r);
592 static void Log(const param_type& p, std::string* l);
593};
594
595template <>
[email protected]141bcc52014-01-27 21:36:00596struct IPC_EXPORT ParamTraits<base::File::Info> {
597 typedef base::File::Info param_type;
rockot0457af102016-02-05 02:12:32598 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16599 static void Write(base::Pickle* m, const param_type& p);
600 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25601 base::PickleIterator* iter,
602 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25603 static void Log(const param_type& p, std::string* l);
604};
605
606template <>
[email protected]141bcc52014-01-27 21:36:00607struct SimilarTypeTraits<base::File::Error> {
[email protected]bf5aedf02012-06-04 21:18:25608 typedef int Type;
609};
610
[email protected]ecf59c72013-02-28 21:46:11611#if defined(OS_WIN)
612template <>
613struct SimilarTypeTraits<HWND> {
614 typedef HANDLE Type;
615};
616#endif // defined(OS_WIN)
617
[email protected]bf5aedf02012-06-04 21:18:25618template <>
619struct IPC_EXPORT ParamTraits<base::Time> {
620 typedef base::Time param_type;
rockot0457af102016-02-05 02:12:32621 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16622 static void Write(base::Pickle* m, const param_type& p);
623 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25624 base::PickleIterator* iter,
625 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25626 static void Log(const param_type& p, std::string* l);
627};
628
629template <>
630struct IPC_EXPORT ParamTraits<base::TimeDelta> {
631 typedef base::TimeDelta param_type;
rockot0457af102016-02-05 02:12:32632 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16633 static void Write(base::Pickle* m, const param_type& p);
634 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25635 base::PickleIterator* iter,
636 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25637 static void Log(const param_type& p, std::string* l);
638};
639
640template <>
641struct IPC_EXPORT ParamTraits<base::TimeTicks> {
642 typedef base::TimeTicks param_type;
rockot0457af102016-02-05 02:12:32643 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16644 static void Write(base::Pickle* m, const param_type& p);
645 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25646 base::PickleIterator* iter,
647 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25648 static void Log(const param_type& p, std::string* l);
[email protected]503683f2009-02-26 09:13:01649};
650
651template <>
brettwd5ca2bc2015-05-29 22:15:47652struct ParamTraits<base::Tuple<>> {
653 typedef base::Tuple<> param_type;
rockot0457af102016-02-05 02:12:32654 static void GetSize(base::PickleSizer* sizer, const param_type& p) {}
rockot502c94f2016-02-03 20:20:16655 static void Write(base::Pickle* m, const param_type& p) {}
656 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25657 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47658 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19659 return true;
660 }
[email protected]252cad62010-08-18 18:33:57661 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19662 }
663};
664
665template <class A>
brettwd5ca2bc2015-05-29 22:15:47666struct ParamTraits<base::Tuple<A>> {
667 typedef base::Tuple<A> param_type;
rockot0457af102016-02-05 02:12:32668 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
669 GetParamSize(sizer, base::get<0>(p));
670 }
rockot502c94f2016-02-03 20:20:16671 static void Write(base::Pickle* m, const param_type& p) {
brettwd5ca2bc2015-05-29 22:15:47672 WriteParam(m, base::get<0>(p));
[email protected]7d5c3ac2009-02-04 08:58:19673 }
rockot502c94f2016-02-03 20:20:16674 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25675 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47676 param_type* r) {
brettwd5ca2bc2015-05-29 22:15:47677 return ReadParam(m, iter, &base::get<0>(*r));
[email protected]7d5c3ac2009-02-04 08:58:19678 }
[email protected]252cad62010-08-18 18:33:57679 static void Log(const param_type& p, std::string* l) {
brettwd5ca2bc2015-05-29 22:15:47680 LogParam(base::get<0>(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19681 }
682};
683
684template <class A, class B>
brettwd5ca2bc2015-05-29 22:15:47685struct ParamTraits<base::Tuple<A, B>> {
686 typedef base::Tuple<A, B> param_type;
rockot0457af102016-02-05 02:12:32687 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
688 GetParamSize(sizer, base::get<0>(p));
689 GetParamSize(sizer, base::get<1>(p));
690 }
rockot502c94f2016-02-03 20:20:16691 static void Write(base::Pickle* m, const param_type& p) {
brettwd5ca2bc2015-05-29 22:15:47692 WriteParam(m, base::get<0>(p));
693 WriteParam(m, base::get<1>(p));
[email protected]7d5c3ac2009-02-04 08:58:19694 }
rockot502c94f2016-02-03 20:20:16695 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25696 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47697 param_type* r) {
brettwd5ca2bc2015-05-29 22:15:47698 return (ReadParam(m, iter, &base::get<0>(*r)) &&
699 ReadParam(m, iter, &base::get<1>(*r)));
[email protected]7d5c3ac2009-02-04 08:58:19700 }
[email protected]252cad62010-08-18 18:33:57701 static void Log(const param_type& p, std::string* l) {
brettwd5ca2bc2015-05-29 22:15:47702 LogParam(base::get<0>(p), l);
[email protected]252cad62010-08-18 18:33:57703 l->append(", ");
brettwd5ca2bc2015-05-29 22:15:47704 LogParam(base::get<1>(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19705 }
706};
707
708template <class A, class B, class C>
brettwd5ca2bc2015-05-29 22:15:47709struct ParamTraits<base::Tuple<A, B, C>> {
710 typedef base::Tuple<A, B, C> param_type;
rockot0457af102016-02-05 02:12:32711 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
712 GetParamSize(sizer, base::get<0>(p));
713 GetParamSize(sizer, base::get<1>(p));
714 GetParamSize(sizer, base::get<2>(p));
715 }
rockot502c94f2016-02-03 20:20:16716 static void Write(base::Pickle* m, const param_type& p) {
brettwd5ca2bc2015-05-29 22:15:47717 WriteParam(m, base::get<0>(p));
718 WriteParam(m, base::get<1>(p));
719 WriteParam(m, base::get<2>(p));
[email protected]7d5c3ac2009-02-04 08:58:19720 }
rockot502c94f2016-02-03 20:20:16721 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25722 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47723 param_type* r) {
brettwd5ca2bc2015-05-29 22:15:47724 return (ReadParam(m, iter, &base::get<0>(*r)) &&
725 ReadParam(m, iter, &base::get<1>(*r)) &&
726 ReadParam(m, iter, &base::get<2>(*r)));
[email protected]7d5c3ac2009-02-04 08:58:19727 }
[email protected]252cad62010-08-18 18:33:57728 static void Log(const param_type& p, std::string* l) {
brettwd5ca2bc2015-05-29 22:15:47729 LogParam(base::get<0>(p), l);
[email protected]252cad62010-08-18 18:33:57730 l->append(", ");
brettwd5ca2bc2015-05-29 22:15:47731 LogParam(base::get<1>(p), l);
[email protected]252cad62010-08-18 18:33:57732 l->append(", ");
brettwd5ca2bc2015-05-29 22:15:47733 LogParam(base::get<2>(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19734 }
735};
736
737template <class A, class B, class C, class D>
brettwd5ca2bc2015-05-29 22:15:47738struct ParamTraits<base::Tuple<A, B, C, D>> {
739 typedef base::Tuple<A, B, C, D> param_type;
rockot0457af102016-02-05 02:12:32740 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
741 GetParamSize(sizer, base::get<0>(p));
742 GetParamSize(sizer, base::get<1>(p));
743 GetParamSize(sizer, base::get<2>(p));
744 GetParamSize(sizer, base::get<3>(p));
745 }
rockot502c94f2016-02-03 20:20:16746 static void Write(base::Pickle* m, const param_type& p) {
brettwd5ca2bc2015-05-29 22:15:47747 WriteParam(m, base::get<0>(p));
748 WriteParam(m, base::get<1>(p));
749 WriteParam(m, base::get<2>(p));
750 WriteParam(m, base::get<3>(p));
[email protected]7d5c3ac2009-02-04 08:58:19751 }
rockot502c94f2016-02-03 20:20:16752 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25753 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47754 param_type* r) {
brettwd5ca2bc2015-05-29 22:15:47755 return (ReadParam(m, iter, &base::get<0>(*r)) &&
756 ReadParam(m, iter, &base::get<1>(*r)) &&
757 ReadParam(m, iter, &base::get<2>(*r)) &&
758 ReadParam(m, iter, &base::get<3>(*r)));
[email protected]7d5c3ac2009-02-04 08:58:19759 }
[email protected]252cad62010-08-18 18:33:57760 static void Log(const param_type& p, std::string* l) {
brettwd5ca2bc2015-05-29 22:15:47761 LogParam(base::get<0>(p), l);
[email protected]252cad62010-08-18 18:33:57762 l->append(", ");
brettwd5ca2bc2015-05-29 22:15:47763 LogParam(base::get<1>(p), l);
[email protected]252cad62010-08-18 18:33:57764 l->append(", ");
brettwd5ca2bc2015-05-29 22:15:47765 LogParam(base::get<2>(p), l);
[email protected]252cad62010-08-18 18:33:57766 l->append(", ");
brettwd5ca2bc2015-05-29 22:15:47767 LogParam(base::get<3>(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19768 }
769};
770
771template <class A, class B, class C, class D, class E>
brettwd5ca2bc2015-05-29 22:15:47772struct ParamTraits<base::Tuple<A, B, C, D, E>> {
773 typedef base::Tuple<A, B, C, D, E> param_type;
rockot0457af102016-02-05 02:12:32774 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
775 GetParamSize(sizer, base::get<0>(p));
776 GetParamSize(sizer, base::get<1>(p));
777 GetParamSize(sizer, base::get<2>(p));
778 GetParamSize(sizer, base::get<3>(p));
779 GetParamSize(sizer, base::get<4>(p));
780 }
rockot502c94f2016-02-03 20:20:16781 static void Write(base::Pickle* m, const param_type& p) {
brettwd5ca2bc2015-05-29 22:15:47782 WriteParam(m, base::get<0>(p));
783 WriteParam(m, base::get<1>(p));
784 WriteParam(m, base::get<2>(p));
785 WriteParam(m, base::get<3>(p));
786 WriteParam(m, base::get<4>(p));
[email protected]7d5c3ac2009-02-04 08:58:19787 }
rockot502c94f2016-02-03 20:20:16788 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25789 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47790 param_type* r) {
brettwd5ca2bc2015-05-29 22:15:47791 return (ReadParam(m, iter, &base::get<0>(*r)) &&
792 ReadParam(m, iter, &base::get<1>(*r)) &&
793 ReadParam(m, iter, &base::get<2>(*r)) &&
794 ReadParam(m, iter, &base::get<3>(*r)) &&
795 ReadParam(m, iter, &base::get<4>(*r)));
[email protected]7d5c3ac2009-02-04 08:58:19796 }
[email protected]252cad62010-08-18 18:33:57797 static void Log(const param_type& p, std::string* l) {
brettwd5ca2bc2015-05-29 22:15:47798 LogParam(base::get<0>(p), l);
[email protected]252cad62010-08-18 18:33:57799 l->append(", ");
brettwd5ca2bc2015-05-29 22:15:47800 LogParam(base::get<1>(p), l);
[email protected]252cad62010-08-18 18:33:57801 l->append(", ");
brettwd5ca2bc2015-05-29 22:15:47802 LogParam(base::get<2>(p), l);
[email protected]252cad62010-08-18 18:33:57803 l->append(", ");
brettwd5ca2bc2015-05-29 22:15:47804 LogParam(base::get<3>(p), l);
[email protected]252cad62010-08-18 18:33:57805 l->append(", ");
brettwd5ca2bc2015-05-29 22:15:47806 LogParam(base::get<4>(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19807 }
808};
809
[email protected]b1064d62012-11-14 06:35:52810template<class P>
811struct ParamTraits<ScopedVector<P> > {
812 typedef ScopedVector<P> param_type;
rockot502c94f2016-02-03 20:20:16813 static void Write(base::Pickle* m, const param_type& p) {
[email protected]b1064d62012-11-14 06:35:52814 WriteParam(m, static_cast<int>(p.size()));
815 for (size_t i = 0; i < p.size(); i++)
816 WriteParam(m, *p[i]);
817 }
rockot502c94f2016-02-03 20:20:16818 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25819 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47820 param_type* r) {
[email protected]b1064d62012-11-14 06:35:52821 int size = 0;
avi48fc13b2014-12-28 23:31:48822 if (!iter->ReadLength(&size))
[email protected]b1064d62012-11-14 06:35:52823 return false;
824 if (INT_MAX/sizeof(P) <= static_cast<size_t>(size))
825 return false;
826 r->resize(size);
827 for (int i = 0; i < size; i++) {
828 (*r)[i] = new P();
829 if (!ReadParam(m, iter, (*r)[i]))
830 return false;
831 }
832 return true;
833 }
834 static void Log(const param_type& p, std::string* l) {
835 for (size_t i = 0; i < p.size(); ++i) {
836 if (i != 0)
837 l->append(" ");
838 LogParam(*p[i], l);
839 }
840 }
841};
842
miletus1edf97f92015-07-23 19:42:36843template <class P, size_t stack_capacity>
844struct ParamTraits<base::StackVector<P, stack_capacity> > {
845 typedef base::StackVector<P, stack_capacity> param_type;
rockot0457af102016-02-05 02:12:32846 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
847 GetParamSize(sizer, static_cast<int>(p->size()));
848 for (size_t i = 0; i < p->size(); i++)
849 GetParamSize(sizer, p[i]);
850 }
rockot502c94f2016-02-03 20:20:16851 static void Write(base::Pickle* m, const param_type& p) {
miletus1edf97f92015-07-23 19:42:36852 WriteParam(m, static_cast<int>(p->size()));
853 for (size_t i = 0; i < p->size(); i++)
854 WriteParam(m, p[i]);
855 }
rockot502c94f2016-02-03 20:20:16856 static bool Read(const base::Pickle* m,
miletus1edf97f92015-07-23 19:42:36857 base::PickleIterator* iter,
858 param_type* r) {
859 int size;
860 // ReadLength() checks for < 0 itself.
861 if (!iter->ReadLength(&size))
862 return false;
863 // Sanity check for the vector size.
864 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
865 return false;
866 P value;
867 for (int i = 0; i < size; i++) {
868 if (!ReadParam(m, iter, &value))
869 return false;
870 (*r)->push_back(value);
871 }
872 return true;
873 }
874 static void Log(const param_type& p, std::string* l) {
875 for (size_t i = 0; i < p->size(); ++i) {
876 if (i != 0)
877 l->append(" ");
878 LogParam((p[i]), l);
879 }
880 }
881};
882
[email protected]205294b2014-03-18 20:48:35883template <typename NormalMap,
884 int kArraySize,
885 typename EqualKey,
886 typename MapInit>
887struct ParamTraits<base::SmallMap<NormalMap, kArraySize, EqualKey, MapInit> > {
888 typedef base::SmallMap<NormalMap, kArraySize, EqualKey, MapInit> param_type;
889 typedef typename param_type::key_type K;
890 typedef typename param_type::data_type V;
rockot0457af102016-02-05 02:12:32891 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
892 GetParamSize(sizer, static_cast<int>(p.size()));
893 typename param_type::const_iterator iter;
894 for (iter = p.begin(); iter != p.end(); ++iter) {
895 GetParamSize(sizer, iter->first);
896 GetParamSize(sizer, iter->second);
897 }
898 }
rockot502c94f2016-02-03 20:20:16899 static void Write(base::Pickle* m, const param_type& p) {
[email protected]205294b2014-03-18 20:48:35900 WriteParam(m, static_cast<int>(p.size()));
901 typename param_type::const_iterator iter;
902 for (iter = p.begin(); iter != p.end(); ++iter) {
903 WriteParam(m, iter->first);
904 WriteParam(m, iter->second);
905 }
906 }
rockot502c94f2016-02-03 20:20:16907 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25908 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47909 param_type* r) {
[email protected]205294b2014-03-18 20:48:35910 int size;
avi48fc13b2014-12-28 23:31:48911 if (!iter->ReadLength(&size))
[email protected]205294b2014-03-18 20:48:35912 return false;
913 for (int i = 0; i < size; ++i) {
914 K key;
915 if (!ReadParam(m, iter, &key))
916 return false;
917 V& value = (*r)[key];
918 if (!ReadParam(m, iter, &value))
919 return false;
920 }
921 return true;
922 }
923 static void Log(const param_type& p, std::string* l) {
924 l->append("<base::SmallMap>");
925 }
926};
927
[email protected]8e431f2032014-05-20 02:34:56928template <class P>
929struct ParamTraits<scoped_ptr<P> > {
930 typedef scoped_ptr<P> param_type;
rockot0457af102016-02-05 02:12:32931 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
932 bool valid = !!p;
933 GetParamSize(sizer, valid);
934 if (valid)
935 GetParamSize(sizer, *p);
936 }
rockot502c94f2016-02-03 20:20:16937 static void Write(base::Pickle* m, const param_type& p) {
[email protected]8e431f2032014-05-20 02:34:56938 bool valid = !!p;
939 WriteParam(m, valid);
940 if (valid)
941 WriteParam(m, *p);
942 }
rockot502c94f2016-02-03 20:20:16943 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25944 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47945 param_type* r) {
[email protected]8e431f2032014-05-20 02:34:56946 bool valid = false;
947 if (!ReadParam(m, iter, &valid))
948 return false;
949
950 if (!valid) {
951 r->reset();
952 return true;
953 }
954
955 param_type temp(new P());
956 if (!ReadParam(m, iter, temp.get()))
957 return false;
958
959 r->swap(temp);
960 return true;
961 }
962 static void Log(const param_type& p, std::string* l) {
963 if (p)
964 LogParam(*p, l);
965 else
966 l->append("NULL");
967 }
968};
969
[email protected]bf5aedf02012-06-04 21:18:25970// IPC types ParamTraits -------------------------------------------------------
971
972// A ChannelHandle is basically a platform-inspecific wrapper around the
973// fact that IPC endpoints are handled specially on POSIX. See above comments
974// on FileDescriptor for more background.
975template<>
976struct IPC_EXPORT ParamTraits<IPC::ChannelHandle> {
977 typedef ChannelHandle param_type;
rockot502c94f2016-02-03 20:20:16978 static void Write(base::Pickle* m, const param_type& p);
979 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25980 base::PickleIterator* iter,
981 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25982 static void Log(const param_type& p, std::string* l);
983};
984
985template <>
986struct IPC_EXPORT ParamTraits<LogData> {
987 typedef LogData param_type;
rockot0457af102016-02-05 02:12:32988 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16989 static void Write(base::Pickle* m, const param_type& p);
990 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25991 base::PickleIterator* iter,
992 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25993 static void Log(const param_type& p, std::string* l);
994};
995
996template <>
997struct IPC_EXPORT ParamTraits<Message> {
rockot502c94f2016-02-03 20:20:16998 static void Write(base::Pickle* m, const Message& p);
999 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251000 base::PickleIterator* iter,
1001 Message* r);
[email protected]bf5aedf02012-06-04 21:18:251002 static void Log(const Message& p, std::string* l);
1003};
1004
1005// Windows ParamTraits ---------------------------------------------------------
1006
1007#if defined(OS_WIN)
1008template <>
1009struct IPC_EXPORT ParamTraits<HANDLE> {
1010 typedef HANDLE param_type;
rockot0457af102016-02-05 02:12:321011 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:161012 static void Write(base::Pickle* m, const param_type& p);
1013 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251014 base::PickleIterator* iter,
1015 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:251016 static void Log(const param_type& p, std::string* l);
1017};
1018
1019template <>
1020struct IPC_EXPORT ParamTraits<LOGFONT> {
1021 typedef LOGFONT param_type;
rockot0457af102016-02-05 02:12:321022 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:161023 static void Write(base::Pickle* m, const param_type& p);
1024 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251025 base::PickleIterator* iter,
1026 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:251027 static void Log(const param_type& p, std::string* l);
1028};
1029
1030template <>
1031struct IPC_EXPORT ParamTraits<MSG> {
1032 typedef MSG param_type;
rockot0457af102016-02-05 02:12:321033 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:161034 static void Write(base::Pickle* m, const param_type& p);
1035 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251036 base::PickleIterator* iter,
1037 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:251038 static void Log(const param_type& p, std::string* l);
1039};
1040#endif // defined(OS_WIN)
1041
[email protected]7d5c3ac2009-02-04 08:58:191042//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:291043// Generic message subclasses
1044
[email protected]7a4de7a62010-08-17 18:38:241045// defined in ipc_logging.cc
[email protected]7c854372011-08-15 20:41:461046IPC_EXPORT void GenerateLogData(const std::string& channel,
1047 const Message& message,
[email protected]ea7744a2011-10-20 19:34:431048 LogData* data, bool get_params);
[email protected]7a4de7a62010-08-17 18:38:241049
1050
1051#if defined(IPC_MESSAGE_LOG_ENABLED)
[email protected]252cad62010-08-18 18:33:571052inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
1053 const std::string& output_params = msg->output_params();
[email protected]7a4de7a62010-08-17 18:38:241054 if (!l->empty() && !output_params.empty())
[email protected]252cad62010-08-18 18:33:571055 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:241056
1057 l->append(output_params);
1058}
1059
1060template <class ReplyParamType>
1061inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1062 const Message* msg) {
1063 if (msg->received_time() != 0) {
[email protected]252cad62010-08-18 18:33:571064 std::string output_params;
[email protected]7a4de7a62010-08-17 18:38:241065 LogParam(reply_params, &output_params);
1066 msg->set_output_params(output_params);
1067 }
1068}
1069
1070inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
1071 if (msg->sent_time()) {
1072 // Don't log the sync message after dispatch, as we don't have the
1073 // output parameters at that point. Instead, save its data and log it
1074 // with the outgoing reply message when it's sent.
1075 LogData* data = new LogData;
[email protected]ea7744a2011-10-20 19:34:431076 GenerateLogData("", *msg, data, true);
[email protected]7a4de7a62010-08-17 18:38:241077 msg->set_dont_log();
1078 reply->set_sync_log_data(data);
1079 }
1080}
1081#else
[email protected]252cad62010-08-18 18:33:571082inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
[email protected]7a4de7a62010-08-17 18:38:241083
1084template <class ReplyParamType>
1085inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1086 const Message* msg) {}
1087
1088inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1089#endif
1090
[email protected]3178f4e22008-08-05 21:20:411091} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291092
[email protected]946d1b22009-07-22 23:57:211093#endif // IPC_IPC_MESSAGE_UTILS_H_