blob: 47546141f1d52ce3565903d0a256193d05556e02 [file] [log] [blame]
Avi Drissmanea1be232022-09-14 23:29:061// Copyright 2012 The Chromium Authors
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]946d1b22009-07-22 23:57:215#ifndef IPC_IPC_MESSAGE_UTILS_H_
6#define IPC_IPC_MESSAGE_UTILS_H_
initial.commit09911bf2008-07-26 23:55:297
avi51ba3e692015-12-26 17:30:508#include <limits.h>
avi246998d82015-12-22 02:39:049#include <stddef.h>
tfarina10a5c062015-09-04 18:47:5710#include <stdint.h>
11
initial.commit09911bf2008-07-26 23:55:2912#include <map>
danakj03de39b22016-04-23 04:21:0913#include <memory>
[email protected]96da6962010-05-13 19:10:3414#include <set>
[email protected]663bd9e2011-03-21 01:07:0115#include <string>
tzik55e3e4d2016-03-08 05:47:4416#include <tuple>
Stuart Langley48300392017-11-02 03:54:4417#include <unordered_map>
[email protected]663bd9e2011-03-21 01:07:0118#include <vector>
initial.commit09911bf2008-07-26 23:55:2919
Lei Zhang5226db72022-01-25 03:38:5520#include "base/check.h"
21#include "base/compiler_specific.h"
Ken Rockot3044d212018-01-23 02:44:3922#include "base/component_export.h"
brettwca2ec7632017-04-20 06:10:2023#include "base/containers/flat_map.h"
miletus1edf97f92015-07-23 19:42:3624#include "base/containers/stack_container.h"
[email protected]141bcc52014-01-27 21:36:0025#include "base/files/file.h"
Alexandr Ilind497eee2018-04-19 22:50:5426#include "base/memory/platform_shared_memory_region.h"
27#include "base/memory/read_only_shared_memory_region.h"
Alexandr Ilind497eee2018-04-19 22:50:5428#include "base/memory/unsafe_shared_memory_region.h"
29#include "base/memory/writable_shared_memory_region.h"
brettwca2ec7632017-04-20 06:10:2030#include "base/numerics/safe_conversions.h"
Lei Zhang5226db72022-01-25 03:38:5531#include "base/pickle.h"
Albert J. Wong1b6dc962021-07-09 18:06:5732#include "base/types/id_type.h"
Fabrice de Gans43eebf702022-04-01 23:43:0433#include "base/values.h"
avi246998d82015-12-22 02:39:0434#include "build/build_config.h"
Lei Zhang5226db72022-01-25 03:38:5535#include "ipc/ipc_buildflags.h"
[email protected]939856a2010-08-24 20:29:0236#include "ipc/ipc_param_traits.h"
Anton Bikineev1f42a452021-05-15 18:02:5037#include "third_party/abseil-cpp/absl/types/optional.h"
[email protected]55b4e212010-08-13 20:43:5838
Xiaohan Wangab909b32022-01-12 17:57:3939#if BUILDFLAG(IS_ANDROID)
Ken Rockot097248f02018-04-23 16:23:3440#include "base/android/scoped_hardware_buffer_handle.h"
41#endif
42
Xiaohan Wangab909b32022-01-12 17:57:3943#if BUILDFLAG(IS_FUCHSIA)
Sergey Ulanov7b343ff2019-08-15 07:52:3744#include <lib/zx/channel.h>
45#include <lib/zx/vmo.h>
46#endif
47
Lei Zhang5226db72022-01-25 03:38:5548#if BUILDFLAG(IS_WIN)
49#include "base/strings/string_util_win.h"
50#endif
51
52#if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
53#include "ipc/ipc_message.h"
54#endif
55
[email protected]7a4de7a62010-08-17 18:38:2456namespace base {
[email protected]a3ef4832013-02-02 05:12:3357class FilePath;
[email protected]7a4de7a62010-08-17 18:38:2458class Time;
[email protected]d84e48b2010-10-21 22:04:5259class TimeDelta;
[email protected]1d14f582011-09-02 20:42:0460class TimeTicks;
tguilbert4a5ac602016-09-19 21:11:2561class UnguessableToken;
[email protected]7a4de7a62010-08-17 18:38:2462struct FileDescriptor;
Fabrice de Gans43eebf702022-04-01 23:43:0463} // namespace base
[email protected]7a4de7a62010-08-17 18:38:2464
initial.commit09911bf2008-07-26 23:55:2965namespace IPC {
66
Lei Zhang5226db72022-01-25 03:38:5567class Message;
[email protected]7a4de7a62010-08-17 18:38:2468struct ChannelHandle;
69
Xiaohan Wangab909b32022-01-12 17:57:3970#if BUILDFLAG(IS_WIN)
erikchend804e1052017-04-29 02:24:3671class PlatformFileForTransit;
72#endif
73
[email protected]bf5aedf02012-06-04 21:18:2574// -----------------------------------------------------------------------------
75// How we send IPC message logs across channels.
Ken Rockot3044d212018-01-23 02:44:3976struct COMPONENT_EXPORT(IPC) LogData {
[email protected]bf5aedf02012-06-04 21:18:2577 LogData();
vmpstrbf0d713a2016-03-24 20:22:5478 LogData(const LogData& other);
[email protected]bf5aedf02012-06-04 21:18:2579 ~LogData();
80
81 std::string channel;
tfarina10a5c062015-09-04 18:47:5782 int32_t routing_id;
83 uint32_t type; // "User-defined" message type, from ipc_message.h.
[email protected]bf5aedf02012-06-04 21:18:2584 std::string flags;
tfarina10a5c062015-09-04 18:47:5785 int64_t sent; // Time that the message was sent (i.e. at Send()).
86 int64_t receive; // Time before it was dispatched (i.e. before calling
87 // OnMessageReceived).
88 int64_t dispatch; // Time after it was dispatched (i.e. after calling
89 // OnMessageReceived).
[email protected]bf5aedf02012-06-04 21:18:2590 std::string message_name;
91 std::string params;
92};
93
initial.commit09911bf2008-07-26 23:55:2994//-----------------------------------------------------------------------------
[email protected]7edae3d02012-12-17 20:23:4795
[email protected]6476c72c2011-02-11 18:46:1996// A dummy struct to place first just to allow leading commas for all
97// members in the macro-generated constructor initializer lists.
98struct NoParams {
99};
100
dskiba2bc89462016-04-06 15:51:06101// Specializations are checked by 'IPC checker' part of find-bad-constructs
102// Clang plugin (see WriteParam() below for the details).
103template <typename... Ts>
104struct CheckedTuple {
105 typedef std::tuple<Ts...> Tuple;
106};
107
dskiba2bc89462016-04-06 15:51:06108// This function is checked by 'IPC checker' part of find-bad-constructs
109// Clang plugin to make it's not called on the following types:
110// 1. long / unsigned long (but not typedefs to)
111// 2. intmax_t, uintmax_t, intptr_t, uintptr_t, wint_t,
112// size_t, rsize_t, ssize_t, ptrdiff_t, dev_t, off_t, clock_t,
113// time_t, suseconds_t (including typedefs to)
114// 3. Any template referencing types above (e.g. std::vector<size_t>)
rockot0457af102016-02-05 02:12:32115template <class P>
Sajjad Mirza9e4a469e2021-01-28 18:30:39116inline void WriteParam(base::Pickle* m, const P& p) {
[email protected]7b291f92009-08-14 05:43:53117 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53118 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
[email protected]7d5c3ac2009-02-04 08:58:19119}
120
121template <class P>
Daniel Chenge618e802022-01-14 18:56:52122[[nodiscard]] inline bool ReadParam(const base::Pickle* m,
123 base::PickleIterator* iter,
124 P* p) {
[email protected]7b291f92009-08-14 05:43:53125 typedef typename SimilarTypeTraits<P>::Type Type;
126 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
[email protected]7d5c3ac2009-02-04 08:58:19127}
128
129template <class P>
Sajjad Mirza9e4a469e2021-01-28 18:30:39130inline void LogParam(const P& p, std::string* l) {
[email protected]7b291f92009-08-14 05:43:53131 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53132 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19133}
134
[email protected]bf5aedf02012-06-04 21:18:25135// Primitive ParamTraits -------------------------------------------------------
136
[email protected]7d5c3ac2009-02-04 08:58:19137template <>
138struct ParamTraits<bool> {
139 typedef bool param_type;
rockot502c94f2016-02-03 20:20:16140 static void Write(base::Pickle* m, const param_type& p) { m->WriteBool(p); }
141 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25142 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47143 param_type* r) {
avi48fc13b2014-12-28 23:31:48144 return iter->ReadBool(r);
[email protected]7d5c3ac2009-02-04 08:58:19145 }
Ken Rockot3044d212018-01-23 02:44:39146 COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19147};
148
149template <>
Ken Rockot3044d212018-01-23 02:44:39150struct COMPONENT_EXPORT(IPC) ParamTraits<signed char> {
ortuno19ecf1842015-10-30 00:46:20151 typedef signed char param_type;
rockot502c94f2016-02-03 20:20:16152 static void Write(base::Pickle* m, const param_type& p);
153 static bool Read(const base::Pickle* m,
154 base::PickleIterator* iter,
155 param_type* r);
ortuno19ecf1842015-10-30 00:46:20156 static void Log(const param_type& p, std::string* l);
157};
158
159template <>
Ken Rockot3044d212018-01-23 02:44:39160struct COMPONENT_EXPORT(IPC) ParamTraits<unsigned char> {
[email protected]7bea7352013-07-13 04:42:10161 typedef unsigned char param_type;
rockot502c94f2016-02-03 20:20:16162 static void Write(base::Pickle* m, const param_type& p);
163 static bool Read(const base::Pickle* m,
164 base::PickleIterator* iter,
165 param_type* r);
[email protected]c1ee48d2013-07-12 23:12:28166 static void Log(const param_type& p, std::string* l);
167};
168
169template <>
Ken Rockot3044d212018-01-23 02:44:39170struct COMPONENT_EXPORT(IPC) ParamTraits<unsigned short> {
[email protected]c1ee48d2013-07-12 23:12:28171 typedef unsigned short param_type;
rockot502c94f2016-02-03 20:20:16172 static void Write(base::Pickle* m, const param_type& p);
173 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25174 base::PickleIterator* iter,
175 param_type* r);
[email protected]c1ee48d2013-07-12 23:12:28176 static void Log(const param_type& p, std::string* l);
177};
178
179template <>
[email protected]7d5c3ac2009-02-04 08:58:19180struct ParamTraits<int> {
181 typedef int param_type;
rockot502c94f2016-02-03 20:20:16182 static void Write(base::Pickle* m, const param_type& p) { m->WriteInt(p); }
183 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25184 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47185 param_type* r) {
avi48fc13b2014-12-28 23:31:48186 return iter->ReadInt(r);
[email protected]7d5c3ac2009-02-04 08:58:19187 }
Ken Rockot3044d212018-01-23 02:44:39188 COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19189};
190
191template <>
[email protected]63263f92009-07-28 19:35:08192struct ParamTraits<unsigned int> {
193 typedef unsigned int param_type;
Peter Kasting7064abb2022-08-11 18:11:38194 static void Write(base::Pickle* m, const param_type& p) {
195 m->WriteInt(static_cast<int>(p));
196 }
rockot502c94f2016-02-03 20:20:16197 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25198 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47199 param_type* r) {
avi48fc13b2014-12-28 23:31:48200 return iter->ReadInt(reinterpret_cast<int*>(r));
[email protected]63263f92009-07-28 19:35:08201 }
Ken Rockot3044d212018-01-23 02:44:39202 COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08203};
204
jam03d8a782016-02-10 20:13:39205// long isn't safe to send over IPC because it's 4 bytes on 32 bit builds but
206// 8 bytes on 64 bit builds. So if a 32 bit and 64 bit process have a channel
207// that would cause problem.
208// We need to keep this on for a few configs:
209// 1) Windows because DWORD is typedef'd to it, which is fine because we have
210// very few IPCs that cross this boundary.
211// 2) We also need to keep it for Linux for two reasons: int64_t is typedef'd
212// to long, and gfx::PluginWindow is long and is used in one GPU IPC.
Scott Grahamf4b38b42017-06-19 23:09:33213// 3) Android 64 bit and Fuchsia also have int64_t typedef'd to long.
jam03d8a782016-02-10 20:13:39214// Since we want to support Android 32<>64 bit IPC, as long as we don't have
215// these traits for 32 bit ARM then that'll catch any errors.
Xiaohan Wangab909b32022-01-12 17:57:39216#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
217 BUILDFLAG(IS_FUCHSIA) || \
218 (BUILDFLAG(IS_ANDROID) && defined(ARCH_CPU_64_BITS))
[email protected]63263f92009-07-28 19:35:08219template <>
[email protected]7d5c3ac2009-02-04 08:58:19220struct ParamTraits<long> {
221 typedef long param_type;
rockot502c94f2016-02-03 20:20:16222 static void Write(base::Pickle* m, const param_type& p) {
jam03d8a782016-02-10 20:13:39223 m->WriteLong(p);
[email protected]7d5c3ac2009-02-04 08:58:19224 }
rockot502c94f2016-02-03 20:20:16225 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25226 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47227 param_type* r) {
avi48fc13b2014-12-28 23:31:48228 return iter->ReadLong(r);
[email protected]7d5c3ac2009-02-04 08:58:19229 }
Ken Rockot3044d212018-01-23 02:44:39230 COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19231};
232
[email protected]140c3032009-06-26 18:22:54233template <>
234struct ParamTraits<unsigned long> {
235 typedef unsigned long param_type;
rockot502c94f2016-02-03 20:20:16236 static void Write(base::Pickle* m, const param_type& p) {
jam03d8a782016-02-10 20:13:39237 m->WriteLong(p);
[email protected]140c3032009-06-26 18:22:54238 }
rockot502c94f2016-02-03 20:20:16239 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25240 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47241 param_type* r) {
avi48fc13b2014-12-28 23:31:48242 return iter->ReadLong(reinterpret_cast<long*>(r));
[email protected]140c3032009-06-26 18:22:54243 }
Ken Rockot3044d212018-01-23 02:44:39244 COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19245};
jam03d8a782016-02-10 20:13:39246#endif
[email protected]7d5c3ac2009-02-04 08:58:19247
248template <>
[email protected]63263f92009-07-28 19:35:08249struct ParamTraits<long long> {
250 typedef long long param_type;
rockot502c94f2016-02-03 20:20:16251 static void Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:57252 m->WriteInt64(static_cast<int64_t>(p));
[email protected]7d5c3ac2009-02-04 08:58:19253 }
rockot502c94f2016-02-03 20:20:16254 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25255 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:56256 param_type* r) {
tfarina10a5c062015-09-04 18:47:57257 return iter->ReadInt64(reinterpret_cast<int64_t*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19258 }
Ken Rockot3044d212018-01-23 02:44:39259 COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08260};
261
262template <>
263struct ParamTraits<unsigned long long> {
264 typedef unsigned long long param_type;
Peter Kasting7064abb2022-08-11 18:11:38265 static void Write(base::Pickle* m, const param_type& p) {
266 m->WriteInt64(static_cast<int64_t>(p));
267 }
rockot502c94f2016-02-03 20:20:16268 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25269 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:56270 param_type* r) {
tfarina10a5c062015-09-04 18:47:57271 return iter->ReadInt64(reinterpret_cast<int64_t*>(r));
[email protected]63263f92009-07-28 19:35:08272 }
Ken Rockot3044d212018-01-23 02:44:39273 COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19274};
275
[email protected]20199662010-06-17 03:29:26276// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
277// should be sure to check the sanity of these values after receiving them over
278// IPC.
279template <>
Ken Rockot3044d212018-01-23 02:44:39280struct COMPONENT_EXPORT(IPC) ParamTraits<float> {
[email protected]20199662010-06-17 03:29:26281 typedef float param_type;
rockot502c94f2016-02-03 20:20:16282 static void Write(base::Pickle* m, const param_type& p) { m->WriteFloat(p); }
283 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25284 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47285 param_type* r) {
avi48fc13b2014-12-28 23:31:48286 return iter->ReadFloat(r);
[email protected]48328ff2013-10-31 09:27:31287 }
[email protected]bf5aedf02012-06-04 21:18:25288 static void Log(const param_type& p, std::string* l);
[email protected]20199662010-06-17 03:29:26289};
290
[email protected]7d5c3ac2009-02-04 08:58:19291template <>
Ken Rockot3044d212018-01-23 02:44:39292struct COMPONENT_EXPORT(IPC) ParamTraits<double> {
[email protected]7d5c3ac2009-02-04 08:58:19293 typedef double param_type;
rockot502c94f2016-02-03 20:20:16294 static void Write(base::Pickle* m, const param_type& p);
295 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25296 base::PickleIterator* iter,
297 param_type* r);
[email protected]c410e022012-05-30 21:15:57298 static void Log(const param_type& p, std::string* l);
299};
300
ericrkb5de4602017-02-10 17:49:35301template <class P, size_t Size>
302struct ParamTraits<P[Size]> {
303 using param_type = P[Size];
ericrkb5de4602017-02-10 17:49:35304 static void Write(base::Pickle* m, const param_type& p) {
305 for (const P& element : p)
306 WriteParam(m, element);
307 }
308 static bool Read(const base::Pickle* m,
309 base::PickleIterator* iter,
310 param_type* r) {
311 for (P& element : *r) {
312 if (!ReadParam(m, iter, &element))
313 return false;
314 }
315 return true;
316 }
317 static void Log(const param_type& p, std::string* l) {
318 l->append("[");
319 for (const P& element : p) {
320 if (&element != &p[0])
321 l->append(" ");
322 LogParam(element, l);
323 }
324 l->append("]");
325 }
326};
327
[email protected]bf5aedf02012-06-04 21:18:25328// STL ParamTraits -------------------------------------------------------------
[email protected]584f2b22009-05-21 01:01:59329
330template <>
[email protected]7d5c3ac2009-02-04 08:58:19331struct ParamTraits<std::string> {
332 typedef std::string param_type;
rockot502c94f2016-02-03 20:20:16333 static void Write(base::Pickle* m, const param_type& p) { m->WriteString(p); }
334 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25335 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:56336 param_type* r) {
avi48fc13b2014-12-28 23:31:48337 return iter->ReadString(r);
[email protected]7d5c3ac2009-02-04 08:58:19338 }
Ken Rockot3044d212018-01-23 02:44:39339 COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19340};
341
[email protected]bf5aedf02012-06-04 21:18:25342template <>
Jan Wilken Dörrie739ccc212021-03-11 18:13:05343struct ParamTraits<std::u16string> {
344 typedef std::u16string param_type;
rockot502c94f2016-02-03 20:20:16345 static void Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25346 m->WriteString16(p);
347 }
rockot502c94f2016-02-03 20:20:16348 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25349 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25350 param_type* r) {
avi48fc13b2014-12-28 23:31:48351 return iter->ReadString16(r);
[email protected]bf5aedf02012-06-04 21:18:25352 }
Ken Rockot3044d212018-01-23 02:44:39353 COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
[email protected]bf5aedf02012-06-04 21:18:25354};
[email protected]3dd7a7a2009-07-27 21:09:07355
Xiaohan Wangab909b32022-01-12 17:57:39356#if BUILDFLAG(IS_WIN)
Jan Wilken Dörriecf5a66902020-12-07 20:51:31357template <>
Peter Kasting31fa0f22021-02-01 21:28:20358struct COMPONENT_EXPORT(IPC) ParamTraits<std::wstring> {
Jan Wilken Dörriecf5a66902020-12-07 20:51:31359 typedef std::wstring param_type;
360 static void Write(base::Pickle* m, const param_type& p) {
361 m->WriteString16(base::AsStringPiece16(p));
362 }
363 static bool Read(const base::Pickle* m,
364 base::PickleIterator* iter,
365 param_type* r);
Peter Kasting31fa0f22021-02-01 21:28:20366 static void Log(const param_type& p, std::string* l);
Jan Wilken Dörriecf5a66902020-12-07 20:51:31367};
368#endif
369
[email protected]7d5c3ac2009-02-04 08:58:19370template <>
Ken Rockot3044d212018-01-23 02:44:39371struct COMPONENT_EXPORT(IPC) ParamTraits<std::vector<char>> {
[email protected]7d5c3ac2009-02-04 08:58:19372 typedef std::vector<char> param_type;
rockot502c94f2016-02-03 20:20:16373 static void Write(base::Pickle* m, const param_type& p);
374 static bool Read(const base::Pickle*,
brettwbd4d7112015-06-03 04:29:25375 base::PickleIterator* iter,
376 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25377 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19378};
379
[email protected]51b63f62011-10-05 18:55:42380template <>
Ken Rockot3044d212018-01-23 02:44:39381struct COMPONENT_EXPORT(IPC) ParamTraits<std::vector<unsigned char>> {
[email protected]bf5aedf02012-06-04 21:18:25382 typedef std::vector<unsigned char> param_type;
rockot502c94f2016-02-03 20:20:16383 static void Write(base::Pickle* m, const param_type& p);
384 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25385 base::PickleIterator* iter,
386 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25387 static void Log(const param_type& p, std::string* l);
388};
389
390template <>
Ken Rockot3044d212018-01-23 02:44:39391struct COMPONENT_EXPORT(IPC) ParamTraits<std::vector<bool>> {
[email protected]51b63f62011-10-05 18:55:42392 typedef std::vector<bool> param_type;
rockot502c94f2016-02-03 20:20:16393 static void Write(base::Pickle* m, const param_type& p);
394 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25395 base::PickleIterator* iter,
396 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25397 static void Log(const param_type& p, std::string* l);
[email protected]51b63f62011-10-05 18:55:42398};
399
[email protected]7d5c3ac2009-02-04 08:58:19400template <class P>
bmcquade18573e12016-07-01 13:13:50401struct ParamTraits<std::vector<P>> {
[email protected]7d5c3ac2009-02-04 08:58:19402 typedef std::vector<P> param_type;
rockot502c94f2016-02-03 20:20:16403 static void Write(base::Pickle* m, const param_type& p) {
Chris Palmerc5ea9b92017-09-25 22:53:22404 WriteParam(m, base::checked_cast<int>(p.size()));
[email protected]7d5c3ac2009-02-04 08:58:19405 for (size_t i = 0; i < p.size(); i++)
406 WriteParam(m, p[i]);
407 }
rockot502c94f2016-02-03 20:20:16408 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25409 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:56410 param_type* r) {
Peter Kasting28b51cf2022-06-28 15:02:43411 size_t size;
[email protected]86440f52009-12-31 05:17:23412 // ReadLength() checks for < 0 itself.
avi48fc13b2014-12-28 23:31:48413 if (!iter->ReadLength(&size))
[email protected]7d5c3ac2009-02-04 08:58:19414 return false;
415 // Resizing beforehand is not safe, see BUG 1006367 for details.
Peter Kasting28b51cf2022-06-28 15:02:43416 if (size > INT_MAX / sizeof(P))
[email protected]86440f52009-12-31 05:17:23417 return false;
418 r->resize(size);
Peter Kasting28b51cf2022-06-28 15:02:43419 for (size_t i = 0; i < size; i++) {
[email protected]86440f52009-12-31 05:17:23420 if (!ReadParam(m, iter, &(*r)[i]))
421 return false;
[email protected]7d5c3ac2009-02-04 08:58:19422 }
423 return true;
424 }
[email protected]252cad62010-08-18 18:33:57425 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19426 for (size_t i = 0; i < p.size(); ++i) {
427 if (i != 0)
[email protected]252cad62010-08-18 18:33:57428 l->append(" ");
[email protected]7d5c3ac2009-02-04 08:58:19429 LogParam((p[i]), l);
430 }
431 }
432};
433
[email protected]96da6962010-05-13 19:10:34434template <class P>
435struct ParamTraits<std::set<P> > {
436 typedef std::set<P> param_type;
rockot502c94f2016-02-03 20:20:16437 static void Write(base::Pickle* m, const param_type& p) {
Chris Palmerc5ea9b92017-09-25 22:53:22438 WriteParam(m, base::checked_cast<int>(p.size()));
[email protected]96da6962010-05-13 19:10:34439 typename param_type::const_iterator iter;
440 for (iter = p.begin(); iter != p.end(); ++iter)
441 WriteParam(m, *iter);
442 }
rockot502c94f2016-02-03 20:20:16443 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25444 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:56445 param_type* r) {
Peter Kasting28b51cf2022-06-28 15:02:43446 size_t size;
avi48fc13b2014-12-28 23:31:48447 if (!iter->ReadLength(&size))
[email protected]96da6962010-05-13 19:10:34448 return false;
Peter Kasting28b51cf2022-06-28 15:02:43449 for (size_t i = 0; i < size; ++i) {
[email protected]96da6962010-05-13 19:10:34450 P item;
451 if (!ReadParam(m, iter, &item))
452 return false;
453 r->insert(item);
454 }
455 return true;
456 }
[email protected]252cad62010-08-18 18:33:57457 static void Log(const param_type& p, std::string* l) {
458 l->append("<std::set>");
[email protected]96da6962010-05-13 19:10:34459 }
460};
461
jkarlinf96d19ba2014-09-24 11:42:37462template <class K, class V, class C, class A>
463struct ParamTraits<std::map<K, V, C, A> > {
464 typedef std::map<K, V, C, A> param_type;
rockot502c94f2016-02-03 20:20:16465 static void Write(base::Pickle* m, const param_type& p) {
Chris Palmerc5ea9b92017-09-25 22:53:22466 WriteParam(m, base::checked_cast<int>(p.size()));
Stuart Langley48300392017-11-02 03:54:44467 for (const auto& iter : p) {
468 WriteParam(m, iter.first);
469 WriteParam(m, iter.second);
[email protected]7d5c3ac2009-02-04 08:58:19470 }
471 }
rockot502c94f2016-02-03 20:20:16472 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25473 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:56474 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19475 int size;
476 if (!ReadParam(m, iter, &size) || size < 0)
477 return false;
478 for (int i = 0; i < size; ++i) {
479 K k;
480 if (!ReadParam(m, iter, &k))
481 return false;
482 V& value = (*r)[k];
483 if (!ReadParam(m, iter, &value))
484 return false;
485 }
486 return true;
487 }
[email protected]252cad62010-08-18 18:33:57488 static void Log(const param_type& p, std::string* l) {
489 l->append("<std::map>");
[email protected]7d5c3ac2009-02-04 08:58:19490 }
491};
492
Stuart Langley48300392017-11-02 03:54:44493template <class K, class V, class C, class A>
494struct ParamTraits<std::unordered_map<K, V, C, A>> {
495 typedef std::unordered_map<K, V, C, A> param_type;
496 static void Write(base::Pickle* m, const param_type& p) {
497 WriteParam(m, base::checked_cast<int>(p.size()));
498 for (const auto& iter : p) {
499 WriteParam(m, iter.first);
500 WriteParam(m, iter.second);
501 }
502 }
503 static bool Read(const base::Pickle* m,
504 base::PickleIterator* iter,
505 param_type* r) {
506 int size;
507 if (!ReadParam(m, iter, &size) || size < 0)
508 return false;
509 for (int i = 0; i < size; ++i) {
510 K k;
511 if (!ReadParam(m, iter, &k))
512 return false;
513 V& value = (*r)[k];
514 if (!ReadParam(m, iter, &value))
515 return false;
516 }
517 return true;
518 }
519 static void Log(const param_type& p, std::string* l) {
520 l->append("<std::unordered_map>");
521 }
522};
523
[email protected]a5da6d612009-08-04 02:00:56524template <class A, class B>
525struct ParamTraits<std::pair<A, B> > {
526 typedef std::pair<A, B> param_type;
rockot502c94f2016-02-03 20:20:16527 static void Write(base::Pickle* m, const param_type& p) {
[email protected]a5da6d612009-08-04 02:00:56528 WriteParam(m, p.first);
529 WriteParam(m, p.second);
530 }
rockot502c94f2016-02-03 20:20:16531 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25532 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:56533 param_type* r) {
[email protected]a5da6d612009-08-04 02:00:56534 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
535 }
[email protected]252cad62010-08-18 18:33:57536 static void Log(const param_type& p, std::string* l) {
537 l->append("(");
[email protected]a5da6d612009-08-04 02:00:56538 LogParam(p.first, l);
[email protected]252cad62010-08-18 18:33:57539 l->append(", ");
[email protected]a5da6d612009-08-04 02:00:56540 LogParam(p.second, l);
[email protected]252cad62010-08-18 18:33:57541 l->append(")");
[email protected]a5da6d612009-08-04 02:00:56542 }
543};
544
[email protected]bf5aedf02012-06-04 21:18:25545// Base ParamTraits ------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19546
547template <>
Fabrice de Gans43eebf702022-04-01 23:43:04548struct COMPONENT_EXPORT(IPC) ParamTraits<base::Value::Dict> {
549 typedef base::Value::Dict param_type;
550 static void Write(base::Pickle* m, const param_type& p);
551 static bool Read(const base::Pickle* m,
552 base::PickleIterator* iter,
553 param_type* r);
554 static void Log(const param_type& p, std::string* l);
555};
556
Xiaohan Wangab909b32022-01-12 17:57:39557#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
[email protected]2749885f2009-03-05 21:40:11558// FileDescriptors may be serialised over IPC channels on POSIX. On the
559// receiving side, the FileDescriptor is a valid duplicate of the file
560// descriptor which was transmitted: *it is not just a copy of the integer like
561// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
562// this case, the receiving end will see a value of -1. *Zero is a valid file
563// descriptor*.
564//
565// The received file descriptor will have the |auto_close| flag set to true. The
566// code which handles the message is responsible for taking ownership of it.
567// File descriptors are OS resources and must be closed when no longer needed.
568//
569// When sending a file descriptor, the file descriptor must be valid at the time
570// of transmission. Since transmission is not synchronous, one should consider
571// dup()ing any file descriptors to be transmitted and setting the |auto_close|
572// flag, which causes the file descriptor to be closed after writing.
Ken Rockot3044d212018-01-23 02:44:39573template <>
574struct COMPONENT_EXPORT(IPC) ParamTraits<base::FileDescriptor> {
[email protected]5fe733de2009-02-11 18:59:20575 typedef base::FileDescriptor param_type;
rockot502c94f2016-02-03 20:20:16576 static void Write(base::Pickle* m, const param_type& p);
577 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25578 base::PickleIterator* iter,
579 param_type* r);
[email protected]252cad62010-08-18 18:33:57580 static void Log(const param_type& p, std::string* l);
[email protected]526776c2009-02-07 00:39:26581};
Sergey Ulanovac89bb92019-03-22 18:46:49582
583template <>
584struct COMPONENT_EXPORT(IPC) ParamTraits<base::ScopedFD> {
585 typedef base::ScopedFD param_type;
586 static void Write(base::Pickle* m, const param_type& p);
587 static bool Read(const base::Pickle* m,
588 base::PickleIterator* iter,
589 param_type* r);
590 static void Log(const param_type& p, std::string* l);
591};
592
Xiaohan Wangab909b32022-01-12 17:57:39593#endif // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
[email protected]526776c2009-02-07 00:39:26594
Xiaohan Wangab909b32022-01-12 17:57:39595#if BUILDFLAG(IS_WIN)
Robert Sesek02910662020-02-28 20:15:51596template <>
597struct COMPONENT_EXPORT(IPC) ParamTraits<base::win::ScopedHandle> {
598 using param_type = base::win::ScopedHandle;
599 static void Write(base::Pickle* m, const param_type& p);
600 static bool Read(const base::Pickle* m,
601 base::PickleIterator* iter,
602 param_type* r);
603 static void Log(const param_type& p, std::string* l);
604};
605#endif
606
Xiaohan Wangab909b32022-01-12 17:57:39607#if BUILDFLAG(IS_FUCHSIA)
Sergey Ulanova97f3282019-04-17 01:27:34608template <>
609struct COMPONENT_EXPORT(IPC) ParamTraits<zx::vmo> {
610 typedef zx::vmo param_type;
611 static void Write(base::Pickle* m, const param_type& p);
612 static bool Read(const base::Pickle* m,
613 base::PickleIterator* iter,
614 param_type* r);
615 static void Log(const param_type& p, std::string* l);
616};
Sergey Ulanov7b343ff2019-08-15 07:52:37617
618template <>
619struct COMPONENT_EXPORT(IPC) ParamTraits<zx::channel> {
620 typedef zx::channel param_type;
621 static void Write(base::Pickle* m, const param_type& p);
622 static bool Read(const base::Pickle* m,
623 base::PickleIterator* iter,
624 param_type* r);
625 static void Log(const param_type& p, std::string* l);
626};
Xiaohan Wangab909b32022-01-12 17:57:39627#endif // BUILDFLAG(IS_FUCHSIA)
Sergey Ulanova97f3282019-04-17 01:27:34628
Xiaohan Wangab909b32022-01-12 17:57:39629#if BUILDFLAG(IS_ANDROID)
Klaus Weidner3824a8882017-11-03 06:24:57630template <>
Alexandr Ilin0443a8f2018-07-20 20:14:50631struct COMPONENT_EXPORT(IPC)
632 ParamTraits<base::android::ScopedHardwareBufferHandle> {
633 typedef base::android::ScopedHardwareBufferHandle param_type;
Klaus Weidner3824a8882017-11-03 06:24:57634 static void Write(base::Pickle* m, const param_type& p);
635 static bool Read(const base::Pickle* m,
636 base::PickleIterator* iter,
637 param_type* r);
638 static void Log(const param_type& p, std::string* l);
639};
640#endif
641
Alexandr Ilind497eee2018-04-19 22:50:54642template <>
643struct COMPONENT_EXPORT(IPC) ParamTraits<base::ReadOnlySharedMemoryRegion> {
644 typedef base::ReadOnlySharedMemoryRegion param_type;
645 static void Write(base::Pickle* m, const param_type& p);
646 static bool Read(const base::Pickle* m,
647 base::PickleIterator* iter,
648 param_type* r);
649 static void Log(const param_type& p, std::string* l);
650};
651
652template <>
653struct COMPONENT_EXPORT(IPC) ParamTraits<base::WritableSharedMemoryRegion> {
654 typedef base::WritableSharedMemoryRegion param_type;
655 static void Write(base::Pickle* m, const param_type& p);
656 static bool Read(const base::Pickle* m,
657 base::PickleIterator* iter,
658 param_type* r);
659 static void Log(const param_type& p, std::string* l);
660};
661
662template <>
663struct COMPONENT_EXPORT(IPC) ParamTraits<base::UnsafeSharedMemoryRegion> {
664 typedef base::UnsafeSharedMemoryRegion param_type;
665 static void Write(base::Pickle* m, const param_type& p);
666 static bool Read(const base::Pickle* m,
667 base::PickleIterator* iter,
668 param_type* r);
669 static void Log(const param_type& p, std::string* l);
670};
671
672template <>
673struct COMPONENT_EXPORT(IPC)
674 ParamTraits<base::subtle::PlatformSharedMemoryRegion> {
675 typedef base::subtle::PlatformSharedMemoryRegion param_type;
676 static void Write(base::Pickle* m, const param_type& p);
677 static bool Read(const base::Pickle* m,
678 base::PickleIterator* iter,
679 param_type* r);
680 static void Log(const param_type& p, std::string* l);
681};
682
683template <>
684struct COMPONENT_EXPORT(IPC)
685 ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode> {
686 typedef base::subtle::PlatformSharedMemoryRegion::Mode param_type;
687 static void Write(base::Pickle* m, const param_type& p);
688 static bool Read(const base::Pickle* m,
689 base::PickleIterator* iter,
690 param_type* r);
691 static void Log(const param_type& p, std::string* l);
692};
693
Xiaohan Wangab909b32022-01-12 17:57:39694#if BUILDFLAG(IS_WIN)
erikchend804e1052017-04-29 02:24:36695template <>
Ken Rockot3044d212018-01-23 02:44:39696struct COMPONENT_EXPORT(IPC) ParamTraits<PlatformFileForTransit> {
erikchend804e1052017-04-29 02:24:36697 typedef PlatformFileForTransit param_type;
erikchend804e1052017-04-29 02:24:36698 static void Write(base::Pickle* m, const param_type& p);
699 static bool Read(const base::Pickle* m,
700 base::PickleIterator* iter,
701 param_type* r);
702 static void Log(const param_type& p, std::string* l);
703};
Xiaohan Wangab909b32022-01-12 17:57:39704#endif // BUILDFLAG(IS_WIN)
erikchend804e1052017-04-29 02:24:36705
[email protected]bf5aedf02012-06-04 21:18:25706template <>
Ken Rockot3044d212018-01-23 02:44:39707struct COMPONENT_EXPORT(IPC) ParamTraits<base::FilePath> {
[email protected]a3ef4832013-02-02 05:12:33708 typedef base::FilePath param_type;
rockot502c94f2016-02-03 20:20:16709 static void Write(base::Pickle* m, const param_type& p);
710 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25711 base::PickleIterator* iter,
712 param_type* r);
[email protected]252cad62010-08-18 18:33:57713 static void Log(const param_type& p, std::string* l);
[email protected]d2e884d2009-06-22 20:37:52714};
715
[email protected]7d5c3ac2009-02-04 08:58:19716template <>
Fabrice de Gans43eebf702022-04-01 23:43:04717struct COMPONENT_EXPORT(IPC) ParamTraits<base::Value::List> {
718 typedef base::Value::List param_type;
719 static void Write(base::Pickle* m, const param_type& p);
720 static bool Read(const base::Pickle* m,
721 base::PickleIterator* iter,
722 param_type* r);
723 static void Log(const param_type& p, std::string* l);
724};
725
726template <>
Devlin Cronin7178a5bd2021-02-02 02:56:47727struct COMPONENT_EXPORT(IPC) ParamTraits<base::Value> {
728 typedef base::Value param_type;
729 static void Write(base::Pickle* m, const param_type& p);
730 static bool Read(const base::Pickle* m,
731 base::PickleIterator* iter,
732 param_type* r);
733 static void Log(const param_type& p, std::string* l);
734};
735
736template <>
Ken Rockot3044d212018-01-23 02:44:39737struct COMPONENT_EXPORT(IPC) ParamTraits<base::File::Info> {
[email protected]141bcc52014-01-27 21:36:00738 typedef base::File::Info param_type;
rockot502c94f2016-02-03 20:20:16739 static void Write(base::Pickle* m, const param_type& p);
740 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25741 base::PickleIterator* iter,
742 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25743 static void Log(const param_type& p, std::string* l);
744};
745
746template <>
[email protected]141bcc52014-01-27 21:36:00747struct SimilarTypeTraits<base::File::Error> {
[email protected]bf5aedf02012-06-04 21:18:25748 typedef int Type;
749};
750
Xiaohan Wangab909b32022-01-12 17:57:39751#if BUILDFLAG(IS_WIN)
[email protected]ecf59c72013-02-28 21:46:11752template <>
753struct SimilarTypeTraits<HWND> {
754 typedef HANDLE Type;
755};
Xiaohan Wangab909b32022-01-12 17:57:39756#endif // BUILDFLAG(IS_WIN)
[email protected]ecf59c72013-02-28 21:46:11757
[email protected]bf5aedf02012-06-04 21:18:25758template <>
Ken Rockot3044d212018-01-23 02:44:39759struct COMPONENT_EXPORT(IPC) ParamTraits<base::Time> {
[email protected]bf5aedf02012-06-04 21:18:25760 typedef base::Time param_type;
rockot502c94f2016-02-03 20:20:16761 static void Write(base::Pickle* m, const param_type& p);
762 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25763 base::PickleIterator* iter,
764 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25765 static void Log(const param_type& p, std::string* l);
766};
767
768template <>
Ken Rockot3044d212018-01-23 02:44:39769struct COMPONENT_EXPORT(IPC) ParamTraits<base::TimeDelta> {
[email protected]bf5aedf02012-06-04 21:18:25770 typedef base::TimeDelta param_type;
rockot502c94f2016-02-03 20:20:16771 static void Write(base::Pickle* m, const param_type& p);
772 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25773 base::PickleIterator* iter,
774 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25775 static void Log(const param_type& p, std::string* l);
776};
777
778template <>
Ken Rockot3044d212018-01-23 02:44:39779struct COMPONENT_EXPORT(IPC) ParamTraits<base::TimeTicks> {
[email protected]bf5aedf02012-06-04 21:18:25780 typedef base::TimeTicks param_type;
rockot502c94f2016-02-03 20:20:16781 static void Write(base::Pickle* m, const param_type& p);
782 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25783 base::PickleIterator* iter,
784 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25785 static void Log(const param_type& p, std::string* l);
[email protected]503683f2009-02-26 09:13:01786};
787
788template <>
Ken Rockot3044d212018-01-23 02:44:39789struct COMPONENT_EXPORT(IPC) ParamTraits<base::UnguessableToken> {
tguilbert4a5ac602016-09-19 21:11:25790 typedef base::UnguessableToken param_type;
tguilbert4a5ac602016-09-19 21:11:25791 static void Write(base::Pickle* m, const param_type& p);
792 static bool Read(const base::Pickle* m,
793 base::PickleIterator* iter,
794 param_type* r);
795 static void Log(const param_type& p, std::string* l);
796};
797
798template <>
tzik9ca302192016-02-11 10:24:45799struct ParamTraits<std::tuple<>> {
800 typedef std::tuple<> param_type;
rockot502c94f2016-02-03 20:20:16801 static void Write(base::Pickle* m, const param_type& p) {}
802 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25803 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47804 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19805 return true;
806 }
[email protected]252cad62010-08-18 18:33:57807 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19808 }
809};
810
ossufdd19a32017-06-22 09:35:39811template <typename T, int index, int count>
812struct TupleParamTraitsHelper {
813 using Next = TupleParamTraitsHelper<T, index + 1, count>;
814
ossufdd19a32017-06-22 09:35:39815 static void Write(base::Pickle* m, const T& p) {
816 WriteParam(m, std::get<index>(p));
817 Next::Write(m, p);
[email protected]7d5c3ac2009-02-04 08:58:19818 }
ossufdd19a32017-06-22 09:35:39819
820 static bool Read(const base::Pickle* m, base::PickleIterator* iter, T* r) {
821 return ReadParam(m, iter, &std::get<index>(*r)) && Next::Read(m, iter, r);
[email protected]7d5c3ac2009-02-04 08:58:19822 }
ossufdd19a32017-06-22 09:35:39823
824 static void Log(const T& p, std::string* l) {
825 LogParam(std::get<index>(p), l);
826 if (index < count - 1)
827 l->append(", ");
828 Next::Log(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19829 }
830};
831
ossufdd19a32017-06-22 09:35:39832template <typename T, int index>
833struct TupleParamTraitsHelper<T, index, index> {
ossufdd19a32017-06-22 09:35:39834 static void Write(base::Pickle* m, const T& p) {}
835 static bool Read(const base::Pickle* m, base::PickleIterator* iter, T* r) {
836 return true;
rockot0457af102016-02-05 02:12:32837 }
ossufdd19a32017-06-22 09:35:39838 static void Log(const T& p, std::string* l) {}
[email protected]7d5c3ac2009-02-04 08:58:19839};
840
ossufdd19a32017-06-22 09:35:39841template <typename... Args>
842struct ParamTraits<std::tuple<Args...>> {
843 using param_type = std::tuple<Args...>;
844 using Helper =
845 TupleParamTraitsHelper<param_type, 0, std::tuple_size<param_type>::value>;
[email protected]7d5c3ac2009-02-04 08:58:19846
rockot502c94f2016-02-03 20:20:16847 static void Write(base::Pickle* m, const param_type& p) {
ossufdd19a32017-06-22 09:35:39848 Helper::Write(m, p);
[email protected]7d5c3ac2009-02-04 08:58:19849 }
ossufdd19a32017-06-22 09:35:39850
rockot502c94f2016-02-03 20:20:16851 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25852 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47853 param_type* r) {
ossufdd19a32017-06-22 09:35:39854 return Helper::Read(m, iter, r);
[email protected]7d5c3ac2009-02-04 08:58:19855 }
ossufdd19a32017-06-22 09:35:39856
857 static void Log(const param_type& p, std::string* l) { Helper::Log(p, l); }
[email protected]7d5c3ac2009-02-04 08:58:19858};
859
miletus1edf97f92015-07-23 19:42:36860template <class P, size_t stack_capacity>
861struct ParamTraits<base::StackVector<P, stack_capacity> > {
862 typedef base::StackVector<P, stack_capacity> param_type;
rockot502c94f2016-02-03 20:20:16863 static void Write(base::Pickle* m, const param_type& p) {
Chris Palmerc5ea9b92017-09-25 22:53:22864 WriteParam(m, base::checked_cast<int>(p->size()));
miletus1edf97f92015-07-23 19:42:36865 for (size_t i = 0; i < p->size(); i++)
866 WriteParam(m, p[i]);
867 }
rockot502c94f2016-02-03 20:20:16868 static bool Read(const base::Pickle* m,
miletus1edf97f92015-07-23 19:42:36869 base::PickleIterator* iter,
870 param_type* r) {
Peter Kasting28b51cf2022-06-28 15:02:43871 size_t size;
miletus1edf97f92015-07-23 19:42:36872 if (!iter->ReadLength(&size))
873 return false;
874 // Sanity check for the vector size.
Peter Kasting28b51cf2022-06-28 15:02:43875 if (size > INT_MAX / sizeof(P))
miletus1edf97f92015-07-23 19:42:36876 return false;
877 P value;
Peter Kasting28b51cf2022-06-28 15:02:43878 for (size_t i = 0; i < size; i++) {
miletus1edf97f92015-07-23 19:42:36879 if (!ReadParam(m, iter, &value))
880 return false;
881 (*r)->push_back(value);
882 }
883 return true;
884 }
885 static void Log(const param_type& p, std::string* l) {
886 for (size_t i = 0; i < p->size(); ++i) {
887 if (i != 0)
888 l->append(" ");
889 LogParam((p[i]), l);
890 }
891 }
892};
893
brettwca2ec7632017-04-20 06:10:20894template <class Key, class Mapped, class Compare>
895struct ParamTraits<base::flat_map<Key, Mapped, Compare>> {
896 using param_type = base::flat_map<Key, Mapped, Compare>;
brettwca2ec7632017-04-20 06:10:20897 static void Write(base::Pickle* m, const param_type& p) {
898 DCHECK(base::IsValueInRangeForNumericType<int>(p.size()));
Chris Palmerc5ea9b92017-09-25 22:53:22899 WriteParam(m, base::checked_cast<int>(p.size()));
brettwca2ec7632017-04-20 06:10:20900 for (const auto& iter : p) {
901 WriteParam(m, iter.first);
902 WriteParam(m, iter.second);
903 }
904 }
905 static bool Read(const base::Pickle* m,
906 base::PickleIterator* iter,
907 param_type* r) {
Peter Kasting28b51cf2022-06-28 15:02:43908 size_t size;
brettwca2ec7632017-04-20 06:10:20909 if (!iter->ReadLength(&size))
910 return false;
911
912 // Construct by creating in a vector and moving into the flat_map. Properly
913 // serialized flat_maps will be in-order so this will be O(n). Incorrectly
914 // serialized ones will still be handled properly.
915 std::vector<typename param_type::value_type> vect;
916 vect.resize(size);
Peter Kasting28b51cf2022-06-28 15:02:43917 for (size_t i = 0; i < size; ++i) {
brettwca2ec7632017-04-20 06:10:20918 if (!ReadParam(m, iter, &vect[i].first))
919 return false;
920 if (!ReadParam(m, iter, &vect[i].second))
921 return false;
922 }
923
Jan Wilken Dörrie5e5c02f2019-09-23 17:30:03924 *r = param_type(std::move(vect));
brettwca2ec7632017-04-20 06:10:20925 return true;
926 }
927 static void Log(const param_type& p, std::string* l) {
928 l->append("<base::flat_map>");
[email protected]205294b2014-03-18 20:48:35929 }
930};
931
[email protected]8e431f2032014-05-20 02:34:56932template <class P>
danakj03de39b22016-04-23 04:21:09933struct ParamTraits<std::unique_ptr<P>> {
934 typedef std::unique_ptr<P> param_type;
rockot502c94f2016-02-03 20:20:16935 static void Write(base::Pickle* m, const param_type& p) {
[email protected]8e431f2032014-05-20 02:34:56936 bool valid = !!p;
937 WriteParam(m, valid);
938 if (valid)
939 WriteParam(m, *p);
940 }
rockot502c94f2016-02-03 20:20:16941 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25942 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47943 param_type* r) {
[email protected]8e431f2032014-05-20 02:34:56944 bool valid = false;
945 if (!ReadParam(m, iter, &valid))
946 return false;
947
948 if (!valid) {
949 r->reset();
950 return true;
951 }
952
953 param_type temp(new P());
954 if (!ReadParam(m, iter, temp.get()))
955 return false;
956
957 r->swap(temp);
958 return true;
959 }
960 static void Log(const param_type& p, std::string* l) {
961 if (p)
962 LogParam(*p, l);
963 else
964 l->append("NULL");
965 }
966};
967
Peter Kasting41b5a8f2022-04-27 09:54:34968// absl types ParamTraits
969
bmcquade18573e12016-07-01 13:13:50970template <class P>
Anton Bikineev1f42a452021-05-15 18:02:50971struct ParamTraits<absl::optional<P>> {
972 typedef absl::optional<P> param_type;
bmcquade18573e12016-07-01 13:13:50973 static void Write(base::Pickle* m, const param_type& p) {
974 const bool is_set = static_cast<bool>(p);
975 WriteParam(m, is_set);
976 if (is_set)
977 WriteParam(m, p.value());
978 }
979 static bool Read(const base::Pickle* m,
980 base::PickleIterator* iter,
981 param_type* r) {
982 bool is_set = false;
983 if (!iter->ReadBool(&is_set))
984 return false;
985 if (is_set) {
986 P value;
987 if (!ReadParam(m, iter, &value))
988 return false;
989 *r = std::move(value);
990 }
991 return true;
992 }
993 static void Log(const param_type& p, std::string* l) {
994 if (p)
995 LogParam(p.value(), l);
996 else
997 l->append("(unset)");
998 }
999};
1000
Peter Kasting41b5a8f2022-04-27 09:54:341001template <>
1002struct ParamTraits<absl::monostate> {
1003 typedef absl::monostate param_type;
1004 static void Write(base::Pickle* m, const param_type& p) {}
1005 static bool Read(const base::Pickle* m,
1006 base::PickleIterator* iter,
1007 param_type* r) {
1008 return true;
1009 }
1010 static void Log(const param_type& p, std::string* l) { l->append("()"); }
1011};
1012
Maciej Pawlowski4a3ac6852019-05-09 17:06:141013// base/util types ParamTraits
1014
1015template <typename TypeMarker, typename WrappedType, WrappedType kInvalidValue>
Albert J. Wong1b6dc962021-07-09 18:06:571016struct ParamTraits<base::IdType<TypeMarker, WrappedType, kInvalidValue>> {
1017 using param_type = base::IdType<TypeMarker, WrappedType, kInvalidValue>;
Maciej Pawlowski4a3ac6852019-05-09 17:06:141018 static void Write(base::Pickle* m, const param_type& p) {
1019 WriteParam(m, p.GetUnsafeValue());
1020 }
1021 static bool Read(const base::Pickle* m,
1022 base::PickleIterator* iter,
1023 param_type* r) {
1024 WrappedType value;
1025 if (!ReadParam(m, iter, &value))
1026 return false;
1027 *r = param_type::FromUnsafeValue(value);
1028 return true;
1029 }
1030 static void Log(const param_type& p, std::string* l) {
1031 LogParam(p.GetUnsafeValue(), l);
1032 }
1033};
1034
Maciej Pawlowskic00800e2019-05-23 08:43:031035template <typename TagType, typename UnderlyingType>
Peter Kasting796cde22020-11-18 21:06:531036struct ParamTraits<base::StrongAlias<TagType, UnderlyingType>> {
1037 using param_type = base::StrongAlias<TagType, UnderlyingType>;
Maciej Pawlowskic00800e2019-05-23 08:43:031038 static void Write(base::Pickle* m, const param_type& p) {
1039 WriteParam(m, p.value());
1040 }
1041 static bool Read(const base::Pickle* m,
1042 base::PickleIterator* iter,
1043 param_type* r) {
1044 UnderlyingType value;
1045 if (!ReadParam(m, iter, &value))
1046 return false;
Istiaque Ahmed4832b03b2020-01-06 23:58:181047 *r = param_type(value);
Maciej Pawlowskic00800e2019-05-23 08:43:031048 return true;
1049 }
1050 static void Log(const param_type& p, std::string* l) {
1051 LogParam(p.value(), l);
1052 }
1053};
1054
[email protected]bf5aedf02012-06-04 21:18:251055// IPC types ParamTraits -------------------------------------------------------
1056
1057// A ChannelHandle is basically a platform-inspecific wrapper around the
1058// fact that IPC endpoints are handled specially on POSIX. See above comments
1059// on FileDescriptor for more background.
Ken Rockot3044d212018-01-23 02:44:391060template <>
1061struct COMPONENT_EXPORT(IPC) ParamTraits<IPC::ChannelHandle> {
[email protected]bf5aedf02012-06-04 21:18:251062 typedef ChannelHandle param_type;
rockot502c94f2016-02-03 20:20:161063 static void Write(base::Pickle* m, const param_type& p);
1064 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251065 base::PickleIterator* iter,
1066 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:251067 static void Log(const param_type& p, std::string* l);
1068};
1069
1070template <>
Ken Rockot3044d212018-01-23 02:44:391071struct COMPONENT_EXPORT(IPC) ParamTraits<LogData> {
[email protected]bf5aedf02012-06-04 21:18:251072 typedef LogData param_type;
rockot502c94f2016-02-03 20:20:161073 static void Write(base::Pickle* m, const param_type& p);
1074 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251075 base::PickleIterator* iter,
1076 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:251077 static void Log(const param_type& p, std::string* l);
1078};
1079
1080template <>
Ken Rockot3044d212018-01-23 02:44:391081struct COMPONENT_EXPORT(IPC) ParamTraits<Message> {
rockot502c94f2016-02-03 20:20:161082 static void Write(base::Pickle* m, const Message& p);
1083 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251084 base::PickleIterator* iter,
1085 Message* r);
[email protected]bf5aedf02012-06-04 21:18:251086 static void Log(const Message& p, std::string* l);
1087};
1088
1089// Windows ParamTraits ---------------------------------------------------------
1090
Xiaohan Wangab909b32022-01-12 17:57:391091#if BUILDFLAG(IS_WIN)
[email protected]bf5aedf02012-06-04 21:18:251092template <>
Ken Rockot3044d212018-01-23 02:44:391093struct COMPONENT_EXPORT(IPC) ParamTraits<HANDLE> {
[email protected]bf5aedf02012-06-04 21:18:251094 typedef HANDLE param_type;
rockot502c94f2016-02-03 20:20:161095 static void Write(base::Pickle* m, const param_type& p);
1096 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251097 base::PickleIterator* iter,
1098 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:251099 static void Log(const param_type& p, std::string* l);
1100};
1101
1102template <>
Ken Rockot3044d212018-01-23 02:44:391103struct COMPONENT_EXPORT(IPC) ParamTraits<MSG> {
[email protected]bf5aedf02012-06-04 21:18:251104 typedef MSG param_type;
rockot502c94f2016-02-03 20:20:161105 static void Write(base::Pickle* m, const param_type& p);
1106 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251107 base::PickleIterator* iter,
1108 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:251109 static void Log(const param_type& p, std::string* l);
1110};
Xiaohan Wangab909b32022-01-12 17:57:391111#endif // BUILDFLAG(IS_WIN)
[email protected]bf5aedf02012-06-04 21:18:251112
[email protected]7d5c3ac2009-02-04 08:58:191113//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:291114// Generic message subclasses
1115
[email protected]7a4de7a62010-08-17 18:38:241116// defined in ipc_logging.cc
Ken Rockot3044d212018-01-23 02:44:391117COMPONENT_EXPORT(IPC)
1118void GenerateLogData(const Message& message, LogData* data, bool get_params);
[email protected]7a4de7a62010-08-17 18:38:241119
davidsz041528a2017-05-12 09:19:231120#if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
[email protected]252cad62010-08-18 18:33:571121inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
1122 const std::string& output_params = msg->output_params();
[email protected]7a4de7a62010-08-17 18:38:241123 if (!l->empty() && !output_params.empty())
[email protected]252cad62010-08-18 18:33:571124 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:241125
1126 l->append(output_params);
1127}
1128
1129template <class ReplyParamType>
1130inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1131 const Message* msg) {
1132 if (msg->received_time() != 0) {
[email protected]252cad62010-08-18 18:33:571133 std::string output_params;
[email protected]7a4de7a62010-08-17 18:38:241134 LogParam(reply_params, &output_params);
1135 msg->set_output_params(output_params);
1136 }
1137}
1138
1139inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
1140 if (msg->sent_time()) {
1141 // Don't log the sync message after dispatch, as we don't have the
1142 // output parameters at that point. Instead, save its data and log it
1143 // with the outgoing reply message when it's sent.
1144 LogData* data = new LogData;
sammca1b3b4d2016-11-15 00:34:361145 GenerateLogData(*msg, data, true);
[email protected]7a4de7a62010-08-17 18:38:241146 msg->set_dont_log();
1147 reply->set_sync_log_data(data);
1148 }
1149}
1150#else
[email protected]252cad62010-08-18 18:33:571151inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
[email protected]7a4de7a62010-08-17 18:38:241152
1153template <class ReplyParamType>
1154inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1155 const Message* msg) {}
1156
1157inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1158#endif
1159
[email protected]3178f4e22008-08-05 21:20:411160} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291161
[email protected]946d1b22009-07-22 23:57:211162#endif // IPC_IPC_MESSAGE_UTILS_H_