blob: 8772b6714ebf9034f40bb3359490fde02233911e [file] [log] [blame]
[email protected]efb5f572012-01-29 10:57:331// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]946d1b22009-07-22 23:57:215#ifndef IPC_IPC_MESSAGE_UTILS_H_
6#define IPC_IPC_MESSAGE_UTILS_H_
[email protected]32b76ef2010-07-26 23:08:247#pragma once
initial.commit09911bf2008-07-26 23:55:298
[email protected]379e7a52010-03-09 00:38:419#include <algorithm>
initial.commit09911bf2008-07-26 23:55:2910#include <map>
[email protected]96da6962010-05-13 19:10:3411#include <set>
[email protected]663bd9e2011-03-21 01:07:0112#include <string>
13#include <vector>
initial.commit09911bf2008-07-26 23:55:2914
[email protected]dce5df52009-06-29 17:58:2515#include "base/format_macros.h"
[email protected]eb47a132009-03-04 00:39:5616#include "base/string16.h"
[email protected]6782f832011-05-10 04:06:0017#include "base/stringprintf.h"
[email protected]dce5df52009-06-29 17:58:2518#include "base/string_util.h"
initial.commit09911bf2008-07-26 23:55:2919#include "base/tuple.h"
[email protected]939856a2010-08-24 20:29:0220#include "ipc/ipc_param_traits.h"
[email protected]0cfe5dae2010-08-17 00:24:5421#include "ipc/ipc_sync_message.h"
[email protected]55b4e212010-08-13 20:43:5822
[email protected]7a4de7a62010-08-17 18:38:2423#if defined(COMPILER_GCC)
24// GCC "helpfully" tries to inline template methods in release mode. Except we
25// want the majority of the template junk being expanded once in the
26// implementation file (and only provide the definitions in
27// ipc_message_utils_impl.h in those files) and exported, instead of expanded
28// at every call site. Special note: GCC happily accepts the attribute before
29// the method declaration, but only acts on it if it is after.
[email protected]efafbbd2010-08-19 20:23:2530#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 40500
31// Starting in gcc 4.5, the noinline no longer implies the concept covered by
32// the introduced noclone attribute, which will create specialized versions of
33// functions/methods when certain types are constant.
34// www.gnu.org/software/gcc/gcc-4.5/changes.html
35#define IPC_MSG_NOINLINE __attribute__((noinline, noclone));
36#else
[email protected]7a4de7a62010-08-17 18:38:2437#define IPC_MSG_NOINLINE __attribute__((noinline));
[email protected]efafbbd2010-08-19 20:23:2538#endif
[email protected]7a4de7a62010-08-17 18:38:2439#elif defined(COMPILER_MSVC)
40// MSVC++ doesn't do this.
41#define IPC_MSG_NOINLINE
42#else
43#error "Please add the noinline property for your new compiler here."
44#endif
45
[email protected]f91cb992009-02-04 20:10:1246// Used by IPC_BEGIN_MESSAGES so that each message class starts from a unique
47// base. Messages have unique IDs across channels in order for the IPC logging
48// code to figure out the message class from its ID.
49enum IPCMessageStart {
[email protected]f91cb992009-02-04 20:10:1250 AutomationMsgStart = 0,
51 ViewMsgStart,
[email protected]f91cb992009-02-04 20:10:1252 PluginMsgStart,
[email protected]21fa3a12010-12-08 23:34:1653 ProfileImportMsgStart,
[email protected]f91cb992009-02-04 20:10:1254 TestMsgStart,
[email protected]21fa3a12010-12-08 23:34:1655 DevToolsMsgStart,
[email protected]eb47a132009-03-04 00:39:5656 WorkerMsgStart,
[email protected]21fa3a12010-12-08 23:34:1657 NaClMsgStart,
[email protected]60f14392009-12-15 20:46:3258 UtilityMsgStart,
[email protected]c0fc0942010-01-13 00:55:3759 GpuMsgStart,
[email protected]38fe1962010-07-31 07:57:0060 ServiceMsgStart,
[email protected]709a847e2010-11-10 01:16:1161 PpapiMsgStart,
[email protected]21fa3a12010-12-08 23:34:1662 FirefoxImporterUnittestMsgStart,
[email protected]9f547bf2010-12-13 17:00:4263 FileUtilitiesMsgStart,
64 MimeRegistryMsgStart,
[email protected]26a9acf2010-12-13 19:35:0565 DatabaseMsgStart,
[email protected]56879f932010-12-13 21:05:3766 DOMStorageMsgStart,
[email protected]2ba871b2010-12-13 21:11:0067 IndexedDBMsgStart,
[email protected]61e78f12010-12-15 21:03:5568 PepperFileMsgStart,
[email protected]c52b2892012-03-07 11:01:0269 SpeechRecognitionMsgStart,
[email protected]f0557932011-01-25 20:20:5170 PepperMsgStart,
[email protected]663bd9e2011-03-21 01:07:0171 AutofillMsgStart,
[email protected]fa685ff2011-02-17 19:47:1372 SafeBrowsingMsgStart,
[email protected]6c54e7e42011-03-02 20:52:3473 P2PMsgStart,
[email protected]db803aae2011-03-05 02:00:4274 SocketStreamMsgStart,
[email protected]94dc971d2011-03-05 19:08:3275 ResourceMsgStart,
[email protected]172f1552011-03-07 21:58:1676 FileSystemMsgStart,
[email protected]ff47b2962011-03-07 23:51:4977 ChildProcessMsgStart,
[email protected]7e3589742011-03-10 18:49:1778 ClipboardMsgStart,
[email protected]db10d8f2011-03-14 00:21:4779 BlobMsgStart,
[email protected]e93e04e2011-03-14 00:27:1080 AppCacheMsgStart,
[email protected]e7c21b812011-03-19 18:03:3081 DeviceOrientationMsgStart,
82 DesktopNotificationMsgStart,
83 GeolocationMsgStart,
[email protected]4460ee52011-03-21 19:19:2484 AudioMsgStart,
[email protected]778574e2011-03-21 22:03:5085 ChromeMsgStart,
[email protected]59f4f2fa2011-03-23 01:00:5586 DragMsgStart,
[email protected]1375e3ab2011-03-24 17:07:2287 PrintMsgStart,
[email protected]3e267192011-03-25 01:55:4588 SpellCheckMsgStart,
[email protected]44c49c92011-03-28 16:17:2389 ExtensionMsgStart,
[email protected]e1a59a22011-04-12 01:36:2590 VideoCaptureMsgStart,
[email protected]10e5cf12011-04-13 04:10:4091 QuotaMsgStart,
[email protected]ae4efe42011-04-18 21:28:0592 IconMsgStart,
[email protected]d4cff272011-05-02 15:46:0193 TextInputClientMsgStart,
[email protected]373c1062011-06-09 21:11:5194 ChromeUtilityMsgStart,
[email protected]47126542011-06-28 12:10:2095 MediaStreamMsgStart,
[email protected]6f08af82011-09-15 01:19:0396 ChromeBenchmarkingMsgStart,
[email protected]1ef93132011-09-16 18:33:4797 IntentsMsgStart,
[email protected]7f3c7af2011-10-20 22:52:5198 JavaBridgeMsgStart,
[email protected]7f5969d2011-10-28 18:42:4299 GamepadMsgStart,
[email protected]efb5f572012-01-29 10:57:33100 ShellMsgStart,
[email protected]68d53322012-02-13 21:29:01101 AccessibilityMsgStart,
[email protected]a0358d72012-03-09 14:06:50102 PrerenderMsgStart,
[email protected]c2b374402012-03-12 19:23:07103 ChromotingMsgStart,
[email protected]8dd709fb2012-04-06 00:49:06104 BrowserPluginMsgStart,
[email protected]e503a122011-03-17 18:20:52105 LastIPCMsgStart // Must come last.
[email protected]f91cb992009-02-04 20:10:12106};
107
[email protected]7a4de7a62010-08-17 18:38:24108class FilePath;
[email protected]7a4de7a62010-08-17 18:38:24109class NullableString16;
110
111namespace base {
[email protected]f3a1c642011-07-12 19:15:03112class DictionaryValue;
113class ListValue;
[email protected]7a4de7a62010-08-17 18:38:24114class Time;
[email protected]d84e48b2010-10-21 22:04:52115class TimeDelta;
[email protected]1d14f582011-09-02 20:42:04116class TimeTicks;
[email protected]7a4de7a62010-08-17 18:38:24117struct FileDescriptor;
118}
119
initial.commit09911bf2008-07-26 23:55:29120namespace IPC {
121
[email protected]7a4de7a62010-08-17 18:38:24122struct ChannelHandle;
123
initial.commit09911bf2008-07-26 23:55:29124//-----------------------------------------------------------------------------
125// An iterator class for reading the fields contained within a Message.
126
127class MessageIterator {
128 public:
[email protected]ce208f872012-03-07 20:42:56129 explicit MessageIterator(const Message& m) : iter_(m) {
initial.commit09911bf2008-07-26 23:55:29130 }
131 int NextInt() const {
[email protected]9422b7dc2009-12-30 20:09:02132 int val = -1;
[email protected]ce208f872012-03-07 20:42:56133 if (!iter_.ReadInt(&val))
initial.commit09911bf2008-07-26 23:55:29134 NOTREACHED();
135 return val;
136 }
initial.commit09911bf2008-07-26 23:55:29137 const std::string NextString() const {
138 std::string val;
[email protected]ce208f872012-03-07 20:42:56139 if (!iter_.ReadString(&val))
initial.commit09911bf2008-07-26 23:55:29140 NOTREACHED();
141 return val;
142 }
143 const std::wstring NextWString() const {
144 std::wstring val;
[email protected]ce208f872012-03-07 20:42:56145 if (!iter_.ReadWString(&val))
initial.commit09911bf2008-07-26 23:55:29146 NOTREACHED();
147 return val;
148 }
[email protected]225c8f52010-02-05 22:23:20149 void NextData(const char** data, int* length) const {
[email protected]ce208f872012-03-07 20:42:56150 if (!iter_.ReadData(data, length)) {
initial.commit09911bf2008-07-26 23:55:29151 NOTREACHED();
152 }
153 }
154 private:
[email protected]ce208f872012-03-07 20:42:56155 mutable PickleIterator iter_;
initial.commit09911bf2008-07-26 23:55:29156};
157
158//-----------------------------------------------------------------------------
[email protected]6476c72c2011-02-11 18:46:19159// A dummy struct to place first just to allow leading commas for all
160// members in the macro-generated constructor initializer lists.
161struct NoParams {
162};
163
164//-----------------------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19165// ParamTraits specializations, etc.
166
[email protected]7d5c3ac2009-02-04 08:58:19167template <class P>
168static inline void WriteParam(Message* m, const P& p) {
[email protected]7b291f92009-08-14 05:43:53169 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53170 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
[email protected]7d5c3ac2009-02-04 08:58:19171}
172
173template <class P>
[email protected]ce208f872012-03-07 20:42:56174static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m,
175 PickleIterator* iter,
[email protected]1e86aa62009-04-24 21:22:33176 P* p) {
[email protected]7b291f92009-08-14 05:43:53177 typedef typename SimilarTypeTraits<P>::Type Type;
178 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
[email protected]7d5c3ac2009-02-04 08:58:19179}
180
181template <class P>
[email protected]252cad62010-08-18 18:33:57182static inline void LogParam(const P& p, std::string* l) {
[email protected]7b291f92009-08-14 05:43:53183 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53184 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19185}
186
187template <>
188struct ParamTraits<bool> {
189 typedef bool param_type;
190 static void Write(Message* m, const param_type& p) {
191 m->WriteBool(p);
192 }
[email protected]ce208f872012-03-07 20:42:56193 static bool Read(const Message* m, PickleIterator* iter,
194 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19195 return m->ReadBool(iter, r);
196 }
[email protected]252cad62010-08-18 18:33:57197 static void Log(const param_type& p, std::string* l) {
198 l->append(p ? "true" : "false");
[email protected]7d5c3ac2009-02-04 08:58:19199 }
200};
201
202template <>
203struct ParamTraits<int> {
204 typedef int param_type;
205 static void Write(Message* m, const param_type& p) {
206 m->WriteInt(p);
207 }
[email protected]ce208f872012-03-07 20:42:56208 static bool Read(const Message* m, PickleIterator* iter,
209 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19210 return m->ReadInt(iter, r);
211 }
[email protected]7c854372011-08-15 20:41:46212 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19213};
214
215template <>
[email protected]63263f92009-07-28 19:35:08216struct ParamTraits<unsigned int> {
217 typedef unsigned int param_type;
218 static void Write(Message* m, const param_type& p) {
219 m->WriteInt(p);
220 }
[email protected]ce208f872012-03-07 20:42:56221 static bool Read(const Message* m, PickleIterator* iter,
222 param_type* r) {
[email protected]63263f92009-07-28 19:35:08223 return m->ReadInt(iter, reinterpret_cast<int*>(r));
224 }
[email protected]7c854372011-08-15 20:41:46225 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08226};
227
228template <>
[email protected]7d5c3ac2009-02-04 08:58:19229struct ParamTraits<long> {
230 typedef long param_type;
231 static void Write(Message* m, const param_type& p) {
[email protected]c272d082012-03-23 00:03:10232 m->WriteLongUsingDangerousNonPortableLessPersistableForm(p);
[email protected]7d5c3ac2009-02-04 08:58:19233 }
[email protected]ce208f872012-03-07 20:42:56234 static bool Read(const Message* m, PickleIterator* iter,
235 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19236 return m->ReadLong(iter, r);
237 }
[email protected]7c854372011-08-15 20:41:46238 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19239};
240
[email protected]140c3032009-06-26 18:22:54241template <>
242struct ParamTraits<unsigned long> {
243 typedef unsigned long param_type;
244 static void Write(Message* m, const param_type& p) {
[email protected]c272d082012-03-23 00:03:10245 m->WriteLongUsingDangerousNonPortableLessPersistableForm(p);
[email protected]140c3032009-06-26 18:22:54246 }
[email protected]ce208f872012-03-07 20:42:56247 static bool Read(const Message* m, PickleIterator* iter,
248 param_type* r) {
[email protected]63263f92009-07-28 19:35:08249 return m->ReadLong(iter, reinterpret_cast<long*>(r));
[email protected]140c3032009-06-26 18:22:54250 }
[email protected]7c854372011-08-15 20:41:46251 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19252};
253
254template <>
[email protected]63263f92009-07-28 19:35:08255struct ParamTraits<long long> {
256 typedef long long param_type;
[email protected]7d5c3ac2009-02-04 08:58:19257 static void Write(Message* m, const param_type& p) {
258 m->WriteInt64(static_cast<int64>(p));
259 }
[email protected]ce208f872012-03-07 20:42:56260 static bool Read(const Message* m, PickleIterator* iter,
261 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19262 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
263 }
[email protected]7c854372011-08-15 20:41:46264 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08265};
266
267template <>
268struct ParamTraits<unsigned long long> {
269 typedef unsigned long long param_type;
270 static void Write(Message* m, const param_type& p) {
271 m->WriteInt64(p);
272 }
[email protected]ce208f872012-03-07 20:42:56273 static bool Read(const Message* m, PickleIterator* iter,
274 param_type* r) {
[email protected]63263f92009-07-28 19:35:08275 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
276 }
[email protected]7c854372011-08-15 20:41:46277 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19278};
279
[email protected]43a40202010-11-12 16:25:01280template <>
[email protected]7c854372011-08-15 20:41:46281struct IPC_EXPORT ParamTraits<unsigned short> {
[email protected]43a40202010-11-12 16:25:01282 typedef unsigned short param_type;
283 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56284 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]43a40202010-11-12 16:25:01285 static void Log(const param_type& p, std::string* l);
286};
287
[email protected]20199662010-06-17 03:29:26288// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
289// should be sure to check the sanity of these values after receiving them over
290// IPC.
291template <>
292struct ParamTraits<float> {
293 typedef float param_type;
294 static void Write(Message* m, const param_type& p) {
295 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
296 }
[email protected]ce208f872012-03-07 20:42:56297 static bool Read(const Message* m, PickleIterator* iter,
298 param_type* r) {
[email protected]20199662010-06-17 03:29:26299 const char *data;
300 int data_size;
301 if (!m->ReadData(iter, &data, &data_size) ||
302 data_size != sizeof(param_type)) {
303 NOTREACHED();
304 return false;
305 }
306 memcpy(r, data, sizeof(param_type));
307 return true;
308 }
[email protected]252cad62010-08-18 18:33:57309 static void Log(const param_type& p, std::string* l) {
310 l->append(StringPrintf("%e", p));
[email protected]20199662010-06-17 03:29:26311 }
312};
313
[email protected]7d5c3ac2009-02-04 08:58:19314template <>
315struct ParamTraits<double> {
316 typedef double param_type;
317 static void Write(Message* m, const param_type& p) {
318 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
319 }
[email protected]ce208f872012-03-07 20:42:56320 static bool Read(const Message* m, PickleIterator* iter,
321 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19322 const char *data;
[email protected]20199662010-06-17 03:29:26323 int data_size;
324 if (!m->ReadData(iter, &data, &data_size) ||
325 data_size != sizeof(param_type)) {
[email protected]7d5c3ac2009-02-04 08:58:19326 NOTREACHED();
[email protected]20199662010-06-17 03:29:26327 return false;
[email protected]7d5c3ac2009-02-04 08:58:19328 }
[email protected]20199662010-06-17 03:29:26329 memcpy(r, data, sizeof(param_type));
330 return true;
[email protected]7d5c3ac2009-02-04 08:58:19331 }
[email protected]252cad62010-08-18 18:33:57332 static void Log(const param_type& p, std::string* l) {
333 l->append(StringPrintf("%e", p));
[email protected]7d5c3ac2009-02-04 08:58:19334 }
335};
336
337template <>
[email protected]7c854372011-08-15 20:41:46338struct IPC_EXPORT ParamTraits<base::Time> {
[email protected]7d5c3ac2009-02-04 08:58:19339 typedef base::Time param_type;
[email protected]7a4de7a62010-08-17 18:38:24340 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56341 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57342 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19343};
344
[email protected]d84e48b2010-10-21 22:04:52345template <>
[email protected]7c854372011-08-15 20:41:46346struct IPC_EXPORT ParamTraits<base::TimeDelta> {
[email protected]d84e48b2010-10-21 22:04:52347 typedef base::TimeDelta param_type;
348 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56349 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]d84e48b2010-10-21 22:04:52350 static void Log(const param_type& p, std::string* l);
351};
352
[email protected]1d14f582011-09-02 20:42:04353template <>
354struct IPC_EXPORT ParamTraits<base::TimeTicks> {
355 typedef base::TimeTicks param_type;
356 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56357 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]1d14f582011-09-02 20:42:04358 static void Log(const param_type& p, std::string* l);
359};
360
[email protected]7d5c3ac2009-02-04 08:58:19361#if defined(OS_WIN)
362template <>
363struct ParamTraits<LOGFONT> {
364 typedef LOGFONT param_type;
365 static void Write(Message* m, const param_type& p) {
366 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
367 }
[email protected]ce208f872012-03-07 20:42:56368 static bool Read(const Message* m, PickleIterator* iter,
369 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19370 const char *data;
371 int data_size = 0;
372 bool result = m->ReadData(iter, &data, &data_size);
373 if (result && data_size == sizeof(LOGFONT)) {
374 memcpy(r, data, sizeof(LOGFONT));
375 } else {
376 result = false;
377 NOTREACHED();
378 }
379
380 return result;
381 }
[email protected]252cad62010-08-18 18:33:57382 static void Log(const param_type& p, std::string* l) {
383 l->append(StringPrintf("<LOGFONT>"));
[email protected]7d5c3ac2009-02-04 08:58:19384 }
385};
386
387template <>
388struct ParamTraits<MSG> {
389 typedef MSG param_type;
390 static void Write(Message* m, const param_type& p) {
391 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
392 }
[email protected]ce208f872012-03-07 20:42:56393 static bool Read(const Message* m, PickleIterator* iter,
394 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19395 const char *data;
396 int data_size = 0;
397 bool result = m->ReadData(iter, &data, &data_size);
398 if (result && data_size == sizeof(MSG)) {
399 memcpy(r, data, sizeof(MSG));
400 } else {
401 result = false;
402 NOTREACHED();
403 }
404
405 return result;
406 }
[email protected]252cad62010-08-18 18:33:57407 static void Log(const param_type& p, std::string* l) {
408 l->append("<MSG>");
[email protected]7a4de7a62010-08-17 18:38:24409 }
[email protected]7d5c3ac2009-02-04 08:58:19410};
411#endif // defined(OS_WIN)
412
413template <>
[email protected]7c854372011-08-15 20:41:46414struct IPC_EXPORT ParamTraits<base::DictionaryValue> {
[email protected]f3a1c642011-07-12 19:15:03415 typedef base::DictionaryValue param_type;
[email protected]584f2b22009-05-21 01:01:59416 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56417 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57418 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59419};
420
421template <>
[email protected]7c854372011-08-15 20:41:46422struct IPC_EXPORT ParamTraits<base::ListValue> {
[email protected]f3a1c642011-07-12 19:15:03423 typedef base::ListValue param_type;
[email protected]584f2b22009-05-21 01:01:59424 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56425 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57426 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59427};
428
429template <>
[email protected]7d5c3ac2009-02-04 08:58:19430struct ParamTraits<std::string> {
431 typedef std::string param_type;
432 static void Write(Message* m, const param_type& p) {
433 m->WriteString(p);
434 }
[email protected]ce208f872012-03-07 20:42:56435 static bool Read(const Message* m, PickleIterator* iter,
436 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19437 return m->ReadString(iter, r);
438 }
[email protected]252cad62010-08-18 18:33:57439 static void Log(const param_type& p, std::string* l) {
440 l->append(p);
[email protected]7d5c3ac2009-02-04 08:58:19441 }
442};
443
[email protected]3dd7a7a2009-07-27 21:09:07444template<typename CharType>
[email protected]252cad62010-08-18 18:33:57445static void LogBytes(const std::vector<CharType>& data, std::string* out) {
[email protected]3dd7a7a2009-07-27 21:09:07446#if defined(OS_WIN)
447 // Windows has a GUI for logging, which can handle arbitrary binary data.
448 for (size_t i = 0; i < data.size(); ++i)
449 out->push_back(data[i]);
450#else
451 // On POSIX, we log to stdout, which we assume can display ASCII.
452 static const size_t kMaxBytesToLog = 100;
453 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
454 if (isprint(data[i]))
455 out->push_back(data[i]);
456 else
[email protected]252cad62010-08-18 18:33:57457 out->append(StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
[email protected]3dd7a7a2009-07-27 21:09:07458 }
459 if (data.size() > kMaxBytesToLog) {
460 out->append(
[email protected]252cad62010-08-18 18:33:57461 StringPrintf(" and %u more bytes",
[email protected]3dd7a7a2009-07-27 21:09:07462 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
463 }
464#endif
465}
466
[email protected]7d5c3ac2009-02-04 08:58:19467template <>
468struct ParamTraits<std::vector<unsigned char> > {
469 typedef std::vector<unsigned char> param_type;
470 static void Write(Message* m, const param_type& p) {
[email protected]f6b8ce32011-03-02 00:03:18471 if (p.empty()) {
[email protected]7d5c3ac2009-02-04 08:58:19472 m->WriteData(NULL, 0);
473 } else {
474 m->WriteData(reinterpret_cast<const char*>(&p.front()),
475 static_cast<int>(p.size()));
476 }
477 }
[email protected]ce208f872012-03-07 20:42:56478 static bool Read(const Message* m, PickleIterator* iter,
479 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19480 const char *data;
481 int data_size = 0;
482 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
483 return false;
484 r->resize(data_size);
485 if (data_size)
486 memcpy(&r->front(), data, data_size);
487 return true;
488 }
[email protected]252cad62010-08-18 18:33:57489 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07490 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19491 }
492};
493
494template <>
495struct ParamTraits<std::vector<char> > {
496 typedef std::vector<char> param_type;
497 static void Write(Message* m, const param_type& p) {
[email protected]f6b8ce32011-03-02 00:03:18498 if (p.empty()) {
[email protected]7d5c3ac2009-02-04 08:58:19499 m->WriteData(NULL, 0);
500 } else {
501 m->WriteData(&p.front(), static_cast<int>(p.size()));
502 }
503 }
[email protected]ce208f872012-03-07 20:42:56504 static bool Read(const Message* m, PickleIterator* iter,
505 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19506 const char *data;
507 int data_size = 0;
508 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
509 return false;
510 r->resize(data_size);
511 if (data_size)
512 memcpy(&r->front(), data, data_size);
513 return true;
514 }
[email protected]252cad62010-08-18 18:33:57515 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07516 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19517 }
518};
519
[email protected]51b63f62011-10-05 18:55:42520template <>
521struct ParamTraits<std::vector<bool> > {
522 typedef std::vector<bool> param_type;
523 static void Write(Message* m, const param_type& p) {
524 WriteParam(m, static_cast<int>(p.size()));
525 for (size_t i = 0; i < p.size(); i++)
526 WriteParam(m, p[i]);
527 }
[email protected]ce208f872012-03-07 20:42:56528 static bool Read(const Message* m, PickleIterator* iter,
529 param_type* r) {
[email protected]51b63f62011-10-05 18:55:42530 int size;
531 // ReadLength() checks for < 0 itself.
532 if (!m->ReadLength(iter, &size))
533 return false;
534 r->resize(size);
535 for (int i = 0; i < size; i++) {
536 bool value;
537 if (!ReadParam(m, iter, &value))
538 return false;
539 (*r)[i] = value;
540 }
541 return true;
542 }
543 static void Log(const param_type& p, std::string* l) {
544 for (size_t i = 0; i < p.size(); ++i) {
545 if (i != 0)
546 l->append(" ");
547 LogParam((p[i]), l);
548 }
549 }
550};
551
[email protected]7d5c3ac2009-02-04 08:58:19552template <class P>
553struct ParamTraits<std::vector<P> > {
554 typedef std::vector<P> param_type;
555 static void Write(Message* m, const param_type& p) {
556 WriteParam(m, static_cast<int>(p.size()));
557 for (size_t i = 0; i < p.size(); i++)
558 WriteParam(m, p[i]);
559 }
[email protected]ce208f872012-03-07 20:42:56560 static bool Read(const Message* m, PickleIterator* iter,
561 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19562 int size;
[email protected]86440f52009-12-31 05:17:23563 // ReadLength() checks for < 0 itself.
[email protected]7d5c3ac2009-02-04 08:58:19564 if (!m->ReadLength(iter, &size))
565 return false;
566 // Resizing beforehand is not safe, see BUG 1006367 for details.
[email protected]86440f52009-12-31 05:17:23567 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
568 return false;
569 r->resize(size);
570 for (int i = 0; i < size; i++) {
571 if (!ReadParam(m, iter, &(*r)[i]))
572 return false;
[email protected]7d5c3ac2009-02-04 08:58:19573 }
574 return true;
575 }
[email protected]252cad62010-08-18 18:33:57576 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19577 for (size_t i = 0; i < p.size(); ++i) {
578 if (i != 0)
[email protected]252cad62010-08-18 18:33:57579 l->append(" ");
[email protected]7d5c3ac2009-02-04 08:58:19580 LogParam((p[i]), l);
581 }
582 }
583};
584
[email protected]96da6962010-05-13 19:10:34585template <class P>
586struct ParamTraits<std::set<P> > {
587 typedef std::set<P> param_type;
588 static void Write(Message* m, const param_type& p) {
589 WriteParam(m, static_cast<int>(p.size()));
590 typename param_type::const_iterator iter;
591 for (iter = p.begin(); iter != p.end(); ++iter)
592 WriteParam(m, *iter);
593 }
[email protected]ce208f872012-03-07 20:42:56594 static bool Read(const Message* m, PickleIterator* iter,
595 param_type* r) {
[email protected]96da6962010-05-13 19:10:34596 int size;
597 if (!m->ReadLength(iter, &size))
598 return false;
599 for (int i = 0; i < size; ++i) {
600 P item;
601 if (!ReadParam(m, iter, &item))
602 return false;
603 r->insert(item);
604 }
605 return true;
606 }
[email protected]252cad62010-08-18 18:33:57607 static void Log(const param_type& p, std::string* l) {
608 l->append("<std::set>");
[email protected]96da6962010-05-13 19:10:34609 }
610};
611
612
[email protected]7d5c3ac2009-02-04 08:58:19613template <class K, class V>
614struct ParamTraits<std::map<K, V> > {
615 typedef std::map<K, V> param_type;
616 static void Write(Message* m, const param_type& p) {
617 WriteParam(m, static_cast<int>(p.size()));
618 typename param_type::const_iterator iter;
619 for (iter = p.begin(); iter != p.end(); ++iter) {
620 WriteParam(m, iter->first);
621 WriteParam(m, iter->second);
622 }
623 }
[email protected]ce208f872012-03-07 20:42:56624 static bool Read(const Message* m, PickleIterator* iter,
625 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19626 int size;
627 if (!ReadParam(m, iter, &size) || size < 0)
628 return false;
629 for (int i = 0; i < size; ++i) {
630 K k;
631 if (!ReadParam(m, iter, &k))
632 return false;
633 V& value = (*r)[k];
634 if (!ReadParam(m, iter, &value))
635 return false;
636 }
637 return true;
638 }
[email protected]252cad62010-08-18 18:33:57639 static void Log(const param_type& p, std::string* l) {
640 l->append("<std::map>");
[email protected]7d5c3ac2009-02-04 08:58:19641 }
642};
643
[email protected]eb47a132009-03-04 00:39:56644
[email protected]7d5c3ac2009-02-04 08:58:19645template <>
646struct ParamTraits<std::wstring> {
647 typedef std::wstring param_type;
648 static void Write(Message* m, const param_type& p) {
649 m->WriteWString(p);
650 }
[email protected]ce208f872012-03-07 20:42:56651 static bool Read(const Message* m, PickleIterator* iter,
652 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19653 return m->ReadWString(iter, r);
654 }
[email protected]7c854372011-08-15 20:41:46655 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19656};
657
[email protected]a5da6d612009-08-04 02:00:56658template <class A, class B>
659struct ParamTraits<std::pair<A, B> > {
660 typedef std::pair<A, B> param_type;
661 static void Write(Message* m, const param_type& p) {
662 WriteParam(m, p.first);
663 WriteParam(m, p.second);
664 }
[email protected]ce208f872012-03-07 20:42:56665 static bool Read(const Message* m, PickleIterator* iter,
666 param_type* r) {
[email protected]a5da6d612009-08-04 02:00:56667 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
668 }
[email protected]252cad62010-08-18 18:33:57669 static void Log(const param_type& p, std::string* l) {
670 l->append("(");
[email protected]a5da6d612009-08-04 02:00:56671 LogParam(p.first, l);
[email protected]252cad62010-08-18 18:33:57672 l->append(", ");
[email protected]a5da6d612009-08-04 02:00:56673 LogParam(p.second, l);
[email protected]252cad62010-08-18 18:33:57674 l->append(")");
[email protected]a5da6d612009-08-04 02:00:56675 }
676};
677
[email protected]15bf8712009-08-27 00:55:02678template <>
[email protected]7c854372011-08-15 20:41:46679struct IPC_EXPORT ParamTraits<NullableString16> {
[email protected]15bf8712009-08-27 00:55:02680 typedef NullableString16 param_type;
[email protected]7a4de7a62010-08-17 18:38:24681 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56682 static bool Read(const Message* m, PickleIterator* iter,
683 param_type* r);
[email protected]252cad62010-08-18 18:33:57684 static void Log(const param_type& p, std::string* l);
[email protected]15bf8712009-08-27 00:55:02685};
686
[email protected]eb47a132009-03-04 00:39:56687// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
688// need this trait.
689#if !defined(WCHAR_T_IS_UTF16)
[email protected]eb47a132009-03-04 00:39:56690template <>
691struct ParamTraits<string16> {
692 typedef string16 param_type;
693 static void Write(Message* m, const param_type& p) {
[email protected]3a2a5d22009-03-04 03:36:36694 m->WriteString16(p);
[email protected]eb47a132009-03-04 00:39:56695 }
[email protected]ce208f872012-03-07 20:42:56696 static bool Read(const Message* m, PickleIterator* iter,
697 param_type* r) {
[email protected]3a2a5d22009-03-04 03:36:36698 return m->ReadString16(iter, r);
[email protected]eb47a132009-03-04 00:39:56699 }
[email protected]7c854372011-08-15 20:41:46700 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]eb47a132009-03-04 00:39:56701};
[email protected]eb47a132009-03-04 00:39:56702#endif
703
[email protected]7d5c3ac2009-02-04 08:58:19704// and, a few more useful types...
705#if defined(OS_WIN)
706template <>
707struct ParamTraits<HANDLE> {
708 typedef HANDLE param_type;
709 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35710 // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
711 // bit systems.
712 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19713 }
[email protected]ce208f872012-03-07 20:42:56714 static bool Read(const Message* m, PickleIterator* iter,
715 param_type* r) {
[email protected]37477912010-02-09 08:06:35716 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
717 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19718 }
[email protected]252cad62010-08-18 18:33:57719 static void Log(const param_type& p, std::string* l) {
720 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19721 }
722};
723
724template <>
[email protected]0a670ed2011-09-06 21:01:09725struct ParamTraits<HCURSOR> {
726 typedef HCURSOR param_type;
[email protected]7d5c3ac2009-02-04 08:58:19727 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35728 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19729 }
[email protected]ce208f872012-03-07 20:42:56730 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35731 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
732 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19733 }
[email protected]252cad62010-08-18 18:33:57734 static void Log(const param_type& p, std::string* l) {
735 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19736 }
737};
738
739template <>
[email protected]7d5c3ac2009-02-04 08:58:19740struct ParamTraits<HACCEL> {
741 typedef HACCEL param_type;
742 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35743 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19744 }
[email protected]ce208f872012-03-07 20:42:56745 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35746 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
747 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19748 }
749};
750
751template <>
752struct ParamTraits<POINT> {
753 typedef POINT param_type;
754 static void Write(Message* m, const param_type& p) {
755 m->WriteInt(p.x);
756 m->WriteInt(p.y);
757 }
[email protected]ce208f872012-03-07 20:42:56758 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19759 int x, y;
760 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
761 return false;
762 r->x = x;
763 r->y = y;
764 return true;
765 }
[email protected]252cad62010-08-18 18:33:57766 static void Log(const param_type& p, std::string* l) {
767 l->append(StringPrintf("(%d, %d)", p.x, p.y));
[email protected]7d5c3ac2009-02-04 08:58:19768 }
769};
770#endif // defined(OS_WIN)
771
772template <>
[email protected]7c854372011-08-15 20:41:46773struct IPC_EXPORT ParamTraits<FilePath> {
[email protected]7d5c3ac2009-02-04 08:58:19774 typedef FilePath param_type;
[email protected]7a4de7a62010-08-17 18:38:24775 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56776 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57777 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19778};
779
[email protected]526776c2009-02-07 00:39:26780#if defined(OS_POSIX)
[email protected]2749885f2009-03-05 21:40:11781// FileDescriptors may be serialised over IPC channels on POSIX. On the
782// receiving side, the FileDescriptor is a valid duplicate of the file
783// descriptor which was transmitted: *it is not just a copy of the integer like
784// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
785// this case, the receiving end will see a value of -1. *Zero is a valid file
786// descriptor*.
787//
788// The received file descriptor will have the |auto_close| flag set to true. The
789// code which handles the message is responsible for taking ownership of it.
790// File descriptors are OS resources and must be closed when no longer needed.
791//
792// When sending a file descriptor, the file descriptor must be valid at the time
793// of transmission. Since transmission is not synchronous, one should consider
794// dup()ing any file descriptors to be transmitted and setting the |auto_close|
795// flag, which causes the file descriptor to be closed after writing.
[email protected]526776c2009-02-07 00:39:26796template<>
[email protected]7c854372011-08-15 20:41:46797struct IPC_EXPORT ParamTraits<base::FileDescriptor> {
[email protected]5fe733de2009-02-11 18:59:20798 typedef base::FileDescriptor param_type;
[email protected]7a4de7a62010-08-17 18:38:24799 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56800 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57801 static void Log(const param_type& p, std::string* l);
[email protected]526776c2009-02-07 00:39:26802};
[email protected]379e7a52010-03-09 00:38:41803#endif // defined(OS_POSIX)
[email protected]526776c2009-02-07 00:39:26804
[email protected]d2e884d2009-06-22 20:37:52805// A ChannelHandle is basically a platform-inspecific wrapper around the
806// fact that IPC endpoints are handled specially on POSIX. See above comments
807// on FileDescriptor for more background.
808template<>
[email protected]7c854372011-08-15 20:41:46809struct IPC_EXPORT ParamTraits<IPC::ChannelHandle> {
[email protected]d2e884d2009-06-22 20:37:52810 typedef ChannelHandle param_type;
[email protected]7a4de7a62010-08-17 18:38:24811 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56812 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57813 static void Log(const param_type& p, std::string* l);
[email protected]d2e884d2009-06-22 20:37:52814};
815
[email protected]7d5c3ac2009-02-04 08:58:19816#if defined(OS_WIN)
817template <>
818struct ParamTraits<XFORM> {
819 typedef XFORM param_type;
820 static void Write(Message* m, const param_type& p) {
821 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
822 }
[email protected]ce208f872012-03-07 20:42:56823 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19824 const char *data;
825 int data_size = 0;
826 bool result = m->ReadData(iter, &data, &data_size);
827 if (result && data_size == sizeof(XFORM)) {
828 memcpy(r, data, sizeof(XFORM));
829 } else {
830 result = false;
831 NOTREACHED();
832 }
833
834 return result;
835 }
[email protected]252cad62010-08-18 18:33:57836 static void Log(const param_type& p, std::string* l) {
837 l->append("<XFORM>");
[email protected]7d5c3ac2009-02-04 08:58:19838 }
839};
840#endif // defined(OS_WIN)
841
[email protected]7c854372011-08-15 20:41:46842struct IPC_EXPORT LogData {
[email protected]20f0487a2010-09-30 20:06:30843 LogData();
844 ~LogData();
845
[email protected]9a3a293b2009-06-04 22:28:16846 std::string channel;
[email protected]8bef70e2009-04-14 19:11:24847 int32 routing_id;
[email protected]168ae922009-12-04 18:08:45848 uint32 type; // "User-defined" message type, from ipc_message.h.
[email protected]252cad62010-08-18 18:33:57849 std::string flags;
[email protected]7d5c3ac2009-02-04 08:58:19850 int64 sent; // Time that the message was sent (i.e. at Send()).
851 int64 receive; // Time before it was dispatched (i.e. before calling
852 // OnMessageReceived).
853 int64 dispatch; // Time after it was dispatched (i.e. after calling
854 // OnMessageReceived).
[email protected]252cad62010-08-18 18:33:57855 std::string message_name;
856 std::string params;
[email protected]7d5c3ac2009-02-04 08:58:19857};
858
859template <>
[email protected]7c854372011-08-15 20:41:46860struct IPC_EXPORT ParamTraits<LogData> {
[email protected]7d5c3ac2009-02-04 08:58:19861 typedef LogData param_type;
[email protected]20f0487a2010-09-30 20:06:30862 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56863 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57864 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19865 // Doesn't make sense to implement this!
866 }
867};
868
[email protected]eb47a132009-03-04 00:39:56869template <>
[email protected]503683f2009-02-26 09:13:01870struct ParamTraits<Message> {
871 static void Write(Message* m, const Message& p) {
[email protected]8a861402011-01-28 19:59:11872 DCHECK(p.size() <= INT_MAX);
873 int message_size = static_cast<int>(p.size());
874 m->WriteInt(message_size);
875 m->WriteData(reinterpret_cast<const char*>(p.data()), message_size);
[email protected]503683f2009-02-26 09:13:01876 }
[email protected]ce208f872012-03-07 20:42:56877 static bool Read(const Message* m, PickleIterator* iter, Message* r) {
[email protected]503683f2009-02-26 09:13:01878 int size;
879 if (!m->ReadInt(iter, &size))
880 return false;
881 const char* data;
882 if (!m->ReadData(iter, &data, &size))
883 return false;
884 *r = Message(data, size);
885 return true;
886 }
[email protected]252cad62010-08-18 18:33:57887 static void Log(const Message& p, std::string* l) {
888 l->append("<IPC::Message>");
[email protected]503683f2009-02-26 09:13:01889 }
890};
891
892template <>
[email protected]7d5c3ac2009-02-04 08:58:19893struct ParamTraits<Tuple0> {
894 typedef Tuple0 param_type;
895 static void Write(Message* m, const param_type& p) {
896 }
[email protected]ce208f872012-03-07 20:42:56897 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19898 return true;
899 }
[email protected]252cad62010-08-18 18:33:57900 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19901 }
902};
903
904template <class A>
905struct ParamTraits< Tuple1<A> > {
906 typedef Tuple1<A> param_type;
907 static void Write(Message* m, const param_type& p) {
908 WriteParam(m, p.a);
909 }
[email protected]ce208f872012-03-07 20:42:56910 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19911 return ReadParam(m, iter, &r->a);
912 }
[email protected]252cad62010-08-18 18:33:57913 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19914 LogParam(p.a, l);
915 }
916};
917
918template <class A, class B>
919struct ParamTraits< Tuple2<A, B> > {
920 typedef Tuple2<A, B> param_type;
921 static void Write(Message* m, const param_type& p) {
922 WriteParam(m, p.a);
923 WriteParam(m, p.b);
924 }
[email protected]ce208f872012-03-07 20:42:56925 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19926 return (ReadParam(m, iter, &r->a) &&
927 ReadParam(m, iter, &r->b));
928 }
[email protected]252cad62010-08-18 18:33:57929 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19930 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57931 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19932 LogParam(p.b, l);
933 }
934};
935
936template <class A, class B, class C>
937struct ParamTraits< Tuple3<A, B, C> > {
938 typedef Tuple3<A, B, C> param_type;
939 static void Write(Message* m, const param_type& p) {
940 WriteParam(m, p.a);
941 WriteParam(m, p.b);
942 WriteParam(m, p.c);
943 }
[email protected]ce208f872012-03-07 20:42:56944 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19945 return (ReadParam(m, iter, &r->a) &&
946 ReadParam(m, iter, &r->b) &&
947 ReadParam(m, iter, &r->c));
948 }
[email protected]252cad62010-08-18 18:33:57949 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19950 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57951 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19952 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57953 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19954 LogParam(p.c, l);
955 }
956};
957
958template <class A, class B, class C, class D>
959struct ParamTraits< Tuple4<A, B, C, D> > {
960 typedef Tuple4<A, B, C, D> param_type;
961 static void Write(Message* m, const param_type& p) {
962 WriteParam(m, p.a);
963 WriteParam(m, p.b);
964 WriteParam(m, p.c);
965 WriteParam(m, p.d);
966 }
[email protected]ce208f872012-03-07 20:42:56967 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19968 return (ReadParam(m, iter, &r->a) &&
969 ReadParam(m, iter, &r->b) &&
970 ReadParam(m, iter, &r->c) &&
971 ReadParam(m, iter, &r->d));
972 }
[email protected]252cad62010-08-18 18:33:57973 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19974 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57975 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19976 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57977 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19978 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57979 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19980 LogParam(p.d, l);
981 }
982};
983
984template <class A, class B, class C, class D, class E>
985struct ParamTraits< Tuple5<A, B, C, D, E> > {
986 typedef Tuple5<A, B, C, D, E> param_type;
987 static void Write(Message* m, const param_type& p) {
988 WriteParam(m, p.a);
989 WriteParam(m, p.b);
990 WriteParam(m, p.c);
991 WriteParam(m, p.d);
992 WriteParam(m, p.e);
993 }
[email protected]ce208f872012-03-07 20:42:56994 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19995 return (ReadParam(m, iter, &r->a) &&
996 ReadParam(m, iter, &r->b) &&
997 ReadParam(m, iter, &r->c) &&
998 ReadParam(m, iter, &r->d) &&
999 ReadParam(m, iter, &r->e));
1000 }
[email protected]252cad62010-08-18 18:33:571001 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:191002 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:571003 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:191004 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:571005 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:191006 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:571007 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:191008 LogParam(p.d, l);
[email protected]252cad62010-08-18 18:33:571009 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:191010 LogParam(p.e, l);
1011 }
1012};
1013
[email protected]7d5c3ac2009-02-04 08:58:191014//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:291015// Generic message subclasses
1016
1017// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:241018template <class ParamType>
[email protected]1d4ecf42011-08-26 21:27:301019class MessageSchema {
initial.commit09911bf2008-07-26 23:55:291020 public:
[email protected]81a34412009-01-05 19:17:241021 typedef ParamType Param;
[email protected]7a4de7a62010-08-17 18:38:241022 typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
[email protected]81a34412009-01-05 19:17:241023
[email protected]1d4ecf42011-08-26 21:27:301024 static void Write(Message* msg, const RefParam& p) IPC_MSG_NOINLINE;
[email protected]7a4de7a62010-08-17 18:38:241025 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:291026};
1027
[email protected]7a4de7a62010-08-17 18:38:241028// defined in ipc_logging.cc
[email protected]7c854372011-08-15 20:41:461029IPC_EXPORT void GenerateLogData(const std::string& channel,
1030 const Message& message,
[email protected]ea7744a2011-10-20 19:34:431031 LogData* data, bool get_params);
[email protected]7a4de7a62010-08-17 18:38:241032
1033
1034#if defined(IPC_MESSAGE_LOG_ENABLED)
[email protected]252cad62010-08-18 18:33:571035inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
1036 const std::string& output_params = msg->output_params();
[email protected]7a4de7a62010-08-17 18:38:241037 if (!l->empty() && !output_params.empty())
[email protected]252cad62010-08-18 18:33:571038 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:241039
1040 l->append(output_params);
1041}
1042
1043template <class ReplyParamType>
1044inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1045 const Message* msg) {
1046 if (msg->received_time() != 0) {
[email protected]252cad62010-08-18 18:33:571047 std::string output_params;
[email protected]7a4de7a62010-08-17 18:38:241048 LogParam(reply_params, &output_params);
1049 msg->set_output_params(output_params);
1050 }
1051}
1052
1053inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
1054 if (msg->sent_time()) {
1055 // Don't log the sync message after dispatch, as we don't have the
1056 // output parameters at that point. Instead, save its data and log it
1057 // with the outgoing reply message when it's sent.
1058 LogData* data = new LogData;
[email protected]ea7744a2011-10-20 19:34:431059 GenerateLogData("", *msg, data, true);
[email protected]7a4de7a62010-08-17 18:38:241060 msg->set_dont_log();
1061 reply->set_sync_log_data(data);
1062 }
1063}
1064#else
[email protected]252cad62010-08-18 18:33:571065inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
[email protected]7a4de7a62010-08-17 18:38:241066
1067template <class ReplyParamType>
1068inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1069 const Message* msg) {}
1070
1071inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1072#endif
1073
initial.commit09911bf2008-07-26 23:55:291074// This class assumes that its template argument is a RefTuple (a Tuple with
[email protected]7a4de7a62010-08-17 18:38:241075// reference elements). This would go into ipc_message_utils_impl.h, but it is
1076// also used by chrome_frame.
initial.commit09911bf2008-07-26 23:55:291077template <class RefTuple>
1078class ParamDeserializer : public MessageReplyDeserializer {
1079 public:
[email protected]e1981f432008-08-12 15:22:131080 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:291081
[email protected]ce208f872012-03-07 20:42:561082 bool SerializeOutputParameters(const IPC::Message& msg, PickleIterator iter) {
initial.commit09911bf2008-07-26 23:55:291083 return ReadParam(&msg, &iter, &out_);
1084 }
1085
1086 RefTuple out_;
1087};
1088
initial.commit09911bf2008-07-26 23:55:291089// Used for synchronous messages.
[email protected]75e5a872009-04-02 23:56:111090template <class SendParamType, class ReplyParamType>
[email protected]1d4ecf42011-08-26 21:27:301091class SyncMessageSchema {
initial.commit09911bf2008-07-26 23:55:291092 public:
[email protected]75e5a872009-04-02 23:56:111093 typedef SendParamType SendParam;
[email protected]7a4de7a62010-08-17 18:38:241094 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
[email protected]75e5a872009-04-02 23:56:111095 typedef ReplyParamType ReplyParam;
1096
[email protected]1d4ecf42011-08-26 21:27:301097 static void Write(Message* msg, const RefSendParam& send) IPC_MSG_NOINLINE;
[email protected]7a4de7a62010-08-17 18:38:241098 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
1099 static bool ReadReplyParam(
1100 const Message* msg,
1101 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:291102
[email protected]65412272010-12-21 20:03:241103 template<class T, class S, class Method>
[email protected]1d4ecf42011-08-26 21:27:301104 static bool DispatchWithSendParams(bool ok, const SendParam& send_params,
1105 const Message* msg, T* obj, S* sender,
1106 Method func) {
1107 Message* reply = SyncMessage::GenerateReply(msg);
1108 if (ok) {
[email protected]7a4de7a62010-08-17 18:38:241109 typename TupleTypes<ReplyParam>::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:291110 DispatchToMethod(obj, func, send_params, &reply_params);
1111 WriteParam(reply, reply_params);
[email protected]7a4de7a62010-08-17 18:38:241112 LogReplyParamsToMessage(reply_params, msg);
initial.commit09911bf2008-07-26 23:55:291113 } else {
1114 NOTREACHED() << "Error deserializing message " << msg->type();
1115 reply->set_reply_error();
initial.commit09911bf2008-07-26 23:55:291116 }
[email protected]65412272010-12-21 20:03:241117 sender->Send(reply);
[email protected]1d4ecf42011-08-26 21:27:301118 return ok;
initial.commit09911bf2008-07-26 23:55:291119 }
1120
1121 template<class T, class Method>
[email protected]1d4ecf42011-08-26 21:27:301122 static bool DispatchDelayReplyWithSendParams(bool ok,
1123 const SendParam& send_params,
1124 const Message* msg, T* obj,
1125 Method func) {
1126 Message* reply = SyncMessage::GenerateReply(msg);
1127 if (ok) {
initial.commit09911bf2008-07-26 23:55:291128 Tuple1<Message&> t = MakeRefTuple(*reply);
[email protected]7a4de7a62010-08-17 18:38:241129 ConnectMessageAndReply(msg, reply);
initial.commit09911bf2008-07-26 23:55:291130 DispatchToMethod(obj, func, send_params, &t);
initial.commit09911bf2008-07-26 23:55:291131 } else {
1132 NOTREACHED() << "Error deserializing message " << msg->type();
1133 reply->set_reply_error();
1134 obj->Send(reply);
initial.commit09911bf2008-07-26 23:55:291135 }
[email protected]1d4ecf42011-08-26 21:27:301136 return ok;
initial.commit09911bf2008-07-26 23:55:291137 }
1138
1139 template<typename TA>
1140 static void WriteReplyParams(Message* reply, TA a) {
1141 ReplyParam p(a);
1142 WriteParam(reply, p);
1143 }
1144
1145 template<typename TA, typename TB>
1146 static void WriteReplyParams(Message* reply, TA a, TB b) {
1147 ReplyParam p(a, b);
1148 WriteParam(reply, p);
1149 }
1150
1151 template<typename TA, typename TB, typename TC>
1152 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1153 ReplyParam p(a, b, c);
1154 WriteParam(reply, p);
1155 }
1156
1157 template<typename TA, typename TB, typename TC, typename TD>
1158 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1159 ReplyParam p(a, b, c, d);
1160 WriteParam(reply, p);
1161 }
1162
1163 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1164 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1165 ReplyParam p(a, b, c, d, e);
1166 WriteParam(reply, p);
1167 }
1168};
1169
[email protected]7d5c3ac2009-02-04 08:58:191170//-----------------------------------------------------------------------------
1171
[email protected]3178f4e22008-08-05 21:20:411172} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291173
[email protected]946d1b22009-07-22 23:57:211174#endif // IPC_IPC_MESSAGE_UTILS_H_