blob: 2c4570311ef79749d93cffe454fc66def6c0926c [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>
danakj03de39b22016-04-23 04:21:0914#include <memory>
[email protected]96da6962010-05-13 19:10:3415#include <set>
[email protected]663bd9e2011-03-21 01:07:0116#include <string>
tzik55e3e4d2016-03-08 05:47:4417#include <tuple>
[email protected]663bd9e2011-03-21 01:07:0118#include <vector>
initial.commit09911bf2008-07-26 23:55:2919
[email protected]205294b2014-03-18 20:48:3520#include "base/containers/small_map.h"
miletus1edf97f92015-07-23 19:42:3621#include "base/containers/stack_container.h"
[email protected]141bcc52014-01-27 21:36:0022#include "base/files/file.h"
[email protected]dce5df52009-06-29 17:58:2523#include "base/format_macros.h"
[email protected]b1064d62012-11-14 06:35:5224#include "base/memory/scoped_vector.h"
[email protected]4aa794a12013-06-11 06:32:1825#include "base/strings/string16.h"
26#include "base/strings/string_util.h"
27#include "base/strings/stringprintf.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();
vmpstrbf0d713a2016-03-24 20:22:5457 LogData(const LogData& other);
[email protected]bf5aedf02012-06-04 21:18:2558 ~LogData();
59
60 std::string channel;
tfarina10a5c062015-09-04 18:47:5761 int32_t routing_id;
62 uint32_t type; // "User-defined" message type, from ipc_message.h.
[email protected]bf5aedf02012-06-04 21:18:2563 std::string flags;
tfarina10a5c062015-09-04 18:47:5764 int64_t sent; // Time that the message was sent (i.e. at Send()).
65 int64_t receive; // Time before it was dispatched (i.e. before calling
66 // OnMessageReceived).
67 int64_t dispatch; // Time after it was dispatched (i.e. after calling
68 // OnMessageReceived).
[email protected]bf5aedf02012-06-04 21:18:2569 std::string message_name;
70 std::string params;
71};
72
initial.commit09911bf2008-07-26 23:55:2973//-----------------------------------------------------------------------------
[email protected]7edae3d02012-12-17 20:23:4774
[email protected]6476c72c2011-02-11 18:46:1975// A dummy struct to place first just to allow leading commas for all
76// members in the macro-generated constructor initializer lists.
77struct NoParams {
78};
79
dskiba2bc89462016-04-06 15:51:0680// Specializations are checked by 'IPC checker' part of find-bad-constructs
81// Clang plugin (see WriteParam() below for the details).
82template <typename... Ts>
83struct CheckedTuple {
84 typedef std::tuple<Ts...> Tuple;
85};
86
[email protected]7d5c3ac2009-02-04 08:58:1987template <class P>
rockot0457af102016-02-05 02:12:3288static inline void GetParamSize(base::PickleSizer* sizer, const P& p) {
89 typedef typename SimilarTypeTraits<P>::Type Type;
90 ParamTraits<Type>::GetSize(sizer, static_cast<const Type&>(p));
91}
92
dskiba2bc89462016-04-06 15:51:0693// This function is checked by 'IPC checker' part of find-bad-constructs
94// Clang plugin to make it's not called on the following types:
95// 1. long / unsigned long (but not typedefs to)
96// 2. intmax_t, uintmax_t, intptr_t, uintptr_t, wint_t,
97// size_t, rsize_t, ssize_t, ptrdiff_t, dev_t, off_t, clock_t,
98// time_t, suseconds_t (including typedefs to)
99// 3. Any template referencing types above (e.g. std::vector<size_t>)
rockot0457af102016-02-05 02:12:32100template <class P>
rockot502c94f2016-02-03 20:20:16101static inline void WriteParam(base::Pickle* m, const P& p) {
[email protected]7b291f92009-08-14 05:43:53102 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53103 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
[email protected]7d5c3ac2009-02-04 08:58:19104}
105
106template <class P>
rockot502c94f2016-02-03 20:20:16107static inline bool WARN_UNUSED_RESULT ReadParam(const base::Pickle* m,
108 base::PickleIterator* iter,
109 P* p) {
[email protected]7b291f92009-08-14 05:43:53110 typedef typename SimilarTypeTraits<P>::Type Type;
111 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
[email protected]7d5c3ac2009-02-04 08:58:19112}
113
114template <class P>
[email protected]252cad62010-08-18 18:33:57115static inline void LogParam(const P& p, std::string* l) {
[email protected]7b291f92009-08-14 05:43:53116 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53117 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19118}
119
[email protected]bf5aedf02012-06-04 21:18:25120// Primitive ParamTraits -------------------------------------------------------
121
[email protected]7d5c3ac2009-02-04 08:58:19122template <>
123struct ParamTraits<bool> {
124 typedef bool param_type;
rockot0457af102016-02-05 02:12:32125 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
126 sizer->AddBool();
127 }
rockot502c94f2016-02-03 20:20:16128 static void Write(base::Pickle* m, const param_type& p) { m->WriteBool(p); }
129 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25130 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47131 param_type* r) {
avi48fc13b2014-12-28 23:31:48132 return iter->ReadBool(r);
[email protected]7d5c3ac2009-02-04 08:58:19133 }
[email protected]bf5aedf02012-06-04 21:18:25134 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19135};
136
137template <>
ortuno19ecf1842015-10-30 00:46:20138struct IPC_EXPORT ParamTraits<signed char> {
139 typedef signed char param_type;
rockot0457af102016-02-05 02:12:32140 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16141 static void Write(base::Pickle* m, const param_type& p);
142 static bool Read(const base::Pickle* m,
143 base::PickleIterator* iter,
144 param_type* r);
ortuno19ecf1842015-10-30 00:46:20145 static void Log(const param_type& p, std::string* l);
146};
147
148template <>
[email protected]c1ee48d2013-07-12 23:12:28149struct IPC_EXPORT ParamTraits<unsigned char> {
[email protected]7bea7352013-07-13 04:42:10150 typedef unsigned char param_type;
rockot0457af102016-02-05 02:12:32151 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16152 static void Write(base::Pickle* m, const param_type& p);
153 static bool Read(const base::Pickle* m,
154 base::PickleIterator* iter,
155 param_type* r);
[email protected]c1ee48d2013-07-12 23:12:28156 static void Log(const param_type& p, std::string* l);
157};
158
159template <>
160struct IPC_EXPORT ParamTraits<unsigned short> {
161 typedef unsigned short param_type;
rockot0457af102016-02-05 02:12:32162 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16163 static void Write(base::Pickle* m, const param_type& p);
164 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25165 base::PickleIterator* iter,
166 param_type* r);
[email protected]c1ee48d2013-07-12 23:12:28167 static void Log(const param_type& p, std::string* l);
168};
169
170template <>
[email protected]7d5c3ac2009-02-04 08:58:19171struct ParamTraits<int> {
172 typedef 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(r);
[email protected]7d5c3ac2009-02-04 08:58:19181 }
[email protected]7c854372011-08-15 20:41:46182 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19183};
184
185template <>
[email protected]63263f92009-07-28 19:35:08186struct ParamTraits<unsigned int> {
187 typedef unsigned int param_type;
rockot0457af102016-02-05 02:12:32188 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
189 sizer->AddInt();
190 }
rockot502c94f2016-02-03 20:20:16191 static void Write(base::Pickle* m, const param_type& p) { m->WriteInt(p); }
192 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25193 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47194 param_type* r) {
avi48fc13b2014-12-28 23:31:48195 return iter->ReadInt(reinterpret_cast<int*>(r));
[email protected]63263f92009-07-28 19:35:08196 }
[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
jam03d8a782016-02-10 20:13:39200// long isn't safe to send over IPC because it's 4 bytes on 32 bit builds but
201// 8 bytes on 64 bit builds. So if a 32 bit and 64 bit process have a channel
202// that would cause problem.
203// We need to keep this on for a few configs:
204// 1) Windows because DWORD is typedef'd to it, which is fine because we have
205// very few IPCs that cross this boundary.
206// 2) We also need to keep it for Linux for two reasons: int64_t is typedef'd
207// to long, and gfx::PluginWindow is long and is used in one GPU IPC.
208// 3) Android 64 bit also has int64_t typedef'd to long.
209// Since we want to support Android 32<>64 bit IPC, as long as we don't have
210// these traits for 32 bit ARM then that'll catch any errors.
jamac78d7d82016-02-11 00:50:28211#if defined(OS_WIN) || defined(OS_LINUX) || \
212 (defined(OS_ANDROID) && defined(ARCH_CPU_64_BITS))
[email protected]63263f92009-07-28 19:35:08213template <>
[email protected]7d5c3ac2009-02-04 08:58:19214struct ParamTraits<long> {
215 typedef long param_type;
rockot0457af102016-02-05 02:12:32216 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
jam03d8a782016-02-10 20:13:39217 sizer->AddLong();
rockot0457af102016-02-05 02:12:32218 }
rockot502c94f2016-02-03 20:20:16219 static void Write(base::Pickle* m, const param_type& p) {
jam03d8a782016-02-10 20:13:39220 m->WriteLong(p);
[email protected]7d5c3ac2009-02-04 08:58:19221 }
rockot502c94f2016-02-03 20:20:16222 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25223 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47224 param_type* r) {
avi48fc13b2014-12-28 23:31:48225 return iter->ReadLong(r);
[email protected]7d5c3ac2009-02-04 08:58:19226 }
[email protected]7c854372011-08-15 20:41:46227 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19228};
229
[email protected]140c3032009-06-26 18:22:54230template <>
231struct ParamTraits<unsigned long> {
232 typedef unsigned long param_type;
rockot0457af102016-02-05 02:12:32233 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
jam03d8a782016-02-10 20:13:39234 sizer->AddLong();
rockot0457af102016-02-05 02:12:32235 }
rockot502c94f2016-02-03 20:20:16236 static void Write(base::Pickle* m, const param_type& p) {
jam03d8a782016-02-10 20:13:39237 m->WriteLong(p);
[email protected]140c3032009-06-26 18:22:54238 }
rockot502c94f2016-02-03 20:20:16239 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25240 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47241 param_type* r) {
avi48fc13b2014-12-28 23:31:48242 return iter->ReadLong(reinterpret_cast<long*>(r));
[email protected]140c3032009-06-26 18:22:54243 }
[email protected]7c854372011-08-15 20:41:46244 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19245};
jam03d8a782016-02-10 20:13:39246#endif
[email protected]7d5c3ac2009-02-04 08:58:19247
248template <>
[email protected]63263f92009-07-28 19:35:08249struct ParamTraits<long long> {
250 typedef long long param_type;
rockot0457af102016-02-05 02:12:32251 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
252 sizer->AddInt64();
253 }
rockot502c94f2016-02-03 20:20:16254 static void Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:57255 m->WriteInt64(static_cast<int64_t>(p));
[email protected]7d5c3ac2009-02-04 08:58:19256 }
rockot502c94f2016-02-03 20:20:16257 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]7d5c3ac2009-02-04 08:58:19261 }
[email protected]7c854372011-08-15 20:41:46262 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08263};
264
265template <>
266struct ParamTraits<unsigned long long> {
267 typedef unsigned long long param_type;
rockot0457af102016-02-05 02:12:32268 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
269 sizer->AddInt64();
270 }
rockot502c94f2016-02-03 20:20:16271 static void Write(base::Pickle* m, const param_type& p) { m->WriteInt64(p); }
272 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25273 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:56274 param_type* r) {
tfarina10a5c062015-09-04 18:47:57275 return iter->ReadInt64(reinterpret_cast<int64_t*>(r));
[email protected]63263f92009-07-28 19:35:08276 }
[email protected]7c854372011-08-15 20:41:46277 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19278};
279
[email protected]20199662010-06-17 03:29:26280// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
281// should be sure to check the sanity of these values after receiving them over
282// IPC.
283template <>
[email protected]bf5aedf02012-06-04 21:18:25284struct IPC_EXPORT ParamTraits<float> {
[email protected]20199662010-06-17 03:29:26285 typedef float param_type;
rockot0457af102016-02-05 02:12:32286 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
287 sizer->AddFloat();
288 }
rockot502c94f2016-02-03 20:20:16289 static void Write(base::Pickle* m, const param_type& p) { m->WriteFloat(p); }
290 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25291 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47292 param_type* r) {
avi48fc13b2014-12-28 23:31:48293 return iter->ReadFloat(r);
[email protected]48328ff2013-10-31 09:27:31294 }
[email protected]bf5aedf02012-06-04 21:18:25295 static void Log(const param_type& p, std::string* l);
[email protected]20199662010-06-17 03:29:26296};
297
[email protected]7d5c3ac2009-02-04 08:58:19298template <>
[email protected]bf5aedf02012-06-04 21:18:25299struct IPC_EXPORT ParamTraits<double> {
[email protected]7d5c3ac2009-02-04 08:58:19300 typedef double param_type;
rockot0457af102016-02-05 02:12:32301 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16302 static void Write(base::Pickle* m, const param_type& p);
303 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25304 base::PickleIterator* iter,
305 param_type* r);
[email protected]c410e022012-05-30 21:15:57306 static void Log(const param_type& p, std::string* l);
307};
308
[email protected]bf5aedf02012-06-04 21:18:25309// STL ParamTraits -------------------------------------------------------------
[email protected]584f2b22009-05-21 01:01:59310
311template <>
[email protected]7d5c3ac2009-02-04 08:58:19312struct ParamTraits<std::string> {
313 typedef std::string param_type;
rockot0457af102016-02-05 02:12:32314 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
315 sizer->AddString(p);
316 }
rockot502c94f2016-02-03 20:20:16317 static void Write(base::Pickle* m, const param_type& p) { m->WriteString(p); }
318 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25319 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:56320 param_type* r) {
avi48fc13b2014-12-28 23:31:48321 return iter->ReadString(r);
[email protected]7d5c3ac2009-02-04 08:58:19322 }
[email protected]bf5aedf02012-06-04 21:18:25323 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19324};
325
[email protected]bf5aedf02012-06-04 21:18:25326template <>
[email protected]476dafb2013-12-03 00:39:26327struct ParamTraits<base::string16> {
328 typedef base::string16 param_type;
rockot0457af102016-02-05 02:12:32329 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
330 sizer->AddString16(p);
331 }
rockot502c94f2016-02-03 20:20:16332 static void Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25333 m->WriteString16(p);
334 }
rockot502c94f2016-02-03 20:20:16335 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25336 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25337 param_type* r) {
avi48fc13b2014-12-28 23:31:48338 return iter->ReadString16(r);
[email protected]bf5aedf02012-06-04 21:18:25339 }
340 IPC_EXPORT static void Log(const param_type& p, std::string* l);
341};
[email protected]3dd7a7a2009-07-27 21:09:07342
[email protected]7d5c3ac2009-02-04 08:58:19343template <>
[email protected]bf5aedf02012-06-04 21:18:25344struct IPC_EXPORT ParamTraits<std::vector<char> > {
[email protected]7d5c3ac2009-02-04 08:58:19345 typedef std::vector<char> param_type;
rockot0457af102016-02-05 02:12:32346 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16347 static void Write(base::Pickle* m, const param_type& p);
348 static bool Read(const base::Pickle*,
brettwbd4d7112015-06-03 04:29:25349 base::PickleIterator* iter,
350 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25351 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19352};
353
[email protected]51b63f62011-10-05 18:55:42354template <>
[email protected]bf5aedf02012-06-04 21:18:25355struct IPC_EXPORT ParamTraits<std::vector<unsigned char> > {
356 typedef std::vector<unsigned char> param_type;
rockot0457af102016-02-05 02:12:32357 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16358 static void Write(base::Pickle* m, const param_type& p);
359 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25360 base::PickleIterator* iter,
361 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25362 static void Log(const param_type& p, std::string* l);
363};
364
365template <>
366struct IPC_EXPORT ParamTraits<std::vector<bool> > {
[email protected]51b63f62011-10-05 18:55:42367 typedef std::vector<bool> param_type;
rockot0457af102016-02-05 02:12:32368 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16369 static void Write(base::Pickle* m, const param_type& p);
370 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25371 base::PickleIterator* iter,
372 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25373 static void Log(const param_type& p, std::string* l);
[email protected]51b63f62011-10-05 18:55:42374};
375
[email protected]7d5c3ac2009-02-04 08:58:19376template <class P>
377struct ParamTraits<std::vector<P> > {
378 typedef std::vector<P> param_type;
rockot0457af102016-02-05 02:12:32379 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
380 GetParamSize(sizer, static_cast<int>(p.size()));
381 for (size_t i = 0; i < p.size(); i++)
382 GetParamSize(sizer, p[i]);
383 }
rockot502c94f2016-02-03 20:20:16384 static void Write(base::Pickle* m, const param_type& p) {
[email protected]7d5c3ac2009-02-04 08:58:19385 WriteParam(m, static_cast<int>(p.size()));
386 for (size_t i = 0; i < p.size(); i++)
387 WriteParam(m, p[i]);
388 }
rockot502c94f2016-02-03 20:20:16389 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25390 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:56391 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19392 int size;
[email protected]86440f52009-12-31 05:17:23393 // ReadLength() checks for < 0 itself.
avi48fc13b2014-12-28 23:31:48394 if (!iter->ReadLength(&size))
[email protected]7d5c3ac2009-02-04 08:58:19395 return false;
396 // Resizing beforehand is not safe, see BUG 1006367 for details.
[email protected]86440f52009-12-31 05:17:23397 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
398 return false;
399 r->resize(size);
400 for (int i = 0; i < size; i++) {
401 if (!ReadParam(m, iter, &(*r)[i]))
402 return false;
[email protected]7d5c3ac2009-02-04 08:58:19403 }
404 return true;
405 }
[email protected]252cad62010-08-18 18:33:57406 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19407 for (size_t i = 0; i < p.size(); ++i) {
408 if (i != 0)
[email protected]252cad62010-08-18 18:33:57409 l->append(" ");
[email protected]7d5c3ac2009-02-04 08:58:19410 LogParam((p[i]), l);
411 }
412 }
413};
414
[email protected]96da6962010-05-13 19:10:34415template <class P>
416struct ParamTraits<std::set<P> > {
417 typedef std::set<P> param_type;
rockot0457af102016-02-05 02:12:32418 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
419 GetParamSize(sizer, static_cast<int>(p.size()));
420 typename param_type::const_iterator iter;
421 for (iter = p.begin(); iter != p.end(); ++iter)
422 GetParamSize(sizer, *iter);
423 }
rockot502c94f2016-02-03 20:20:16424 static void Write(base::Pickle* m, const param_type& p) {
[email protected]96da6962010-05-13 19:10:34425 WriteParam(m, static_cast<int>(p.size()));
426 typename param_type::const_iterator iter;
427 for (iter = p.begin(); iter != p.end(); ++iter)
428 WriteParam(m, *iter);
429 }
rockot502c94f2016-02-03 20:20:16430 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25431 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:56432 param_type* r) {
[email protected]96da6962010-05-13 19:10:34433 int size;
avi48fc13b2014-12-28 23:31:48434 if (!iter->ReadLength(&size))
[email protected]96da6962010-05-13 19:10:34435 return false;
436 for (int i = 0; i < size; ++i) {
437 P item;
438 if (!ReadParam(m, iter, &item))
439 return false;
440 r->insert(item);
441 }
442 return true;
443 }
[email protected]252cad62010-08-18 18:33:57444 static void Log(const param_type& p, std::string* l) {
445 l->append("<std::set>");
[email protected]96da6962010-05-13 19:10:34446 }
447};
448
jkarlinf96d19ba2014-09-24 11:42:37449template <class K, class V, class C, class A>
450struct ParamTraits<std::map<K, V, C, A> > {
451 typedef std::map<K, V, C, A> param_type;
rockot0457af102016-02-05 02:12:32452 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
453 GetParamSize(sizer, static_cast<int>(p.size()));
454 typename param_type::const_iterator iter;
455 for (iter = p.begin(); iter != p.end(); ++iter) {
456 GetParamSize(sizer, iter->first);
457 GetParamSize(sizer, iter->second);
458 }
459 }
rockot502c94f2016-02-03 20:20:16460 static void Write(base::Pickle* m, const param_type& p) {
[email protected]7d5c3ac2009-02-04 08:58:19461 WriteParam(m, static_cast<int>(p.size()));
462 typename param_type::const_iterator iter;
463 for (iter = p.begin(); iter != p.end(); ++iter) {
464 WriteParam(m, iter->first);
465 WriteParam(m, iter->second);
466 }
467 }
rockot502c94f2016-02-03 20:20:16468 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25469 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:56470 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19471 int size;
472 if (!ReadParam(m, iter, &size) || size < 0)
473 return false;
474 for (int i = 0; i < size; ++i) {
475 K k;
476 if (!ReadParam(m, iter, &k))
477 return false;
478 V& value = (*r)[k];
479 if (!ReadParam(m, iter, &value))
480 return false;
481 }
482 return true;
483 }
[email protected]252cad62010-08-18 18:33:57484 static void Log(const param_type& p, std::string* l) {
485 l->append("<std::map>");
[email protected]7d5c3ac2009-02-04 08:58:19486 }
487};
488
[email protected]a5da6d612009-08-04 02:00:56489template <class A, class B>
490struct ParamTraits<std::pair<A, B> > {
491 typedef std::pair<A, B> param_type;
rockot0457af102016-02-05 02:12:32492 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
493 GetParamSize(sizer, p.first);
494 GetParamSize(sizer, p.second);
495 }
rockot502c94f2016-02-03 20:20:16496 static void Write(base::Pickle* m, const param_type& p) {
[email protected]a5da6d612009-08-04 02:00:56497 WriteParam(m, p.first);
498 WriteParam(m, p.second);
499 }
rockot502c94f2016-02-03 20:20:16500 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25501 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:56502 param_type* r) {
[email protected]a5da6d612009-08-04 02:00:56503 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
504 }
[email protected]252cad62010-08-18 18:33:57505 static void Log(const param_type& p, std::string* l) {
506 l->append("(");
[email protected]a5da6d612009-08-04 02:00:56507 LogParam(p.first, l);
[email protected]252cad62010-08-18 18:33:57508 l->append(", ");
[email protected]a5da6d612009-08-04 02:00:56509 LogParam(p.second, l);
[email protected]252cad62010-08-18 18:33:57510 l->append(")");
[email protected]a5da6d612009-08-04 02:00:56511 }
512};
513
erikcheneece6c32015-07-07 22:13:11514// IPC ParamTraits -------------------------------------------------------------
515template <>
516struct IPC_EXPORT ParamTraits<BrokerableAttachment::AttachmentId> {
517 typedef BrokerableAttachment::AttachmentId param_type;
rockot502c94f2016-02-03 20:20:16518 static void Write(base::Pickle* m, const param_type& p);
519 static bool Read(const base::Pickle* m,
520 base::PickleIterator* iter,
521 param_type* r);
erikcheneece6c32015-07-07 22:13:11522 static void Log(const param_type& p, std::string* l);
523};
524
[email protected]bf5aedf02012-06-04 21:18:25525// Base ParamTraits ------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19526
527template <>
[email protected]bf5aedf02012-06-04 21:18:25528struct IPC_EXPORT ParamTraits<base::DictionaryValue> {
529 typedef base::DictionaryValue param_type;
rockot0457af102016-02-05 02:12:32530 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16531 static void Write(base::Pickle* m, const param_type& p);
532 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25533 base::PickleIterator* iter,
534 param_type* r);
[email protected]252cad62010-08-18 18:33:57535 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19536};
537
[email protected]526776c2009-02-07 00:39:26538#if defined(OS_POSIX)
[email protected]2749885f2009-03-05 21:40:11539// FileDescriptors may be serialised over IPC channels on POSIX. On the
540// receiving side, the FileDescriptor is a valid duplicate of the file
541// descriptor which was transmitted: *it is not just a copy of the integer like
542// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
543// this case, the receiving end will see a value of -1. *Zero is a valid file
544// descriptor*.
545//
546// The received file descriptor will have the |auto_close| flag set to true. The
547// code which handles the message is responsible for taking ownership of it.
548// File descriptors are OS resources and must be closed when no longer needed.
549//
550// When sending a file descriptor, the file descriptor must be valid at the time
551// of transmission. Since transmission is not synchronous, one should consider
552// dup()ing any file descriptors to be transmitted and setting the |auto_close|
553// flag, which causes the file descriptor to be closed after writing.
[email protected]526776c2009-02-07 00:39:26554template<>
[email protected]7c854372011-08-15 20:41:46555struct IPC_EXPORT ParamTraits<base::FileDescriptor> {
[email protected]5fe733de2009-02-11 18:59:20556 typedef base::FileDescriptor param_type;
rockot502c94f2016-02-03 20:20:16557 static void Write(base::Pickle* m, const param_type& p);
558 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25559 base::PickleIterator* iter,
560 param_type* r);
[email protected]252cad62010-08-18 18:33:57561 static void Log(const param_type& p, std::string* l);
[email protected]526776c2009-02-07 00:39:26562};
[email protected]379e7a52010-03-09 00:38:41563#endif // defined(OS_POSIX)
[email protected]526776c2009-02-07 00:39:26564
erikchen5ea2ab72015-09-25 22:34:31565#if (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
scottmgd19b4f72015-06-19 22:51:00566template <>
567struct IPC_EXPORT ParamTraits<base::SharedMemoryHandle> {
568 typedef base::SharedMemoryHandle param_type;
rockot502c94f2016-02-03 20:20:16569 static void Write(base::Pickle* m, const param_type& p);
570 static bool Read(const base::Pickle* m,
571 base::PickleIterator* iter,
572 param_type* r);
scottmgd19b4f72015-06-19 22:51:00573 static void Log(const param_type& p, std::string* l);
574};
erikchen5ea2ab72015-09-25 22:34:31575#endif // (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
scottmgd19b4f72015-06-19 22:51:00576
[email protected]bf5aedf02012-06-04 21:18:25577template <>
[email protected]a3ef4832013-02-02 05:12:33578struct IPC_EXPORT ParamTraits<base::FilePath> {
579 typedef base::FilePath param_type;
rockot0457af102016-02-05 02:12:32580 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16581 static void Write(base::Pickle* m, const param_type& p);
582 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25583 base::PickleIterator* iter,
584 param_type* r);
[email protected]252cad62010-08-18 18:33:57585 static void Log(const param_type& p, std::string* l);
[email protected]d2e884d2009-06-22 20:37:52586};
587
[email protected]7d5c3ac2009-02-04 08:58:19588template <>
[email protected]bf5aedf02012-06-04 21:18:25589struct IPC_EXPORT ParamTraits<base::ListValue> {
590 typedef base::ListValue param_type;
rockot0457af102016-02-05 02:12:32591 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16592 static void Write(base::Pickle* m, const param_type& p);
593 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25594 base::PickleIterator* iter,
595 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25596 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19597};
598
[email protected]eb47a132009-03-04 00:39:56599template <>
[email protected]0238a162013-06-13 13:47:46600struct IPC_EXPORT ParamTraits<base::NullableString16> {
601 typedef base::NullableString16 param_type;
rockot0457af102016-02-05 02:12:32602 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16603 static void Write(base::Pickle* m, const param_type& p);
604 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25605 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25606 param_type* r);
607 static void Log(const param_type& p, std::string* l);
608};
609
610template <>
[email protected]141bcc52014-01-27 21:36:00611struct IPC_EXPORT ParamTraits<base::File::Info> {
612 typedef base::File::Info param_type;
rockot0457af102016-02-05 02:12:32613 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16614 static void Write(base::Pickle* m, const param_type& p);
615 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25616 base::PickleIterator* iter,
617 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25618 static void Log(const param_type& p, std::string* l);
619};
620
621template <>
[email protected]141bcc52014-01-27 21:36:00622struct SimilarTypeTraits<base::File::Error> {
[email protected]bf5aedf02012-06-04 21:18:25623 typedef int Type;
624};
625
[email protected]ecf59c72013-02-28 21:46:11626#if defined(OS_WIN)
627template <>
628struct SimilarTypeTraits<HWND> {
629 typedef HANDLE Type;
630};
631#endif // defined(OS_WIN)
632
[email protected]bf5aedf02012-06-04 21:18:25633template <>
634struct IPC_EXPORT ParamTraits<base::Time> {
635 typedef base::Time param_type;
rockot0457af102016-02-05 02:12:32636 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16637 static void Write(base::Pickle* m, const param_type& p);
638 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25639 base::PickleIterator* iter,
640 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25641 static void Log(const param_type& p, std::string* l);
642};
643
644template <>
645struct IPC_EXPORT ParamTraits<base::TimeDelta> {
646 typedef base::TimeDelta param_type;
rockot0457af102016-02-05 02:12:32647 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16648 static void Write(base::Pickle* m, const param_type& p);
649 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25650 base::PickleIterator* iter,
651 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25652 static void Log(const param_type& p, std::string* l);
653};
654
655template <>
656struct IPC_EXPORT ParamTraits<base::TimeTicks> {
657 typedef base::TimeTicks param_type;
rockot0457af102016-02-05 02:12:32658 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:16659 static void Write(base::Pickle* m, const param_type& p);
660 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25661 base::PickleIterator* iter,
662 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25663 static void Log(const param_type& p, std::string* l);
[email protected]503683f2009-02-26 09:13:01664};
665
666template <>
tzik9ca302192016-02-11 10:24:45667struct ParamTraits<std::tuple<>> {
668 typedef std::tuple<> param_type;
rockot0457af102016-02-05 02:12:32669 static void GetSize(base::PickleSizer* sizer, const param_type& p) {}
rockot502c94f2016-02-03 20:20:16670 static void Write(base::Pickle* m, const param_type& p) {}
671 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25672 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47673 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19674 return true;
675 }
[email protected]252cad62010-08-18 18:33:57676 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19677 }
678};
679
680template <class A>
tzik9ca302192016-02-11 10:24:45681struct ParamTraits<std::tuple<A>> {
682 typedef std::tuple<A> param_type;
rockot0457af102016-02-05 02:12:32683 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
tzik55e3e4d2016-03-08 05:47:44684 GetParamSize(sizer, std::get<0>(p));
rockot0457af102016-02-05 02:12:32685 }
rockot502c94f2016-02-03 20:20:16686 static void Write(base::Pickle* m, const param_type& p) {
tzik55e3e4d2016-03-08 05:47:44687 WriteParam(m, std::get<0>(p));
[email protected]7d5c3ac2009-02-04 08:58:19688 }
rockot502c94f2016-02-03 20:20:16689 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25690 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47691 param_type* r) {
tzik55e3e4d2016-03-08 05:47:44692 return ReadParam(m, iter, &std::get<0>(*r));
[email protected]7d5c3ac2009-02-04 08:58:19693 }
[email protected]252cad62010-08-18 18:33:57694 static void Log(const param_type& p, std::string* l) {
tzik55e3e4d2016-03-08 05:47:44695 LogParam(std::get<0>(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19696 }
697};
698
699template <class A, class B>
tzik9ca302192016-02-11 10:24:45700struct ParamTraits<std::tuple<A, B>> {
701 typedef std::tuple<A, B> param_type;
rockot0457af102016-02-05 02:12:32702 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
tzik55e3e4d2016-03-08 05:47:44703 GetParamSize(sizer, std::get<0>(p));
704 GetParamSize(sizer, std::get<1>(p));
rockot0457af102016-02-05 02:12:32705 }
rockot502c94f2016-02-03 20:20:16706 static void Write(base::Pickle* m, const param_type& p) {
tzik55e3e4d2016-03-08 05:47:44707 WriteParam(m, std::get<0>(p));
708 WriteParam(m, std::get<1>(p));
[email protected]7d5c3ac2009-02-04 08:58:19709 }
rockot502c94f2016-02-03 20:20:16710 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25711 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47712 param_type* r) {
tzik55e3e4d2016-03-08 05:47:44713 return (ReadParam(m, iter, &std::get<0>(*r)) &&
714 ReadParam(m, iter, &std::get<1>(*r)));
[email protected]7d5c3ac2009-02-04 08:58:19715 }
[email protected]252cad62010-08-18 18:33:57716 static void Log(const param_type& p, std::string* l) {
tzik55e3e4d2016-03-08 05:47:44717 LogParam(std::get<0>(p), l);
[email protected]252cad62010-08-18 18:33:57718 l->append(", ");
tzik55e3e4d2016-03-08 05:47:44719 LogParam(std::get<1>(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19720 }
721};
722
723template <class A, class B, class C>
tzik9ca302192016-02-11 10:24:45724struct ParamTraits<std::tuple<A, B, C>> {
725 typedef std::tuple<A, B, C> param_type;
rockot0457af102016-02-05 02:12:32726 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
tzik55e3e4d2016-03-08 05:47:44727 GetParamSize(sizer, std::get<0>(p));
728 GetParamSize(sizer, std::get<1>(p));
729 GetParamSize(sizer, std::get<2>(p));
rockot0457af102016-02-05 02:12:32730 }
rockot502c94f2016-02-03 20:20:16731 static void Write(base::Pickle* m, const param_type& p) {
tzik55e3e4d2016-03-08 05:47:44732 WriteParam(m, std::get<0>(p));
733 WriteParam(m, std::get<1>(p));
734 WriteParam(m, std::get<2>(p));
[email protected]7d5c3ac2009-02-04 08:58:19735 }
rockot502c94f2016-02-03 20:20:16736 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25737 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47738 param_type* r) {
tzik55e3e4d2016-03-08 05:47:44739 return (ReadParam(m, iter, &std::get<0>(*r)) &&
740 ReadParam(m, iter, &std::get<1>(*r)) &&
741 ReadParam(m, iter, &std::get<2>(*r)));
[email protected]7d5c3ac2009-02-04 08:58:19742 }
[email protected]252cad62010-08-18 18:33:57743 static void Log(const param_type& p, std::string* l) {
tzik55e3e4d2016-03-08 05:47:44744 LogParam(std::get<0>(p), l);
[email protected]252cad62010-08-18 18:33:57745 l->append(", ");
tzik55e3e4d2016-03-08 05:47:44746 LogParam(std::get<1>(p), l);
[email protected]252cad62010-08-18 18:33:57747 l->append(", ");
tzik55e3e4d2016-03-08 05:47:44748 LogParam(std::get<2>(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19749 }
750};
751
752template <class A, class B, class C, class D>
tzik9ca302192016-02-11 10:24:45753struct ParamTraits<std::tuple<A, B, C, D>> {
754 typedef std::tuple<A, B, C, D> param_type;
rockot0457af102016-02-05 02:12:32755 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
tzik55e3e4d2016-03-08 05:47:44756 GetParamSize(sizer, std::get<0>(p));
757 GetParamSize(sizer, std::get<1>(p));
758 GetParamSize(sizer, std::get<2>(p));
759 GetParamSize(sizer, std::get<3>(p));
rockot0457af102016-02-05 02:12:32760 }
rockot502c94f2016-02-03 20:20:16761 static void Write(base::Pickle* m, const param_type& p) {
tzik55e3e4d2016-03-08 05:47:44762 WriteParam(m, std::get<0>(p));
763 WriteParam(m, std::get<1>(p));
764 WriteParam(m, std::get<2>(p));
765 WriteParam(m, std::get<3>(p));
[email protected]7d5c3ac2009-02-04 08:58:19766 }
rockot502c94f2016-02-03 20:20:16767 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25768 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47769 param_type* r) {
tzik55e3e4d2016-03-08 05:47:44770 return (ReadParam(m, iter, &std::get<0>(*r)) &&
771 ReadParam(m, iter, &std::get<1>(*r)) &&
772 ReadParam(m, iter, &std::get<2>(*r)) &&
773 ReadParam(m, iter, &std::get<3>(*r)));
[email protected]7d5c3ac2009-02-04 08:58:19774 }
[email protected]252cad62010-08-18 18:33:57775 static void Log(const param_type& p, std::string* l) {
tzik55e3e4d2016-03-08 05:47:44776 LogParam(std::get<0>(p), l);
[email protected]252cad62010-08-18 18:33:57777 l->append(", ");
tzik55e3e4d2016-03-08 05:47:44778 LogParam(std::get<1>(p), l);
[email protected]252cad62010-08-18 18:33:57779 l->append(", ");
tzik55e3e4d2016-03-08 05:47:44780 LogParam(std::get<2>(p), l);
[email protected]252cad62010-08-18 18:33:57781 l->append(", ");
tzik55e3e4d2016-03-08 05:47:44782 LogParam(std::get<3>(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19783 }
784};
785
786template <class A, class B, class C, class D, class E>
tzik9ca302192016-02-11 10:24:45787struct ParamTraits<std::tuple<A, B, C, D, E>> {
788 typedef std::tuple<A, B, C, D, E> param_type;
rockot0457af102016-02-05 02:12:32789 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
tzik55e3e4d2016-03-08 05:47:44790 GetParamSize(sizer, std::get<0>(p));
791 GetParamSize(sizer, std::get<1>(p));
792 GetParamSize(sizer, std::get<2>(p));
793 GetParamSize(sizer, std::get<3>(p));
794 GetParamSize(sizer, std::get<4>(p));
rockot0457af102016-02-05 02:12:32795 }
rockot502c94f2016-02-03 20:20:16796 static void Write(base::Pickle* m, const param_type& p) {
tzik55e3e4d2016-03-08 05:47:44797 WriteParam(m, std::get<0>(p));
798 WriteParam(m, std::get<1>(p));
799 WriteParam(m, std::get<2>(p));
800 WriteParam(m, std::get<3>(p));
801 WriteParam(m, std::get<4>(p));
[email protected]7d5c3ac2009-02-04 08:58:19802 }
rockot502c94f2016-02-03 20:20:16803 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25804 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47805 param_type* r) {
tzik55e3e4d2016-03-08 05:47:44806 return (ReadParam(m, iter, &std::get<0>(*r)) &&
807 ReadParam(m, iter, &std::get<1>(*r)) &&
808 ReadParam(m, iter, &std::get<2>(*r)) &&
809 ReadParam(m, iter, &std::get<3>(*r)) &&
810 ReadParam(m, iter, &std::get<4>(*r)));
[email protected]7d5c3ac2009-02-04 08:58:19811 }
[email protected]252cad62010-08-18 18:33:57812 static void Log(const param_type& p, std::string* l) {
tzik55e3e4d2016-03-08 05:47:44813 LogParam(std::get<0>(p), l);
[email protected]252cad62010-08-18 18:33:57814 l->append(", ");
tzik55e3e4d2016-03-08 05:47:44815 LogParam(std::get<1>(p), l);
[email protected]252cad62010-08-18 18:33:57816 l->append(", ");
tzik55e3e4d2016-03-08 05:47:44817 LogParam(std::get<2>(p), l);
[email protected]252cad62010-08-18 18:33:57818 l->append(", ");
tzik55e3e4d2016-03-08 05:47:44819 LogParam(std::get<3>(p), l);
[email protected]252cad62010-08-18 18:33:57820 l->append(", ");
tzik55e3e4d2016-03-08 05:47:44821 LogParam(std::get<4>(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19822 }
823};
824
[email protected]b1064d62012-11-14 06:35:52825template<class P>
826struct ParamTraits<ScopedVector<P> > {
827 typedef ScopedVector<P> param_type;
rockot502c94f2016-02-03 20:20:16828 static void Write(base::Pickle* m, const param_type& p) {
[email protected]b1064d62012-11-14 06:35:52829 WriteParam(m, static_cast<int>(p.size()));
830 for (size_t i = 0; i < p.size(); i++)
831 WriteParam(m, *p[i]);
832 }
rockot502c94f2016-02-03 20:20:16833 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25834 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47835 param_type* r) {
[email protected]b1064d62012-11-14 06:35:52836 int size = 0;
avi48fc13b2014-12-28 23:31:48837 if (!iter->ReadLength(&size))
[email protected]b1064d62012-11-14 06:35:52838 return false;
839 if (INT_MAX/sizeof(P) <= static_cast<size_t>(size))
840 return false;
841 r->resize(size);
842 for (int i = 0; i < size; i++) {
843 (*r)[i] = new P();
844 if (!ReadParam(m, iter, (*r)[i]))
845 return false;
846 }
847 return true;
848 }
849 static void Log(const param_type& p, std::string* l) {
850 for (size_t i = 0; i < p.size(); ++i) {
851 if (i != 0)
852 l->append(" ");
853 LogParam(*p[i], l);
854 }
855 }
856};
857
miletus1edf97f92015-07-23 19:42:36858template <class P, size_t stack_capacity>
859struct ParamTraits<base::StackVector<P, stack_capacity> > {
860 typedef base::StackVector<P, stack_capacity> param_type;
rockot0457af102016-02-05 02:12:32861 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
862 GetParamSize(sizer, static_cast<int>(p->size()));
863 for (size_t i = 0; i < p->size(); i++)
864 GetParamSize(sizer, p[i]);
865 }
rockot502c94f2016-02-03 20:20:16866 static void Write(base::Pickle* m, const param_type& p) {
miletus1edf97f92015-07-23 19:42:36867 WriteParam(m, static_cast<int>(p->size()));
868 for (size_t i = 0; i < p->size(); i++)
869 WriteParam(m, p[i]);
870 }
rockot502c94f2016-02-03 20:20:16871 static bool Read(const base::Pickle* m,
miletus1edf97f92015-07-23 19:42:36872 base::PickleIterator* iter,
873 param_type* r) {
874 int size;
875 // ReadLength() checks for < 0 itself.
876 if (!iter->ReadLength(&size))
877 return false;
878 // Sanity check for the vector size.
879 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
880 return false;
881 P value;
882 for (int i = 0; i < size; i++) {
883 if (!ReadParam(m, iter, &value))
884 return false;
885 (*r)->push_back(value);
886 }
887 return true;
888 }
889 static void Log(const param_type& p, std::string* l) {
890 for (size_t i = 0; i < p->size(); ++i) {
891 if (i != 0)
892 l->append(" ");
893 LogParam((p[i]), l);
894 }
895 }
896};
897
[email protected]205294b2014-03-18 20:48:35898template <typename NormalMap,
899 int kArraySize,
900 typename EqualKey,
901 typename MapInit>
902struct ParamTraits<base::SmallMap<NormalMap, kArraySize, EqualKey, MapInit> > {
903 typedef base::SmallMap<NormalMap, kArraySize, EqualKey, MapInit> param_type;
904 typedef typename param_type::key_type K;
905 typedef typename param_type::data_type V;
rockot0457af102016-02-05 02:12:32906 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
907 GetParamSize(sizer, static_cast<int>(p.size()));
908 typename param_type::const_iterator iter;
909 for (iter = p.begin(); iter != p.end(); ++iter) {
910 GetParamSize(sizer, iter->first);
911 GetParamSize(sizer, iter->second);
912 }
913 }
rockot502c94f2016-02-03 20:20:16914 static void Write(base::Pickle* m, const param_type& p) {
[email protected]205294b2014-03-18 20:48:35915 WriteParam(m, static_cast<int>(p.size()));
916 typename param_type::const_iterator iter;
917 for (iter = p.begin(); iter != p.end(); ++iter) {
918 WriteParam(m, iter->first);
919 WriteParam(m, iter->second);
920 }
921 }
rockot502c94f2016-02-03 20:20:16922 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25923 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47924 param_type* r) {
[email protected]205294b2014-03-18 20:48:35925 int size;
avi48fc13b2014-12-28 23:31:48926 if (!iter->ReadLength(&size))
[email protected]205294b2014-03-18 20:48:35927 return false;
928 for (int i = 0; i < size; ++i) {
929 K key;
930 if (!ReadParam(m, iter, &key))
931 return false;
932 V& value = (*r)[key];
933 if (!ReadParam(m, iter, &value))
934 return false;
935 }
936 return true;
937 }
938 static void Log(const param_type& p, std::string* l) {
939 l->append("<base::SmallMap>");
940 }
941};
942
[email protected]8e431f2032014-05-20 02:34:56943template <class P>
danakj03de39b22016-04-23 04:21:09944struct ParamTraits<std::unique_ptr<P>> {
945 typedef std::unique_ptr<P> param_type;
rockot0457af102016-02-05 02:12:32946 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
947 bool valid = !!p;
948 GetParamSize(sizer, valid);
949 if (valid)
950 GetParamSize(sizer, *p);
951 }
rockot502c94f2016-02-03 20:20:16952 static void Write(base::Pickle* m, const param_type& p) {
[email protected]8e431f2032014-05-20 02:34:56953 bool valid = !!p;
954 WriteParam(m, valid);
955 if (valid)
956 WriteParam(m, *p);
957 }
rockot502c94f2016-02-03 20:20:16958 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25959 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47960 param_type* r) {
[email protected]8e431f2032014-05-20 02:34:56961 bool valid = false;
962 if (!ReadParam(m, iter, &valid))
963 return false;
964
965 if (!valid) {
966 r->reset();
967 return true;
968 }
969
970 param_type temp(new P());
971 if (!ReadParam(m, iter, temp.get()))
972 return false;
973
974 r->swap(temp);
975 return true;
976 }
977 static void Log(const param_type& p, std::string* l) {
978 if (p)
979 LogParam(*p, l);
980 else
981 l->append("NULL");
982 }
983};
984
[email protected]bf5aedf02012-06-04 21:18:25985// IPC types ParamTraits -------------------------------------------------------
986
987// A ChannelHandle is basically a platform-inspecific wrapper around the
988// fact that IPC endpoints are handled specially on POSIX. See above comments
989// on FileDescriptor for more background.
990template<>
991struct IPC_EXPORT ParamTraits<IPC::ChannelHandle> {
992 typedef ChannelHandle param_type;
rockot502c94f2016-02-03 20:20:16993 static void Write(base::Pickle* m, const param_type& p);
994 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25995 base::PickleIterator* iter,
996 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25997 static void Log(const param_type& p, std::string* l);
998};
999
1000template <>
1001struct IPC_EXPORT ParamTraits<LogData> {
1002 typedef LogData param_type;
rockot0457af102016-02-05 02:12:321003 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:161004 static void Write(base::Pickle* m, const param_type& p);
1005 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251006 base::PickleIterator* iter,
1007 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:251008 static void Log(const param_type& p, std::string* l);
1009};
1010
1011template <>
1012struct IPC_EXPORT ParamTraits<Message> {
rockot502c94f2016-02-03 20:20:161013 static void Write(base::Pickle* m, const Message& p);
1014 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251015 base::PickleIterator* iter,
1016 Message* r);
[email protected]bf5aedf02012-06-04 21:18:251017 static void Log(const Message& p, std::string* l);
1018};
1019
1020// Windows ParamTraits ---------------------------------------------------------
1021
1022#if defined(OS_WIN)
1023template <>
1024struct IPC_EXPORT ParamTraits<HANDLE> {
1025 typedef HANDLE param_type;
rockot0457af102016-02-05 02:12:321026 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:161027 static void Write(base::Pickle* m, const param_type& p);
1028 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251029 base::PickleIterator* iter,
1030 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:251031 static void Log(const param_type& p, std::string* l);
1032};
1033
1034template <>
1035struct IPC_EXPORT ParamTraits<LOGFONT> {
1036 typedef LOGFONT param_type;
rockot0457af102016-02-05 02:12:321037 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:161038 static void Write(base::Pickle* m, const param_type& p);
1039 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251040 base::PickleIterator* iter,
1041 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:251042 static void Log(const param_type& p, std::string* l);
1043};
1044
1045template <>
1046struct IPC_EXPORT ParamTraits<MSG> {
1047 typedef MSG param_type;
rockot0457af102016-02-05 02:12:321048 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot502c94f2016-02-03 20:20:161049 static void Write(base::Pickle* m, const param_type& p);
1050 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251051 base::PickleIterator* iter,
1052 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:251053 static void Log(const param_type& p, std::string* l);
1054};
1055#endif // defined(OS_WIN)
1056
[email protected]7d5c3ac2009-02-04 08:58:191057//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:291058// Generic message subclasses
1059
[email protected]7a4de7a62010-08-17 18:38:241060// defined in ipc_logging.cc
[email protected]7c854372011-08-15 20:41:461061IPC_EXPORT void GenerateLogData(const std::string& channel,
1062 const Message& message,
[email protected]ea7744a2011-10-20 19:34:431063 LogData* data, bool get_params);
[email protected]7a4de7a62010-08-17 18:38:241064
1065
1066#if defined(IPC_MESSAGE_LOG_ENABLED)
[email protected]252cad62010-08-18 18:33:571067inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
1068 const std::string& output_params = msg->output_params();
[email protected]7a4de7a62010-08-17 18:38:241069 if (!l->empty() && !output_params.empty())
[email protected]252cad62010-08-18 18:33:571070 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:241071
1072 l->append(output_params);
1073}
1074
1075template <class ReplyParamType>
1076inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1077 const Message* msg) {
1078 if (msg->received_time() != 0) {
[email protected]252cad62010-08-18 18:33:571079 std::string output_params;
[email protected]7a4de7a62010-08-17 18:38:241080 LogParam(reply_params, &output_params);
1081 msg->set_output_params(output_params);
1082 }
1083}
1084
1085inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
1086 if (msg->sent_time()) {
1087 // Don't log the sync message after dispatch, as we don't have the
1088 // output parameters at that point. Instead, save its data and log it
1089 // with the outgoing reply message when it's sent.
1090 LogData* data = new LogData;
[email protected]ea7744a2011-10-20 19:34:431091 GenerateLogData("", *msg, data, true);
[email protected]7a4de7a62010-08-17 18:38:241092 msg->set_dont_log();
1093 reply->set_sync_log_data(data);
1094 }
1095}
1096#else
[email protected]252cad62010-08-18 18:33:571097inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
[email protected]7a4de7a62010-08-17 18:38:241098
1099template <class ReplyParamType>
1100inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1101 const Message* msg) {}
1102
1103inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1104#endif
1105
[email protected]3178f4e22008-08-05 21:20:411106} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291107
[email protected]946d1b22009-07-22 23:57:211108#endif // IPC_IPC_MESSAGE_UTILS_H_