1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #ifndef IPC_IPC_MESSAGE_UTILS_H_
6*6777b538SAndroid Build Coastguard Worker #define IPC_IPC_MESSAGE_UTILS_H_
7*6777b538SAndroid Build Coastguard Worker
8*6777b538SAndroid Build Coastguard Worker #include <limits.h>
9*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
10*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
11*6777b538SAndroid Build Coastguard Worker
12*6777b538SAndroid Build Coastguard Worker #include <map>
13*6777b538SAndroid Build Coastguard Worker #include <memory>
14*6777b538SAndroid Build Coastguard Worker #include <optional>
15*6777b538SAndroid Build Coastguard Worker #include <set>
16*6777b538SAndroid Build Coastguard Worker #include <string>
17*6777b538SAndroid Build Coastguard Worker #include <tuple>
18*6777b538SAndroid Build Coastguard Worker #include <unordered_map>
19*6777b538SAndroid Build Coastguard Worker #include <vector>
20*6777b538SAndroid Build Coastguard Worker
21*6777b538SAndroid Build Coastguard Worker #include "base/check.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/compiler_specific.h"
23*6777b538SAndroid Build Coastguard Worker #include "base/component_export.h"
24*6777b538SAndroid Build Coastguard Worker #include "base/containers/flat_map.h"
25*6777b538SAndroid Build Coastguard Worker #include "base/files/file.h"
26*6777b538SAndroid Build Coastguard Worker #include "base/memory/platform_shared_memory_region.h"
27*6777b538SAndroid Build Coastguard Worker #include "base/memory/read_only_shared_memory_region.h"
28*6777b538SAndroid Build Coastguard Worker #include "base/memory/unsafe_shared_memory_region.h"
29*6777b538SAndroid Build Coastguard Worker #include "base/memory/writable_shared_memory_region.h"
30*6777b538SAndroid Build Coastguard Worker #include "base/numerics/safe_conversions.h"
31*6777b538SAndroid Build Coastguard Worker #include "base/pickle.h"
32*6777b538SAndroid Build Coastguard Worker #include "base/types/id_type.h"
33*6777b538SAndroid Build Coastguard Worker #include "base/values.h"
34*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
35*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_buildflags.h"
36*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_param_traits.h"
37*6777b538SAndroid Build Coastguard Worker #include "third_party/abseil-cpp/absl/container/inlined_vector.h"
38*6777b538SAndroid Build Coastguard Worker
39*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_ANDROID)
40*6777b538SAndroid Build Coastguard Worker #include "base/android/scoped_hardware_buffer_handle.h"
41*6777b538SAndroid Build Coastguard Worker #endif
42*6777b538SAndroid Build Coastguard Worker
43*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_FUCHSIA)
44*6777b538SAndroid Build Coastguard Worker #include <lib/zx/channel.h>
45*6777b538SAndroid Build Coastguard Worker #include <lib/zx/vmo.h>
46*6777b538SAndroid Build Coastguard Worker #endif
47*6777b538SAndroid Build Coastguard Worker
48*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
49*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_util_win.h"
50*6777b538SAndroid Build Coastguard Worker #endif
51*6777b538SAndroid Build Coastguard Worker
52*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
53*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_message.h"
54*6777b538SAndroid Build Coastguard Worker #endif
55*6777b538SAndroid Build Coastguard Worker
56*6777b538SAndroid Build Coastguard Worker namespace base {
57*6777b538SAndroid Build Coastguard Worker class FilePath;
58*6777b538SAndroid Build Coastguard Worker class Time;
59*6777b538SAndroid Build Coastguard Worker class TimeDelta;
60*6777b538SAndroid Build Coastguard Worker class TimeTicks;
61*6777b538SAndroid Build Coastguard Worker class UnguessableToken;
62*6777b538SAndroid Build Coastguard Worker struct FileDescriptor;
63*6777b538SAndroid Build Coastguard Worker } // namespace base
64*6777b538SAndroid Build Coastguard Worker
65*6777b538SAndroid Build Coastguard Worker namespace IPC {
66*6777b538SAndroid Build Coastguard Worker
67*6777b538SAndroid Build Coastguard Worker class Message;
68*6777b538SAndroid Build Coastguard Worker struct ChannelHandle;
69*6777b538SAndroid Build Coastguard Worker
70*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
71*6777b538SAndroid Build Coastguard Worker class PlatformFileForTransit;
72*6777b538SAndroid Build Coastguard Worker #endif
73*6777b538SAndroid Build Coastguard Worker
74*6777b538SAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
75*6777b538SAndroid Build Coastguard Worker // How we send IPC message logs across channels.
COMPONENT_EXPORT(IPC)76*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) LogData {
77*6777b538SAndroid Build Coastguard Worker LogData();
78*6777b538SAndroid Build Coastguard Worker LogData(const LogData& other);
79*6777b538SAndroid Build Coastguard Worker ~LogData();
80*6777b538SAndroid Build Coastguard Worker
81*6777b538SAndroid Build Coastguard Worker std::string channel;
82*6777b538SAndroid Build Coastguard Worker int32_t routing_id;
83*6777b538SAndroid Build Coastguard Worker uint32_t type; // "User-defined" message type, from ipc_message.h.
84*6777b538SAndroid Build Coastguard Worker std::string flags;
85*6777b538SAndroid Build Coastguard Worker int64_t sent; // Time that the message was sent (i.e. at Send()).
86*6777b538SAndroid Build Coastguard Worker int64_t receive; // Time before it was dispatched (i.e. before calling
87*6777b538SAndroid Build Coastguard Worker // OnMessageReceived).
88*6777b538SAndroid Build Coastguard Worker int64_t dispatch; // Time after it was dispatched (i.e. after calling
89*6777b538SAndroid Build Coastguard Worker // OnMessageReceived).
90*6777b538SAndroid Build Coastguard Worker std::string message_name;
91*6777b538SAndroid Build Coastguard Worker std::string params;
92*6777b538SAndroid Build Coastguard Worker };
93*6777b538SAndroid Build Coastguard Worker
94*6777b538SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
95*6777b538SAndroid Build Coastguard Worker
96*6777b538SAndroid Build Coastguard Worker // A dummy struct to place first just to allow leading commas for all
97*6777b538SAndroid Build Coastguard Worker // members in the macro-generated constructor initializer lists.
98*6777b538SAndroid Build Coastguard Worker struct NoParams {
99*6777b538SAndroid Build Coastguard Worker };
100*6777b538SAndroid Build Coastguard Worker
101*6777b538SAndroid Build Coastguard Worker // Specializations are checked by 'IPC checker' part of find-bad-constructs
102*6777b538SAndroid Build Coastguard Worker // Clang plugin (see WriteParam() below for the details).
103*6777b538SAndroid Build Coastguard Worker template <typename... Ts>
104*6777b538SAndroid Build Coastguard Worker struct CheckedTuple {
105*6777b538SAndroid Build Coastguard Worker typedef std::tuple<Ts...> Tuple;
106*6777b538SAndroid Build Coastguard Worker };
107*6777b538SAndroid Build Coastguard Worker
108*6777b538SAndroid Build Coastguard Worker // This function is checked by 'IPC checker' part of find-bad-constructs
109*6777b538SAndroid Build Coastguard Worker // Clang plugin to make it's not called on the following types:
110*6777b538SAndroid Build Coastguard Worker // 1. long / unsigned long (but not typedefs to)
111*6777b538SAndroid Build Coastguard Worker // 2. intmax_t, uintmax_t, intptr_t, uintptr_t, wint_t,
112*6777b538SAndroid Build Coastguard Worker // size_t, rsize_t, ssize_t, ptrdiff_t, dev_t, off_t, clock_t,
113*6777b538SAndroid Build Coastguard Worker // time_t, suseconds_t (including typedefs to)
114*6777b538SAndroid Build Coastguard Worker // 3. Any template referencing types above (e.g. std::vector<size_t>)
115*6777b538SAndroid Build Coastguard Worker template <class P>
WriteParam(base::Pickle * m,const P & p)116*6777b538SAndroid Build Coastguard Worker inline void WriteParam(base::Pickle* m, const P& p) {
117*6777b538SAndroid Build Coastguard Worker typedef typename SimilarTypeTraits<P>::Type Type;
118*6777b538SAndroid Build Coastguard Worker ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
119*6777b538SAndroid Build Coastguard Worker }
120*6777b538SAndroid Build Coastguard Worker
121*6777b538SAndroid Build Coastguard Worker template <class P>
ReadParam(const base::Pickle * m,base::PickleIterator * iter,P * p)122*6777b538SAndroid Build Coastguard Worker [[nodiscard]] inline bool ReadParam(const base::Pickle* m,
123*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
124*6777b538SAndroid Build Coastguard Worker P* p) {
125*6777b538SAndroid Build Coastguard Worker typedef typename SimilarTypeTraits<P>::Type Type;
126*6777b538SAndroid Build Coastguard Worker return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
127*6777b538SAndroid Build Coastguard Worker }
128*6777b538SAndroid Build Coastguard Worker
129*6777b538SAndroid Build Coastguard Worker template <class P>
LogParam(const P & p,std::string * l)130*6777b538SAndroid Build Coastguard Worker inline void LogParam(const P& p, std::string* l) {
131*6777b538SAndroid Build Coastguard Worker typedef typename SimilarTypeTraits<P>::Type Type;
132*6777b538SAndroid Build Coastguard Worker ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
133*6777b538SAndroid Build Coastguard Worker }
134*6777b538SAndroid Build Coastguard Worker
135*6777b538SAndroid Build Coastguard Worker // Primitive ParamTraits -------------------------------------------------------
136*6777b538SAndroid Build Coastguard Worker
137*6777b538SAndroid Build Coastguard Worker template <>
138*6777b538SAndroid Build Coastguard Worker struct ParamTraits<bool> {
139*6777b538SAndroid Build Coastguard Worker typedef bool param_type;
140*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p) { m->WriteBool(p); }
141*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
142*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
143*6777b538SAndroid Build Coastguard Worker param_type* r) {
144*6777b538SAndroid Build Coastguard Worker return iter->ReadBool(r);
145*6777b538SAndroid Build Coastguard Worker }
146*6777b538SAndroid Build Coastguard Worker COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
147*6777b538SAndroid Build Coastguard Worker };
148*6777b538SAndroid Build Coastguard Worker
149*6777b538SAndroid Build Coastguard Worker template <>
150*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<signed char> {
151*6777b538SAndroid Build Coastguard Worker typedef signed char param_type;
152*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
153*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
154*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
155*6777b538SAndroid Build Coastguard Worker param_type* r);
156*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
157*6777b538SAndroid Build Coastguard Worker };
158*6777b538SAndroid Build Coastguard Worker
159*6777b538SAndroid Build Coastguard Worker template <>
160*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<unsigned char> {
161*6777b538SAndroid Build Coastguard Worker typedef unsigned char param_type;
162*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
163*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
164*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
165*6777b538SAndroid Build Coastguard Worker param_type* r);
166*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
167*6777b538SAndroid Build Coastguard Worker };
168*6777b538SAndroid Build Coastguard Worker
169*6777b538SAndroid Build Coastguard Worker template <>
170*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<unsigned short> {
171*6777b538SAndroid Build Coastguard Worker typedef unsigned short param_type;
172*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
173*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
174*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
175*6777b538SAndroid Build Coastguard Worker param_type* r);
176*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
177*6777b538SAndroid Build Coastguard Worker };
178*6777b538SAndroid Build Coastguard Worker
179*6777b538SAndroid Build Coastguard Worker template <>
180*6777b538SAndroid Build Coastguard Worker struct ParamTraits<int> {
181*6777b538SAndroid Build Coastguard Worker typedef int param_type;
182*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p) { m->WriteInt(p); }
183*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
184*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
185*6777b538SAndroid Build Coastguard Worker param_type* r) {
186*6777b538SAndroid Build Coastguard Worker return iter->ReadInt(r);
187*6777b538SAndroid Build Coastguard Worker }
188*6777b538SAndroid Build Coastguard Worker COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
189*6777b538SAndroid Build Coastguard Worker };
190*6777b538SAndroid Build Coastguard Worker
191*6777b538SAndroid Build Coastguard Worker template <>
192*6777b538SAndroid Build Coastguard Worker struct ParamTraits<unsigned int> {
193*6777b538SAndroid Build Coastguard Worker typedef unsigned int param_type;
194*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p) {
195*6777b538SAndroid Build Coastguard Worker m->WriteInt(static_cast<int>(p));
196*6777b538SAndroid Build Coastguard Worker }
197*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
198*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
199*6777b538SAndroid Build Coastguard Worker param_type* r) {
200*6777b538SAndroid Build Coastguard Worker return iter->ReadInt(reinterpret_cast<int*>(r));
201*6777b538SAndroid Build Coastguard Worker }
202*6777b538SAndroid Build Coastguard Worker COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
203*6777b538SAndroid Build Coastguard Worker };
204*6777b538SAndroid Build Coastguard Worker
205*6777b538SAndroid Build Coastguard Worker // long isn't safe to send over IPC because it's 4 bytes on 32 bit builds but
206*6777b538SAndroid Build Coastguard Worker // 8 bytes on 64 bit builds. So if a 32 bit and 64 bit process have a channel
207*6777b538SAndroid Build Coastguard Worker // that would cause problem.
208*6777b538SAndroid Build Coastguard Worker // We need to keep this on for a few configs:
209*6777b538SAndroid Build Coastguard Worker // 1) Windows because DWORD is typedef'd to it, which is fine because we have
210*6777b538SAndroid Build Coastguard Worker // very few IPCs that cross this boundary.
211*6777b538SAndroid Build Coastguard Worker // 2) We also need to keep it for Linux for two reasons: int64_t is typedef'd
212*6777b538SAndroid Build Coastguard Worker // to long, and gfx::PluginWindow is long and is used in one GPU IPC.
213*6777b538SAndroid Build Coastguard Worker // 3) Android 64 bit and Fuchsia also have int64_t typedef'd to long.
214*6777b538SAndroid Build Coastguard Worker // Since we want to support Android 32<>64 bit IPC, as long as we don't have
215*6777b538SAndroid Build Coastguard Worker // these traits for 32 bit ARM then that'll catch any errors.
216*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
217*6777b538SAndroid Build Coastguard Worker BUILDFLAG(IS_FUCHSIA) || \
218*6777b538SAndroid Build Coastguard Worker (BUILDFLAG(IS_ANDROID) && defined(ARCH_CPU_64_BITS))
219*6777b538SAndroid Build Coastguard Worker template <>
220*6777b538SAndroid Build Coastguard Worker struct ParamTraits<long> {
221*6777b538SAndroid Build Coastguard Worker typedef long param_type;
222*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p) {
223*6777b538SAndroid Build Coastguard Worker m->WriteLong(p);
224*6777b538SAndroid Build Coastguard Worker }
225*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
226*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
227*6777b538SAndroid Build Coastguard Worker param_type* r) {
228*6777b538SAndroid Build Coastguard Worker return iter->ReadLong(r);
229*6777b538SAndroid Build Coastguard Worker }
230*6777b538SAndroid Build Coastguard Worker COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
231*6777b538SAndroid Build Coastguard Worker };
232*6777b538SAndroid Build Coastguard Worker
233*6777b538SAndroid Build Coastguard Worker template <>
234*6777b538SAndroid Build Coastguard Worker struct ParamTraits<unsigned long> {
235*6777b538SAndroid Build Coastguard Worker typedef unsigned long param_type;
236*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p) {
237*6777b538SAndroid Build Coastguard Worker m->WriteLong(p);
238*6777b538SAndroid Build Coastguard Worker }
239*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
240*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
241*6777b538SAndroid Build Coastguard Worker param_type* r) {
242*6777b538SAndroid Build Coastguard Worker return iter->ReadLong(reinterpret_cast<long*>(r));
243*6777b538SAndroid Build Coastguard Worker }
244*6777b538SAndroid Build Coastguard Worker COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
245*6777b538SAndroid Build Coastguard Worker };
246*6777b538SAndroid Build Coastguard Worker #endif
247*6777b538SAndroid Build Coastguard Worker
248*6777b538SAndroid Build Coastguard Worker template <>
249*6777b538SAndroid Build Coastguard Worker struct ParamTraits<long long> {
250*6777b538SAndroid Build Coastguard Worker typedef long long param_type;
251*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p) {
252*6777b538SAndroid Build Coastguard Worker m->WriteInt64(static_cast<int64_t>(p));
253*6777b538SAndroid Build Coastguard Worker }
254*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
255*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
256*6777b538SAndroid Build Coastguard Worker param_type* r) {
257*6777b538SAndroid Build Coastguard Worker return iter->ReadInt64(reinterpret_cast<int64_t*>(r));
258*6777b538SAndroid Build Coastguard Worker }
259*6777b538SAndroid Build Coastguard Worker COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
260*6777b538SAndroid Build Coastguard Worker };
261*6777b538SAndroid Build Coastguard Worker
262*6777b538SAndroid Build Coastguard Worker template <>
263*6777b538SAndroid Build Coastguard Worker struct ParamTraits<unsigned long long> {
264*6777b538SAndroid Build Coastguard Worker typedef unsigned long long param_type;
265*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p) {
266*6777b538SAndroid Build Coastguard Worker m->WriteInt64(static_cast<int64_t>(p));
267*6777b538SAndroid Build Coastguard Worker }
268*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
269*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
270*6777b538SAndroid Build Coastguard Worker param_type* r) {
271*6777b538SAndroid Build Coastguard Worker return iter->ReadInt64(reinterpret_cast<int64_t*>(r));
272*6777b538SAndroid Build Coastguard Worker }
273*6777b538SAndroid Build Coastguard Worker COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
274*6777b538SAndroid Build Coastguard Worker };
275*6777b538SAndroid Build Coastguard Worker
276*6777b538SAndroid Build Coastguard Worker // Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
277*6777b538SAndroid Build Coastguard Worker // should be sure to check the sanity of these values after receiving them over
278*6777b538SAndroid Build Coastguard Worker // IPC.
279*6777b538SAndroid Build Coastguard Worker template <>
280*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<float> {
281*6777b538SAndroid Build Coastguard Worker typedef float param_type;
282*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p) { m->WriteFloat(p); }
283*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
284*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
285*6777b538SAndroid Build Coastguard Worker param_type* r) {
286*6777b538SAndroid Build Coastguard Worker return iter->ReadFloat(r);
287*6777b538SAndroid Build Coastguard Worker }
288*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
289*6777b538SAndroid Build Coastguard Worker };
290*6777b538SAndroid Build Coastguard Worker
291*6777b538SAndroid Build Coastguard Worker template <>
292*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<double> {
293*6777b538SAndroid Build Coastguard Worker typedef double param_type;
294*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
295*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
296*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
297*6777b538SAndroid Build Coastguard Worker param_type* r);
298*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
299*6777b538SAndroid Build Coastguard Worker };
300*6777b538SAndroid Build Coastguard Worker
301*6777b538SAndroid Build Coastguard Worker template <class P, size_t Size>
302*6777b538SAndroid Build Coastguard Worker struct ParamTraits<P[Size]> {
303*6777b538SAndroid Build Coastguard Worker using param_type = P[Size];
304*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p) {
305*6777b538SAndroid Build Coastguard Worker for (const P& element : p)
306*6777b538SAndroid Build Coastguard Worker WriteParam(m, element);
307*6777b538SAndroid Build Coastguard Worker }
308*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
309*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
310*6777b538SAndroid Build Coastguard Worker param_type* r) {
311*6777b538SAndroid Build Coastguard Worker for (P& element : *r) {
312*6777b538SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &element))
313*6777b538SAndroid Build Coastguard Worker return false;
314*6777b538SAndroid Build Coastguard Worker }
315*6777b538SAndroid Build Coastguard Worker return true;
316*6777b538SAndroid Build Coastguard Worker }
317*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l) {
318*6777b538SAndroid Build Coastguard Worker l->append("[");
319*6777b538SAndroid Build Coastguard Worker for (const P& element : p) {
320*6777b538SAndroid Build Coastguard Worker if (&element != &p[0])
321*6777b538SAndroid Build Coastguard Worker l->append(" ");
322*6777b538SAndroid Build Coastguard Worker LogParam(element, l);
323*6777b538SAndroid Build Coastguard Worker }
324*6777b538SAndroid Build Coastguard Worker l->append("]");
325*6777b538SAndroid Build Coastguard Worker }
326*6777b538SAndroid Build Coastguard Worker };
327*6777b538SAndroid Build Coastguard Worker
328*6777b538SAndroid Build Coastguard Worker // STL ParamTraits -------------------------------------------------------------
329*6777b538SAndroid Build Coastguard Worker
330*6777b538SAndroid Build Coastguard Worker template <>
331*6777b538SAndroid Build Coastguard Worker struct ParamTraits<std::string> {
332*6777b538SAndroid Build Coastguard Worker typedef std::string param_type;
333*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p) { m->WriteString(p); }
334*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
335*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
336*6777b538SAndroid Build Coastguard Worker param_type* r) {
337*6777b538SAndroid Build Coastguard Worker return iter->ReadString(r);
338*6777b538SAndroid Build Coastguard Worker }
339*6777b538SAndroid Build Coastguard Worker COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
340*6777b538SAndroid Build Coastguard Worker };
341*6777b538SAndroid Build Coastguard Worker
342*6777b538SAndroid Build Coastguard Worker template <>
343*6777b538SAndroid Build Coastguard Worker struct ParamTraits<std::u16string> {
344*6777b538SAndroid Build Coastguard Worker typedef std::u16string param_type;
345*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p) {
346*6777b538SAndroid Build Coastguard Worker m->WriteString16(p);
347*6777b538SAndroid Build Coastguard Worker }
348*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
349*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
350*6777b538SAndroid Build Coastguard Worker param_type* r) {
351*6777b538SAndroid Build Coastguard Worker return iter->ReadString16(r);
352*6777b538SAndroid Build Coastguard Worker }
353*6777b538SAndroid Build Coastguard Worker COMPONENT_EXPORT(IPC) static void Log(const param_type& p, std::string* l);
354*6777b538SAndroid Build Coastguard Worker };
355*6777b538SAndroid Build Coastguard Worker
356*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
357*6777b538SAndroid Build Coastguard Worker template <>
358*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<std::wstring> {
359*6777b538SAndroid Build Coastguard Worker typedef std::wstring param_type;
360*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p) {
361*6777b538SAndroid Build Coastguard Worker m->WriteString16(base::AsStringPiece16(p));
362*6777b538SAndroid Build Coastguard Worker }
363*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
364*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
365*6777b538SAndroid Build Coastguard Worker param_type* r);
366*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
367*6777b538SAndroid Build Coastguard Worker };
368*6777b538SAndroid Build Coastguard Worker #endif
369*6777b538SAndroid Build Coastguard Worker
370*6777b538SAndroid Build Coastguard Worker template <>
371*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<std::vector<char>> {
372*6777b538SAndroid Build Coastguard Worker typedef std::vector<char> param_type;
373*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
374*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle*,
375*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
376*6777b538SAndroid Build Coastguard Worker param_type* r);
377*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
378*6777b538SAndroid Build Coastguard Worker };
379*6777b538SAndroid Build Coastguard Worker
380*6777b538SAndroid Build Coastguard Worker template <>
381*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<std::vector<unsigned char>> {
382*6777b538SAndroid Build Coastguard Worker typedef std::vector<unsigned char> param_type;
383*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
384*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
385*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
386*6777b538SAndroid Build Coastguard Worker param_type* r);
387*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
388*6777b538SAndroid Build Coastguard Worker };
389*6777b538SAndroid Build Coastguard Worker
390*6777b538SAndroid Build Coastguard Worker template <>
391*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<std::vector<bool>> {
392*6777b538SAndroid Build Coastguard Worker typedef std::vector<bool> param_type;
393*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
394*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
395*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
396*6777b538SAndroid Build Coastguard Worker param_type* r);
397*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
398*6777b538SAndroid Build Coastguard Worker };
399*6777b538SAndroid Build Coastguard Worker
400*6777b538SAndroid Build Coastguard Worker template <class P>
401*6777b538SAndroid Build Coastguard Worker struct ParamTraits<std::vector<P>> {
402*6777b538SAndroid Build Coastguard Worker typedef std::vector<P> param_type;
403*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p) {
404*6777b538SAndroid Build Coastguard Worker WriteParam(m, base::checked_cast<int>(p.size()));
405*6777b538SAndroid Build Coastguard Worker for (size_t i = 0; i < p.size(); i++)
406*6777b538SAndroid Build Coastguard Worker WriteParam(m, p[i]);
407*6777b538SAndroid Build Coastguard Worker }
408*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
409*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
410*6777b538SAndroid Build Coastguard Worker param_type* r) {
411*6777b538SAndroid Build Coastguard Worker size_t size;
412*6777b538SAndroid Build Coastguard Worker // ReadLength() checks for < 0 itself.
413*6777b538SAndroid Build Coastguard Worker if (!iter->ReadLength(&size))
414*6777b538SAndroid Build Coastguard Worker return false;
415*6777b538SAndroid Build Coastguard Worker // Resizing beforehand is not safe, see BUG 1006367 for details.
416*6777b538SAndroid Build Coastguard Worker if (size > INT_MAX / sizeof(P))
417*6777b538SAndroid Build Coastguard Worker return false;
418*6777b538SAndroid Build Coastguard Worker r->resize(size);
419*6777b538SAndroid Build Coastguard Worker for (size_t i = 0; i < size; i++) {
420*6777b538SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &(*r)[i]))
421*6777b538SAndroid Build Coastguard Worker return false;
422*6777b538SAndroid Build Coastguard Worker }
423*6777b538SAndroid Build Coastguard Worker return true;
424*6777b538SAndroid Build Coastguard Worker }
425*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l) {
426*6777b538SAndroid Build Coastguard Worker for (size_t i = 0; i < p.size(); ++i) {
427*6777b538SAndroid Build Coastguard Worker if (i != 0)
428*6777b538SAndroid Build Coastguard Worker l->append(" ");
429*6777b538SAndroid Build Coastguard Worker LogParam((p[i]), l);
430*6777b538SAndroid Build Coastguard Worker }
431*6777b538SAndroid Build Coastguard Worker }
432*6777b538SAndroid Build Coastguard Worker };
433*6777b538SAndroid Build Coastguard Worker
434*6777b538SAndroid Build Coastguard Worker template <class P>
435*6777b538SAndroid Build Coastguard Worker struct ParamTraits<std::set<P> > {
436*6777b538SAndroid Build Coastguard Worker typedef std::set<P> param_type;
437*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p) {
438*6777b538SAndroid Build Coastguard Worker WriteParam(m, base::checked_cast<int>(p.size()));
439*6777b538SAndroid Build Coastguard Worker typename param_type::const_iterator iter;
440*6777b538SAndroid Build Coastguard Worker for (iter = p.begin(); iter != p.end(); ++iter)
441*6777b538SAndroid Build Coastguard Worker WriteParam(m, *iter);
442*6777b538SAndroid Build Coastguard Worker }
443*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
444*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
445*6777b538SAndroid Build Coastguard Worker param_type* r) {
446*6777b538SAndroid Build Coastguard Worker size_t size;
447*6777b538SAndroid Build Coastguard Worker if (!iter->ReadLength(&size))
448*6777b538SAndroid Build Coastguard Worker return false;
449*6777b538SAndroid Build Coastguard Worker for (size_t i = 0; i < size; ++i) {
450*6777b538SAndroid Build Coastguard Worker P item;
451*6777b538SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &item))
452*6777b538SAndroid Build Coastguard Worker return false;
453*6777b538SAndroid Build Coastguard Worker r->insert(item);
454*6777b538SAndroid Build Coastguard Worker }
455*6777b538SAndroid Build Coastguard Worker return true;
456*6777b538SAndroid Build Coastguard Worker }
457*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l) {
458*6777b538SAndroid Build Coastguard Worker l->append("<std::set>");
459*6777b538SAndroid Build Coastguard Worker }
460*6777b538SAndroid Build Coastguard Worker };
461*6777b538SAndroid Build Coastguard Worker
462*6777b538SAndroid Build Coastguard Worker template <class K, class V, class C, class A>
463*6777b538SAndroid Build Coastguard Worker struct ParamTraits<std::map<K, V, C, A> > {
464*6777b538SAndroid Build Coastguard Worker typedef std::map<K, V, C, A> param_type;
465*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p) {
466*6777b538SAndroid Build Coastguard Worker WriteParam(m, base::checked_cast<int>(p.size()));
467*6777b538SAndroid Build Coastguard Worker for (const auto& iter : p) {
468*6777b538SAndroid Build Coastguard Worker WriteParam(m, iter.first);
469*6777b538SAndroid Build Coastguard Worker WriteParam(m, iter.second);
470*6777b538SAndroid Build Coastguard Worker }
471*6777b538SAndroid Build Coastguard Worker }
472*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
473*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
474*6777b538SAndroid Build Coastguard Worker param_type* r) {
475*6777b538SAndroid Build Coastguard Worker int size;
476*6777b538SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &size) || size < 0)
477*6777b538SAndroid Build Coastguard Worker return false;
478*6777b538SAndroid Build Coastguard Worker for (int i = 0; i < size; ++i) {
479*6777b538SAndroid Build Coastguard Worker K k;
480*6777b538SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &k))
481*6777b538SAndroid Build Coastguard Worker return false;
482*6777b538SAndroid Build Coastguard Worker V& value = (*r)[k];
483*6777b538SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &value))
484*6777b538SAndroid Build Coastguard Worker return false;
485*6777b538SAndroid Build Coastguard Worker }
486*6777b538SAndroid Build Coastguard Worker return true;
487*6777b538SAndroid Build Coastguard Worker }
488*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l) {
489*6777b538SAndroid Build Coastguard Worker l->append("<std::map>");
490*6777b538SAndroid Build Coastguard Worker }
491*6777b538SAndroid Build Coastguard Worker };
492*6777b538SAndroid Build Coastguard Worker
493*6777b538SAndroid Build Coastguard Worker template <class K, class V, class C, class A>
494*6777b538SAndroid Build Coastguard Worker struct ParamTraits<std::unordered_map<K, V, C, A>> {
495*6777b538SAndroid Build Coastguard Worker typedef std::unordered_map<K, V, C, A> param_type;
496*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p) {
497*6777b538SAndroid Build Coastguard Worker WriteParam(m, base::checked_cast<int>(p.size()));
498*6777b538SAndroid Build Coastguard Worker for (const auto& iter : p) {
499*6777b538SAndroid Build Coastguard Worker WriteParam(m, iter.first);
500*6777b538SAndroid Build Coastguard Worker WriteParam(m, iter.second);
501*6777b538SAndroid Build Coastguard Worker }
502*6777b538SAndroid Build Coastguard Worker }
503*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
504*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
505*6777b538SAndroid Build Coastguard Worker param_type* r) {
506*6777b538SAndroid Build Coastguard Worker int size;
507*6777b538SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &size) || size < 0)
508*6777b538SAndroid Build Coastguard Worker return false;
509*6777b538SAndroid Build Coastguard Worker for (int i = 0; i < size; ++i) {
510*6777b538SAndroid Build Coastguard Worker K k;
511*6777b538SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &k))
512*6777b538SAndroid Build Coastguard Worker return false;
513*6777b538SAndroid Build Coastguard Worker V& value = (*r)[k];
514*6777b538SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &value))
515*6777b538SAndroid Build Coastguard Worker return false;
516*6777b538SAndroid Build Coastguard Worker }
517*6777b538SAndroid Build Coastguard Worker return true;
518*6777b538SAndroid Build Coastguard Worker }
519*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l) {
520*6777b538SAndroid Build Coastguard Worker l->append("<std::unordered_map>");
521*6777b538SAndroid Build Coastguard Worker }
522*6777b538SAndroid Build Coastguard Worker };
523*6777b538SAndroid Build Coastguard Worker
524*6777b538SAndroid Build Coastguard Worker template <class A, class B>
525*6777b538SAndroid Build Coastguard Worker struct ParamTraits<std::pair<A, B> > {
526*6777b538SAndroid Build Coastguard Worker typedef std::pair<A, B> param_type;
527*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p) {
528*6777b538SAndroid Build Coastguard Worker WriteParam(m, p.first);
529*6777b538SAndroid Build Coastguard Worker WriteParam(m, p.second);
530*6777b538SAndroid Build Coastguard Worker }
531*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
532*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
533*6777b538SAndroid Build Coastguard Worker param_type* r) {
534*6777b538SAndroid Build Coastguard Worker return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
535*6777b538SAndroid Build Coastguard Worker }
536*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l) {
537*6777b538SAndroid Build Coastguard Worker l->append("(");
538*6777b538SAndroid Build Coastguard Worker LogParam(p.first, l);
539*6777b538SAndroid Build Coastguard Worker l->append(", ");
540*6777b538SAndroid Build Coastguard Worker LogParam(p.second, l);
541*6777b538SAndroid Build Coastguard Worker l->append(")");
542*6777b538SAndroid Build Coastguard Worker }
543*6777b538SAndroid Build Coastguard Worker };
544*6777b538SAndroid Build Coastguard Worker
545*6777b538SAndroid Build Coastguard Worker // Base ParamTraits ------------------------------------------------------------
546*6777b538SAndroid Build Coastguard Worker
547*6777b538SAndroid Build Coastguard Worker template <>
548*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<base::Value::Dict> {
549*6777b538SAndroid Build Coastguard Worker typedef base::Value::Dict param_type;
550*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
551*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
552*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
553*6777b538SAndroid Build Coastguard Worker param_type* r);
554*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
555*6777b538SAndroid Build Coastguard Worker };
556*6777b538SAndroid Build Coastguard Worker
557*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
558*6777b538SAndroid Build Coastguard Worker // FileDescriptors may be serialised over IPC channels on POSIX. On the
559*6777b538SAndroid Build Coastguard Worker // receiving side, the FileDescriptor is a valid duplicate of the file
560*6777b538SAndroid Build Coastguard Worker // descriptor which was transmitted: *it is not just a copy of the integer like
561*6777b538SAndroid Build Coastguard Worker // HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
562*6777b538SAndroid Build Coastguard Worker // this case, the receiving end will see a value of -1. *Zero is a valid file
563*6777b538SAndroid Build Coastguard Worker // descriptor*.
564*6777b538SAndroid Build Coastguard Worker //
565*6777b538SAndroid Build Coastguard Worker // The received file descriptor will have the |auto_close| flag set to true. The
566*6777b538SAndroid Build Coastguard Worker // code which handles the message is responsible for taking ownership of it.
567*6777b538SAndroid Build Coastguard Worker // File descriptors are OS resources and must be closed when no longer needed.
568*6777b538SAndroid Build Coastguard Worker //
569*6777b538SAndroid Build Coastguard Worker // When sending a file descriptor, the file descriptor must be valid at the time
570*6777b538SAndroid Build Coastguard Worker // of transmission. Since transmission is not synchronous, one should consider
571*6777b538SAndroid Build Coastguard Worker // dup()ing any file descriptors to be transmitted and setting the |auto_close|
572*6777b538SAndroid Build Coastguard Worker // flag, which causes the file descriptor to be closed after writing.
573*6777b538SAndroid Build Coastguard Worker template <>
574*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<base::FileDescriptor> {
575*6777b538SAndroid Build Coastguard Worker typedef base::FileDescriptor param_type;
576*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
577*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
578*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
579*6777b538SAndroid Build Coastguard Worker param_type* r);
580*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
581*6777b538SAndroid Build Coastguard Worker };
582*6777b538SAndroid Build Coastguard Worker
583*6777b538SAndroid Build Coastguard Worker template <>
584*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<base::ScopedFD> {
585*6777b538SAndroid Build Coastguard Worker typedef base::ScopedFD param_type;
586*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
587*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
588*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
589*6777b538SAndroid Build Coastguard Worker param_type* r);
590*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
591*6777b538SAndroid Build Coastguard Worker };
592*6777b538SAndroid Build Coastguard Worker
593*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
594*6777b538SAndroid Build Coastguard Worker
595*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
596*6777b538SAndroid Build Coastguard Worker template <>
597*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<base::win::ScopedHandle> {
598*6777b538SAndroid Build Coastguard Worker using param_type = base::win::ScopedHandle;
599*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
600*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
601*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
602*6777b538SAndroid Build Coastguard Worker param_type* r);
603*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
604*6777b538SAndroid Build Coastguard Worker };
605*6777b538SAndroid Build Coastguard Worker #endif
606*6777b538SAndroid Build Coastguard Worker
607*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_FUCHSIA)
608*6777b538SAndroid Build Coastguard Worker template <>
609*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<zx::vmo> {
610*6777b538SAndroid Build Coastguard Worker typedef zx::vmo param_type;
611*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
612*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
613*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
614*6777b538SAndroid Build Coastguard Worker param_type* r);
615*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
616*6777b538SAndroid Build Coastguard Worker };
617*6777b538SAndroid Build Coastguard Worker
618*6777b538SAndroid Build Coastguard Worker template <>
619*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<zx::channel> {
620*6777b538SAndroid Build Coastguard Worker typedef zx::channel param_type;
621*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
622*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
623*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
624*6777b538SAndroid Build Coastguard Worker param_type* r);
625*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
626*6777b538SAndroid Build Coastguard Worker };
627*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_FUCHSIA)
628*6777b538SAndroid Build Coastguard Worker
629*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_ANDROID)
630*6777b538SAndroid Build Coastguard Worker template <>
631*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC)
632*6777b538SAndroid Build Coastguard Worker ParamTraits<base::android::ScopedHardwareBufferHandle> {
633*6777b538SAndroid Build Coastguard Worker typedef base::android::ScopedHardwareBufferHandle param_type;
634*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
635*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
636*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
637*6777b538SAndroid Build Coastguard Worker param_type* r);
638*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
639*6777b538SAndroid Build Coastguard Worker };
640*6777b538SAndroid Build Coastguard Worker #endif
641*6777b538SAndroid Build Coastguard Worker
642*6777b538SAndroid Build Coastguard Worker template <>
643*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<base::ReadOnlySharedMemoryRegion> {
644*6777b538SAndroid Build Coastguard Worker typedef base::ReadOnlySharedMemoryRegion param_type;
645*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
646*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
647*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
648*6777b538SAndroid Build Coastguard Worker param_type* r);
649*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
650*6777b538SAndroid Build Coastguard Worker };
651*6777b538SAndroid Build Coastguard Worker
652*6777b538SAndroid Build Coastguard Worker template <>
653*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<base::WritableSharedMemoryRegion> {
654*6777b538SAndroid Build Coastguard Worker typedef base::WritableSharedMemoryRegion param_type;
655*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
656*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
657*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
658*6777b538SAndroid Build Coastguard Worker param_type* r);
659*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
660*6777b538SAndroid Build Coastguard Worker };
661*6777b538SAndroid Build Coastguard Worker
662*6777b538SAndroid Build Coastguard Worker template <>
663*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<base::UnsafeSharedMemoryRegion> {
664*6777b538SAndroid Build Coastguard Worker typedef base::UnsafeSharedMemoryRegion param_type;
665*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
666*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
667*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
668*6777b538SAndroid Build Coastguard Worker param_type* r);
669*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
670*6777b538SAndroid Build Coastguard Worker };
671*6777b538SAndroid Build Coastguard Worker
672*6777b538SAndroid Build Coastguard Worker template <>
673*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC)
674*6777b538SAndroid Build Coastguard Worker ParamTraits<base::subtle::PlatformSharedMemoryRegion> {
675*6777b538SAndroid Build Coastguard Worker typedef base::subtle::PlatformSharedMemoryRegion param_type;
676*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
677*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
678*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
679*6777b538SAndroid Build Coastguard Worker param_type* r);
680*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
681*6777b538SAndroid Build Coastguard Worker };
682*6777b538SAndroid Build Coastguard Worker
683*6777b538SAndroid Build Coastguard Worker template <>
684*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC)
685*6777b538SAndroid Build Coastguard Worker ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode> {
686*6777b538SAndroid Build Coastguard Worker typedef base::subtle::PlatformSharedMemoryRegion::Mode param_type;
687*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
688*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
689*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
690*6777b538SAndroid Build Coastguard Worker param_type* r);
691*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
692*6777b538SAndroid Build Coastguard Worker };
693*6777b538SAndroid Build Coastguard Worker
694*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
695*6777b538SAndroid Build Coastguard Worker template <>
696*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<PlatformFileForTransit> {
697*6777b538SAndroid Build Coastguard Worker typedef PlatformFileForTransit param_type;
698*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
699*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
700*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
701*6777b538SAndroid Build Coastguard Worker param_type* r);
702*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
703*6777b538SAndroid Build Coastguard Worker };
704*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_WIN)
705*6777b538SAndroid Build Coastguard Worker
706*6777b538SAndroid Build Coastguard Worker template <>
707*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<base::FilePath> {
708*6777b538SAndroid Build Coastguard Worker typedef base::FilePath param_type;
709*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
710*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
711*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
712*6777b538SAndroid Build Coastguard Worker param_type* r);
713*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
714*6777b538SAndroid Build Coastguard Worker };
715*6777b538SAndroid Build Coastguard Worker
716*6777b538SAndroid Build Coastguard Worker template <>
717*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<base::Value::List> {
718*6777b538SAndroid Build Coastguard Worker typedef base::Value::List param_type;
719*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
720*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
721*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
722*6777b538SAndroid Build Coastguard Worker param_type* r);
723*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
724*6777b538SAndroid Build Coastguard Worker };
725*6777b538SAndroid Build Coastguard Worker
726*6777b538SAndroid Build Coastguard Worker template <>
727*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<base::Value> {
728*6777b538SAndroid Build Coastguard Worker typedef base::Value param_type;
729*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
730*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
731*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
732*6777b538SAndroid Build Coastguard Worker param_type* r);
733*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
734*6777b538SAndroid Build Coastguard Worker };
735*6777b538SAndroid Build Coastguard Worker
736*6777b538SAndroid Build Coastguard Worker template <>
737*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<base::File::Info> {
738*6777b538SAndroid Build Coastguard Worker typedef base::File::Info param_type;
739*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
740*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
741*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
742*6777b538SAndroid Build Coastguard Worker param_type* r);
743*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
744*6777b538SAndroid Build Coastguard Worker };
745*6777b538SAndroid Build Coastguard Worker
746*6777b538SAndroid Build Coastguard Worker template <>
747*6777b538SAndroid Build Coastguard Worker struct SimilarTypeTraits<base::File::Error> {
748*6777b538SAndroid Build Coastguard Worker typedef int Type;
749*6777b538SAndroid Build Coastguard Worker };
750*6777b538SAndroid Build Coastguard Worker
751*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
752*6777b538SAndroid Build Coastguard Worker template <>
753*6777b538SAndroid Build Coastguard Worker struct SimilarTypeTraits<HWND> {
754*6777b538SAndroid Build Coastguard Worker typedef HANDLE Type;
755*6777b538SAndroid Build Coastguard Worker };
756*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_WIN)
757*6777b538SAndroid Build Coastguard Worker
758*6777b538SAndroid Build Coastguard Worker template <>
759*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<base::Time> {
760*6777b538SAndroid Build Coastguard Worker typedef base::Time param_type;
761*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
762*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
763*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
764*6777b538SAndroid Build Coastguard Worker param_type* r);
765*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
766*6777b538SAndroid Build Coastguard Worker };
767*6777b538SAndroid Build Coastguard Worker
768*6777b538SAndroid Build Coastguard Worker template <>
769*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<base::TimeDelta> {
770*6777b538SAndroid Build Coastguard Worker typedef base::TimeDelta param_type;
771*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
772*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
773*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
774*6777b538SAndroid Build Coastguard Worker param_type* r);
775*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
776*6777b538SAndroid Build Coastguard Worker };
777*6777b538SAndroid Build Coastguard Worker
778*6777b538SAndroid Build Coastguard Worker template <>
779*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<base::TimeTicks> {
780*6777b538SAndroid Build Coastguard Worker typedef base::TimeTicks param_type;
781*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
782*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
783*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
784*6777b538SAndroid Build Coastguard Worker param_type* r);
785*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
786*6777b538SAndroid Build Coastguard Worker };
787*6777b538SAndroid Build Coastguard Worker
788*6777b538SAndroid Build Coastguard Worker template <>
789*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<base::UnguessableToken> {
790*6777b538SAndroid Build Coastguard Worker typedef base::UnguessableToken param_type;
791*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
792*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
793*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
794*6777b538SAndroid Build Coastguard Worker param_type* r);
795*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
796*6777b538SAndroid Build Coastguard Worker };
797*6777b538SAndroid Build Coastguard Worker
798*6777b538SAndroid Build Coastguard Worker template <>
799*6777b538SAndroid Build Coastguard Worker struct ParamTraits<std::tuple<>> {
800*6777b538SAndroid Build Coastguard Worker typedef std::tuple<> param_type;
801*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p) {}
802*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
803*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
804*6777b538SAndroid Build Coastguard Worker param_type* r) {
805*6777b538SAndroid Build Coastguard Worker return true;
806*6777b538SAndroid Build Coastguard Worker }
807*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l) {
808*6777b538SAndroid Build Coastguard Worker }
809*6777b538SAndroid Build Coastguard Worker };
810*6777b538SAndroid Build Coastguard Worker
811*6777b538SAndroid Build Coastguard Worker template <typename T, int index, int count>
812*6777b538SAndroid Build Coastguard Worker struct TupleParamTraitsHelper {
813*6777b538SAndroid Build Coastguard Worker using Next = TupleParamTraitsHelper<T, index + 1, count>;
814*6777b538SAndroid Build Coastguard Worker
815*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const T& p) {
816*6777b538SAndroid Build Coastguard Worker WriteParam(m, std::get<index>(p));
817*6777b538SAndroid Build Coastguard Worker Next::Write(m, p);
818*6777b538SAndroid Build Coastguard Worker }
819*6777b538SAndroid Build Coastguard Worker
820*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m, base::PickleIterator* iter, T* r) {
821*6777b538SAndroid Build Coastguard Worker return ReadParam(m, iter, &std::get<index>(*r)) && Next::Read(m, iter, r);
822*6777b538SAndroid Build Coastguard Worker }
823*6777b538SAndroid Build Coastguard Worker
824*6777b538SAndroid Build Coastguard Worker static void Log(const T& p, std::string* l) {
825*6777b538SAndroid Build Coastguard Worker LogParam(std::get<index>(p), l);
826*6777b538SAndroid Build Coastguard Worker if (index < count - 1)
827*6777b538SAndroid Build Coastguard Worker l->append(", ");
828*6777b538SAndroid Build Coastguard Worker Next::Log(p, l);
829*6777b538SAndroid Build Coastguard Worker }
830*6777b538SAndroid Build Coastguard Worker };
831*6777b538SAndroid Build Coastguard Worker
832*6777b538SAndroid Build Coastguard Worker template <typename T, int index>
833*6777b538SAndroid Build Coastguard Worker struct TupleParamTraitsHelper<T, index, index> {
834*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const T& p) {}
835*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m, base::PickleIterator* iter, T* r) {
836*6777b538SAndroid Build Coastguard Worker return true;
837*6777b538SAndroid Build Coastguard Worker }
838*6777b538SAndroid Build Coastguard Worker static void Log(const T& p, std::string* l) {}
839*6777b538SAndroid Build Coastguard Worker };
840*6777b538SAndroid Build Coastguard Worker
841*6777b538SAndroid Build Coastguard Worker template <typename... Args>
842*6777b538SAndroid Build Coastguard Worker struct ParamTraits<std::tuple<Args...>> {
843*6777b538SAndroid Build Coastguard Worker using param_type = std::tuple<Args...>;
844*6777b538SAndroid Build Coastguard Worker using Helper =
845*6777b538SAndroid Build Coastguard Worker TupleParamTraitsHelper<param_type, 0, std::tuple_size<param_type>::value>;
846*6777b538SAndroid Build Coastguard Worker
847*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p) {
848*6777b538SAndroid Build Coastguard Worker Helper::Write(m, p);
849*6777b538SAndroid Build Coastguard Worker }
850*6777b538SAndroid Build Coastguard Worker
851*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
852*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
853*6777b538SAndroid Build Coastguard Worker param_type* r) {
854*6777b538SAndroid Build Coastguard Worker return Helper::Read(m, iter, r);
855*6777b538SAndroid Build Coastguard Worker }
856*6777b538SAndroid Build Coastguard Worker
857*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l) { Helper::Log(p, l); }
858*6777b538SAndroid Build Coastguard Worker };
859*6777b538SAndroid Build Coastguard Worker
860*6777b538SAndroid Build Coastguard Worker template <class P, size_t stack_capacity>
861*6777b538SAndroid Build Coastguard Worker struct ParamTraits<absl::InlinedVector<P, stack_capacity>> {
862*6777b538SAndroid Build Coastguard Worker typedef absl::InlinedVector<P, stack_capacity> param_type;
863*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p) {
864*6777b538SAndroid Build Coastguard Worker WriteParam(m, base::checked_cast<int>(p.size()));
865*6777b538SAndroid Build Coastguard Worker for (size_t i = 0; i < p.size(); i++) {
866*6777b538SAndroid Build Coastguard Worker WriteParam(m, p[i]);
867*6777b538SAndroid Build Coastguard Worker }
868*6777b538SAndroid Build Coastguard Worker }
869*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
870*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
871*6777b538SAndroid Build Coastguard Worker param_type* r) {
872*6777b538SAndroid Build Coastguard Worker size_t size;
873*6777b538SAndroid Build Coastguard Worker if (!iter->ReadLength(&size)) {
874*6777b538SAndroid Build Coastguard Worker return false;
875*6777b538SAndroid Build Coastguard Worker }
876*6777b538SAndroid Build Coastguard Worker // Sanity check for the vector size.
877*6777b538SAndroid Build Coastguard Worker if (size > INT_MAX / sizeof(P)) {
878*6777b538SAndroid Build Coastguard Worker return false;
879*6777b538SAndroid Build Coastguard Worker }
880*6777b538SAndroid Build Coastguard Worker P value;
881*6777b538SAndroid Build Coastguard Worker for (size_t i = 0; i < size; i++) {
882*6777b538SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &value)) {
883*6777b538SAndroid Build Coastguard Worker return false;
884*6777b538SAndroid Build Coastguard Worker }
885*6777b538SAndroid Build Coastguard Worker r->push_back(value);
886*6777b538SAndroid Build Coastguard Worker }
887*6777b538SAndroid Build Coastguard Worker return true;
888*6777b538SAndroid Build Coastguard Worker }
889*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l) {
890*6777b538SAndroid Build Coastguard Worker for (size_t i = 0; i < p.size(); ++i) {
891*6777b538SAndroid Build Coastguard Worker if (i != 0) {
892*6777b538SAndroid Build Coastguard Worker l->append(" ");
893*6777b538SAndroid Build Coastguard Worker }
894*6777b538SAndroid Build Coastguard Worker LogParam((p[i]), l);
895*6777b538SAndroid Build Coastguard Worker }
896*6777b538SAndroid Build Coastguard Worker }
897*6777b538SAndroid Build Coastguard Worker };
898*6777b538SAndroid Build Coastguard Worker
899*6777b538SAndroid Build Coastguard Worker template <class Key, class Mapped, class Compare>
900*6777b538SAndroid Build Coastguard Worker struct ParamTraits<base::flat_map<Key, Mapped, Compare>> {
901*6777b538SAndroid Build Coastguard Worker using param_type = base::flat_map<Key, Mapped, Compare>;
902*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p) {
903*6777b538SAndroid Build Coastguard Worker DCHECK(base::IsValueInRangeForNumericType<int>(p.size()));
904*6777b538SAndroid Build Coastguard Worker WriteParam(m, base::checked_cast<int>(p.size()));
905*6777b538SAndroid Build Coastguard Worker for (const auto& iter : p) {
906*6777b538SAndroid Build Coastguard Worker WriteParam(m, iter.first);
907*6777b538SAndroid Build Coastguard Worker WriteParam(m, iter.second);
908*6777b538SAndroid Build Coastguard Worker }
909*6777b538SAndroid Build Coastguard Worker }
910*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
911*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
912*6777b538SAndroid Build Coastguard Worker param_type* r) {
913*6777b538SAndroid Build Coastguard Worker size_t size;
914*6777b538SAndroid Build Coastguard Worker if (!iter->ReadLength(&size))
915*6777b538SAndroid Build Coastguard Worker return false;
916*6777b538SAndroid Build Coastguard Worker
917*6777b538SAndroid Build Coastguard Worker // Construct by creating in a vector and moving into the flat_map. Properly
918*6777b538SAndroid Build Coastguard Worker // serialized flat_maps will be in-order so this will be O(n). Incorrectly
919*6777b538SAndroid Build Coastguard Worker // serialized ones will still be handled properly.
920*6777b538SAndroid Build Coastguard Worker std::vector<typename param_type::value_type> vect;
921*6777b538SAndroid Build Coastguard Worker vect.resize(size);
922*6777b538SAndroid Build Coastguard Worker for (size_t i = 0; i < size; ++i) {
923*6777b538SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &vect[i].first))
924*6777b538SAndroid Build Coastguard Worker return false;
925*6777b538SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &vect[i].second))
926*6777b538SAndroid Build Coastguard Worker return false;
927*6777b538SAndroid Build Coastguard Worker }
928*6777b538SAndroid Build Coastguard Worker
929*6777b538SAndroid Build Coastguard Worker *r = param_type(std::move(vect));
930*6777b538SAndroid Build Coastguard Worker return true;
931*6777b538SAndroid Build Coastguard Worker }
932*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l) {
933*6777b538SAndroid Build Coastguard Worker l->append("<base::flat_map>");
934*6777b538SAndroid Build Coastguard Worker }
935*6777b538SAndroid Build Coastguard Worker };
936*6777b538SAndroid Build Coastguard Worker
937*6777b538SAndroid Build Coastguard Worker template <class P>
938*6777b538SAndroid Build Coastguard Worker struct ParamTraits<std::unique_ptr<P>> {
939*6777b538SAndroid Build Coastguard Worker typedef std::unique_ptr<P> param_type;
940*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p) {
941*6777b538SAndroid Build Coastguard Worker bool valid = !!p;
942*6777b538SAndroid Build Coastguard Worker WriteParam(m, valid);
943*6777b538SAndroid Build Coastguard Worker if (valid)
944*6777b538SAndroid Build Coastguard Worker WriteParam(m, *p);
945*6777b538SAndroid Build Coastguard Worker }
946*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
947*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
948*6777b538SAndroid Build Coastguard Worker param_type* r) {
949*6777b538SAndroid Build Coastguard Worker bool valid = false;
950*6777b538SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &valid))
951*6777b538SAndroid Build Coastguard Worker return false;
952*6777b538SAndroid Build Coastguard Worker
953*6777b538SAndroid Build Coastguard Worker if (!valid) {
954*6777b538SAndroid Build Coastguard Worker r->reset();
955*6777b538SAndroid Build Coastguard Worker return true;
956*6777b538SAndroid Build Coastguard Worker }
957*6777b538SAndroid Build Coastguard Worker
958*6777b538SAndroid Build Coastguard Worker param_type temp(new P());
959*6777b538SAndroid Build Coastguard Worker if (!ReadParam(m, iter, temp.get()))
960*6777b538SAndroid Build Coastguard Worker return false;
961*6777b538SAndroid Build Coastguard Worker
962*6777b538SAndroid Build Coastguard Worker r->swap(temp);
963*6777b538SAndroid Build Coastguard Worker return true;
964*6777b538SAndroid Build Coastguard Worker }
965*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l) {
966*6777b538SAndroid Build Coastguard Worker if (p)
967*6777b538SAndroid Build Coastguard Worker LogParam(*p, l);
968*6777b538SAndroid Build Coastguard Worker else
969*6777b538SAndroid Build Coastguard Worker l->append("NULL");
970*6777b538SAndroid Build Coastguard Worker }
971*6777b538SAndroid Build Coastguard Worker };
972*6777b538SAndroid Build Coastguard Worker
973*6777b538SAndroid Build Coastguard Worker // absl types ParamTraits
974*6777b538SAndroid Build Coastguard Worker
975*6777b538SAndroid Build Coastguard Worker template <class P>
976*6777b538SAndroid Build Coastguard Worker struct ParamTraits<std::optional<P>> {
977*6777b538SAndroid Build Coastguard Worker typedef std::optional<P> param_type;
978*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p) {
979*6777b538SAndroid Build Coastguard Worker const bool is_set = static_cast<bool>(p);
980*6777b538SAndroid Build Coastguard Worker WriteParam(m, is_set);
981*6777b538SAndroid Build Coastguard Worker if (is_set)
982*6777b538SAndroid Build Coastguard Worker WriteParam(m, p.value());
983*6777b538SAndroid Build Coastguard Worker }
984*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
985*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
986*6777b538SAndroid Build Coastguard Worker param_type* r) {
987*6777b538SAndroid Build Coastguard Worker bool is_set = false;
988*6777b538SAndroid Build Coastguard Worker if (!iter->ReadBool(&is_set))
989*6777b538SAndroid Build Coastguard Worker return false;
990*6777b538SAndroid Build Coastguard Worker if (is_set) {
991*6777b538SAndroid Build Coastguard Worker P value;
992*6777b538SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &value))
993*6777b538SAndroid Build Coastguard Worker return false;
994*6777b538SAndroid Build Coastguard Worker *r = std::move(value);
995*6777b538SAndroid Build Coastguard Worker }
996*6777b538SAndroid Build Coastguard Worker return true;
997*6777b538SAndroid Build Coastguard Worker }
998*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l) {
999*6777b538SAndroid Build Coastguard Worker if (p)
1000*6777b538SAndroid Build Coastguard Worker LogParam(p.value(), l);
1001*6777b538SAndroid Build Coastguard Worker else
1002*6777b538SAndroid Build Coastguard Worker l->append("(unset)");
1003*6777b538SAndroid Build Coastguard Worker }
1004*6777b538SAndroid Build Coastguard Worker };
1005*6777b538SAndroid Build Coastguard Worker
1006*6777b538SAndroid Build Coastguard Worker template <>
1007*6777b538SAndroid Build Coastguard Worker struct ParamTraits<absl::monostate> {
1008*6777b538SAndroid Build Coastguard Worker typedef absl::monostate param_type;
1009*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p) {}
1010*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
1011*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
1012*6777b538SAndroid Build Coastguard Worker param_type* r) {
1013*6777b538SAndroid Build Coastguard Worker return true;
1014*6777b538SAndroid Build Coastguard Worker }
1015*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l) { l->append("()"); }
1016*6777b538SAndroid Build Coastguard Worker };
1017*6777b538SAndroid Build Coastguard Worker
1018*6777b538SAndroid Build Coastguard Worker // base/util types ParamTraits
1019*6777b538SAndroid Build Coastguard Worker
1020*6777b538SAndroid Build Coastguard Worker template <typename TypeMarker, typename WrappedType, WrappedType kInvalidValue>
1021*6777b538SAndroid Build Coastguard Worker struct ParamTraits<base::IdType<TypeMarker, WrappedType, kInvalidValue>> {
1022*6777b538SAndroid Build Coastguard Worker using param_type = base::IdType<TypeMarker, WrappedType, kInvalidValue>;
1023*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p) {
1024*6777b538SAndroid Build Coastguard Worker WriteParam(m, p.GetUnsafeValue());
1025*6777b538SAndroid Build Coastguard Worker }
1026*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
1027*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
1028*6777b538SAndroid Build Coastguard Worker param_type* r) {
1029*6777b538SAndroid Build Coastguard Worker WrappedType value;
1030*6777b538SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &value))
1031*6777b538SAndroid Build Coastguard Worker return false;
1032*6777b538SAndroid Build Coastguard Worker *r = param_type::FromUnsafeValue(value);
1033*6777b538SAndroid Build Coastguard Worker return true;
1034*6777b538SAndroid Build Coastguard Worker }
1035*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l) {
1036*6777b538SAndroid Build Coastguard Worker LogParam(p.GetUnsafeValue(), l);
1037*6777b538SAndroid Build Coastguard Worker }
1038*6777b538SAndroid Build Coastguard Worker };
1039*6777b538SAndroid Build Coastguard Worker
1040*6777b538SAndroid Build Coastguard Worker template <typename TagType, typename UnderlyingType>
1041*6777b538SAndroid Build Coastguard Worker struct ParamTraits<base::StrongAlias<TagType, UnderlyingType>> {
1042*6777b538SAndroid Build Coastguard Worker using param_type = base::StrongAlias<TagType, UnderlyingType>;
1043*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p) {
1044*6777b538SAndroid Build Coastguard Worker WriteParam(m, p.value());
1045*6777b538SAndroid Build Coastguard Worker }
1046*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
1047*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
1048*6777b538SAndroid Build Coastguard Worker param_type* r) {
1049*6777b538SAndroid Build Coastguard Worker UnderlyingType value;
1050*6777b538SAndroid Build Coastguard Worker if (!ReadParam(m, iter, &value))
1051*6777b538SAndroid Build Coastguard Worker return false;
1052*6777b538SAndroid Build Coastguard Worker *r = param_type(value);
1053*6777b538SAndroid Build Coastguard Worker return true;
1054*6777b538SAndroid Build Coastguard Worker }
1055*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l) {
1056*6777b538SAndroid Build Coastguard Worker LogParam(p.value(), l);
1057*6777b538SAndroid Build Coastguard Worker }
1058*6777b538SAndroid Build Coastguard Worker };
1059*6777b538SAndroid Build Coastguard Worker
1060*6777b538SAndroid Build Coastguard Worker // IPC types ParamTraits -------------------------------------------------------
1061*6777b538SAndroid Build Coastguard Worker
1062*6777b538SAndroid Build Coastguard Worker // A ChannelHandle is basically a platform-inspecific wrapper around the
1063*6777b538SAndroid Build Coastguard Worker // fact that IPC endpoints are handled specially on POSIX. See above comments
1064*6777b538SAndroid Build Coastguard Worker // on FileDescriptor for more background.
1065*6777b538SAndroid Build Coastguard Worker template <>
1066*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<IPC::ChannelHandle> {
1067*6777b538SAndroid Build Coastguard Worker typedef ChannelHandle param_type;
1068*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
1069*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
1070*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
1071*6777b538SAndroid Build Coastguard Worker param_type* r);
1072*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
1073*6777b538SAndroid Build Coastguard Worker };
1074*6777b538SAndroid Build Coastguard Worker
1075*6777b538SAndroid Build Coastguard Worker template <>
1076*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<LogData> {
1077*6777b538SAndroid Build Coastguard Worker typedef LogData param_type;
1078*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
1079*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
1080*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
1081*6777b538SAndroid Build Coastguard Worker param_type* r);
1082*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
1083*6777b538SAndroid Build Coastguard Worker };
1084*6777b538SAndroid Build Coastguard Worker
1085*6777b538SAndroid Build Coastguard Worker template <>
1086*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<Message> {
1087*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const Message& p);
1088*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
1089*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
1090*6777b538SAndroid Build Coastguard Worker Message* r);
1091*6777b538SAndroid Build Coastguard Worker static void Log(const Message& p, std::string* l);
1092*6777b538SAndroid Build Coastguard Worker };
1093*6777b538SAndroid Build Coastguard Worker
1094*6777b538SAndroid Build Coastguard Worker // Windows ParamTraits ---------------------------------------------------------
1095*6777b538SAndroid Build Coastguard Worker
1096*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
1097*6777b538SAndroid Build Coastguard Worker template <>
1098*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<HANDLE> {
1099*6777b538SAndroid Build Coastguard Worker typedef HANDLE param_type;
1100*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
1101*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
1102*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
1103*6777b538SAndroid Build Coastguard Worker param_type* r);
1104*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
1105*6777b538SAndroid Build Coastguard Worker };
1106*6777b538SAndroid Build Coastguard Worker
1107*6777b538SAndroid Build Coastguard Worker template <>
1108*6777b538SAndroid Build Coastguard Worker struct COMPONENT_EXPORT(IPC) ParamTraits<MSG> {
1109*6777b538SAndroid Build Coastguard Worker typedef MSG param_type;
1110*6777b538SAndroid Build Coastguard Worker static void Write(base::Pickle* m, const param_type& p);
1111*6777b538SAndroid Build Coastguard Worker static bool Read(const base::Pickle* m,
1112*6777b538SAndroid Build Coastguard Worker base::PickleIterator* iter,
1113*6777b538SAndroid Build Coastguard Worker param_type* r);
1114*6777b538SAndroid Build Coastguard Worker static void Log(const param_type& p, std::string* l);
1115*6777b538SAndroid Build Coastguard Worker };
1116*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_WIN)
1117*6777b538SAndroid Build Coastguard Worker
1118*6777b538SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
1119*6777b538SAndroid Build Coastguard Worker // Generic message subclasses
1120*6777b538SAndroid Build Coastguard Worker
1121*6777b538SAndroid Build Coastguard Worker // defined in ipc_logging.cc
1122*6777b538SAndroid Build Coastguard Worker COMPONENT_EXPORT(IPC)
1123*6777b538SAndroid Build Coastguard Worker void GenerateLogData(const Message& message, LogData* data, bool get_params);
1124*6777b538SAndroid Build Coastguard Worker
1125*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
1126*6777b538SAndroid Build Coastguard Worker inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
1127*6777b538SAndroid Build Coastguard Worker const std::string& output_params = msg->output_params();
1128*6777b538SAndroid Build Coastguard Worker if (!l->empty() && !output_params.empty())
1129*6777b538SAndroid Build Coastguard Worker l->append(", ");
1130*6777b538SAndroid Build Coastguard Worker
1131*6777b538SAndroid Build Coastguard Worker l->append(output_params);
1132*6777b538SAndroid Build Coastguard Worker }
1133*6777b538SAndroid Build Coastguard Worker
1134*6777b538SAndroid Build Coastguard Worker template <class ReplyParamType>
1135*6777b538SAndroid Build Coastguard Worker inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1136*6777b538SAndroid Build Coastguard Worker const Message* msg) {
1137*6777b538SAndroid Build Coastguard Worker if (msg->received_time() != 0) {
1138*6777b538SAndroid Build Coastguard Worker std::string output_params;
1139*6777b538SAndroid Build Coastguard Worker LogParam(reply_params, &output_params);
1140*6777b538SAndroid Build Coastguard Worker msg->set_output_params(output_params);
1141*6777b538SAndroid Build Coastguard Worker }
1142*6777b538SAndroid Build Coastguard Worker }
1143*6777b538SAndroid Build Coastguard Worker
1144*6777b538SAndroid Build Coastguard Worker inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
1145*6777b538SAndroid Build Coastguard Worker if (msg->sent_time()) {
1146*6777b538SAndroid Build Coastguard Worker // Don't log the sync message after dispatch, as we don't have the
1147*6777b538SAndroid Build Coastguard Worker // output parameters at that point. Instead, save its data and log it
1148*6777b538SAndroid Build Coastguard Worker // with the outgoing reply message when it's sent.
1149*6777b538SAndroid Build Coastguard Worker LogData* data = new LogData;
1150*6777b538SAndroid Build Coastguard Worker GenerateLogData(*msg, data, true);
1151*6777b538SAndroid Build Coastguard Worker msg->set_dont_log();
1152*6777b538SAndroid Build Coastguard Worker reply->set_sync_log_data(data);
1153*6777b538SAndroid Build Coastguard Worker }
1154*6777b538SAndroid Build Coastguard Worker }
1155*6777b538SAndroid Build Coastguard Worker #else
1156*6777b538SAndroid Build Coastguard Worker inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
1157*6777b538SAndroid Build Coastguard Worker
1158*6777b538SAndroid Build Coastguard Worker template <class ReplyParamType>
1159*6777b538SAndroid Build Coastguard Worker inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1160*6777b538SAndroid Build Coastguard Worker const Message* msg) {}
1161*6777b538SAndroid Build Coastguard Worker
1162*6777b538SAndroid Build Coastguard Worker inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1163*6777b538SAndroid Build Coastguard Worker #endif
1164*6777b538SAndroid Build Coastguard Worker
1165*6777b538SAndroid Build Coastguard Worker } // namespace IPC
1166*6777b538SAndroid Build Coastguard Worker
1167*6777b538SAndroid Build Coastguard Worker #endif // IPC_IPC_MESSAGE_UTILS_H_
1168