blob: 84324ebaf417f5aee89cdfb33b60d513ac19c7c5 [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
avi2f68ea02015-12-27 02:30:50 +09008#include <limits.h>
avi42ebda42015-12-22 11:39:04 +09009#include <stddef.h>
tfarina1cbfa082015-09-05 03:47:57 +090010#include <stdint.h>
11
jhawkins@chromium.org63c75eb2010-03-09 09:38:41 +090012#include <algorithm>
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090013#include <map>
danakjc3fb6c52016-04-23 13:21:09 +090014#include <memory>
mirandac@chromium.orgee262ad2010-05-14 04:10:34 +090015#include <set>
tfarina@chromium.org439aef62011-03-21 10:07:01 +090016#include <string>
tzika088e352016-03-08 14:47:44 +090017#include <tuple>
tfarina@chromium.org439aef62011-03-21 10:07:01 +090018#include <vector>
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090019
brettwd3d9de02017-04-20 15:10:20 +090020#include "base/containers/flat_map.h"
jdduke@chromium.org556db8b2014-03-19 05:48:35 +090021#include "base/containers/small_map.h"
miletusd41fe222015-07-24 04:42:36 +090022#include "base/containers/stack_container.h"
rvargas@chromium.org9e469f62014-01-28 06:36:00 +090023#include "base/files/file.h"
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090024#include "base/format_macros.h"
brettwd3d9de02017-04-20 15:10:20 +090025#include "base/numerics/safe_conversions.h"
bmcquade11758372016-07-01 22:13:50 +090026#include "base/optional.h"
avi@chromium.orge7eaf392013-06-11 15:32:18 +090027#include "base/strings/string16.h"
28#include "base/strings/string_util.h"
29#include "base/strings/stringprintf.h"
avi42ebda42015-12-22 11:39:04 +090030#include "build/build_config.h"
tsepez@chromium.org4afe8f72012-10-24 08:03:35 +090031#include "ipc/ipc_message_start.h"
erg@google.comb16c8a62010-08-25 05:29:02 +090032#include "ipc/ipc_param_traits.h"
erg@google.combfae8592010-08-17 09:24:54 +090033#include "ipc/ipc_sync_message.h"
erg@google.comcab37e72010-08-14 05:43:58 +090034
erg@google.come6ffcb52010-08-18 03:38:24 +090035namespace base {
dmazzoni@chromium.org13e53652011-07-13 04:15:03 +090036class DictionaryValue;
brettw@chromium.orga7086942013-02-02 14:12:33 +090037class FilePath;
dmazzoni@chromium.org13e53652011-07-13 04:15:03 +090038class ListValue;
avi@chromium.orgd8179652013-06-13 22:47:46 +090039class NullableString16;
erikchendf302482017-04-29 02:10:50 +090040class SharedMemoryHandle;
erg@google.come6ffcb52010-08-18 03:38:24 +090041class Time;
apatrick@chromium.org519c1c62010-10-22 07:04:52 +090042class TimeDelta;
isherman@chromium.org9952aaf2011-09-03 05:42:04 +090043class TimeTicks;
tguilbert76e690d2016-09-20 06:11:25 +090044class UnguessableToken;
erg@google.come6ffcb52010-08-18 03:38:24 +090045struct FileDescriptor;
46}
47
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090048namespace IPC {
49
erg@google.come6ffcb52010-08-18 03:38:24 +090050struct ChannelHandle;
51
erikchen9a454c12017-04-29 11:24:36 +090052#if defined(OS_WIN)
53class PlatformFileForTransit;
54#endif
55
brettw@chromium.orgce352e52012-06-05 06:18:25 +090056// -----------------------------------------------------------------------------
57// How we send IPC message logs across channels.
58struct IPC_EXPORT LogData {
59 LogData();
vmpstrd661bf72016-03-25 05:22:54 +090060 LogData(const LogData& other);
brettw@chromium.orgce352e52012-06-05 06:18:25 +090061 ~LogData();
62
63 std::string channel;
tfarina1cbfa082015-09-05 03:47:57 +090064 int32_t routing_id;
65 uint32_t type; // "User-defined" message type, from ipc_message.h.
brettw@chromium.orgce352e52012-06-05 06:18:25 +090066 std::string flags;
tfarina1cbfa082015-09-05 03:47:57 +090067 int64_t sent; // Time that the message was sent (i.e. at Send()).
68 int64_t receive; // Time before it was dispatched (i.e. before calling
69 // OnMessageReceived).
70 int64_t dispatch; // Time after it was dispatched (i.e. after calling
71 // OnMessageReceived).
brettw@chromium.orgce352e52012-06-05 06:18:25 +090072 std::string message_name;
73 std::string params;
74};
75
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090076//-----------------------------------------------------------------------------
viettrungluu@chromium.orgc3ad0512012-12-18 05:23:47 +090077
tsepez@chromium.org1ac46132011-02-12 03:46:19 +090078// A dummy struct to place first just to allow leading commas for all
79// members in the macro-generated constructor initializer lists.
80struct NoParams {
81};
82
dskibaa789c212016-04-07 00:51:06 +090083// Specializations are checked by 'IPC checker' part of find-bad-constructs
84// Clang plugin (see WriteParam() below for the details).
85template <typename... Ts>
86struct CheckedTuple {
87 typedef std::tuple<Ts...> Tuple;
88};
89
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090090template <class P>
rockot15c8ac42016-02-05 11:12:32 +090091static inline void GetParamSize(base::PickleSizer* sizer, const P& p) {
92 typedef typename SimilarTypeTraits<P>::Type Type;
93 ParamTraits<Type>::GetSize(sizer, static_cast<const Type&>(p));
94}
95
dskibaa789c212016-04-07 00:51:06 +090096// This function is checked by 'IPC checker' part of find-bad-constructs
97// Clang plugin to make it's not called on the following types:
98// 1. long / unsigned long (but not typedefs to)
99// 2. intmax_t, uintmax_t, intptr_t, uintptr_t, wint_t,
100// size_t, rsize_t, ssize_t, ptrdiff_t, dev_t, off_t, clock_t,
101// time_t, suseconds_t (including typedefs to)
102// 3. Any template referencing types above (e.g. std::vector<size_t>)
rockot15c8ac42016-02-05 11:12:32 +0900103template <class P>
rockot6dbfea52016-02-04 05:20:16 +0900104static inline void WriteParam(base::Pickle* m, const P& p) {
aa@chromium.org1605b6d2009-08-14 14:43:53 +0900105 typedef typename SimilarTypeTraits<P>::Type Type;
thakis@chromium.orgb13bd1d2010-06-17 03:39:53 +0900106 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900107}
108
109template <class P>
rockot6dbfea52016-02-04 05:20:16 +0900110static inline bool WARN_UNUSED_RESULT ReadParam(const base::Pickle* m,
111 base::PickleIterator* iter,
112 P* p) {
aa@chromium.org1605b6d2009-08-14 14:43:53 +0900113 typedef typename SimilarTypeTraits<P>::Type Type;
114 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900115}
116
117template <class P>
erg@google.com8aca7272010-08-19 03:33:57 +0900118static inline void LogParam(const P& p, std::string* l) {
aa@chromium.org1605b6d2009-08-14 14:43:53 +0900119 typedef typename SimilarTypeTraits<P>::Type Type;
thakis@chromium.orgb13bd1d2010-06-17 03:39:53 +0900120 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900121}
122
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900123// Primitive ParamTraits -------------------------------------------------------
124
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900125template <>
126struct ParamTraits<bool> {
127 typedef bool param_type;
rockot15c8ac42016-02-05 11:12:32 +0900128 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
129 sizer->AddBool();
130 }
rockot6dbfea52016-02-04 05:20:16 +0900131 static void Write(base::Pickle* m, const param_type& p) { m->WriteBool(p); }
132 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900133 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +0900134 param_type* r) {
avic9f0ad02014-12-29 08:31:48 +0900135 return iter->ReadBool(r);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900136 }
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900137 IPC_EXPORT static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900138};
139
140template <>
ortuno6e3f7b32015-10-30 09:46:20 +0900141struct IPC_EXPORT ParamTraits<signed char> {
142 typedef signed char param_type;
rockot15c8ac42016-02-05 11:12:32 +0900143 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot6dbfea52016-02-04 05:20:16 +0900144 static void Write(base::Pickle* m, const param_type& p);
145 static bool Read(const base::Pickle* m,
146 base::PickleIterator* iter,
147 param_type* r);
ortuno6e3f7b32015-10-30 09:46:20 +0900148 static void Log(const param_type& p, std::string* l);
149};
150
151template <>
tsepez@chromium.org09eb95f2013-07-13 08:12:28 +0900152struct IPC_EXPORT ParamTraits<unsigned char> {
jschuh@chromium.orgccd324a2013-07-13 13:42:10 +0900153 typedef unsigned char param_type;
rockot15c8ac42016-02-05 11:12:32 +0900154 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot6dbfea52016-02-04 05:20:16 +0900155 static void Write(base::Pickle* m, const param_type& p);
156 static bool Read(const base::Pickle* m,
157 base::PickleIterator* iter,
158 param_type* r);
tsepez@chromium.org09eb95f2013-07-13 08:12:28 +0900159 static void Log(const param_type& p, std::string* l);
160};
161
162template <>
163struct IPC_EXPORT ParamTraits<unsigned short> {
164 typedef unsigned short param_type;
rockot15c8ac42016-02-05 11:12:32 +0900165 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot6dbfea52016-02-04 05:20:16 +0900166 static void Write(base::Pickle* m, const param_type& p);
167 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900168 base::PickleIterator* iter,
169 param_type* r);
tsepez@chromium.org09eb95f2013-07-13 08:12:28 +0900170 static void Log(const param_type& p, std::string* l);
171};
172
173template <>
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900174struct ParamTraits<int> {
175 typedef int param_type;
rockot15c8ac42016-02-05 11:12:32 +0900176 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
177 sizer->AddInt();
178 }
rockot6dbfea52016-02-04 05:20:16 +0900179 static void Write(base::Pickle* m, const param_type& p) { m->WriteInt(p); }
180 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900181 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +0900182 param_type* r) {
avic9f0ad02014-12-29 08:31:48 +0900183 return iter->ReadInt(r);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900184 }
darin@chromium.org80e4c5e2011-08-16 05:41:46 +0900185 IPC_EXPORT static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900186};
187
188template <>
deanm@chromium.org1543aa72009-07-29 04:35:08 +0900189struct ParamTraits<unsigned int> {
190 typedef unsigned int param_type;
rockot15c8ac42016-02-05 11:12:32 +0900191 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
192 sizer->AddInt();
193 }
rockot6dbfea52016-02-04 05:20:16 +0900194 static void Write(base::Pickle* m, const param_type& p) { m->WriteInt(p); }
195 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900196 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +0900197 param_type* r) {
avic9f0ad02014-12-29 08:31:48 +0900198 return iter->ReadInt(reinterpret_cast<int*>(r));
deanm@chromium.org1543aa72009-07-29 04:35:08 +0900199 }
darin@chromium.org80e4c5e2011-08-16 05:41:46 +0900200 IPC_EXPORT static void Log(const param_type& p, std::string* l);
deanm@chromium.org1543aa72009-07-29 04:35:08 +0900201};
202
jam923e5462016-02-11 05:13:39 +0900203// long isn't safe to send over IPC because it's 4 bytes on 32 bit builds but
204// 8 bytes on 64 bit builds. So if a 32 bit and 64 bit process have a channel
205// that would cause problem.
206// We need to keep this on for a few configs:
207// 1) Windows because DWORD is typedef'd to it, which is fine because we have
208// very few IPCs that cross this boundary.
209// 2) We also need to keep it for Linux for two reasons: int64_t is typedef'd
210// to long, and gfx::PluginWindow is long and is used in one GPU IPC.
211// 3) Android 64 bit also has int64_t typedef'd to long.
212// Since we want to support Android 32<>64 bit IPC, as long as we don't have
213// these traits for 32 bit ARM then that'll catch any errors.
jam739d8d12016-02-11 09:50:28 +0900214#if defined(OS_WIN) || defined(OS_LINUX) || \
215 (defined(OS_ANDROID) && defined(ARCH_CPU_64_BITS))
deanm@chromium.org1543aa72009-07-29 04:35:08 +0900216template <>
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900217struct ParamTraits<long> {
218 typedef long param_type;
rockot15c8ac42016-02-05 11:12:32 +0900219 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
jam923e5462016-02-11 05:13:39 +0900220 sizer->AddLong();
rockot15c8ac42016-02-05 11:12:32 +0900221 }
rockot6dbfea52016-02-04 05:20:16 +0900222 static void Write(base::Pickle* m, const param_type& p) {
jam923e5462016-02-11 05:13:39 +0900223 m->WriteLong(p);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900224 }
rockot6dbfea52016-02-04 05:20:16 +0900225 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900226 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +0900227 param_type* r) {
avic9f0ad02014-12-29 08:31:48 +0900228 return iter->ReadLong(r);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900229 }
darin@chromium.org80e4c5e2011-08-16 05:41:46 +0900230 IPC_EXPORT static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900231};
232
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900233template <>
234struct ParamTraits<unsigned long> {
235 typedef unsigned long param_type;
rockot15c8ac42016-02-05 11:12:32 +0900236 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
jam923e5462016-02-11 05:13:39 +0900237 sizer->AddLong();
rockot15c8ac42016-02-05 11:12:32 +0900238 }
rockot6dbfea52016-02-04 05:20:16 +0900239 static void Write(base::Pickle* m, const param_type& p) {
jam923e5462016-02-11 05:13:39 +0900240 m->WriteLong(p);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900241 }
rockot6dbfea52016-02-04 05:20:16 +0900242 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900243 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +0900244 param_type* r) {
avic9f0ad02014-12-29 08:31:48 +0900245 return iter->ReadLong(reinterpret_cast<long*>(r));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900246 }
darin@chromium.org80e4c5e2011-08-16 05:41:46 +0900247 IPC_EXPORT static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900248};
jam923e5462016-02-11 05:13:39 +0900249#endif
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900250
251template <>
deanm@chromium.org1543aa72009-07-29 04:35:08 +0900252struct ParamTraits<long long> {
253 typedef long long param_type;
rockot15c8ac42016-02-05 11:12:32 +0900254 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
255 sizer->AddInt64();
256 }
rockot6dbfea52016-02-04 05:20:16 +0900257 static void Write(base::Pickle* m, const param_type& p) {
tfarina1cbfa082015-09-05 03:47:57 +0900258 m->WriteInt64(static_cast<int64_t>(p));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900259 }
rockot6dbfea52016-02-04 05:20:16 +0900260 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900261 base::PickleIterator* iter,
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900262 param_type* r) {
tfarina1cbfa082015-09-05 03:47:57 +0900263 return iter->ReadInt64(reinterpret_cast<int64_t*>(r));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900264 }
darin@chromium.org80e4c5e2011-08-16 05:41:46 +0900265 IPC_EXPORT static void Log(const param_type& p, std::string* l);
deanm@chromium.org1543aa72009-07-29 04:35:08 +0900266};
267
268template <>
269struct ParamTraits<unsigned long long> {
270 typedef unsigned long long param_type;
rockot15c8ac42016-02-05 11:12:32 +0900271 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
272 sizer->AddInt64();
273 }
rockot6dbfea52016-02-04 05:20:16 +0900274 static void Write(base::Pickle* m, const param_type& p) { m->WriteInt64(p); }
275 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900276 base::PickleIterator* iter,
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900277 param_type* r) {
tfarina1cbfa082015-09-05 03:47:57 +0900278 return iter->ReadInt64(reinterpret_cast<int64_t*>(r));
deanm@chromium.org1543aa72009-07-29 04:35:08 +0900279 }
darin@chromium.org80e4c5e2011-08-16 05:41:46 +0900280 IPC_EXPORT static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900281};
282
jeremy@chromium.org4be619f2010-06-17 12:29:26 +0900283// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
284// should be sure to check the sanity of these values after receiving them over
285// IPC.
286template <>
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900287struct IPC_EXPORT ParamTraits<float> {
jeremy@chromium.org4be619f2010-06-17 12:29:26 +0900288 typedef float param_type;
rockot15c8ac42016-02-05 11:12:32 +0900289 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
290 sizer->AddFloat();
291 }
rockot6dbfea52016-02-04 05:20:16 +0900292 static void Write(base::Pickle* m, const param_type& p) { m->WriteFloat(p); }
293 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900294 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +0900295 param_type* r) {
avic9f0ad02014-12-29 08:31:48 +0900296 return iter->ReadFloat(r);
piman@chromium.orgdd413b42013-10-31 18:27:31 +0900297 }
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900298 static void Log(const param_type& p, std::string* l);
jeremy@chromium.org4be619f2010-06-17 12:29:26 +0900299};
300
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900301template <>
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900302struct IPC_EXPORT ParamTraits<double> {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900303 typedef double param_type;
rockot15c8ac42016-02-05 11:12:32 +0900304 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot6dbfea52016-02-04 05:20:16 +0900305 static void Write(base::Pickle* m, const param_type& p);
306 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900307 base::PickleIterator* iter,
308 param_type* r);
tsepez@chromium.org3081fac2012-05-31 06:15:57 +0900309 static void Log(const param_type& p, std::string* l);
310};
311
ericrk43a3bd52017-02-11 02:49:35 +0900312template <class P, size_t Size>
313struct ParamTraits<P[Size]> {
314 using param_type = P[Size];
315 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
316 for (const P& element : p)
317 GetParamSize(sizer, element);
318 }
319 static void Write(base::Pickle* m, const param_type& p) {
320 for (const P& element : p)
321 WriteParam(m, element);
322 }
323 static bool Read(const base::Pickle* m,
324 base::PickleIterator* iter,
325 param_type* r) {
326 for (P& element : *r) {
327 if (!ReadParam(m, iter, &element))
328 return false;
329 }
330 return true;
331 }
332 static void Log(const param_type& p, std::string* l) {
333 l->append("[");
334 for (const P& element : p) {
335 if (&element != &p[0])
336 l->append(" ");
337 LogParam(element, l);
338 }
339 l->append("]");
340 }
341};
342
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900343// STL ParamTraits -------------------------------------------------------------
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900344
345template <>
346struct ParamTraits<std::string> {
347 typedef std::string param_type;
rockot15c8ac42016-02-05 11:12:32 +0900348 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
349 sizer->AddString(p);
350 }
rockot6dbfea52016-02-04 05:20:16 +0900351 static void Write(base::Pickle* m, const param_type& p) { m->WriteString(p); }
352 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900353 base::PickleIterator* iter,
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900354 param_type* r) {
avic9f0ad02014-12-29 08:31:48 +0900355 return iter->ReadString(r);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900356 }
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900357 IPC_EXPORT static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900358};
359
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900360template <>
brettw@chromium.org5b040852013-12-03 09:39:26 +0900361struct ParamTraits<base::string16> {
362 typedef base::string16 param_type;
rockot15c8ac42016-02-05 11:12:32 +0900363 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
364 sizer->AddString16(p);
365 }
rockot6dbfea52016-02-04 05:20:16 +0900366 static void Write(base::Pickle* m, const param_type& p) {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900367 m->WriteString16(p);
368 }
rockot6dbfea52016-02-04 05:20:16 +0900369 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900370 base::PickleIterator* iter,
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900371 param_type* r) {
avic9f0ad02014-12-29 08:31:48 +0900372 return iter->ReadString16(r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900373 }
374 IPC_EXPORT static void Log(const param_type& p, std::string* l);
375};
evan@chromium.orga6590362009-07-28 06:09:07 +0900376
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900377template <>
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900378struct IPC_EXPORT ParamTraits<std::vector<char> > {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900379 typedef std::vector<char> param_type;
rockot15c8ac42016-02-05 11:12:32 +0900380 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot6dbfea52016-02-04 05:20:16 +0900381 static void Write(base::Pickle* m, const param_type& p);
382 static bool Read(const base::Pickle*,
brettwf3146202015-06-03 13:29:25 +0900383 base::PickleIterator* iter,
384 param_type* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900385 static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900386};
387
bauerb@chromium.org17246c72011-10-06 03:55:42 +0900388template <>
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900389struct IPC_EXPORT ParamTraits<std::vector<unsigned char> > {
390 typedef std::vector<unsigned char> param_type;
rockot15c8ac42016-02-05 11:12:32 +0900391 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot6dbfea52016-02-04 05:20:16 +0900392 static void Write(base::Pickle* m, const param_type& p);
393 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900394 base::PickleIterator* iter,
395 param_type* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900396 static void Log(const param_type& p, std::string* l);
397};
398
399template <>
400struct IPC_EXPORT ParamTraits<std::vector<bool> > {
bauerb@chromium.org17246c72011-10-06 03:55:42 +0900401 typedef std::vector<bool> param_type;
rockot15c8ac42016-02-05 11:12:32 +0900402 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot6dbfea52016-02-04 05:20:16 +0900403 static void Write(base::Pickle* m, const param_type& p);
404 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900405 base::PickleIterator* iter,
406 param_type* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900407 static void Log(const param_type& p, std::string* l);
bauerb@chromium.org17246c72011-10-06 03:55:42 +0900408};
409
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900410template <class P>
bmcquade11758372016-07-01 22:13:50 +0900411struct ParamTraits<std::vector<P>> {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900412 typedef std::vector<P> param_type;
rockot15c8ac42016-02-05 11:12:32 +0900413 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
414 GetParamSize(sizer, static_cast<int>(p.size()));
415 for (size_t i = 0; i < p.size(); i++)
416 GetParamSize(sizer, p[i]);
417 }
rockot6dbfea52016-02-04 05:20:16 +0900418 static void Write(base::Pickle* m, const param_type& p) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900419 WriteParam(m, static_cast<int>(p.size()));
420 for (size_t i = 0; i < p.size(); i++)
421 WriteParam(m, p[i]);
422 }
rockot6dbfea52016-02-04 05:20:16 +0900423 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900424 base::PickleIterator* iter,
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900425 param_type* r) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900426 int size;
cevans@chromium.org7600d942009-12-31 14:17:23 +0900427 // ReadLength() checks for < 0 itself.
avic9f0ad02014-12-29 08:31:48 +0900428 if (!iter->ReadLength(&size))
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900429 return false;
430 // Resizing beforehand is not safe, see BUG 1006367 for details.
cevans@chromium.org7600d942009-12-31 14:17:23 +0900431 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
432 return false;
433 r->resize(size);
434 for (int i = 0; i < size; i++) {
435 if (!ReadParam(m, iter, &(*r)[i]))
436 return false;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900437 }
438 return true;
439 }
erg@google.com8aca7272010-08-19 03:33:57 +0900440 static void Log(const param_type& p, std::string* l) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900441 for (size_t i = 0; i < p.size(); ++i) {
442 if (i != 0)
erg@google.com8aca7272010-08-19 03:33:57 +0900443 l->append(" ");
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900444 LogParam((p[i]), l);
445 }
446 }
447};
448
mirandac@chromium.orgee262ad2010-05-14 04:10:34 +0900449template <class P>
450struct ParamTraits<std::set<P> > {
451 typedef std::set<P> param_type;
rockot15c8ac42016-02-05 11:12:32 +0900452 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);
457 }
rockot6dbfea52016-02-04 05:20:16 +0900458 static void Write(base::Pickle* m, const param_type& p) {
mirandac@chromium.orgee262ad2010-05-14 04:10:34 +0900459 WriteParam(m, static_cast<int>(p.size()));
460 typename param_type::const_iterator iter;
461 for (iter = p.begin(); iter != p.end(); ++iter)
462 WriteParam(m, *iter);
463 }
rockot6dbfea52016-02-04 05:20:16 +0900464 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900465 base::PickleIterator* iter,
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900466 param_type* r) {
mirandac@chromium.orgee262ad2010-05-14 04:10:34 +0900467 int size;
avic9f0ad02014-12-29 08:31:48 +0900468 if (!iter->ReadLength(&size))
mirandac@chromium.orgee262ad2010-05-14 04:10:34 +0900469 return false;
470 for (int i = 0; i < size; ++i) {
471 P item;
472 if (!ReadParam(m, iter, &item))
473 return false;
474 r->insert(item);
475 }
476 return true;
477 }
erg@google.com8aca7272010-08-19 03:33:57 +0900478 static void Log(const param_type& p, std::string* l) {
479 l->append("<std::set>");
mirandac@chromium.orgee262ad2010-05-14 04:10:34 +0900480 }
481};
482
jkarlin45b11f92014-09-24 20:42:37 +0900483template <class K, class V, class C, class A>
484struct ParamTraits<std::map<K, V, C, A> > {
485 typedef std::map<K, V, C, A> param_type;
rockot15c8ac42016-02-05 11:12:32 +0900486 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
487 GetParamSize(sizer, static_cast<int>(p.size()));
488 typename param_type::const_iterator iter;
489 for (iter = p.begin(); iter != p.end(); ++iter) {
490 GetParamSize(sizer, iter->first);
491 GetParamSize(sizer, iter->second);
492 }
493 }
rockot6dbfea52016-02-04 05:20:16 +0900494 static void Write(base::Pickle* m, const param_type& p) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900495 WriteParam(m, static_cast<int>(p.size()));
496 typename param_type::const_iterator iter;
497 for (iter = p.begin(); iter != p.end(); ++iter) {
498 WriteParam(m, iter->first);
499 WriteParam(m, iter->second);
500 }
501 }
rockot6dbfea52016-02-04 05:20:16 +0900502 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900503 base::PickleIterator* iter,
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900504 param_type* r) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900505 int size;
506 if (!ReadParam(m, iter, &size) || size < 0)
507 return false;
508 for (int i = 0; i < size; ++i) {
509 K k;
510 if (!ReadParam(m, iter, &k))
511 return false;
512 V& value = (*r)[k];
513 if (!ReadParam(m, iter, &value))
514 return false;
515 }
516 return true;
517 }
erg@google.com8aca7272010-08-19 03:33:57 +0900518 static void Log(const param_type& p, std::string* l) {
519 l->append("<std::map>");
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900520 }
521};
522
jam@chromium.org0aa05022009-08-04 11:00:56 +0900523template <class A, class B>
524struct ParamTraits<std::pair<A, B> > {
525 typedef std::pair<A, B> param_type;
rockot15c8ac42016-02-05 11:12:32 +0900526 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
527 GetParamSize(sizer, p.first);
528 GetParamSize(sizer, p.second);
529 }
rockot6dbfea52016-02-04 05:20:16 +0900530 static void Write(base::Pickle* m, const param_type& p) {
jam@chromium.org0aa05022009-08-04 11:00:56 +0900531 WriteParam(m, p.first);
532 WriteParam(m, p.second);
533 }
rockot6dbfea52016-02-04 05:20:16 +0900534 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900535 base::PickleIterator* iter,
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900536 param_type* r) {
jam@chromium.org0aa05022009-08-04 11:00:56 +0900537 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
538 }
erg@google.com8aca7272010-08-19 03:33:57 +0900539 static void Log(const param_type& p, std::string* l) {
540 l->append("(");
jam@chromium.org0aa05022009-08-04 11:00:56 +0900541 LogParam(p.first, l);
erg@google.com8aca7272010-08-19 03:33:57 +0900542 l->append(", ");
jam@chromium.org0aa05022009-08-04 11:00:56 +0900543 LogParam(p.second, l);
erg@google.com8aca7272010-08-19 03:33:57 +0900544 l->append(")");
jam@chromium.org0aa05022009-08-04 11:00:56 +0900545 }
546};
547
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900548// Base ParamTraits ------------------------------------------------------------
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900549
550template <>
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900551struct IPC_EXPORT ParamTraits<base::DictionaryValue> {
552 typedef base::DictionaryValue param_type;
rockot15c8ac42016-02-05 11:12:32 +0900553 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot6dbfea52016-02-04 05:20:16 +0900554 static void Write(base::Pickle* m, const param_type& p);
555 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900556 base::PickleIterator* iter,
557 param_type* r);
erg@google.com8aca7272010-08-19 03:33:57 +0900558 static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900559};
560
561#if defined(OS_POSIX)
562// FileDescriptors may be serialised over IPC channels on POSIX. On the
563// receiving side, the FileDescriptor is a valid duplicate of the file
564// descriptor which was transmitted: *it is not just a copy of the integer like
565// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
566// this case, the receiving end will see a value of -1. *Zero is a valid file
567// descriptor*.
568//
569// The received file descriptor will have the |auto_close| flag set to true. The
570// code which handles the message is responsible for taking ownership of it.
571// File descriptors are OS resources and must be closed when no longer needed.
572//
573// When sending a file descriptor, the file descriptor must be valid at the time
574// of transmission. Since transmission is not synchronous, one should consider
575// dup()ing any file descriptors to be transmitted and setting the |auto_close|
576// flag, which causes the file descriptor to be closed after writing.
577template<>
darin@chromium.org80e4c5e2011-08-16 05:41:46 +0900578struct IPC_EXPORT ParamTraits<base::FileDescriptor> {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900579 typedef base::FileDescriptor param_type;
jam7f5c5742016-05-12 06:05:05 +0900580 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot6dbfea52016-02-04 05:20:16 +0900581 static void Write(base::Pickle* m, const param_type& p);
582 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900583 base::PickleIterator* iter,
584 param_type* r);
erg@google.com8aca7272010-08-19 03:33:57 +0900585 static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900586};
jhawkins@chromium.org63c75eb2010-03-09 09:38:41 +0900587#endif // defined(OS_POSIX)
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900588
scottmg81491272015-06-20 07:51:00 +0900589template <>
590struct IPC_EXPORT ParamTraits<base::SharedMemoryHandle> {
591 typedef base::SharedMemoryHandle param_type;
jam7f5c5742016-05-12 06:05:05 +0900592 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot6dbfea52016-02-04 05:20:16 +0900593 static void Write(base::Pickle* m, const param_type& p);
594 static bool Read(const base::Pickle* m,
595 base::PickleIterator* iter,
596 param_type* r);
scottmg81491272015-06-20 07:51:00 +0900597 static void Log(const param_type& p, std::string* l);
598};
scottmg81491272015-06-20 07:51:00 +0900599
erikchen9a454c12017-04-29 11:24:36 +0900600#if defined(OS_WIN)
601template <>
602struct IPC_EXPORT ParamTraits<PlatformFileForTransit> {
603 typedef PlatformFileForTransit param_type;
604 static void GetSize(base::PickleSizer* sizer, const param_type& p);
605 static void Write(base::Pickle* m, const param_type& p);
606 static bool Read(const base::Pickle* m,
607 base::PickleIterator* iter,
608 param_type* r);
609 static void Log(const param_type& p, std::string* l);
610};
611#endif // defined(OS_WIN)
612
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900613template <>
brettw@chromium.orga7086942013-02-02 14:12:33 +0900614struct IPC_EXPORT ParamTraits<base::FilePath> {
615 typedef base::FilePath param_type;
rockot15c8ac42016-02-05 11:12:32 +0900616 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot6dbfea52016-02-04 05:20:16 +0900617 static void Write(base::Pickle* m, const param_type& p);
618 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900619 base::PickleIterator* iter,
620 param_type* r);
erg@google.com8aca7272010-08-19 03:33:57 +0900621 static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900622};
623
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900624template <>
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900625struct IPC_EXPORT ParamTraits<base::ListValue> {
626 typedef base::ListValue param_type;
rockot15c8ac42016-02-05 11:12:32 +0900627 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot6dbfea52016-02-04 05:20:16 +0900628 static void Write(base::Pickle* m, const param_type& p);
629 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900630 base::PickleIterator* iter,
631 param_type* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900632 static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900633};
634
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900635template <>
avi@chromium.orgd8179652013-06-13 22:47:46 +0900636struct IPC_EXPORT ParamTraits<base::NullableString16> {
637 typedef base::NullableString16 param_type;
rockot15c8ac42016-02-05 11:12:32 +0900638 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot6dbfea52016-02-04 05:20:16 +0900639 static void Write(base::Pickle* m, const param_type& p);
640 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900641 base::PickleIterator* iter,
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900642 param_type* r);
643 static void Log(const param_type& p, std::string* l);
644};
645
646template <>
rvargas@chromium.org9e469f62014-01-28 06:36:00 +0900647struct IPC_EXPORT ParamTraits<base::File::Info> {
648 typedef base::File::Info param_type;
rockot15c8ac42016-02-05 11:12:32 +0900649 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot6dbfea52016-02-04 05:20:16 +0900650 static void Write(base::Pickle* m, const param_type& p);
651 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900652 base::PickleIterator* iter,
653 param_type* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900654 static void Log(const param_type& p, std::string* l);
655};
656
657template <>
rvargas@chromium.org9e469f62014-01-28 06:36:00 +0900658struct SimilarTypeTraits<base::File::Error> {
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900659 typedef int Type;
660};
661
grt@chromium.orgb9abb172013-03-01 06:46:11 +0900662#if defined(OS_WIN)
663template <>
664struct SimilarTypeTraits<HWND> {
665 typedef HANDLE Type;
666};
667#endif // defined(OS_WIN)
668
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900669template <>
670struct IPC_EXPORT ParamTraits<base::Time> {
671 typedef base::Time param_type;
rockot15c8ac42016-02-05 11:12:32 +0900672 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot6dbfea52016-02-04 05:20:16 +0900673 static void Write(base::Pickle* m, const param_type& p);
674 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900675 base::PickleIterator* iter,
676 param_type* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900677 static void Log(const param_type& p, std::string* l);
678};
679
680template <>
681struct IPC_EXPORT ParamTraits<base::TimeDelta> {
682 typedef base::TimeDelta param_type;
rockot15c8ac42016-02-05 11:12:32 +0900683 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot6dbfea52016-02-04 05:20:16 +0900684 static void Write(base::Pickle* m, const param_type& p);
685 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900686 base::PickleIterator* iter,
687 param_type* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900688 static void Log(const param_type& p, std::string* l);
689};
690
691template <>
692struct IPC_EXPORT ParamTraits<base::TimeTicks> {
693 typedef base::TimeTicks param_type;
rockot15c8ac42016-02-05 11:12:32 +0900694 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot6dbfea52016-02-04 05:20:16 +0900695 static void Write(base::Pickle* m, const param_type& p);
696 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900697 base::PickleIterator* iter,
698 param_type* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +0900699 static void Log(const param_type& p, std::string* l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900700};
701
702template <>
tguilbert76e690d2016-09-20 06:11:25 +0900703struct IPC_EXPORT ParamTraits<base::UnguessableToken> {
704 typedef base::UnguessableToken param_type;
705 static void GetSize(base::PickleSizer* sizer, const param_type& p);
706 static void Write(base::Pickle* m, const param_type& p);
707 static bool Read(const base::Pickle* m,
708 base::PickleIterator* iter,
709 param_type* r);
710 static void Log(const param_type& p, std::string* l);
711};
712
713template <>
tzik51faa092016-02-11 19:24:45 +0900714struct ParamTraits<std::tuple<>> {
715 typedef std::tuple<> param_type;
rockot15c8ac42016-02-05 11:12:32 +0900716 static void GetSize(base::PickleSizer* sizer, const param_type& p) {}
rockot6dbfea52016-02-04 05:20:16 +0900717 static void Write(base::Pickle* m, const param_type& p) {}
718 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900719 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +0900720 param_type* r) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900721 return true;
722 }
erg@google.com8aca7272010-08-19 03:33:57 +0900723 static void Log(const param_type& p, std::string* l) {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900724 }
725};
726
727template <class A>
tzik51faa092016-02-11 19:24:45 +0900728struct ParamTraits<std::tuple<A>> {
729 typedef std::tuple<A> param_type;
rockot15c8ac42016-02-05 11:12:32 +0900730 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
tzika088e352016-03-08 14:47:44 +0900731 GetParamSize(sizer, std::get<0>(p));
rockot15c8ac42016-02-05 11:12:32 +0900732 }
rockot6dbfea52016-02-04 05:20:16 +0900733 static void Write(base::Pickle* m, const param_type& p) {
tzika088e352016-03-08 14:47:44 +0900734 WriteParam(m, std::get<0>(p));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900735 }
rockot6dbfea52016-02-04 05:20:16 +0900736 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900737 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +0900738 param_type* r) {
tzika088e352016-03-08 14:47:44 +0900739 return ReadParam(m, iter, &std::get<0>(*r));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900740 }
erg@google.com8aca7272010-08-19 03:33:57 +0900741 static void Log(const param_type& p, std::string* l) {
tzika088e352016-03-08 14:47:44 +0900742 LogParam(std::get<0>(p), l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900743 }
744};
745
746template <class A, class B>
tzik51faa092016-02-11 19:24:45 +0900747struct ParamTraits<std::tuple<A, B>> {
748 typedef std::tuple<A, B> param_type;
rockot15c8ac42016-02-05 11:12:32 +0900749 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
tzika088e352016-03-08 14:47:44 +0900750 GetParamSize(sizer, std::get<0>(p));
751 GetParamSize(sizer, std::get<1>(p));
rockot15c8ac42016-02-05 11:12:32 +0900752 }
rockot6dbfea52016-02-04 05:20:16 +0900753 static void Write(base::Pickle* m, const param_type& p) {
tzika088e352016-03-08 14:47:44 +0900754 WriteParam(m, std::get<0>(p));
755 WriteParam(m, std::get<1>(p));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900756 }
rockot6dbfea52016-02-04 05:20:16 +0900757 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900758 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +0900759 param_type* r) {
tzika088e352016-03-08 14:47:44 +0900760 return (ReadParam(m, iter, &std::get<0>(*r)) &&
761 ReadParam(m, iter, &std::get<1>(*r)));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900762 }
erg@google.com8aca7272010-08-19 03:33:57 +0900763 static void Log(const param_type& p, std::string* l) {
tzika088e352016-03-08 14:47:44 +0900764 LogParam(std::get<0>(p), l);
erg@google.com8aca7272010-08-19 03:33:57 +0900765 l->append(", ");
tzika088e352016-03-08 14:47:44 +0900766 LogParam(std::get<1>(p), l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900767 }
768};
769
770template <class A, class B, class C>
tzik51faa092016-02-11 19:24:45 +0900771struct ParamTraits<std::tuple<A, B, C>> {
772 typedef std::tuple<A, B, C> param_type;
rockot15c8ac42016-02-05 11:12:32 +0900773 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
tzika088e352016-03-08 14:47:44 +0900774 GetParamSize(sizer, std::get<0>(p));
775 GetParamSize(sizer, std::get<1>(p));
776 GetParamSize(sizer, std::get<2>(p));
rockot15c8ac42016-02-05 11:12:32 +0900777 }
rockot6dbfea52016-02-04 05:20:16 +0900778 static void Write(base::Pickle* m, const param_type& p) {
tzika088e352016-03-08 14:47:44 +0900779 WriteParam(m, std::get<0>(p));
780 WriteParam(m, std::get<1>(p));
781 WriteParam(m, std::get<2>(p));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900782 }
rockot6dbfea52016-02-04 05:20:16 +0900783 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900784 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +0900785 param_type* r) {
tzika088e352016-03-08 14:47:44 +0900786 return (ReadParam(m, iter, &std::get<0>(*r)) &&
787 ReadParam(m, iter, &std::get<1>(*r)) &&
788 ReadParam(m, iter, &std::get<2>(*r)));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900789 }
erg@google.com8aca7272010-08-19 03:33:57 +0900790 static void Log(const param_type& p, std::string* l) {
tzika088e352016-03-08 14:47:44 +0900791 LogParam(std::get<0>(p), l);
erg@google.com8aca7272010-08-19 03:33:57 +0900792 l->append(", ");
tzika088e352016-03-08 14:47:44 +0900793 LogParam(std::get<1>(p), l);
erg@google.com8aca7272010-08-19 03:33:57 +0900794 l->append(", ");
tzika088e352016-03-08 14:47:44 +0900795 LogParam(std::get<2>(p), l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900796 }
797};
798
799template <class A, class B, class C, class D>
tzik51faa092016-02-11 19:24:45 +0900800struct ParamTraits<std::tuple<A, B, C, D>> {
801 typedef std::tuple<A, B, C, D> param_type;
rockot15c8ac42016-02-05 11:12:32 +0900802 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
tzika088e352016-03-08 14:47:44 +0900803 GetParamSize(sizer, std::get<0>(p));
804 GetParamSize(sizer, std::get<1>(p));
805 GetParamSize(sizer, std::get<2>(p));
806 GetParamSize(sizer, std::get<3>(p));
rockot15c8ac42016-02-05 11:12:32 +0900807 }
rockot6dbfea52016-02-04 05:20:16 +0900808 static void Write(base::Pickle* m, const param_type& p) {
tzika088e352016-03-08 14:47:44 +0900809 WriteParam(m, std::get<0>(p));
810 WriteParam(m, std::get<1>(p));
811 WriteParam(m, std::get<2>(p));
812 WriteParam(m, std::get<3>(p));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900813 }
rockot6dbfea52016-02-04 05:20:16 +0900814 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900815 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +0900816 param_type* r) {
tzika088e352016-03-08 14:47:44 +0900817 return (ReadParam(m, iter, &std::get<0>(*r)) &&
818 ReadParam(m, iter, &std::get<1>(*r)) &&
819 ReadParam(m, iter, &std::get<2>(*r)) &&
820 ReadParam(m, iter, &std::get<3>(*r)));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900821 }
erg@google.com8aca7272010-08-19 03:33:57 +0900822 static void Log(const param_type& p, std::string* l) {
tzika088e352016-03-08 14:47:44 +0900823 LogParam(std::get<0>(p), l);
erg@google.com8aca7272010-08-19 03:33:57 +0900824 l->append(", ");
tzika088e352016-03-08 14:47:44 +0900825 LogParam(std::get<1>(p), l);
erg@google.com8aca7272010-08-19 03:33:57 +0900826 l->append(", ");
tzika088e352016-03-08 14:47:44 +0900827 LogParam(std::get<2>(p), l);
erg@google.com8aca7272010-08-19 03:33:57 +0900828 l->append(", ");
tzika088e352016-03-08 14:47:44 +0900829 LogParam(std::get<3>(p), l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900830 }
831};
832
833template <class A, class B, class C, class D, class E>
tzik51faa092016-02-11 19:24:45 +0900834struct ParamTraits<std::tuple<A, B, C, D, E>> {
835 typedef std::tuple<A, B, C, D, E> param_type;
rockot15c8ac42016-02-05 11:12:32 +0900836 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
tzika088e352016-03-08 14:47:44 +0900837 GetParamSize(sizer, std::get<0>(p));
838 GetParamSize(sizer, std::get<1>(p));
839 GetParamSize(sizer, std::get<2>(p));
840 GetParamSize(sizer, std::get<3>(p));
841 GetParamSize(sizer, std::get<4>(p));
rockot15c8ac42016-02-05 11:12:32 +0900842 }
rockot6dbfea52016-02-04 05:20:16 +0900843 static void Write(base::Pickle* m, const param_type& p) {
tzika088e352016-03-08 14:47:44 +0900844 WriteParam(m, std::get<0>(p));
845 WriteParam(m, std::get<1>(p));
846 WriteParam(m, std::get<2>(p));
847 WriteParam(m, std::get<3>(p));
848 WriteParam(m, std::get<4>(p));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900849 }
rockot6dbfea52016-02-04 05:20:16 +0900850 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900851 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +0900852 param_type* r) {
tzika088e352016-03-08 14:47:44 +0900853 return (ReadParam(m, iter, &std::get<0>(*r)) &&
854 ReadParam(m, iter, &std::get<1>(*r)) &&
855 ReadParam(m, iter, &std::get<2>(*r)) &&
856 ReadParam(m, iter, &std::get<3>(*r)) &&
857 ReadParam(m, iter, &std::get<4>(*r)));
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900858 }
erg@google.com8aca7272010-08-19 03:33:57 +0900859 static void Log(const param_type& p, std::string* l) {
tzika088e352016-03-08 14:47:44 +0900860 LogParam(std::get<0>(p), l);
erg@google.com8aca7272010-08-19 03:33:57 +0900861 l->append(", ");
tzika088e352016-03-08 14:47:44 +0900862 LogParam(std::get<1>(p), l);
erg@google.com8aca7272010-08-19 03:33:57 +0900863 l->append(", ");
tzika088e352016-03-08 14:47:44 +0900864 LogParam(std::get<2>(p), l);
erg@google.com8aca7272010-08-19 03:33:57 +0900865 l->append(", ");
tzika088e352016-03-08 14:47:44 +0900866 LogParam(std::get<3>(p), l);
erg@google.com8aca7272010-08-19 03:33:57 +0900867 l->append(", ");
tzika088e352016-03-08 14:47:44 +0900868 LogParam(std::get<4>(p), l);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900869 }
870};
871
miletusd41fe222015-07-24 04:42:36 +0900872template <class P, size_t stack_capacity>
873struct ParamTraits<base::StackVector<P, stack_capacity> > {
874 typedef base::StackVector<P, stack_capacity> param_type;
rockot15c8ac42016-02-05 11:12:32 +0900875 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
876 GetParamSize(sizer, static_cast<int>(p->size()));
877 for (size_t i = 0; i < p->size(); i++)
878 GetParamSize(sizer, p[i]);
879 }
rockot6dbfea52016-02-04 05:20:16 +0900880 static void Write(base::Pickle* m, const param_type& p) {
miletusd41fe222015-07-24 04:42:36 +0900881 WriteParam(m, static_cast<int>(p->size()));
882 for (size_t i = 0; i < p->size(); i++)
883 WriteParam(m, p[i]);
884 }
rockot6dbfea52016-02-04 05:20:16 +0900885 static bool Read(const base::Pickle* m,
miletusd41fe222015-07-24 04:42:36 +0900886 base::PickleIterator* iter,
887 param_type* r) {
888 int size;
889 // ReadLength() checks for < 0 itself.
890 if (!iter->ReadLength(&size))
891 return false;
892 // Sanity check for the vector size.
893 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
894 return false;
895 P value;
896 for (int i = 0; i < size; i++) {
897 if (!ReadParam(m, iter, &value))
898 return false;
899 (*r)->push_back(value);
900 }
901 return true;
902 }
903 static void Log(const param_type& p, std::string* l) {
904 for (size_t i = 0; i < p->size(); ++i) {
905 if (i != 0)
906 l->append(" ");
907 LogParam((p[i]), l);
908 }
909 }
910};
911
jdduke@chromium.org556db8b2014-03-19 05:48:35 +0900912template <typename NormalMap,
913 int kArraySize,
914 typename EqualKey,
915 typename MapInit>
brettwd3d9de02017-04-20 15:10:20 +0900916struct ParamTraits<base::small_map<NormalMap, kArraySize, EqualKey, MapInit>> {
917 using param_type = base::small_map<NormalMap, kArraySize, EqualKey, MapInit>;
918 using K = typename param_type::key_type;
919 using V = typename param_type::data_type;
rockot15c8ac42016-02-05 11:12:32 +0900920 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
921 GetParamSize(sizer, static_cast<int>(p.size()));
922 typename param_type::const_iterator iter;
923 for (iter = p.begin(); iter != p.end(); ++iter) {
924 GetParamSize(sizer, iter->first);
925 GetParamSize(sizer, iter->second);
926 }
927 }
rockot6dbfea52016-02-04 05:20:16 +0900928 static void Write(base::Pickle* m, const param_type& p) {
jdduke@chromium.org556db8b2014-03-19 05:48:35 +0900929 WriteParam(m, static_cast<int>(p.size()));
930 typename param_type::const_iterator iter;
931 for (iter = p.begin(); iter != p.end(); ++iter) {
932 WriteParam(m, iter->first);
933 WriteParam(m, iter->second);
934 }
935 }
rockot6dbfea52016-02-04 05:20:16 +0900936 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +0900937 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +0900938 param_type* r) {
jdduke@chromium.org556db8b2014-03-19 05:48:35 +0900939 int size;
avic9f0ad02014-12-29 08:31:48 +0900940 if (!iter->ReadLength(&size))
jdduke@chromium.org556db8b2014-03-19 05:48:35 +0900941 return false;
942 for (int i = 0; i < size; ++i) {
943 K key;
944 if (!ReadParam(m, iter, &key))
945 return false;
946 V& value = (*r)[key];
947 if (!ReadParam(m, iter, &value))
948 return false;
949 }
950 return true;
951 }
952 static void Log(const param_type& p, std::string* l) {
brettwd3d9de02017-04-20 15:10:20 +0900953 l->append("<base::small_map>");
954 }
955};
956
957template <class Key, class Mapped, class Compare>
958struct ParamTraits<base::flat_map<Key, Mapped, Compare>> {
959 using param_type = base::flat_map<Key, Mapped, Compare>;
960 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
961 DCHECK(base::IsValueInRangeForNumericType<int>(p.size()));
962 GetParamSize(sizer, static_cast<int>(p.size()));
963 for (const auto& iter : p) {
964 GetParamSize(sizer, iter.first);
965 GetParamSize(sizer, iter.second);
966 }
967 }
968 static void Write(base::Pickle* m, const param_type& p) {
969 DCHECK(base::IsValueInRangeForNumericType<int>(p.size()));
970 WriteParam(m, static_cast<int>(p.size()));
971 for (const auto& iter : p) {
972 WriteParam(m, iter.first);
973 WriteParam(m, iter.second);
974 }
975 }
976 static bool Read(const base::Pickle* m,
977 base::PickleIterator* iter,
978 param_type* r) {
979 int size;
980 if (!iter->ReadLength(&size))
981 return false;
982
983 // Construct by creating in a vector and moving into the flat_map. Properly
984 // serialized flat_maps will be in-order so this will be O(n). Incorrectly
985 // serialized ones will still be handled properly.
986 std::vector<typename param_type::value_type> vect;
987 vect.resize(size);
988 for (int i = 0; i < size; ++i) {
989 if (!ReadParam(m, iter, &vect[i].first))
990 return false;
991 if (!ReadParam(m, iter, &vect[i].second))
992 return false;
993 }
994
995 *r = param_type(std::move(vect), base::KEEP_FIRST_OF_DUPES);
996 return true;
997 }
998 static void Log(const param_type& p, std::string* l) {
999 l->append("<base::flat_map>");
jdduke@chromium.org556db8b2014-03-19 05:48:35 +09001000 }
1001};
1002
jdduke@chromium.orgc6d80f02014-05-20 11:34:56 +09001003template <class P>
danakjc3fb6c52016-04-23 13:21:09 +09001004struct ParamTraits<std::unique_ptr<P>> {
1005 typedef std::unique_ptr<P> param_type;
rockot15c8ac42016-02-05 11:12:32 +09001006 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
1007 bool valid = !!p;
1008 GetParamSize(sizer, valid);
1009 if (valid)
1010 GetParamSize(sizer, *p);
1011 }
rockot6dbfea52016-02-04 05:20:16 +09001012 static void Write(base::Pickle* m, const param_type& p) {
jdduke@chromium.orgc6d80f02014-05-20 11:34:56 +09001013 bool valid = !!p;
1014 WriteParam(m, valid);
1015 if (valid)
1016 WriteParam(m, *p);
1017 }
rockot6dbfea52016-02-04 05:20:16 +09001018 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +09001019 base::PickleIterator* iter,
brettwa4879472015-06-02 16:02:47 +09001020 param_type* r) {
jdduke@chromium.orgc6d80f02014-05-20 11:34:56 +09001021 bool valid = false;
1022 if (!ReadParam(m, iter, &valid))
1023 return false;
1024
1025 if (!valid) {
1026 r->reset();
1027 return true;
1028 }
1029
1030 param_type temp(new P());
1031 if (!ReadParam(m, iter, temp.get()))
1032 return false;
1033
1034 r->swap(temp);
1035 return true;
1036 }
1037 static void Log(const param_type& p, std::string* l) {
1038 if (p)
1039 LogParam(*p, l);
1040 else
1041 l->append("NULL");
1042 }
1043};
1044
bmcquade11758372016-07-01 22:13:50 +09001045template <class P>
1046struct ParamTraits<base::Optional<P>> {
1047 typedef base::Optional<P> param_type;
1048 static void GetSize(base::PickleSizer* sizer, const param_type& p) {
1049 const bool is_set = static_cast<bool>(p);
1050 GetParamSize(sizer, is_set);
1051 if (is_set)
1052 GetParamSize(sizer, p.value());
1053 }
1054 static void Write(base::Pickle* m, const param_type& p) {
1055 const bool is_set = static_cast<bool>(p);
1056 WriteParam(m, is_set);
1057 if (is_set)
1058 WriteParam(m, p.value());
1059 }
1060 static bool Read(const base::Pickle* m,
1061 base::PickleIterator* iter,
1062 param_type* r) {
1063 bool is_set = false;
1064 if (!iter->ReadBool(&is_set))
1065 return false;
1066 if (is_set) {
1067 P value;
1068 if (!ReadParam(m, iter, &value))
1069 return false;
1070 *r = std::move(value);
1071 }
1072 return true;
1073 }
1074 static void Log(const param_type& p, std::string* l) {
1075 if (p)
1076 LogParam(p.value(), l);
1077 else
1078 l->append("(unset)");
1079 }
1080};
1081
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001082// IPC types ParamTraits -------------------------------------------------------
1083
1084// A ChannelHandle is basically a platform-inspecific wrapper around the
1085// fact that IPC endpoints are handled specially on POSIX. See above comments
1086// on FileDescriptor for more background.
1087template<>
1088struct IPC_EXPORT ParamTraits<IPC::ChannelHandle> {
1089 typedef ChannelHandle param_type;
jam1ea1e0d2016-05-14 00:09:58 +09001090 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot6dbfea52016-02-04 05:20:16 +09001091 static void Write(base::Pickle* m, const param_type& p);
1092 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +09001093 base::PickleIterator* iter,
1094 param_type* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001095 static void Log(const param_type& p, std::string* l);
1096};
1097
1098template <>
1099struct IPC_EXPORT ParamTraits<LogData> {
1100 typedef LogData param_type;
rockot15c8ac42016-02-05 11:12:32 +09001101 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot6dbfea52016-02-04 05:20:16 +09001102 static void Write(base::Pickle* m, const param_type& p);
1103 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +09001104 base::PickleIterator* iter,
1105 param_type* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001106 static void Log(const param_type& p, std::string* l);
1107};
1108
1109template <>
1110struct IPC_EXPORT ParamTraits<Message> {
rockot6dbfea52016-02-04 05:20:16 +09001111 static void Write(base::Pickle* m, const Message& p);
1112 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +09001113 base::PickleIterator* iter,
1114 Message* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001115 static void Log(const Message& p, std::string* l);
1116};
1117
1118// Windows ParamTraits ---------------------------------------------------------
1119
1120#if defined(OS_WIN)
1121template <>
1122struct IPC_EXPORT ParamTraits<HANDLE> {
1123 typedef HANDLE param_type;
rockot15c8ac42016-02-05 11:12:32 +09001124 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot6dbfea52016-02-04 05:20:16 +09001125 static void Write(base::Pickle* m, const param_type& p);
1126 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +09001127 base::PickleIterator* iter,
1128 param_type* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001129 static void Log(const param_type& p, std::string* l);
1130};
1131
1132template <>
1133struct IPC_EXPORT ParamTraits<LOGFONT> {
1134 typedef LOGFONT param_type;
rockot15c8ac42016-02-05 11:12:32 +09001135 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot6dbfea52016-02-04 05:20:16 +09001136 static void Write(base::Pickle* m, const param_type& p);
1137 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +09001138 base::PickleIterator* iter,
1139 param_type* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001140 static void Log(const param_type& p, std::string* l);
1141};
1142
1143template <>
1144struct IPC_EXPORT ParamTraits<MSG> {
1145 typedef MSG param_type;
rockot15c8ac42016-02-05 11:12:32 +09001146 static void GetSize(base::PickleSizer* sizer, const param_type& p);
rockot6dbfea52016-02-04 05:20:16 +09001147 static void Write(base::Pickle* m, const param_type& p);
1148 static bool Read(const base::Pickle* m,
brettwf3146202015-06-03 13:29:25 +09001149 base::PickleIterator* iter,
1150 param_type* r);
brettw@chromium.orgce352e52012-06-05 06:18:25 +09001151 static void Log(const param_type& p, std::string* l);
1152};
1153#endif // defined(OS_WIN)
1154
agl@chromium.org1c6dcf22009-07-23 08:57:21 +09001155//-----------------------------------------------------------------------------
1156// Generic message subclasses
1157
erg@google.come6ffcb52010-08-18 03:38:24 +09001158// defined in ipc_logging.cc
sammc65f302f2016-11-15 09:34:36 +09001159IPC_EXPORT void GenerateLogData(const Message& message,
1160 LogData* data,
1161 bool get_params);
erg@google.come6ffcb52010-08-18 03:38:24 +09001162
davidsz3bf38eb2017-05-12 18:19:23 +09001163#if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
erg@google.com8aca7272010-08-19 03:33:57 +09001164inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
1165 const std::string& output_params = msg->output_params();
erg@google.come6ffcb52010-08-18 03:38:24 +09001166 if (!l->empty() && !output_params.empty())
erg@google.com8aca7272010-08-19 03:33:57 +09001167 l->append(", ");
erg@google.come6ffcb52010-08-18 03:38:24 +09001168
1169 l->append(output_params);
1170}
1171
1172template <class ReplyParamType>
1173inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1174 const Message* msg) {
1175 if (msg->received_time() != 0) {
erg@google.com8aca7272010-08-19 03:33:57 +09001176 std::string output_params;
erg@google.come6ffcb52010-08-18 03:38:24 +09001177 LogParam(reply_params, &output_params);
1178 msg->set_output_params(output_params);
1179 }
1180}
1181
1182inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
1183 if (msg->sent_time()) {
1184 // Don't log the sync message after dispatch, as we don't have the
1185 // output parameters at that point. Instead, save its data and log it
1186 // with the outgoing reply message when it's sent.
1187 LogData* data = new LogData;
sammc65f302f2016-11-15 09:34:36 +09001188 GenerateLogData(*msg, data, true);
erg@google.come6ffcb52010-08-18 03:38:24 +09001189 msg->set_dont_log();
1190 reply->set_sync_log_data(data);
1191 }
1192}
1193#else
erg@google.com8aca7272010-08-19 03:33:57 +09001194inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
erg@google.come6ffcb52010-08-18 03:38:24 +09001195
1196template <class ReplyParamType>
1197inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1198 const Message* msg) {}
1199
1200inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1201#endif
1202
agl@chromium.org1c6dcf22009-07-23 08:57:21 +09001203} // namespace IPC
1204
1205#endif // IPC_IPC_MESSAGE_UTILS_H_