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