blob: 97b95e986a9237ee881594416e93ebefbf99b875 [file] [log] [blame]
jochen@chromium.org30c8e912012-01-29 19:57:33 +09001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
agl@chromium.org1c6dcf22009-07-23 08:57:21 +09002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef IPC_IPC_MESSAGE_UTILS_H_
6#define IPC_IPC_MESSAGE_UTILS_H_
7
tfarina1cbfa082015-09-05 03:47:57 +09008#include <stdint.h>
9
jhawkins@chromium.org63c75eb2010-03-09 09:38:41 +090010#include <algorithm>
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090011#include <map>
mirandac@chromium.orgee262ad2010-05-14 04:10:34 +090012#include <set>
tfarina@chromium.org439aef62011-03-21 10:07:01 +090013#include <string>
14#include <vector>
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090015
jdduke@chromium.org556db8b2014-03-19 05:48:35 +090016#include "base/containers/small_map.h"
miletusd41fe222015-07-24 04:42:36 +090017#include "base/containers/stack_container.h"
rvargas@chromium.org9e469f62014-01-28 06:36:00 +090018#include "base/files/file.h"
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090019#include "base/format_macros.h"
jdduke@chromium.orgc6d80f02014-05-20 11:34:56 +090020#include "base/memory/scoped_ptr.h"
hashimoto@chromium.orgbbf7c502012-11-14 15:35:52 +090021#include "base/memory/scoped_vector.h"
avi@chromium.orge7eaf392013-06-11 15:32:18 +090022#include "base/strings/string16.h"
23#include "base/strings/string_util.h"
24#include "base/strings/stringprintf.h"
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090025#include "base/tuple.h"
erikchenfdd43fe2015-07-08 07:13:11 +090026#include "ipc/brokerable_attachment.h"
tsepez@chromium.org4afe8f72012-10-24 08:03:35 +090027#include "ipc/ipc_message_start.h"
erg@google.comb16c8a62010-08-25 05:29:02 +090028#include "ipc/ipc_param_traits.h"
erg@google.combfae8592010-08-17 09:24:54 +090029#include "ipc/ipc_sync_message.h"
erg@google.comcab37e72010-08-14 05:43:58 +090030
erg@google.come6ffcb52010-08-18 03:38:24 +090031#if defined(COMPILER_GCC)
32// GCC "helpfully" tries to inline template methods in release mode. Except we
33// want the majority of the template junk being expanded once in the
34// implementation file (and only provide the definitions in
35// ipc_message_utils_impl.h in those files) and exported, instead of expanded
36// at every call site. Special note: GCC happily accepts the attribute before
37// the method declaration, but only acts on it if it is after.
erg@google.comcb9c43f2010-08-20 05:23:25 +090038#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 40500
39// Starting in gcc 4.5, the noinline no longer implies the concept covered by
40// the introduced noclone attribute, which will create specialized versions of
41// functions/methods when certain types are constant.
42// www.gnu.org/software/gcc/gcc-4.5/changes.html
43#define IPC_MSG_NOINLINE __attribute__((noinline, noclone));
44#else
erg@google.come6ffcb52010-08-18 03:38:24 +090045#define IPC_MSG_NOINLINE __attribute__((noinline));
erg@google.comcb9c43f2010-08-20 05:23:25 +090046#endif
erg@google.come6ffcb52010-08-18 03:38:24 +090047#elif defined(COMPILER_MSVC)
48// MSVC++ doesn't do this.
49#define IPC_MSG_NOINLINE
50#else
51#error "Please add the noinline property for your new compiler here."
52#endif
53
erg@google.come6ffcb52010-08-18 03:38:24 +090054namespace base {
dmazzoni@chromium.org13e53652011-07-13 04:15:03 +090055class DictionaryValue;
brettw@chromium.orga7086942013-02-02 14:12:33 +090056class FilePath;
dmazzoni@chromium.org13e53652011-07-13 04:15:03 +090057class ListValue;
avi@chromium.orgd8179652013-06-13 22:47:46 +090058class NullableString16;
erg@google.come6ffcb52010-08-18 03:38:24 +090059class Time;
apatrick@chromium.org519c1c62010-10-22 07:04:52 +090060class TimeDelta;
isherman@chromium.org9952aaf2011-09-03 05:42:04 +090061class TimeTicks;
erg@google.come6ffcb52010-08-18 03:38:24 +090062struct FileDescriptor;
scottmg81491272015-06-20 07:51:00 +090063
erikchen18430e52015-09-26 07:34:31 +090064#if (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
scottmg81491272015-06-20 07:51:00 +090065class SharedMemoryHandle;
erikchen18430e52015-09-26 07:34:31 +090066#endif // (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
erg@google.come6ffcb52010-08-18 03:38:24 +090067}
68
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090069namespace IPC {
70
erg@google.come6ffcb52010-08-18 03:38:24 +090071struct ChannelHandle;
72
brettw@chromium.orgce352e52012-06-05 06:18:25 +090073// -----------------------------------------------------------------------------
74// How we send IPC message logs across channels.
75struct IPC_EXPORT LogData {
76 LogData();
77 ~LogData();
78
79 std::string channel;
tfarina1cbfa082015-09-05 03:47:57 +090080 int32_t routing_id;
81 uint32_t type; // "User-defined" message type, from ipc_message.h.
brettw@chromium.orgce352e52012-06-05 06:18:25 +090082 std::string flags;
tfarina1cbfa082015-09-05 03:47:57 +090083 int64_t sent; // Time that the message was sent (i.e. at Send()).
84 int64_t receive; // Time before it was dispatched (i.e. before calling
85 // OnMessageReceived).
86 int64_t dispatch; // Time after it was dispatched (i.e. after calling
87 // OnMessageReceived).
brettw@chromium.orgce352e52012-06-05 06:18:25 +090088 std::string message_name;
89 std::string params;
90};
91
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090092//-----------------------------------------------------------------------------
viettrungluu@chromium.orgc3ad0512012-12-18 05:23:47 +090093
tsepez@chromium.org1ac46132011-02-12 03:46:19 +090094// A dummy struct to place first just to allow leading commas for all
95// members in the macro-generated constructor initializer lists.
96struct NoParams {
97};
98
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090099template <class P>
100static inline void WriteParam(Message* m, const P& p) {
aa@chromium.org1605b6d2009-08-14 14:43:53 +0900101 typedef typename SimilarTypeTraits<P>::Type Type;
thakis@chromium.orgb13bd1d2010-06-17 03:39:53 +0900102 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900103}
104
105template <class P>
brettwf3146202015-06-03 13:29:25 +0900106static inline bool WARN_UNUSED_RESULT
107ReadParam(const Message* m, base::PickleIterator* iter, P* p) {
aa@chromium.org1605b6d2009-08-14 14:43:53 +0900108 typedef typename SimilarTypeTraits<P>::Type Type;
109 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900110}
111
112template <class P>
erg@google.com8aca7272010-08-19 03:33:57 +0900113static inline void LogParam(const P& p, std::string* l) {
aa@chromium.org1605b6d2009-08-14 14:43:53 +0900114 typedef typename SimilarTypeTraits<P>::Type Type;
thakis@chromium.orgb13bd1d2010-06-17 03:39:53 +0900115 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900116}
117
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900118// Primitive ParamTraits -------------------------------------------------------
119
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900120template <>
121struct ParamTraits<bool> {
122 typedef bool param_type;
123 static void Write(Message* m, const param_type& p) {
124 m->WriteBool(p);
125 }
brettwf3146202015-06-03 13:29:25 +0900126 static bool Read(const Message* m,
127 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +0900128 param_type* r) {
avic9f0ad02014-12-29 08:31:48 +0900129 return iter->ReadBool(r);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900130 }
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900131 IPC_EXPORT static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900132};
133
134template <>
ortuno6e3f7b32015-10-30 09:46:20 +0900135struct IPC_EXPORT ParamTraits<signed char> {
136 typedef signed char param_type;
137 static void Write(Message* m, const param_type& p);
138 static bool Read(const Message* m, base::PickleIterator* iter, param_type* r);
139 static void Log(const param_type& p, std::string* l);
140};
141
142template <>
tsepez@chromium.org09eb95f2013-07-13 08:12:28 +0900143struct IPC_EXPORT ParamTraits<unsigned char> {
jschuh@chromium.orgccd324a2013-07-13 13:42:10 +0900144 typedef unsigned char param_type;
tsepez@chromium.org09eb95f2013-07-13 08:12:28 +0900145 static void Write(Message* m, const param_type& p);
brettwf3146202015-06-03 13:29:25 +0900146 static bool Read(const Message* m, base::PickleIterator* iter, param_type* r);
tsepez@chromium.org09eb95f2013-07-13 08:12:28 +0900147 static void Log(const param_type& p, std::string* l);
148};
149
150template <>
151struct IPC_EXPORT ParamTraits<unsigned short> {
152 typedef unsigned short param_type;
153 static void Write(Message* m, const param_type& p);
brettwf3146202015-06-03 13:29:25 +0900154 static bool Read(const Message* m,
155 base::PickleIterator* iter,
156 param_type* r);
tsepez@chromium.org09eb95f2013-07-13 08:12:28 +0900157 static void Log(const param_type& p, std::string* l);
158};
159
160template <>
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900161struct ParamTraits<int> {
162 typedef int param_type;
163 static void Write(Message* m, const param_type& p) {
164 m->WriteInt(p);
165 }
brettwf3146202015-06-03 13:29:25 +0900166 static bool Read(const Message* m,
167 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +0900168 param_type* r) {
avic9f0ad02014-12-29 08:31:48 +0900169 return iter->ReadInt(r);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900170 }
darin@chromium.org80e4c5e2011-08-16 05:41:46 +0900171 IPC_EXPORT static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900172};
173
174template <>
deanm@chromium.org1543aa72009-07-29 04:35:08 +0900175struct ParamTraits<unsigned int> {
176 typedef unsigned int param_type;
177 static void Write(Message* m, const param_type& p) {
178 m->WriteInt(p);
179 }
brettwf3146202015-06-03 13:29:25 +0900180 static bool Read(const Message* m,
181 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +0900182 param_type* r) {
avic9f0ad02014-12-29 08:31:48 +0900183 return iter->ReadInt(reinterpret_cast<int*>(r));
deanm@chromium.org1543aa72009-07-29 04:35:08 +0900184 }
darin@chromium.org80e4c5e2011-08-16 05:41:46 +0900185 IPC_EXPORT static void Log(const param_type& p, std::string* l);
deanm@chromium.org1543aa72009-07-29 04:35:08 +0900186};
187
188template <>
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900189struct ParamTraits<long> {
190 typedef long param_type;
191 static void Write(Message* m, const param_type& p) {
mdm@chromium.org69bca9d2012-03-23 09:03:10 +0900192 m->WriteLongUsingDangerousNonPortableLessPersistableForm(p);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900193 }
brettwf3146202015-06-03 13:29:25 +0900194 static bool Read(const Message* m,
195 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +0900196 param_type* r) {
avic9f0ad02014-12-29 08:31:48 +0900197 return iter->ReadLong(r);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900198 }
darin@chromium.org80e4c5e2011-08-16 05:41:46 +0900199 IPC_EXPORT static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900200};
201
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900202template <>
203struct ParamTraits<unsigned long> {
204 typedef unsigned long param_type;
205 static void Write(Message* m, const param_type& p) {
mdm@chromium.org69bca9d2012-03-23 09:03:10 +0900206 m->WriteLongUsingDangerousNonPortableLessPersistableForm(p);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900207 }
brettwf3146202015-06-03 13:29:25 +0900208 static bool Read(const Message* m,
209 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +0900210 param_type* r) {
avic9f0ad02014-12-29 08:31:48 +0900211 return iter->ReadLong(reinterpret_cast<long*>(r));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900212 }
darin@chromium.org80e4c5e2011-08-16 05:41:46 +0900213 IPC_EXPORT static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900214};
215
216template <>
deanm@chromium.org1543aa72009-07-29 04:35:08 +0900217struct ParamTraits<long long> {
218 typedef long long param_type;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900219 static void Write(Message* m, const param_type& p) {
tfarina1cbfa082015-09-05 03:47:57 +0900220 m->WriteInt64(static_cast<int64_t>(p));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900221 }
brettwf3146202015-06-03 13:29:25 +0900222 static bool Read(const Message* m,
223 base::PickleIterator* iter,
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900224 param_type* r) {
tfarina1cbfa082015-09-05 03:47:57 +0900225 return iter->ReadInt64(reinterpret_cast<int64_t*>(r));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900226 }
darin@chromium.org80e4c5e2011-08-16 05:41:46 +0900227 IPC_EXPORT static void Log(const param_type& p, std::string* l);
deanm@chromium.org1543aa72009-07-29 04:35:08 +0900228};
229
230template <>
231struct ParamTraits<unsigned long long> {
232 typedef unsigned long long param_type;
233 static void Write(Message* m, const param_type& p) {
234 m->WriteInt64(p);
235 }
brettwf3146202015-06-03 13:29:25 +0900236 static bool Read(const Message* m,
237 base::PickleIterator* iter,
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900238 param_type* r) {
tfarina1cbfa082015-09-05 03:47:57 +0900239 return iter->ReadInt64(reinterpret_cast<int64_t*>(r));
deanm@chromium.org1543aa72009-07-29 04:35:08 +0900240 }
darin@chromium.org80e4c5e2011-08-16 05:41:46 +0900241 IPC_EXPORT static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900242};
243
jeremy@chromium.org4be619f2010-06-17 12:29:26 +0900244// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
245// should be sure to check the sanity of these values after receiving them over
246// IPC.
247template <>
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900248struct IPC_EXPORT ParamTraits<float> {
jeremy@chromium.org4be619f2010-06-17 12:29:26 +0900249 typedef float param_type;
piman@chromium.orgdd413b42013-10-31 18:27:31 +0900250 static void Write(Message* m, const param_type& p) {
251 m->WriteFloat(p);
252 }
brettwf3146202015-06-03 13:29:25 +0900253 static bool Read(const Message* m,
254 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +0900255 param_type* r) {
avic9f0ad02014-12-29 08:31:48 +0900256 return iter->ReadFloat(r);
piman@chromium.orgdd413b42013-10-31 18:27:31 +0900257 }
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900258 static void Log(const param_type& p, std::string* l);
jeremy@chromium.org4be619f2010-06-17 12:29:26 +0900259};
260
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900261template <>
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900262struct IPC_EXPORT ParamTraits<double> {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900263 typedef double param_type;
tsepez@chromium.org3081fac2012-05-31 06:15:57 +0900264 static void Write(Message* m, const param_type& p);
brettwf3146202015-06-03 13:29:25 +0900265 static bool Read(const Message* m,
266 base::PickleIterator* iter,
267 param_type* r);
tsepez@chromium.org3081fac2012-05-31 06:15:57 +0900268 static void Log(const param_type& p, std::string* l);
269};
270
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900271// STL ParamTraits -------------------------------------------------------------
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900272
273template <>
274struct ParamTraits<std::string> {
275 typedef std::string param_type;
276 static void Write(Message* m, const param_type& p) {
277 m->WriteString(p);
278 }
brettwf3146202015-06-03 13:29:25 +0900279 static bool Read(const Message* m,
280 base::PickleIterator* iter,
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900281 param_type* r) {
avic9f0ad02014-12-29 08:31:48 +0900282 return iter->ReadString(r);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900283 }
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900284 IPC_EXPORT static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900285};
286
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900287template <>
brettw@chromium.org5b040852013-12-03 09:39:26 +0900288struct ParamTraits<base::string16> {
289 typedef base::string16 param_type;
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900290 static void Write(Message* m, const param_type& p) {
291 m->WriteString16(p);
292 }
brettwf3146202015-06-03 13:29:25 +0900293 static bool Read(const Message* m,
294 base::PickleIterator* iter,
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900295 param_type* r) {
avic9f0ad02014-12-29 08:31:48 +0900296 return iter->ReadString16(r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900297 }
298 IPC_EXPORT static void Log(const param_type& p, std::string* l);
299};
evan@chromium.orga6590362009-07-28 06:09:07 +0900300
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900301template <>
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900302struct IPC_EXPORT ParamTraits<std::vector<char> > {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900303 typedef std::vector<char> param_type;
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900304 static void Write(Message* m, const param_type& p);
brettwf3146202015-06-03 13:29:25 +0900305 static bool Read(const Message*,
306 base::PickleIterator* iter,
307 param_type* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900308 static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900309};
310
bauerb@chromium.org17246c72011-10-06 03:55:42 +0900311template <>
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900312struct IPC_EXPORT ParamTraits<std::vector<unsigned char> > {
313 typedef std::vector<unsigned char> param_type;
314 static void Write(Message* m, const param_type& p);
brettwf3146202015-06-03 13:29:25 +0900315 static bool Read(const Message* m,
316 base::PickleIterator* iter,
317 param_type* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900318 static void Log(const param_type& p, std::string* l);
319};
320
321template <>
322struct IPC_EXPORT ParamTraits<std::vector<bool> > {
bauerb@chromium.org17246c72011-10-06 03:55:42 +0900323 typedef std::vector<bool> param_type;
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900324 static void Write(Message* m, const param_type& p);
brettwf3146202015-06-03 13:29:25 +0900325 static bool Read(const Message* m,
326 base::PickleIterator* iter,
327 param_type* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900328 static void Log(const param_type& p, std::string* l);
bauerb@chromium.org17246c72011-10-06 03:55:42 +0900329};
330
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900331template <class P>
332struct ParamTraits<std::vector<P> > {
333 typedef std::vector<P> param_type;
334 static void Write(Message* m, const param_type& p) {
335 WriteParam(m, static_cast<int>(p.size()));
336 for (size_t i = 0; i < p.size(); i++)
337 WriteParam(m, p[i]);
338 }
brettwf3146202015-06-03 13:29:25 +0900339 static bool Read(const Message* m,
340 base::PickleIterator* iter,
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900341 param_type* r) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900342 int size;
cevans@chromium.org7600d942009-12-31 14:17:23 +0900343 // ReadLength() checks for < 0 itself.
avic9f0ad02014-12-29 08:31:48 +0900344 if (!iter->ReadLength(&size))
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900345 return false;
346 // Resizing beforehand is not safe, see BUG 1006367 for details.
cevans@chromium.org7600d942009-12-31 14:17:23 +0900347 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
348 return false;
349 r->resize(size);
350 for (int i = 0; i < size; i++) {
351 if (!ReadParam(m, iter, &(*r)[i]))
352 return false;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900353 }
354 return true;
355 }
erg@google.com8aca7272010-08-19 03:33:57 +0900356 static void Log(const param_type& p, std::string* l) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900357 for (size_t i = 0; i < p.size(); ++i) {
358 if (i != 0)
erg@google.com8aca7272010-08-19 03:33:57 +0900359 l->append(" ");
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900360 LogParam((p[i]), l);
361 }
362 }
363};
364
mirandac@chromium.orgee262ad2010-05-14 04:10:34 +0900365template <class P>
366struct ParamTraits<std::set<P> > {
367 typedef std::set<P> param_type;
368 static void Write(Message* m, const param_type& p) {
369 WriteParam(m, static_cast<int>(p.size()));
370 typename param_type::const_iterator iter;
371 for (iter = p.begin(); iter != p.end(); ++iter)
372 WriteParam(m, *iter);
373 }
brettwf3146202015-06-03 13:29:25 +0900374 static bool Read(const Message* m,
375 base::PickleIterator* iter,
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900376 param_type* r) {
mirandac@chromium.orgee262ad2010-05-14 04:10:34 +0900377 int size;
avic9f0ad02014-12-29 08:31:48 +0900378 if (!iter->ReadLength(&size))
mirandac@chromium.orgee262ad2010-05-14 04:10:34 +0900379 return false;
380 for (int i = 0; i < size; ++i) {
381 P item;
382 if (!ReadParam(m, iter, &item))
383 return false;
384 r->insert(item);
385 }
386 return true;
387 }
erg@google.com8aca7272010-08-19 03:33:57 +0900388 static void Log(const param_type& p, std::string* l) {
389 l->append("<std::set>");
mirandac@chromium.orgee262ad2010-05-14 04:10:34 +0900390 }
391};
392
jkarlin45b11f92014-09-24 20:42:37 +0900393template <class K, class V, class C, class A>
394struct ParamTraits<std::map<K, V, C, A> > {
395 typedef std::map<K, V, C, A> param_type;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900396 static void Write(Message* m, const param_type& p) {
397 WriteParam(m, static_cast<int>(p.size()));
398 typename param_type::const_iterator iter;
399 for (iter = p.begin(); iter != p.end(); ++iter) {
400 WriteParam(m, iter->first);
401 WriteParam(m, iter->second);
402 }
403 }
brettwf3146202015-06-03 13:29:25 +0900404 static bool Read(const Message* m,
405 base::PickleIterator* iter,
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900406 param_type* r) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900407 int size;
408 if (!ReadParam(m, iter, &size) || size < 0)
409 return false;
410 for (int i = 0; i < size; ++i) {
411 K k;
412 if (!ReadParam(m, iter, &k))
413 return false;
414 V& value = (*r)[k];
415 if (!ReadParam(m, iter, &value))
416 return false;
417 }
418 return true;
419 }
erg@google.com8aca7272010-08-19 03:33:57 +0900420 static void Log(const param_type& p, std::string* l) {
421 l->append("<std::map>");
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900422 }
423};
424
jam@chromium.org0aa05022009-08-04 11:00:56 +0900425template <class A, class B>
426struct ParamTraits<std::pair<A, B> > {
427 typedef std::pair<A, B> param_type;
428 static void Write(Message* m, const param_type& p) {
429 WriteParam(m, p.first);
430 WriteParam(m, p.second);
431 }
brettwf3146202015-06-03 13:29:25 +0900432 static bool Read(const Message* m,
433 base::PickleIterator* iter,
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900434 param_type* r) {
jam@chromium.org0aa05022009-08-04 11:00:56 +0900435 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
436 }
erg@google.com8aca7272010-08-19 03:33:57 +0900437 static void Log(const param_type& p, std::string* l) {
438 l->append("(");
jam@chromium.org0aa05022009-08-04 11:00:56 +0900439 LogParam(p.first, l);
erg@google.com8aca7272010-08-19 03:33:57 +0900440 l->append(", ");
jam@chromium.org0aa05022009-08-04 11:00:56 +0900441 LogParam(p.second, l);
erg@google.com8aca7272010-08-19 03:33:57 +0900442 l->append(")");
jam@chromium.org0aa05022009-08-04 11:00:56 +0900443 }
444};
445
erikchenfdd43fe2015-07-08 07:13:11 +0900446// IPC ParamTraits -------------------------------------------------------------
447template <>
448struct IPC_EXPORT ParamTraits<BrokerableAttachment::AttachmentId> {
449 typedef BrokerableAttachment::AttachmentId param_type;
450 static void Write(Message* m, const param_type& p);
451 static bool Read(const Message* m, base::PickleIterator* iter, param_type* r);
452 static void Log(const param_type& p, std::string* l);
453};
454
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900455// Base ParamTraits ------------------------------------------------------------
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900456
457template <>
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900458struct IPC_EXPORT ParamTraits<base::DictionaryValue> {
459 typedef base::DictionaryValue param_type;
erg@google.come6ffcb52010-08-18 03:38:24 +0900460 static void Write(Message* m, const param_type& p);
brettwf3146202015-06-03 13:29:25 +0900461 static bool Read(const Message* m,
462 base::PickleIterator* iter,
463 param_type* r);
erg@google.com8aca7272010-08-19 03:33:57 +0900464 static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900465};
466
467#if defined(OS_POSIX)
468// FileDescriptors may be serialised over IPC channels on POSIX. On the
469// receiving side, the FileDescriptor is a valid duplicate of the file
470// descriptor which was transmitted: *it is not just a copy of the integer like
471// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
472// this case, the receiving end will see a value of -1. *Zero is a valid file
473// descriptor*.
474//
475// The received file descriptor will have the |auto_close| flag set to true. The
476// code which handles the message is responsible for taking ownership of it.
477// File descriptors are OS resources and must be closed when no longer needed.
478//
479// When sending a file descriptor, the file descriptor must be valid at the time
480// of transmission. Since transmission is not synchronous, one should consider
481// dup()ing any file descriptors to be transmitted and setting the |auto_close|
482// flag, which causes the file descriptor to be closed after writing.
483template<>
darin@chromium.org80e4c5e2011-08-16 05:41:46 +0900484struct IPC_EXPORT ParamTraits<base::FileDescriptor> {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900485 typedef base::FileDescriptor param_type;
erg@google.come6ffcb52010-08-18 03:38:24 +0900486 static void Write(Message* m, const param_type& p);
brettwf3146202015-06-03 13:29:25 +0900487 static bool Read(const Message* m,
488 base::PickleIterator* iter,
489 param_type* r);
erg@google.com8aca7272010-08-19 03:33:57 +0900490 static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900491};
jhawkins@chromium.org63c75eb2010-03-09 09:38:41 +0900492#endif // defined(OS_POSIX)
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900493
erikchen18430e52015-09-26 07:34:31 +0900494#if (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
scottmg81491272015-06-20 07:51:00 +0900495template <>
496struct IPC_EXPORT ParamTraits<base::SharedMemoryHandle> {
497 typedef base::SharedMemoryHandle param_type;
498 static void Write(Message* m, const param_type& p);
499 static bool Read(const Message* m, base::PickleIterator* iter, param_type* r);
500 static void Log(const param_type& p, std::string* l);
501};
erikchen18430e52015-09-26 07:34:31 +0900502#endif // (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
scottmg81491272015-06-20 07:51:00 +0900503
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900504template <>
brettw@chromium.orga7086942013-02-02 14:12:33 +0900505struct IPC_EXPORT ParamTraits<base::FilePath> {
506 typedef base::FilePath param_type;
erg@google.come6ffcb52010-08-18 03:38:24 +0900507 static void Write(Message* m, const param_type& p);
brettwf3146202015-06-03 13:29:25 +0900508 static bool Read(const Message* m,
509 base::PickleIterator* iter,
510 param_type* r);
erg@google.com8aca7272010-08-19 03:33:57 +0900511 static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900512};
513
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900514template <>
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900515struct IPC_EXPORT ParamTraits<base::ListValue> {
516 typedef base::ListValue param_type;
erg@google.com20b66e32010-10-01 05:06:30 +0900517 static void Write(Message* m, const param_type& p);
brettwf3146202015-06-03 13:29:25 +0900518 static bool Read(const Message* m,
519 base::PickleIterator* iter,
520 param_type* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900521 static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900522};
523
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900524template <>
avi@chromium.orgd8179652013-06-13 22:47:46 +0900525struct IPC_EXPORT ParamTraits<base::NullableString16> {
526 typedef base::NullableString16 param_type;
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900527 static void Write(Message* m, const param_type& p);
brettwf3146202015-06-03 13:29:25 +0900528 static bool Read(const Message* m,
529 base::PickleIterator* iter,
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900530 param_type* r);
531 static void Log(const param_type& p, std::string* l);
532};
533
534template <>
rvargas@chromium.org9e469f62014-01-28 06:36:00 +0900535struct IPC_EXPORT ParamTraits<base::File::Info> {
536 typedef base::File::Info param_type;
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900537 static void Write(Message* m, const param_type& p);
brettwf3146202015-06-03 13:29:25 +0900538 static bool Read(const Message* m,
539 base::PickleIterator* iter,
540 param_type* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900541 static void Log(const param_type& p, std::string* l);
542};
543
544template <>
rvargas@chromium.org9e469f62014-01-28 06:36:00 +0900545struct SimilarTypeTraits<base::File::Error> {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900546 typedef int Type;
547};
548
grt@chromium.orgb9abb172013-03-01 06:46:11 +0900549#if defined(OS_WIN)
550template <>
551struct SimilarTypeTraits<HWND> {
552 typedef HANDLE Type;
553};
554#endif // defined(OS_WIN)
555
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900556template <>
557struct IPC_EXPORT ParamTraits<base::Time> {
558 typedef base::Time param_type;
559 static void Write(Message* m, const param_type& p);
brettwf3146202015-06-03 13:29:25 +0900560 static bool Read(const Message* m,
561 base::PickleIterator* iter,
562 param_type* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900563 static void Log(const param_type& p, std::string* l);
564};
565
566template <>
567struct IPC_EXPORT ParamTraits<base::TimeDelta> {
568 typedef base::TimeDelta param_type;
569 static void Write(Message* m, const param_type& p);
brettwf3146202015-06-03 13:29:25 +0900570 static bool Read(const Message* m,
571 base::PickleIterator* iter,
572 param_type* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900573 static void Log(const param_type& p, std::string* l);
574};
575
576template <>
577struct IPC_EXPORT ParamTraits<base::TimeTicks> {
578 typedef base::TimeTicks param_type;
579 static void Write(Message* m, const param_type& p);
brettwf3146202015-06-03 13:29:25 +0900580 static bool Read(const Message* m,
581 base::PickleIterator* iter,
582 param_type* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900583 static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900584};
585
586template <>
brettw79a90902015-05-30 07:15:47 +0900587struct ParamTraits<base::Tuple<>> {
588 typedef base::Tuple<> param_type;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900589 static void Write(Message* m, const param_type& p) {
590 }
brettwf3146202015-06-03 13:29:25 +0900591 static bool Read(const Message* m,
592 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +0900593 param_type* r) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900594 return true;
595 }
erg@google.com8aca7272010-08-19 03:33:57 +0900596 static void Log(const param_type& p, std::string* l) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900597 }
598};
599
600template <class A>
brettw79a90902015-05-30 07:15:47 +0900601struct ParamTraits<base::Tuple<A>> {
602 typedef base::Tuple<A> param_type;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900603 static void Write(Message* m, const param_type& p) {
brettw79a90902015-05-30 07:15:47 +0900604 WriteParam(m, base::get<0>(p));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900605 }
brettwf3146202015-06-03 13:29:25 +0900606 static bool Read(const Message* m,
607 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +0900608 param_type* r) {
brettw79a90902015-05-30 07:15:47 +0900609 return ReadParam(m, iter, &base::get<0>(*r));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900610 }
erg@google.com8aca7272010-08-19 03:33:57 +0900611 static void Log(const param_type& p, std::string* l) {
brettw79a90902015-05-30 07:15:47 +0900612 LogParam(base::get<0>(p), l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900613 }
614};
615
616template <class A, class B>
brettw79a90902015-05-30 07:15:47 +0900617struct ParamTraits<base::Tuple<A, B>> {
618 typedef base::Tuple<A, B> param_type;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900619 static void Write(Message* m, const param_type& p) {
brettw79a90902015-05-30 07:15:47 +0900620 WriteParam(m, base::get<0>(p));
621 WriteParam(m, base::get<1>(p));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900622 }
brettwf3146202015-06-03 13:29:25 +0900623 static bool Read(const Message* m,
624 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +0900625 param_type* r) {
brettw79a90902015-05-30 07:15:47 +0900626 return (ReadParam(m, iter, &base::get<0>(*r)) &&
627 ReadParam(m, iter, &base::get<1>(*r)));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900628 }
erg@google.com8aca7272010-08-19 03:33:57 +0900629 static void Log(const param_type& p, std::string* l) {
brettw79a90902015-05-30 07:15:47 +0900630 LogParam(base::get<0>(p), l);
erg@google.com8aca7272010-08-19 03:33:57 +0900631 l->append(", ");
brettw79a90902015-05-30 07:15:47 +0900632 LogParam(base::get<1>(p), l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900633 }
634};
635
636template <class A, class B, class C>
brettw79a90902015-05-30 07:15:47 +0900637struct ParamTraits<base::Tuple<A, B, C>> {
638 typedef base::Tuple<A, B, C> param_type;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900639 static void Write(Message* m, const param_type& p) {
brettw79a90902015-05-30 07:15:47 +0900640 WriteParam(m, base::get<0>(p));
641 WriteParam(m, base::get<1>(p));
642 WriteParam(m, base::get<2>(p));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900643 }
brettwf3146202015-06-03 13:29:25 +0900644 static bool Read(const Message* m,
645 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +0900646 param_type* r) {
brettw79a90902015-05-30 07:15:47 +0900647 return (ReadParam(m, iter, &base::get<0>(*r)) &&
648 ReadParam(m, iter, &base::get<1>(*r)) &&
649 ReadParam(m, iter, &base::get<2>(*r)));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900650 }
erg@google.com8aca7272010-08-19 03:33:57 +0900651 static void Log(const param_type& p, std::string* l) {
brettw79a90902015-05-30 07:15:47 +0900652 LogParam(base::get<0>(p), l);
erg@google.com8aca7272010-08-19 03:33:57 +0900653 l->append(", ");
brettw79a90902015-05-30 07:15:47 +0900654 LogParam(base::get<1>(p), l);
erg@google.com8aca7272010-08-19 03:33:57 +0900655 l->append(", ");
brettw79a90902015-05-30 07:15:47 +0900656 LogParam(base::get<2>(p), l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900657 }
658};
659
660template <class A, class B, class C, class D>
brettw79a90902015-05-30 07:15:47 +0900661struct ParamTraits<base::Tuple<A, B, C, D>> {
662 typedef base::Tuple<A, B, C, D> param_type;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900663 static void Write(Message* m, const param_type& p) {
brettw79a90902015-05-30 07:15:47 +0900664 WriteParam(m, base::get<0>(p));
665 WriteParam(m, base::get<1>(p));
666 WriteParam(m, base::get<2>(p));
667 WriteParam(m, base::get<3>(p));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900668 }
brettwf3146202015-06-03 13:29:25 +0900669 static bool Read(const Message* m,
670 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +0900671 param_type* r) {
brettw79a90902015-05-30 07:15:47 +0900672 return (ReadParam(m, iter, &base::get<0>(*r)) &&
673 ReadParam(m, iter, &base::get<1>(*r)) &&
674 ReadParam(m, iter, &base::get<2>(*r)) &&
675 ReadParam(m, iter, &base::get<3>(*r)));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900676 }
erg@google.com8aca7272010-08-19 03:33:57 +0900677 static void Log(const param_type& p, std::string* l) {
brettw79a90902015-05-30 07:15:47 +0900678 LogParam(base::get<0>(p), l);
erg@google.com8aca7272010-08-19 03:33:57 +0900679 l->append(", ");
brettw79a90902015-05-30 07:15:47 +0900680 LogParam(base::get<1>(p), l);
erg@google.com8aca7272010-08-19 03:33:57 +0900681 l->append(", ");
brettw79a90902015-05-30 07:15:47 +0900682 LogParam(base::get<2>(p), l);
erg@google.com8aca7272010-08-19 03:33:57 +0900683 l->append(", ");
brettw79a90902015-05-30 07:15:47 +0900684 LogParam(base::get<3>(p), l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900685 }
686};
687
688template <class A, class B, class C, class D, class E>
brettw79a90902015-05-30 07:15:47 +0900689struct ParamTraits<base::Tuple<A, B, C, D, E>> {
690 typedef base::Tuple<A, B, C, D, E> param_type;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900691 static void Write(Message* m, const param_type& p) {
brettw79a90902015-05-30 07:15:47 +0900692 WriteParam(m, base::get<0>(p));
693 WriteParam(m, base::get<1>(p));
694 WriteParam(m, base::get<2>(p));
695 WriteParam(m, base::get<3>(p));
696 WriteParam(m, base::get<4>(p));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900697 }
brettwf3146202015-06-03 13:29:25 +0900698 static bool Read(const Message* m,
699 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +0900700 param_type* r) {
brettw79a90902015-05-30 07:15:47 +0900701 return (ReadParam(m, iter, &base::get<0>(*r)) &&
702 ReadParam(m, iter, &base::get<1>(*r)) &&
703 ReadParam(m, iter, &base::get<2>(*r)) &&
704 ReadParam(m, iter, &base::get<3>(*r)) &&
705 ReadParam(m, iter, &base::get<4>(*r)));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900706 }
erg@google.com8aca7272010-08-19 03:33:57 +0900707 static void Log(const param_type& p, std::string* l) {
brettw79a90902015-05-30 07:15:47 +0900708 LogParam(base::get<0>(p), l);
erg@google.com8aca7272010-08-19 03:33:57 +0900709 l->append(", ");
brettw79a90902015-05-30 07:15:47 +0900710 LogParam(base::get<1>(p), l);
erg@google.com8aca7272010-08-19 03:33:57 +0900711 l->append(", ");
brettw79a90902015-05-30 07:15:47 +0900712 LogParam(base::get<2>(p), l);
erg@google.com8aca7272010-08-19 03:33:57 +0900713 l->append(", ");
brettw79a90902015-05-30 07:15:47 +0900714 LogParam(base::get<3>(p), l);
erg@google.com8aca7272010-08-19 03:33:57 +0900715 l->append(", ");
brettw79a90902015-05-30 07:15:47 +0900716 LogParam(base::get<4>(p), l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900717 }
718};
719
hashimoto@chromium.orgbbf7c502012-11-14 15:35:52 +0900720template<class P>
721struct ParamTraits<ScopedVector<P> > {
722 typedef ScopedVector<P> param_type;
723 static void Write(Message* m, const param_type& p) {
724 WriteParam(m, static_cast<int>(p.size()));
725 for (size_t i = 0; i < p.size(); i++)
726 WriteParam(m, *p[i]);
727 }
brettwf3146202015-06-03 13:29:25 +0900728 static bool Read(const Message* m,
729 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +0900730 param_type* r) {
hashimoto@chromium.orgbbf7c502012-11-14 15:35:52 +0900731 int size = 0;
avic9f0ad02014-12-29 08:31:48 +0900732 if (!iter->ReadLength(&size))
hashimoto@chromium.orgbbf7c502012-11-14 15:35:52 +0900733 return false;
734 if (INT_MAX/sizeof(P) <= static_cast<size_t>(size))
735 return false;
736 r->resize(size);
737 for (int i = 0; i < size; i++) {
738 (*r)[i] = new P();
739 if (!ReadParam(m, iter, (*r)[i]))
740 return false;
741 }
742 return true;
743 }
744 static void Log(const param_type& p, std::string* l) {
745 for (size_t i = 0; i < p.size(); ++i) {
746 if (i != 0)
747 l->append(" ");
748 LogParam(*p[i], l);
749 }
750 }
751};
752
miletusd41fe222015-07-24 04:42:36 +0900753template <class P, size_t stack_capacity>
754struct ParamTraits<base::StackVector<P, stack_capacity> > {
755 typedef base::StackVector<P, stack_capacity> param_type;
756 static void Write(Message* m, const param_type& p) {
757 WriteParam(m, static_cast<int>(p->size()));
758 for (size_t i = 0; i < p->size(); i++)
759 WriteParam(m, p[i]);
760 }
761 static bool Read(const Message* m,
762 base::PickleIterator* iter,
763 param_type* r) {
764 int size;
765 // ReadLength() checks for < 0 itself.
766 if (!iter->ReadLength(&size))
767 return false;
768 // Sanity check for the vector size.
769 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
770 return false;
771 P value;
772 for (int i = 0; i < size; i++) {
773 if (!ReadParam(m, iter, &value))
774 return false;
775 (*r)->push_back(value);
776 }
777 return true;
778 }
779 static void Log(const param_type& p, std::string* l) {
780 for (size_t i = 0; i < p->size(); ++i) {
781 if (i != 0)
782 l->append(" ");
783 LogParam((p[i]), l);
784 }
785 }
786};
787
jdduke@chromium.org556db8b2014-03-19 05:48:35 +0900788template <typename NormalMap,
789 int kArraySize,
790 typename EqualKey,
791 typename MapInit>
792struct ParamTraits<base::SmallMap<NormalMap, kArraySize, EqualKey, MapInit> > {
793 typedef base::SmallMap<NormalMap, kArraySize, EqualKey, MapInit> param_type;
794 typedef typename param_type::key_type K;
795 typedef typename param_type::data_type V;
796 static void Write(Message* m, const param_type& p) {
797 WriteParam(m, static_cast<int>(p.size()));
798 typename param_type::const_iterator iter;
799 for (iter = p.begin(); iter != p.end(); ++iter) {
800 WriteParam(m, iter->first);
801 WriteParam(m, iter->second);
802 }
803 }
brettwf3146202015-06-03 13:29:25 +0900804 static bool Read(const Message* m,
805 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +0900806 param_type* r) {
jdduke@chromium.org556db8b2014-03-19 05:48:35 +0900807 int size;
avic9f0ad02014-12-29 08:31:48 +0900808 if (!iter->ReadLength(&size))
jdduke@chromium.org556db8b2014-03-19 05:48:35 +0900809 return false;
810 for (int i = 0; i < size; ++i) {
811 K key;
812 if (!ReadParam(m, iter, &key))
813 return false;
814 V& value = (*r)[key];
815 if (!ReadParam(m, iter, &value))
816 return false;
817 }
818 return true;
819 }
820 static void Log(const param_type& p, std::string* l) {
821 l->append("<base::SmallMap>");
822 }
823};
824
jdduke@chromium.orgc6d80f02014-05-20 11:34:56 +0900825template <class P>
826struct ParamTraits<scoped_ptr<P> > {
827 typedef scoped_ptr<P> param_type;
828 static void Write(Message* m, const param_type& p) {
829 bool valid = !!p;
830 WriteParam(m, valid);
831 if (valid)
832 WriteParam(m, *p);
833 }
brettwf3146202015-06-03 13:29:25 +0900834 static bool Read(const Message* m,
835 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +0900836 param_type* r) {
jdduke@chromium.orgc6d80f02014-05-20 11:34:56 +0900837 bool valid = false;
838 if (!ReadParam(m, iter, &valid))
839 return false;
840
841 if (!valid) {
842 r->reset();
843 return true;
844 }
845
846 param_type temp(new P());
847 if (!ReadParam(m, iter, temp.get()))
848 return false;
849
850 r->swap(temp);
851 return true;
852 }
853 static void Log(const param_type& p, std::string* l) {
854 if (p)
855 LogParam(*p, l);
856 else
857 l->append("NULL");
858 }
859};
860
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900861// IPC types ParamTraits -------------------------------------------------------
862
863// A ChannelHandle is basically a platform-inspecific wrapper around the
864// fact that IPC endpoints are handled specially on POSIX. See above comments
865// on FileDescriptor for more background.
866template<>
867struct IPC_EXPORT ParamTraits<IPC::ChannelHandle> {
868 typedef ChannelHandle param_type;
869 static void Write(Message* m, const param_type& p);
brettwf3146202015-06-03 13:29:25 +0900870 static bool Read(const Message* m,
871 base::PickleIterator* iter,
872 param_type* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900873 static void Log(const param_type& p, std::string* l);
874};
875
876template <>
877struct IPC_EXPORT ParamTraits<LogData> {
878 typedef LogData param_type;
879 static void Write(Message* m, const param_type& p);
brettwf3146202015-06-03 13:29:25 +0900880 static bool Read(const Message* m,
881 base::PickleIterator* iter,
882 param_type* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900883 static void Log(const param_type& p, std::string* l);
884};
885
886template <>
887struct IPC_EXPORT ParamTraits<Message> {
888 static void Write(Message* m, const Message& p);
brettwf3146202015-06-03 13:29:25 +0900889 static bool Read(const Message* m,
890 base::PickleIterator* iter,
891 Message* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900892 static void Log(const Message& p, std::string* l);
893};
894
895// Windows ParamTraits ---------------------------------------------------------
896
897#if defined(OS_WIN)
898template <>
899struct IPC_EXPORT ParamTraits<HANDLE> {
900 typedef HANDLE param_type;
901 static void Write(Message* m, const param_type& p);
brettwf3146202015-06-03 13:29:25 +0900902 static bool Read(const Message* m,
903 base::PickleIterator* iter,
904 param_type* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900905 static void Log(const param_type& p, std::string* l);
906};
907
908template <>
909struct IPC_EXPORT ParamTraits<LOGFONT> {
910 typedef LOGFONT param_type;
911 static void Write(Message* m, const param_type& p);
brettwf3146202015-06-03 13:29:25 +0900912 static bool Read(const Message* m,
913 base::PickleIterator* iter,
914 param_type* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900915 static void Log(const param_type& p, std::string* l);
916};
917
918template <>
919struct IPC_EXPORT ParamTraits<MSG> {
920 typedef MSG param_type;
921 static void Write(Message* m, const param_type& p);
brettwf3146202015-06-03 13:29:25 +0900922 static bool Read(const Message* m,
923 base::PickleIterator* iter,
924 param_type* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900925 static void Log(const param_type& p, std::string* l);
926};
927#endif // defined(OS_WIN)
928
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900929//-----------------------------------------------------------------------------
930// Generic message subclasses
931
932// Used for asynchronous messages.
933template <class ParamType>
darin@chromium.orgb4587d52011-08-27 06:27:30 +0900934class MessageSchema {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900935 public:
936 typedef ParamType Param;
brettw79a90902015-05-30 07:15:47 +0900937 typedef typename base::TupleTypes<ParamType>::ParamTuple RefParam;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900938
darin@chromium.orgb4587d52011-08-27 06:27:30 +0900939 static void Write(Message* msg, const RefParam& p) IPC_MSG_NOINLINE;
erg@google.come6ffcb52010-08-18 03:38:24 +0900940 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900941};
942
erg@google.come6ffcb52010-08-18 03:38:24 +0900943// defined in ipc_logging.cc
darin@chromium.org80e4c5e2011-08-16 05:41:46 +0900944IPC_EXPORT void GenerateLogData(const std::string& channel,
945 const Message& message,
scottbyer@chromium.orgf0cf0b72011-10-21 04:34:43 +0900946 LogData* data, bool get_params);
erg@google.come6ffcb52010-08-18 03:38:24 +0900947
948
949#if defined(IPC_MESSAGE_LOG_ENABLED)
erg@google.com8aca7272010-08-19 03:33:57 +0900950inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
951 const std::string& output_params = msg->output_params();
erg@google.come6ffcb52010-08-18 03:38:24 +0900952 if (!l->empty() && !output_params.empty())
erg@google.com8aca7272010-08-19 03:33:57 +0900953 l->append(", ");
erg@google.come6ffcb52010-08-18 03:38:24 +0900954
955 l->append(output_params);
956}
957
958template <class ReplyParamType>
959inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
960 const Message* msg) {
961 if (msg->received_time() != 0) {
erg@google.com8aca7272010-08-19 03:33:57 +0900962 std::string output_params;
erg@google.come6ffcb52010-08-18 03:38:24 +0900963 LogParam(reply_params, &output_params);
964 msg->set_output_params(output_params);
965 }
966}
967
968inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
969 if (msg->sent_time()) {
970 // Don't log the sync message after dispatch, as we don't have the
971 // output parameters at that point. Instead, save its data and log it
972 // with the outgoing reply message when it's sent.
973 LogData* data = new LogData;
scottbyer@chromium.orgf0cf0b72011-10-21 04:34:43 +0900974 GenerateLogData("", *msg, data, true);
erg@google.come6ffcb52010-08-18 03:38:24 +0900975 msg->set_dont_log();
976 reply->set_sync_log_data(data);
977 }
978}
979#else
erg@google.com8aca7272010-08-19 03:33:57 +0900980inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
erg@google.come6ffcb52010-08-18 03:38:24 +0900981
982template <class ReplyParamType>
983inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
984 const Message* msg) {}
985
986inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
987#endif
988
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900989// This class assumes that its template argument is a RefTuple (a Tuple with
erg@google.come6ffcb52010-08-18 03:38:24 +0900990// reference elements). This would go into ipc_message_utils_impl.h, but it is
991// also used by chrome_frame.
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900992template <class RefTuple>
993class ParamDeserializer : public MessageReplyDeserializer {
994 public:
995 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
996
dmichaela5a9c962014-12-18 10:53:14 +0900997 bool SerializeOutputParameters(const IPC::Message& msg,
brettwa4879472015-06-02 16:02:47 +0900998 base::PickleIterator iter) override {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900999 return ReadParam(&msg, &iter, &out_);
1000 }
1001
1002 RefTuple out_;
1003};
1004
agl@chromium.org1c6dcf22009-07-23 08:57:21 +09001005// Used for synchronous messages.
1006template <class SendParamType, class ReplyParamType>
darin@chromium.orgb4587d52011-08-27 06:27:30 +09001007class SyncMessageSchema {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +09001008 public:
1009 typedef SendParamType SendParam;
brettw79a90902015-05-30 07:15:47 +09001010 typedef typename base::TupleTypes<SendParam>::ParamTuple RefSendParam;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +09001011 typedef ReplyParamType ReplyParam;
1012
darin@chromium.orgb4587d52011-08-27 06:27:30 +09001013 static void Write(Message* msg, const RefSendParam& send) IPC_MSG_NOINLINE;
erg@google.come6ffcb52010-08-18 03:38:24 +09001014 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
1015 static bool ReadReplyParam(
1016 const Message* msg,
brettw79a90902015-05-30 07:15:47 +09001017 typename base::TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +09001018
jam@chromium.org82f52f82010-12-22 05:03:24 +09001019 template<class T, class S, class Method>
darin@chromium.orgb4587d52011-08-27 06:27:30 +09001020 static bool DispatchWithSendParams(bool ok, const SendParam& send_params,
1021 const Message* msg, T* obj, S* sender,
1022 Method func) {
1023 Message* reply = SyncMessage::GenerateReply(msg);
1024 if (ok) {
brettw79a90902015-05-30 07:15:47 +09001025 typename base::TupleTypes<ReplyParam>::ValueTuple reply_params;
tzik6c7c93f2015-11-20 08:31:21 +09001026 base::DispatchToMethod(obj, func, send_params, &reply_params);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +09001027 WriteParam(reply, reply_params);
erg@google.come6ffcb52010-08-18 03:38:24 +09001028 LogReplyParamsToMessage(reply_params, msg);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +09001029 } else {
1030 NOTREACHED() << "Error deserializing message " << msg->type();
1031 reply->set_reply_error();
agl@chromium.org1c6dcf22009-07-23 08:57:21 +09001032 }
jam@chromium.org82f52f82010-12-22 05:03:24 +09001033 sender->Send(reply);
darin@chromium.orgb4587d52011-08-27 06:27:30 +09001034 return ok;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +09001035 }
1036
1037 template<class T, class Method>
darin@chromium.orgb4587d52011-08-27 06:27:30 +09001038 static bool DispatchDelayReplyWithSendParams(bool ok,
1039 const SendParam& send_params,
1040 const Message* msg, T* obj,
1041 Method func) {
1042 Message* reply = SyncMessage::GenerateReply(msg);
1043 if (ok) {
brettw79a90902015-05-30 07:15:47 +09001044 base::Tuple<Message&> t = base::MakeRefTuple(*reply);
erg@google.come6ffcb52010-08-18 03:38:24 +09001045 ConnectMessageAndReply(msg, reply);
tzik6c7c93f2015-11-20 08:31:21 +09001046 base::DispatchToMethod(obj, func, send_params, &t);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +09001047 } else {
1048 NOTREACHED() << "Error deserializing message " << msg->type();
1049 reply->set_reply_error();
1050 obj->Send(reply);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +09001051 }
darin@chromium.orgb4587d52011-08-27 06:27:30 +09001052 return ok;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +09001053 }
1054
mikhail.pozdnyakov4c5bdf12015-03-26 21:24:40 +09001055 template <typename... Ts>
1056 static void WriteReplyParams(Message* reply, Ts... args) {
1057 ReplyParam p(args...);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +09001058 WriteParam(reply, p);
1059 }
1060};
1061
agl@chromium.org1c6dcf22009-07-23 08:57:21 +09001062} // namespace IPC
1063
1064#endif // IPC_IPC_MESSAGE_UTILS_H_