blob: 724539d359adbb32a35a93d43a1b564d50a35b92 [file] [log] [blame]
[email protected]efb5f572012-01-29 10:57:331// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]946d1b22009-07-22 23:57:215#ifndef IPC_IPC_MESSAGE_UTILS_H_
6#define IPC_IPC_MESSAGE_UTILS_H_
initial.commit09911bf2008-07-26 23:55:297
avi51ba3e692015-12-26 17:30:508#include <limits.h>
avi246998d82015-12-22 02:39:049#include <stddef.h>
tfarina10a5c062015-09-04 18:47:5710#include <stdint.h>
11
[email protected]379e7a52010-03-09 00:38:4112#include <algorithm>
Yao Xiaoaf79ca9b2019-03-12 19:54:1813#include <bitset>
initial.commit09911bf2008-07-26 23:55:2914#include <map>
danakj03de39b22016-04-23 04:21:0915#include <memory>
[email protected]96da6962010-05-13 19:10:3416#include <set>
[email protected]663bd9e2011-03-21 01:07:0117#include <string>
tzik55e3e4d2016-03-08 05:47:4418#include <tuple>
Stuart Langley48300392017-11-02 03:54:4419#include <unordered_map>
[email protected]663bd9e2011-03-21 01:07:0120#include <vector>
initial.commit09911bf2008-07-26 23:55:2921
Ken Rockot3044d212018-01-23 02:44:3922#include "base/component_export.h"
brettwca2ec7632017-04-20 06:10:2023#include "base/containers/flat_map.h"
[email protected]205294b2014-03-18 20:48:3524#include "base/containers/small_map.h"
miletus1edf97f92015-07-23 19:42:3625#include "base/containers/stack_container.h"
[email protected]141bcc52014-01-27 21:36:0026#include "base/files/file.h"
[email protected]dce5df52009-06-29 17:58:2527#include "base/format_macros.h"
Alexandr Ilind497eee2018-04-19 22:50:5428#include "base/memory/platform_shared_memory_region.h"
29#include "base/memory/read_only_shared_memory_region.h"
Klaus Weidner3824a8882017-11-03 06:24:5730#include "base/memory/shared_memory_handle.h"
Alexandr Ilind497eee2018-04-19 22:50:5431#include "base/memory/unsafe_shared_memory_region.h"
32#include "base/memory/writable_shared_memory_region.h"
brettwca2ec7632017-04-20 06:10:2033#include "base/numerics/safe_conversions.h"
bmcquade18573e12016-07-01 13:13:5034#include "base/optional.h"
[email protected]4aa794a12013-06-11 06:32:1835#include "base/strings/string16.h"
36#include "base/strings/string_util.h"
37#include "base/strings/stringprintf.h"
Maciej Pawlowskia37782a02019-05-16 06:40:2838#include "base/util/type_safety/id_type.h"
avi246998d82015-12-22 02:39:0439#include "build/build_config.h"
[email protected]f9509812012-10-23 23:03:3540#include "ipc/ipc_message_start.h"
[email protected]939856a2010-08-24 20:29:0241#include "ipc/ipc_param_traits.h"
[email protected]0cfe5dae2010-08-17 00:24:5442#include "ipc/ipc_sync_message.h"
[email protected]55b4e212010-08-13 20:43:5843
Ken Rockot097248f02018-04-23 16:23:3444#if defined(OS_ANDROID)
45#include "base/android/scoped_hardware_buffer_handle.h"
46#endif
47
[email protected]7a4de7a62010-08-17 18:38:2448namespace base {
[email protected]f3a1c642011-07-12 19:15:0349class DictionaryValue;
[email protected]a3ef4832013-02-02 05:12:3350class FilePath;
[email protected]f3a1c642011-07-12 19:15:0351class ListValue;
[email protected]0238a162013-06-13 13:47:4652class NullableString16;
[email protected]7a4de7a62010-08-17 18:38:2453class Time;
[email protected]d84e48b2010-10-21 22:04:5254class TimeDelta;
[email protected]1d14f582011-09-02 20:42:0455class TimeTicks;
tguilbert4a5ac602016-09-19 21:11:2556class UnguessableToken;
[email protected]7a4de7a62010-08-17 18:38:2457struct FileDescriptor;
58}
59
initial.commit09911bf2008-07-26 23:55:2960namespace IPC {
61
[email protected]7a4de7a62010-08-17 18:38:2462struct ChannelHandle;
63
erikchend804e1052017-04-29 02:24:3664#if defined(OS_WIN)
65class PlatformFileForTransit;
66#endif
67
[email protected]bf5aedf02012-06-04 21:18:2568// -----------------------------------------------------------------------------
69// How we send IPC message logs across channels.
Ken Rockot3044d212018-01-23 02:44:3970struct COMPONENT_EXPORT(IPC) LogData {
[email protected]bf5aedf02012-06-04 21:18:2571 LogData();
vmpstrbf0d713a2016-03-24 20:22:5472 LogData(const LogData& other);
[email protected]bf5aedf02012-06-04 21:18:2573 ~LogData();
74
75 std::string channel;
tfarina10a5c062015-09-04 18:47:5776 int32_t routing_id;
77 uint32_t type; // "User-defined" message type, from ipc_message.h.
[email protected]bf5aedf02012-06-04 21:18:2578 std::string flags;
tfarina10a5c062015-09-04 18:47:5779 int64_t sent; // Time that the message was sent (i.e. at Send()).
80 int64_t receive; // Time before it was dispatched (i.e. before calling
81 // OnMessageReceived).
82 int64_t dispatch; // Time after it was dispatched (i.e. after calling
83 // OnMessageReceived).
[email protected]bf5aedf02012-06-04 21:18:2584 std::string message_name;
85 std::string params;
86};
87
initial.commit09911bf2008-07-26 23:55:2988//-----------------------------------------------------------------------------
[email protected]7edae3d02012-12-17 20:23:4789
[email protected]6476c72c2011-02-11 18:46:1990// A dummy struct to place first just to allow leading commas for all
91// members in the macro-generated constructor initializer lists.
92struct NoParams {
93};
94
dskiba2bc89462016-04-06 15:51:0695// Specializations are checked by 'IPC checker' part of find-bad-constructs
96// Clang plugin (see WriteParam() below for the details).
97template <typename... Ts>
98struct CheckedTuple {
99 typedef std::tuple<Ts...> Tuple;
100};
101
dskiba2bc89462016-04-06 15:51:06102// This function is checked by 'IPC checker' part of find-bad-constructs
103// Clang plugin to make it's not called on the following types:
104// 1. long / unsigned long (but not typedefs to)
105// 2. intmax_t, uintmax_t, intptr_t, uintptr_t, wint_t,
106// size_t, rsize_t, ssize_t, ptrdiff_t, dev_t, off_t, clock_t,
107// time_t, suseconds_t (including typedefs to)
108// 3. Any template referencing types above (e.g. std::vector<size_t>)
rockot0457af102016-02-05 02:12:32109template <class P>
rockot502c94f2016-02-03 20:20:16110static inline void WriteParam(base::Pickle* m, const P& p) {
[email protected]7b291f92009-08-14 05:43:53111 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53112 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
[email protected]7d5c3ac2009-02-04 08:58:19113}
114
115template <class P>
rockot502c94f2016-02-03 20:20:16116static inline bool WARN_UNUSED_RESULT ReadParam(const base::Pickle* m,
117 base::PickleIterator* iter,
118 P* p) {
[email protected]7b291f92009-08-14 05:43:53119 typedef typename SimilarTypeTraits<P>::Type Type;
120 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
[email protected]7d5c3ac2009-02-04 08:58:19121}
122
123template <class P>
[email protected]252cad62010-08-18 18:33:57124static inline void LogParam(const P& p, std::string* l) {
[email protected]7b291f92009-08-14 05:43:53125 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53126 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19127}
128
[email protected]bf5aedf02012-06-04 21:18:25129// Primitive ParamTraits -------------------------------------------------------
130
[email protected]7d5c3ac2009-02-04 08:58:19131template <>
132struct ParamTraits<bool> {
133 typedef bool param_type;
rockot502c94f2016-02-03 20:20:16134 static void Write(base::Pickle* m, const param_type& p) { m->WriteBool(p); }
135 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25136 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47137 param_type* r) {
avi48fc13b2014-12-28 23:31:48138 return iter->ReadBool(r);
[email protected]7d5c3ac2009-02-04 08:58:19139 }
Ken Rockot3044d212018-01-23 02:44:39140 COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19141};
142
143template <>
Ken Rockot3044d212018-01-23 02:44:39144struct COMPONENT_EXPORT(IPC) ParamTraits<signed char> {
ortuno19ecf1842015-10-30 00:46:20145 typedef signed char param_type;
rockot502c94f2016-02-03 20:20:16146 static void Write(base::Pickle* m, const param_type& p);
147 static bool Read(const base::Pickle* m,
148 base::PickleIterator* iter,
149 param_type* r);
ortuno19ecf1842015-10-30 00:46:20150 static void Log(const param_type& p, std::string* l);
151};
152
153template <>
Ken Rockot3044d212018-01-23 02:44:39154struct COMPONENT_EXPORT(IPC) ParamTraits<unsigned char> {
[email protected]7bea7352013-07-13 04:42:10155 typedef unsigned char param_type;
rockot502c94f2016-02-03 20:20:16156 static void Write(base::Pickle* m, const param_type& p);
157 static bool Read(const base::Pickle* m,
158 base::PickleIterator* iter,
159 param_type* r);
[email protected]c1ee48d2013-07-12 23:12:28160 static void Log(const param_type& p, std::string* l);
161};
162
163template <>
Ken Rockot3044d212018-01-23 02:44:39164struct COMPONENT_EXPORT(IPC) ParamTraits<unsigned short> {
[email protected]c1ee48d2013-07-12 23:12:28165 typedef unsigned short param_type;
rockot502c94f2016-02-03 20:20:16166 static void Write(base::Pickle* m, const param_type& p);
167 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25168 base::PickleIterator* iter,
169 param_type* r);
[email protected]c1ee48d2013-07-12 23:12:28170 static void Log(const param_type& p, std::string* l);
171};
172
173template <>
[email protected]7d5c3ac2009-02-04 08:58:19174struct ParamTraits<int> {
175 typedef int param_type;
rockot502c94f2016-02-03 20:20:16176 static void Write(base::Pickle* m, const param_type& p) { m->WriteInt(p); }
177 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25178 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47179 param_type* r) {
avi48fc13b2014-12-28 23:31:48180 return iter->ReadInt(r);
[email protected]7d5c3ac2009-02-04 08:58:19181 }
Ken Rockot3044d212018-01-23 02:44:39182 COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19183};
184
185template <>
[email protected]63263f92009-07-28 19:35:08186struct ParamTraits<unsigned int> {
187 typedef unsigned int param_type;
rockot502c94f2016-02-03 20:20:16188 static void Write(base::Pickle* m, const param_type& p) { m->WriteInt(p); }
189 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25190 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47191 param_type* r) {
avi48fc13b2014-12-28 23:31:48192 return iter->ReadInt(reinterpret_cast<int*>(r));
[email protected]63263f92009-07-28 19:35:08193 }
Ken Rockot3044d212018-01-23 02:44:39194 COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08195};
196
jam03d8a782016-02-10 20:13:39197// long isn't safe to send over IPC because it's 4 bytes on 32 bit builds but
198// 8 bytes on 64 bit builds. So if a 32 bit and 64 bit process have a channel
199// that would cause problem.
200// We need to keep this on for a few configs:
201// 1) Windows because DWORD is typedef'd to it, which is fine because we have
202// very few IPCs that cross this boundary.
203// 2) We also need to keep it for Linux for two reasons: int64_t is typedef'd
204// to long, and gfx::PluginWindow is long and is used in one GPU IPC.
Scott Grahamf4b38b42017-06-19 23:09:33205// 3) Android 64 bit and Fuchsia also have int64_t typedef'd to long.
jam03d8a782016-02-10 20:13:39206// Since we want to support Android 32<>64 bit IPC, as long as we don't have
207// these traits for 32 bit ARM then that'll catch any errors.
Scott Grahamf4b38b42017-06-19 23:09:33208#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_FUCHSIA) || \
jamac78d7d82016-02-11 00:50:28209 (defined(OS_ANDROID) && defined(ARCH_CPU_64_BITS))
[email protected]63263f92009-07-28 19:35:08210template <>
[email protected]7d5c3ac2009-02-04 08:58:19211struct ParamTraits<long> {
212 typedef long param_type;
rockot502c94f2016-02-03 20:20:16213 static void Write(base::Pickle* m, const param_type& p) {
jam03d8a782016-02-10 20:13:39214 m->WriteLong(p);
[email protected]7d5c3ac2009-02-04 08:58:19215 }
rockot502c94f2016-02-03 20:20:16216 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25217 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47218 param_type* r) {
avi48fc13b2014-12-28 23:31:48219 return iter->ReadLong(r);
[email protected]7d5c3ac2009-02-04 08:58:19220 }
Ken Rockot3044d212018-01-23 02:44:39221 COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19222};
223
[email protected]140c3032009-06-26 18:22:54224template <>
225struct ParamTraits<unsigned long> {
226 typedef unsigned long param_type;
rockot502c94f2016-02-03 20:20:16227 static void Write(base::Pickle* m, const param_type& p) {
jam03d8a782016-02-10 20:13:39228 m->WriteLong(p);
[email protected]140c3032009-06-26 18:22:54229 }
rockot502c94f2016-02-03 20:20:16230 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25231 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47232 param_type* r) {
avi48fc13b2014-12-28 23:31:48233 return iter->ReadLong(reinterpret_cast<long*>(r));
[email protected]140c3032009-06-26 18:22:54234 }
Ken Rockot3044d212018-01-23 02:44:39235 COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19236};
jam03d8a782016-02-10 20:13:39237#endif
[email protected]7d5c3ac2009-02-04 08:58:19238
239template <>
[email protected]63263f92009-07-28 19:35:08240struct ParamTraits<long long> {
241 typedef long long param_type;
rockot502c94f2016-02-03 20:20:16242 static void Write(base::Pickle* m, const param_type& p) {
tfarina10a5c062015-09-04 18:47:57243 m->WriteInt64(static_cast<int64_t>(p));
[email protected]7d5c3ac2009-02-04 08:58:19244 }
rockot502c94f2016-02-03 20:20:16245 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25246 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:56247 param_type* r) {
tfarina10a5c062015-09-04 18:47:57248 return iter->ReadInt64(reinterpret_cast<int64_t*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19249 }
Ken Rockot3044d212018-01-23 02:44:39250 COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08251};
252
253template <>
254struct ParamTraits<unsigned long long> {
255 typedef unsigned long long param_type;
rockot502c94f2016-02-03 20:20:16256 static void Write(base::Pickle* m, const param_type& p) { m->WriteInt64(p); }
257 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25258 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:56259 param_type* r) {
tfarina10a5c062015-09-04 18:47:57260 return iter->ReadInt64(reinterpret_cast<int64_t*>(r));
[email protected]63263f92009-07-28 19:35:08261 }
Ken Rockot3044d212018-01-23 02:44:39262 COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19263};
264
[email protected]20199662010-06-17 03:29:26265// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
266// should be sure to check the sanity of these values after receiving them over
267// IPC.
268template <>
Ken Rockot3044d212018-01-23 02:44:39269struct COMPONENT_EXPORT(IPC) ParamTraits<float> {
[email protected]20199662010-06-17 03:29:26270 typedef float param_type;
rockot502c94f2016-02-03 20:20:16271 static void Write(base::Pickle* m, const param_type& p) { m->WriteFloat(p); }
272 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25273 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47274 param_type* r) {
avi48fc13b2014-12-28 23:31:48275 return iter->ReadFloat(r);
[email protected]48328ff2013-10-31 09:27:31276 }
[email protected]bf5aedf02012-06-04 21:18:25277 static void Log(const param_type& p, std::string* l);
[email protected]20199662010-06-17 03:29:26278};
279
[email protected]7d5c3ac2009-02-04 08:58:19280template <>
Ken Rockot3044d212018-01-23 02:44:39281struct COMPONENT_EXPORT(IPC) ParamTraits<double> {
[email protected]7d5c3ac2009-02-04 08:58:19282 typedef double param_type;
rockot502c94f2016-02-03 20:20:16283 static void Write(base::Pickle* m, const param_type& p);
284 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25285 base::PickleIterator* iter,
286 param_type* r);
[email protected]c410e022012-05-30 21:15:57287 static void Log(const param_type& p, std::string* l);
288};
289
ericrkb5de4602017-02-10 17:49:35290template <class P, size_t Size>
291struct ParamTraits<P[Size]> {
292 using param_type = P[Size];
ericrkb5de4602017-02-10 17:49:35293 static void Write(base::Pickle* m, const param_type& p) {
294 for (const P& element : p)
295 WriteParam(m, element);
296 }
297 static bool Read(const base::Pickle* m,
298 base::PickleIterator* iter,
299 param_type* r) {
300 for (P& element : *r) {
301 if (!ReadParam(m, iter, &element))
302 return false;
303 }
304 return true;
305 }
306 static void Log(const param_type& p, std::string* l) {
307 l->append("[");
308 for (const P& element : p) {
309 if (&element != &p[0])
310 l->append(" ");
311 LogParam(element, l);
312 }
313 l->append("]");
314 }
315};
316
[email protected]bf5aedf02012-06-04 21:18:25317// STL ParamTraits -------------------------------------------------------------
[email protected]584f2b22009-05-21 01:01:59318
319template <>
[email protected]7d5c3ac2009-02-04 08:58:19320struct ParamTraits<std::string> {
321 typedef std::string param_type;
rockot502c94f2016-02-03 20:20:16322 static void Write(base::Pickle* m, const param_type& p) { m->WriteString(p); }
323 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25324 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:56325 param_type* r) {
avi48fc13b2014-12-28 23:31:48326 return iter->ReadString(r);
[email protected]7d5c3ac2009-02-04 08:58:19327 }
Ken Rockot3044d212018-01-23 02:44:39328 COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19329};
330
[email protected]bf5aedf02012-06-04 21:18:25331template <>
[email protected]476dafb2013-12-03 00:39:26332struct ParamTraits<base::string16> {
333 typedef base::string16 param_type;
rockot502c94f2016-02-03 20:20:16334 static void Write(base::Pickle* m, const param_type& p) {
[email protected]bf5aedf02012-06-04 21:18:25335 m->WriteString16(p);
336 }
rockot502c94f2016-02-03 20:20:16337 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25338 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25339 param_type* r) {
avi48fc13b2014-12-28 23:31:48340 return iter->ReadString16(r);
[email protected]bf5aedf02012-06-04 21:18:25341 }
Ken Rockot3044d212018-01-23 02:44:39342 COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
[email protected]bf5aedf02012-06-04 21:18:25343};
[email protected]3dd7a7a2009-07-27 21:09:07344
[email protected]7d5c3ac2009-02-04 08:58:19345template <>
Ken Rockot3044d212018-01-23 02:44:39346struct COMPONENT_EXPORT(IPC) ParamTraits<std::vector<char>> {
[email protected]7d5c3ac2009-02-04 08:58:19347 typedef std::vector<char> param_type;
rockot502c94f2016-02-03 20:20:16348 static void Write(base::Pickle* m, const param_type& p);
349 static bool Read(const base::Pickle*,
brettwbd4d7112015-06-03 04:29:25350 base::PickleIterator* iter,
351 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25352 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19353};
354
[email protected]51b63f62011-10-05 18:55:42355template <>
Ken Rockot3044d212018-01-23 02:44:39356struct COMPONENT_EXPORT(IPC) ParamTraits<std::vector<unsigned char>> {
[email protected]bf5aedf02012-06-04 21:18:25357 typedef std::vector<unsigned char> param_type;
rockot502c94f2016-02-03 20:20:16358 static void Write(base::Pickle* m, const param_type& p);
359 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25360 base::PickleIterator* iter,
361 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25362 static void Log(const param_type& p, std::string* l);
363};
364
365template <>
Ken Rockot3044d212018-01-23 02:44:39366struct COMPONENT_EXPORT(IPC) ParamTraits<std::vector<bool>> {
[email protected]51b63f62011-10-05 18:55:42367 typedef std::vector<bool> param_type;
rockot502c94f2016-02-03 20:20:16368 static void Write(base::Pickle* m, const param_type& p);
369 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25370 base::PickleIterator* iter,
371 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25372 static void Log(const param_type& p, std::string* l);
[email protected]51b63f62011-10-05 18:55:42373};
374
[email protected]7d5c3ac2009-02-04 08:58:19375template <class P>
bmcquade18573e12016-07-01 13:13:50376struct ParamTraits<std::vector<P>> {
[email protected]7d5c3ac2009-02-04 08:58:19377 typedef std::vector<P> param_type;
rockot502c94f2016-02-03 20:20:16378 static void Write(base::Pickle* m, const param_type& p) {
Chris Palmerc5ea9b92017-09-25 22:53:22379 WriteParam(m, base::checked_cast<int>(p.size()));
[email protected]7d5c3ac2009-02-04 08:58:19380 for (size_t i = 0; i < p.size(); i++)
381 WriteParam(m, p[i]);
382 }
rockot502c94f2016-02-03 20:20:16383 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25384 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:56385 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19386 int size;
[email protected]86440f52009-12-31 05:17:23387 // ReadLength() checks for < 0 itself.
avi48fc13b2014-12-28 23:31:48388 if (!iter->ReadLength(&size))
[email protected]7d5c3ac2009-02-04 08:58:19389 return false;
390 // Resizing beforehand is not safe, see BUG 1006367 for details.
[email protected]86440f52009-12-31 05:17:23391 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
392 return false;
393 r->resize(size);
394 for (int i = 0; i < size; i++) {
395 if (!ReadParam(m, iter, &(*r)[i]))
396 return false;
[email protected]7d5c3ac2009-02-04 08:58:19397 }
398 return true;
399 }
[email protected]252cad62010-08-18 18:33:57400 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19401 for (size_t i = 0; i < p.size(); ++i) {
402 if (i != 0)
[email protected]252cad62010-08-18 18:33:57403 l->append(" ");
[email protected]7d5c3ac2009-02-04 08:58:19404 LogParam((p[i]), l);
405 }
406 }
407};
408
Yao Xiaoaf79ca9b2019-03-12 19:54:18409template <std::size_t N>
410struct ParamTraits<std::bitset<N>> {
411 typedef std::bitset<N> param_type;
412 static void Write(base::Pickle* m, const param_type& p) {
413 WriteParam(m, base::checked_cast<int>(p.size()));
414 for (size_t i = 0; i < p.size(); i++)
415 WriteParam(m, p.test(i));
416 }
417
418 static bool Read(const base::Pickle* m,
419 base::PickleIterator* iter,
420 param_type* r) {
421 int size;
422 // ReadLength() checks for < 0 itself.
423 if (!iter->ReadLength(&size))
424 return false;
425 if (static_cast<size_t>(size) != r->size())
426 return false;
427 for (size_t i = 0; i < r->size(); i++) {
428 bool value;
429 if (!ReadParam(m, iter, &value))
430 return false;
431 (*r)[i] = value;
432 }
433 return true;
434 }
435
436 static void Log(const param_type& p, std::string* l) {
437 for (size_t i = 0; i < p.size(); ++i) {
438 if (i != 0)
439 l->push_back(' ');
440 LogParam(p.test(i), l);
441 }
442 }
443};
444
[email protected]96da6962010-05-13 19:10:34445template <class P>
446struct ParamTraits<std::set<P> > {
447 typedef std::set<P> param_type;
rockot502c94f2016-02-03 20:20:16448 static void Write(base::Pickle* m, const param_type& p) {
Chris Palmerc5ea9b92017-09-25 22:53:22449 WriteParam(m, base::checked_cast<int>(p.size()));
[email protected]96da6962010-05-13 19:10:34450 typename param_type::const_iterator iter;
451 for (iter = p.begin(); iter != p.end(); ++iter)
452 WriteParam(m, *iter);
453 }
rockot502c94f2016-02-03 20:20:16454 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25455 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:56456 param_type* r) {
[email protected]96da6962010-05-13 19:10:34457 int size;
avi48fc13b2014-12-28 23:31:48458 if (!iter->ReadLength(&size))
[email protected]96da6962010-05-13 19:10:34459 return false;
460 for (int i = 0; i < size; ++i) {
461 P item;
462 if (!ReadParam(m, iter, &item))
463 return false;
464 r->insert(item);
465 }
466 return true;
467 }
[email protected]252cad62010-08-18 18:33:57468 static void Log(const param_type& p, std::string* l) {
469 l->append("<std::set>");
[email protected]96da6962010-05-13 19:10:34470 }
471};
472
jkarlinf96d19ba2014-09-24 11:42:37473template <class K, class V, class C, class A>
474struct ParamTraits<std::map<K, V, C, A> > {
475 typedef std::map<K, V, C, A> param_type;
rockot502c94f2016-02-03 20:20:16476 static void Write(base::Pickle* m, const param_type& p) {
Chris Palmerc5ea9b92017-09-25 22:53:22477 WriteParam(m, base::checked_cast<int>(p.size()));
Stuart Langley48300392017-11-02 03:54:44478 for (const auto& iter : p) {
479 WriteParam(m, iter.first);
480 WriteParam(m, iter.second);
[email protected]7d5c3ac2009-02-04 08:58:19481 }
482 }
rockot502c94f2016-02-03 20:20:16483 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25484 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:56485 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19486 int size;
487 if (!ReadParam(m, iter, &size) || size < 0)
488 return false;
489 for (int i = 0; i < size; ++i) {
490 K k;
491 if (!ReadParam(m, iter, &k))
492 return false;
493 V& value = (*r)[k];
494 if (!ReadParam(m, iter, &value))
495 return false;
496 }
497 return true;
498 }
[email protected]252cad62010-08-18 18:33:57499 static void Log(const param_type& p, std::string* l) {
500 l->append("<std::map>");
[email protected]7d5c3ac2009-02-04 08:58:19501 }
502};
503
Stuart Langley48300392017-11-02 03:54:44504template <class K, class V, class C, class A>
505struct ParamTraits<std::unordered_map<K, V, C, A>> {
506 typedef std::unordered_map<K, V, C, A> param_type;
507 static void Write(base::Pickle* m, const param_type& p) {
508 WriteParam(m, base::checked_cast<int>(p.size()));
509 for (const auto& iter : p) {
510 WriteParam(m, iter.first);
511 WriteParam(m, iter.second);
512 }
513 }
514 static bool Read(const base::Pickle* m,
515 base::PickleIterator* iter,
516 param_type* r) {
517 int size;
518 if (!ReadParam(m, iter, &size) || size < 0)
519 return false;
520 for (int i = 0; i < size; ++i) {
521 K k;
522 if (!ReadParam(m, iter, &k))
523 return false;
524 V& value = (*r)[k];
525 if (!ReadParam(m, iter, &value))
526 return false;
527 }
528 return true;
529 }
530 static void Log(const param_type& p, std::string* l) {
531 l->append("<std::unordered_map>");
532 }
533};
534
[email protected]a5da6d612009-08-04 02:00:56535template <class A, class B>
536struct ParamTraits<std::pair<A, B> > {
537 typedef std::pair<A, B> param_type;
rockot502c94f2016-02-03 20:20:16538 static void Write(base::Pickle* m, const param_type& p) {
[email protected]a5da6d612009-08-04 02:00:56539 WriteParam(m, p.first);
540 WriteParam(m, p.second);
541 }
rockot502c94f2016-02-03 20:20:16542 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25543 base::PickleIterator* iter,
[email protected]ce208f872012-03-07 20:42:56544 param_type* r) {
[email protected]a5da6d612009-08-04 02:00:56545 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
546 }
[email protected]252cad62010-08-18 18:33:57547 static void Log(const param_type& p, std::string* l) {
548 l->append("(");
[email protected]a5da6d612009-08-04 02:00:56549 LogParam(p.first, l);
[email protected]252cad62010-08-18 18:33:57550 l->append(", ");
[email protected]a5da6d612009-08-04 02:00:56551 LogParam(p.second, l);
[email protected]252cad62010-08-18 18:33:57552 l->append(")");
[email protected]a5da6d612009-08-04 02:00:56553 }
554};
555
[email protected]bf5aedf02012-06-04 21:18:25556// Base ParamTraits ------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19557
558template <>
Ken Rockot3044d212018-01-23 02:44:39559struct COMPONENT_EXPORT(IPC) ParamTraits<base::DictionaryValue> {
[email protected]bf5aedf02012-06-04 21:18:25560 typedef base::DictionaryValue param_type;
rockot502c94f2016-02-03 20:20:16561 static void Write(base::Pickle* m, const param_type& p);
562 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25563 base::PickleIterator* iter,
564 param_type* r);
[email protected]252cad62010-08-18 18:33:57565 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19566};
567
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09568#if defined(OS_POSIX) || defined(OS_FUCHSIA)
[email protected]2749885f2009-03-05 21:40:11569// FileDescriptors may be serialised over IPC channels on POSIX. On the
570// receiving side, the FileDescriptor is a valid duplicate of the file
571// descriptor which was transmitted: *it is not just a copy of the integer like
572// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
573// this case, the receiving end will see a value of -1. *Zero is a valid file
574// descriptor*.
575//
576// The received file descriptor will have the |auto_close| flag set to true. The
577// code which handles the message is responsible for taking ownership of it.
578// File descriptors are OS resources and must be closed when no longer needed.
579//
580// When sending a file descriptor, the file descriptor must be valid at the time
581// of transmission. Since transmission is not synchronous, one should consider
582// dup()ing any file descriptors to be transmitted and setting the |auto_close|
583// flag, which causes the file descriptor to be closed after writing.
Ken Rockot3044d212018-01-23 02:44:39584template <>
585struct COMPONENT_EXPORT(IPC) ParamTraits<base::FileDescriptor> {
[email protected]5fe733de2009-02-11 18:59:20586 typedef base::FileDescriptor param_type;
rockot502c94f2016-02-03 20:20:16587 static void Write(base::Pickle* m, const param_type& p);
588 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25589 base::PickleIterator* iter,
590 param_type* r);
[email protected]252cad62010-08-18 18:33:57591 static void Log(const param_type& p, std::string* l);
[email protected]526776c2009-02-07 00:39:26592};
Sergey Ulanovac89bb92019-03-22 18:46:49593
594template <>
595struct COMPONENT_EXPORT(IPC) ParamTraits<base::ScopedFD> {
596 typedef base::ScopedFD param_type;
597 static void Write(base::Pickle* m, const param_type& p);
598 static bool Read(const base::Pickle* m,
599 base::PickleIterator* iter,
600 param_type* r);
601 static void Log(const param_type& p, std::string* l);
602};
603
Fabrice de Gans-Ribericbce4342018-05-07 20:02:09604#endif // defined(OS_POSIX) || defined(OS_FUCHSIA)
[email protected]526776c2009-02-07 00:39:26605
Sergey Ulanova97f3282019-04-17 01:27:34606#if defined(OS_FUCHSIA)
607template <>
608struct COMPONENT_EXPORT(IPC) ParamTraits<zx::vmo> {
609 typedef zx::vmo param_type;
610 static void Write(base::Pickle* m, const param_type& p);
611 static bool Read(const base::Pickle* m,
612 base::PickleIterator* iter,
613 param_type* r);
614 static void Log(const param_type& p, std::string* l);
615};
616#endif // defined(OS_FUCHSIA)
617
scottmgd19b4f72015-06-19 22:51:00618template <>
Ken Rockot3044d212018-01-23 02:44:39619struct COMPONENT_EXPORT(IPC) ParamTraits<base::SharedMemoryHandle> {
scottmgd19b4f72015-06-19 22:51:00620 typedef base::SharedMemoryHandle param_type;
rockot502c94f2016-02-03 20:20:16621 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);
scottmgd19b4f72015-06-19 22:51:00625 static void Log(const param_type& p, std::string* l);
626};
scottmgd19b4f72015-06-19 22:51:00627
Klaus Weidner3824a8882017-11-03 06:24:57628#if defined(OS_ANDROID)
629template <>
Alexandr Ilin0443a8f2018-07-20 20:14:50630struct COMPONENT_EXPORT(IPC)
631 ParamTraits<base::android::ScopedHardwareBufferHandle> {
632 typedef base::android::ScopedHardwareBufferHandle param_type;
Klaus Weidner3824a8882017-11-03 06:24:57633 static void Write(base::Pickle* m, const param_type& p);
634 static bool Read(const base::Pickle* m,
635 base::PickleIterator* iter,
636 param_type* r);
637 static void Log(const param_type& p, std::string* l);
638};
639#endif
640
Alexandr Ilind497eee2018-04-19 22:50:54641template <>
642struct COMPONENT_EXPORT(IPC) ParamTraits<base::ReadOnlySharedMemoryRegion> {
643 typedef base::ReadOnlySharedMemoryRegion param_type;
644 static void Write(base::Pickle* m, const param_type& p);
645 static bool Read(const base::Pickle* m,
646 base::PickleIterator* iter,
647 param_type* r);
648 static void Log(const param_type& p, std::string* l);
649};
650
651template <>
652struct COMPONENT_EXPORT(IPC) ParamTraits<base::WritableSharedMemoryRegion> {
653 typedef base::WritableSharedMemoryRegion param_type;
654 static void Write(base::Pickle* m, const param_type& p);
655 static bool Read(const base::Pickle* m,
656 base::PickleIterator* iter,
657 param_type* r);
658 static void Log(const param_type& p, std::string* l);
659};
660
661template <>
662struct COMPONENT_EXPORT(IPC) ParamTraits<base::UnsafeSharedMemoryRegion> {
663 typedef base::UnsafeSharedMemoryRegion param_type;
664 static void Write(base::Pickle* m, const param_type& p);
665 static bool Read(const base::Pickle* m,
666 base::PickleIterator* iter,
667 param_type* r);
668 static void Log(const param_type& p, std::string* l);
669};
670
671template <>
672struct COMPONENT_EXPORT(IPC)
673 ParamTraits<base::subtle::PlatformSharedMemoryRegion> {
674 typedef base::subtle::PlatformSharedMemoryRegion param_type;
675 static void Write(base::Pickle* m, const param_type& p);
676 static bool Read(const base::Pickle* m,
677 base::PickleIterator* iter,
678 param_type* r);
679 static void Log(const param_type& p, std::string* l);
680};
681
682template <>
683struct COMPONENT_EXPORT(IPC)
684 ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode> {
685 typedef base::subtle::PlatformSharedMemoryRegion::Mode param_type;
686 static void Write(base::Pickle* m, const param_type& p);
687 static bool Read(const base::Pickle* m,
688 base::PickleIterator* iter,
689 param_type* r);
690 static void Log(const param_type& p, std::string* l);
691};
692
erikchend804e1052017-04-29 02:24:36693#if defined(OS_WIN)
694template <>
Ken Rockot3044d212018-01-23 02:44:39695struct COMPONENT_EXPORT(IPC) ParamTraits<PlatformFileForTransit> {
erikchend804e1052017-04-29 02:24:36696 typedef PlatformFileForTransit param_type;
erikchend804e1052017-04-29 02:24:36697 static void Write(base::Pickle* m, const param_type& p);
698 static bool Read(const base::Pickle* m,
699 base::PickleIterator* iter,
700 param_type* r);
701 static void Log(const param_type& p, std::string* l);
702};
703#endif // defined(OS_WIN)
704
[email protected]bf5aedf02012-06-04 21:18:25705template <>
Ken Rockot3044d212018-01-23 02:44:39706struct COMPONENT_EXPORT(IPC) ParamTraits<base::FilePath> {
[email protected]a3ef4832013-02-02 05:12:33707 typedef base::FilePath param_type;
rockot502c94f2016-02-03 20:20:16708 static void Write(base::Pickle* m, const param_type& p);
709 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25710 base::PickleIterator* iter,
711 param_type* r);
[email protected]252cad62010-08-18 18:33:57712 static void Log(const param_type& p, std::string* l);
[email protected]d2e884d2009-06-22 20:37:52713};
714
[email protected]7d5c3ac2009-02-04 08:58:19715template <>
Ken Rockot3044d212018-01-23 02:44:39716struct COMPONENT_EXPORT(IPC) ParamTraits<base::ListValue> {
[email protected]bf5aedf02012-06-04 21:18:25717 typedef base::ListValue param_type;
rockot502c94f2016-02-03 20:20:16718 static void Write(base::Pickle* m, const param_type& p);
719 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25720 base::PickleIterator* iter,
721 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25722 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19723};
724
[email protected]eb47a132009-03-04 00:39:56725template <>
Ken Rockot3044d212018-01-23 02:44:39726struct COMPONENT_EXPORT(IPC) ParamTraits<base::NullableString16> {
[email protected]0238a162013-06-13 13:47:46727 typedef base::NullableString16 param_type;
rockot502c94f2016-02-03 20:20:16728 static void Write(base::Pickle* m, const param_type& p);
729 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25730 base::PickleIterator* iter,
[email protected]bf5aedf02012-06-04 21:18:25731 param_type* r);
732 static void Log(const param_type& p, std::string* l);
733};
734
735template <>
Ken Rockot3044d212018-01-23 02:44:39736struct COMPONENT_EXPORT(IPC) ParamTraits<base::File::Info> {
[email protected]141bcc52014-01-27 21:36:00737 typedef base::File::Info param_type;
rockot502c94f2016-02-03 20:20:16738 static void Write(base::Pickle* m, const param_type& p);
739 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25740 base::PickleIterator* iter,
741 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25742 static void Log(const param_type& p, std::string* l);
743};
744
745template <>
[email protected]141bcc52014-01-27 21:36:00746struct SimilarTypeTraits<base::File::Error> {
[email protected]bf5aedf02012-06-04 21:18:25747 typedef int Type;
748};
749
[email protected]ecf59c72013-02-28 21:46:11750#if defined(OS_WIN)
751template <>
752struct SimilarTypeTraits<HWND> {
753 typedef HANDLE Type;
754};
755#endif // defined(OS_WIN)
756
[email protected]bf5aedf02012-06-04 21:18:25757template <>
Ken Rockot3044d212018-01-23 02:44:39758struct COMPONENT_EXPORT(IPC) ParamTraits<base::Time> {
[email protected]bf5aedf02012-06-04 21:18:25759 typedef base::Time param_type;
rockot502c94f2016-02-03 20:20:16760 static void Write(base::Pickle* m, const param_type& p);
761 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25762 base::PickleIterator* iter,
763 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25764 static void Log(const param_type& p, std::string* l);
765};
766
767template <>
Ken Rockot3044d212018-01-23 02:44:39768struct COMPONENT_EXPORT(IPC) ParamTraits<base::TimeDelta> {
[email protected]bf5aedf02012-06-04 21:18:25769 typedef base::TimeDelta param_type;
rockot502c94f2016-02-03 20:20:16770 static void Write(base::Pickle* m, const param_type& p);
771 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25772 base::PickleIterator* iter,
773 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25774 static void Log(const param_type& p, std::string* l);
775};
776
777template <>
Ken Rockot3044d212018-01-23 02:44:39778struct COMPONENT_EXPORT(IPC) ParamTraits<base::TimeTicks> {
[email protected]bf5aedf02012-06-04 21:18:25779 typedef base::TimeTicks param_type;
rockot502c94f2016-02-03 20:20:16780 static void Write(base::Pickle* m, const param_type& p);
781 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25782 base::PickleIterator* iter,
783 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25784 static void Log(const param_type& p, std::string* l);
[email protected]503683f2009-02-26 09:13:01785};
786
787template <>
Ken Rockot3044d212018-01-23 02:44:39788struct COMPONENT_EXPORT(IPC) ParamTraits<base::UnguessableToken> {
tguilbert4a5ac602016-09-19 21:11:25789 typedef base::UnguessableToken param_type;
tguilbert4a5ac602016-09-19 21:11:25790 static void Write(base::Pickle* m, const param_type& p);
791 static bool Read(const base::Pickle* m,
792 base::PickleIterator* iter,
793 param_type* r);
794 static void Log(const param_type& p, std::string* l);
795};
796
797template <>
tzik9ca302192016-02-11 10:24:45798struct ParamTraits<std::tuple<>> {
799 typedef std::tuple<> param_type;
rockot502c94f2016-02-03 20:20:16800 static void Write(base::Pickle* m, const param_type& p) {}
801 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25802 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47803 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19804 return true;
805 }
[email protected]252cad62010-08-18 18:33:57806 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19807 }
808};
809
ossufdd19a32017-06-22 09:35:39810template <typename T, int index, int count>
811struct TupleParamTraitsHelper {
812 using Next = TupleParamTraitsHelper<T, index + 1, count>;
813
ossufdd19a32017-06-22 09:35:39814 static void Write(base::Pickle* m, const T& p) {
815 WriteParam(m, std::get<index>(p));
816 Next::Write(m, p);
[email protected]7d5c3ac2009-02-04 08:58:19817 }
ossufdd19a32017-06-22 09:35:39818
819 static bool Read(const base::Pickle* m, base::PickleIterator* iter, T* r) {
820 return ReadParam(m, iter, &std::get<index>(*r)) && Next::Read(m, iter, r);
[email protected]7d5c3ac2009-02-04 08:58:19821 }
ossufdd19a32017-06-22 09:35:39822
823 static void Log(const T& p, std::string* l) {
824 LogParam(std::get<index>(p), l);
825 if (index < count - 1)
826 l->append(", ");
827 Next::Log(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19828 }
829};
830
ossufdd19a32017-06-22 09:35:39831template <typename T, int index>
832struct TupleParamTraitsHelper<T, index, index> {
ossufdd19a32017-06-22 09:35:39833 static void Write(base::Pickle* m, const T& p) {}
834 static bool Read(const base::Pickle* m, base::PickleIterator* iter, T* r) {
835 return true;
rockot0457af102016-02-05 02:12:32836 }
ossufdd19a32017-06-22 09:35:39837 static void Log(const T& p, std::string* l) {}
[email protected]7d5c3ac2009-02-04 08:58:19838};
839
ossufdd19a32017-06-22 09:35:39840template <typename... Args>
841struct ParamTraits<std::tuple<Args...>> {
842 using param_type = std::tuple<Args...>;
843 using Helper =
844 TupleParamTraitsHelper<param_type, 0, std::tuple_size<param_type>::value>;
[email protected]7d5c3ac2009-02-04 08:58:19845
rockot502c94f2016-02-03 20:20:16846 static void Write(base::Pickle* m, const param_type& p) {
ossufdd19a32017-06-22 09:35:39847 Helper::Write(m, p);
[email protected]7d5c3ac2009-02-04 08:58:19848 }
ossufdd19a32017-06-22 09:35:39849
rockot502c94f2016-02-03 20:20:16850 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25851 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47852 param_type* r) {
ossufdd19a32017-06-22 09:35:39853 return Helper::Read(m, iter, r);
[email protected]7d5c3ac2009-02-04 08:58:19854 }
ossufdd19a32017-06-22 09:35:39855
856 static void Log(const param_type& p, std::string* l) { Helper::Log(p, l); }
[email protected]7d5c3ac2009-02-04 08:58:19857};
858
miletus1edf97f92015-07-23 19:42:36859template <class P, size_t stack_capacity>
860struct ParamTraits<base::StackVector<P, stack_capacity> > {
861 typedef base::StackVector<P, stack_capacity> param_type;
rockot502c94f2016-02-03 20:20:16862 static void Write(base::Pickle* m, const param_type& p) {
Chris Palmerc5ea9b92017-09-25 22:53:22863 WriteParam(m, base::checked_cast<int>(p->size()));
miletus1edf97f92015-07-23 19:42:36864 for (size_t i = 0; i < p->size(); i++)
865 WriteParam(m, p[i]);
866 }
rockot502c94f2016-02-03 20:20:16867 static bool Read(const base::Pickle* m,
miletus1edf97f92015-07-23 19:42:36868 base::PickleIterator* iter,
869 param_type* r) {
870 int size;
871 // ReadLength() checks for < 0 itself.
872 if (!iter->ReadLength(&size))
873 return false;
874 // Sanity check for the vector size.
875 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
876 return false;
877 P value;
878 for (int i = 0; i < size; i++) {
879 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
[email protected]205294b2014-03-18 20:48:35894template <typename NormalMap,
895 int kArraySize,
896 typename EqualKey,
897 typename MapInit>
brettwca2ec7632017-04-20 06:10:20898struct ParamTraits<base::small_map<NormalMap, kArraySize, EqualKey, MapInit>> {
899 using param_type = base::small_map<NormalMap, kArraySize, EqualKey, MapInit>;
900 using K = typename param_type::key_type;
901 using V = typename param_type::data_type;
rockot502c94f2016-02-03 20:20:16902 static void Write(base::Pickle* m, const param_type& p) {
Chris Palmerc5ea9b92017-09-25 22:53:22903 WriteParam(m, base::checked_cast<int>(p.size()));
[email protected]205294b2014-03-18 20:48:35904 typename param_type::const_iterator iter;
905 for (iter = p.begin(); iter != p.end(); ++iter) {
906 WriteParam(m, iter->first);
907 WriteParam(m, iter->second);
908 }
909 }
rockot502c94f2016-02-03 20:20:16910 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25911 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47912 param_type* r) {
[email protected]205294b2014-03-18 20:48:35913 int size;
avi48fc13b2014-12-28 23:31:48914 if (!iter->ReadLength(&size))
[email protected]205294b2014-03-18 20:48:35915 return false;
916 for (int i = 0; i < size; ++i) {
917 K key;
918 if (!ReadParam(m, iter, &key))
919 return false;
920 V& value = (*r)[key];
921 if (!ReadParam(m, iter, &value))
922 return false;
923 }
924 return true;
925 }
926 static void Log(const param_type& p, std::string* l) {
brettwca2ec7632017-04-20 06:10:20927 l->append("<base::small_map>");
928 }
929};
930
931template <class Key, class Mapped, class Compare>
932struct ParamTraits<base::flat_map<Key, Mapped, Compare>> {
933 using param_type = base::flat_map<Key, Mapped, Compare>;
brettwca2ec7632017-04-20 06:10:20934 static void Write(base::Pickle* m, const param_type& p) {
935 DCHECK(base::IsValueInRangeForNumericType<int>(p.size()));
Chris Palmerc5ea9b92017-09-25 22:53:22936 WriteParam(m, base::checked_cast<int>(p.size()));
brettwca2ec7632017-04-20 06:10:20937 for (const auto& iter : p) {
938 WriteParam(m, iter.first);
939 WriteParam(m, iter.second);
940 }
941 }
942 static bool Read(const base::Pickle* m,
943 base::PickleIterator* iter,
944 param_type* r) {
945 int size;
946 if (!iter->ReadLength(&size))
947 return false;
948
949 // Construct by creating in a vector and moving into the flat_map. Properly
950 // serialized flat_maps will be in-order so this will be O(n). Incorrectly
951 // serialized ones will still be handled properly.
952 std::vector<typename param_type::value_type> vect;
953 vect.resize(size);
954 for (int i = 0; i < size; ++i) {
955 if (!ReadParam(m, iter, &vect[i].first))
956 return false;
957 if (!ReadParam(m, iter, &vect[i].second))
958 return false;
959 }
960
961 *r = param_type(std::move(vect), base::KEEP_FIRST_OF_DUPES);
962 return true;
963 }
964 static void Log(const param_type& p, std::string* l) {
965 l->append("<base::flat_map>");
[email protected]205294b2014-03-18 20:48:35966 }
967};
968
[email protected]8e431f2032014-05-20 02:34:56969template <class P>
danakj03de39b22016-04-23 04:21:09970struct ParamTraits<std::unique_ptr<P>> {
971 typedef std::unique_ptr<P> param_type;
rockot502c94f2016-02-03 20:20:16972 static void Write(base::Pickle* m, const param_type& p) {
[email protected]8e431f2032014-05-20 02:34:56973 bool valid = !!p;
974 WriteParam(m, valid);
975 if (valid)
976 WriteParam(m, *p);
977 }
rockot502c94f2016-02-03 20:20:16978 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:25979 base::PickleIterator* iter,
brettw05cfd8ddb2015-06-02 07:02:47980 param_type* r) {
[email protected]8e431f2032014-05-20 02:34:56981 bool valid = false;
982 if (!ReadParam(m, iter, &valid))
983 return false;
984
985 if (!valid) {
986 r->reset();
987 return true;
988 }
989
990 param_type temp(new P());
991 if (!ReadParam(m, iter, temp.get()))
992 return false;
993
994 r->swap(temp);
995 return true;
996 }
997 static void Log(const param_type& p, std::string* l) {
998 if (p)
999 LogParam(*p, l);
1000 else
1001 l->append("NULL");
1002 }
1003};
1004
bmcquade18573e12016-07-01 13:13:501005template <class P>
1006struct ParamTraits<base::Optional<P>> {
1007 typedef base::Optional<P> param_type;
bmcquade18573e12016-07-01 13:13:501008 static void Write(base::Pickle* m, const param_type& p) {
1009 const bool is_set = static_cast<bool>(p);
1010 WriteParam(m, is_set);
1011 if (is_set)
1012 WriteParam(m, p.value());
1013 }
1014 static bool Read(const base::Pickle* m,
1015 base::PickleIterator* iter,
1016 param_type* r) {
1017 bool is_set = false;
1018 if (!iter->ReadBool(&is_set))
1019 return false;
1020 if (is_set) {
1021 P value;
1022 if (!ReadParam(m, iter, &value))
1023 return false;
1024 *r = std::move(value);
1025 }
1026 return true;
1027 }
1028 static void Log(const param_type& p, std::string* l) {
1029 if (p)
1030 LogParam(p.value(), l);
1031 else
1032 l->append("(unset)");
1033 }
1034};
1035
Maciej Pawlowski4a3ac6852019-05-09 17:06:141036// base/util types ParamTraits
1037
1038template <typename TypeMarker, typename WrappedType, WrappedType kInvalidValue>
1039struct ParamTraits<util::IdType<TypeMarker, WrappedType, kInvalidValue>> {
1040 using param_type = util::IdType<TypeMarker, WrappedType, kInvalidValue>;
1041 static void Write(base::Pickle* m, const param_type& p) {
1042 WriteParam(m, p.GetUnsafeValue());
1043 }
1044 static bool Read(const base::Pickle* m,
1045 base::PickleIterator* iter,
1046 param_type* r) {
1047 WrappedType value;
1048 if (!ReadParam(m, iter, &value))
1049 return false;
1050 *r = param_type::FromUnsafeValue(value);
1051 return true;
1052 }
1053 static void Log(const param_type& p, std::string* l) {
1054 LogParam(p.GetUnsafeValue(), l);
1055 }
1056};
1057
Maciej Pawlowskic00800e2019-05-23 08:43:031058template <typename TagType, typename UnderlyingType>
1059struct ParamTraits<util::StrongAlias<TagType, UnderlyingType>> {
1060 using param_type = util::StrongAlias<TagType, UnderlyingType>;
1061 static void Write(base::Pickle* m, const param_type& p) {
1062 WriteParam(m, p.value());
1063 }
1064 static bool Read(const base::Pickle* m,
1065 base::PickleIterator* iter,
1066 param_type* r) {
1067 UnderlyingType value;
1068 if (!ReadParam(m, iter, &value))
1069 return false;
1070 *r = param_type::StrongAlias(value);
1071 return true;
1072 }
1073 static void Log(const param_type& p, std::string* l) {
1074 LogParam(p.value(), l);
1075 }
1076};
1077
[email protected]bf5aedf02012-06-04 21:18:251078// IPC types ParamTraits -------------------------------------------------------
1079
1080// A ChannelHandle is basically a platform-inspecific wrapper around the
1081// fact that IPC endpoints are handled specially on POSIX. See above comments
1082// on FileDescriptor for more background.
Ken Rockot3044d212018-01-23 02:44:391083template <>
1084struct COMPONENT_EXPORT(IPC) ParamTraits<IPC::ChannelHandle> {
[email protected]bf5aedf02012-06-04 21:18:251085 typedef ChannelHandle param_type;
rockot502c94f2016-02-03 20:20:161086 static void Write(base::Pickle* m, const param_type& p);
1087 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251088 base::PickleIterator* iter,
1089 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:251090 static void Log(const param_type& p, std::string* l);
1091};
1092
1093template <>
Ken Rockot3044d212018-01-23 02:44:391094struct COMPONENT_EXPORT(IPC) ParamTraits<LogData> {
[email protected]bf5aedf02012-06-04 21:18:251095 typedef LogData param_type;
rockot502c94f2016-02-03 20:20:161096 static void Write(base::Pickle* m, const param_type& p);
1097 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251098 base::PickleIterator* iter,
1099 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:251100 static void Log(const param_type& p, std::string* l);
1101};
1102
1103template <>
Ken Rockot3044d212018-01-23 02:44:391104struct COMPONENT_EXPORT(IPC) ParamTraits<Message> {
rockot502c94f2016-02-03 20:20:161105 static void Write(base::Pickle* m, const Message& p);
1106 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251107 base::PickleIterator* iter,
1108 Message* r);
[email protected]bf5aedf02012-06-04 21:18:251109 static void Log(const Message& p, std::string* l);
1110};
1111
1112// Windows ParamTraits ---------------------------------------------------------
1113
1114#if defined(OS_WIN)
1115template <>
Ken Rockot3044d212018-01-23 02:44:391116struct COMPONENT_EXPORT(IPC) ParamTraits<HANDLE> {
[email protected]bf5aedf02012-06-04 21:18:251117 typedef HANDLE param_type;
rockot502c94f2016-02-03 20:20:161118 static void Write(base::Pickle* m, const param_type& p);
1119 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251120 base::PickleIterator* iter,
1121 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:251122 static void Log(const param_type& p, std::string* l);
1123};
1124
1125template <>
Ken Rockot3044d212018-01-23 02:44:391126struct COMPONENT_EXPORT(IPC) ParamTraits<MSG> {
[email protected]bf5aedf02012-06-04 21:18:251127 typedef MSG param_type;
rockot502c94f2016-02-03 20:20:161128 static void Write(base::Pickle* m, const param_type& p);
1129 static bool Read(const base::Pickle* m,
brettwbd4d7112015-06-03 04:29:251130 base::PickleIterator* iter,
1131 param_type* r);
[email protected]bf5aedf02012-06-04 21:18:251132 static void Log(const param_type& p, std::string* l);
1133};
1134#endif // defined(OS_WIN)
1135
[email protected]7d5c3ac2009-02-04 08:58:191136//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:291137// Generic message subclasses
1138
[email protected]7a4de7a62010-08-17 18:38:241139// defined in ipc_logging.cc
Ken Rockot3044d212018-01-23 02:44:391140COMPONENT_EXPORT(IPC)
1141void GenerateLogData(const Message& message, LogData* data, bool get_params);
[email protected]7a4de7a62010-08-17 18:38:241142
davidsz041528a2017-05-12 09:19:231143#if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
[email protected]252cad62010-08-18 18:33:571144inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
1145 const std::string& output_params = msg->output_params();
[email protected]7a4de7a62010-08-17 18:38:241146 if (!l->empty() && !output_params.empty())
[email protected]252cad62010-08-18 18:33:571147 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:241148
1149 l->append(output_params);
1150}
1151
1152template <class ReplyParamType>
1153inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1154 const Message* msg) {
1155 if (msg->received_time() != 0) {
[email protected]252cad62010-08-18 18:33:571156 std::string output_params;
[email protected]7a4de7a62010-08-17 18:38:241157 LogParam(reply_params, &output_params);
1158 msg->set_output_params(output_params);
1159 }
1160}
1161
1162inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
1163 if (msg->sent_time()) {
1164 // Don't log the sync message after dispatch, as we don't have the
1165 // output parameters at that point. Instead, save its data and log it
1166 // with the outgoing reply message when it's sent.
1167 LogData* data = new LogData;
sammca1b3b4d2016-11-15 00:34:361168 GenerateLogData(*msg, data, true);
[email protected]7a4de7a62010-08-17 18:38:241169 msg->set_dont_log();
1170 reply->set_sync_log_data(data);
1171 }
1172}
1173#else
[email protected]252cad62010-08-18 18:33:571174inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
[email protected]7a4de7a62010-08-17 18:38:241175
1176template <class ReplyParamType>
1177inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1178 const Message* msg) {}
1179
1180inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1181#endif
1182
[email protected]3178f4e22008-08-05 21:20:411183} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291184
[email protected]946d1b22009-07-22 23:57:211185#endif // IPC_IPC_MESSAGE_UTILS_H_