blob: 5176847930c92f3138fc4394f818855e86e717e2 [file] [log] [blame]
[email protected]663bd9e2011-03-21 01:07:011// Copyright (c) 2011 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]ca97f302011-01-20 13:57:0569 SpeechInputMsgStart,
[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]208d3b72011-08-31 22:35:1396 ChromePluginMsgStart,
[email protected]6f08af82011-09-15 01:19:0397 ChromeBenchmarkingMsgStart,
[email protected]1ef93132011-09-16 18:33:4798 IntentsMsgStart,
[email protected]7f3c7af2011-10-20 22:52:5199 JavaBridgeMsgStart,
[email protected]7f5969d2011-10-28 18:42:42100 GamepadMsgStart,
[email protected]e503a122011-03-17 18:20:52101 LastIPCMsgStart // Must come last.
[email protected]f91cb992009-02-04 20:10:12102};
103
[email protected]7a4de7a62010-08-17 18:38:24104class FilePath;
[email protected]7a4de7a62010-08-17 18:38:24105class NullableString16;
106
107namespace base {
[email protected]f3a1c642011-07-12 19:15:03108class DictionaryValue;
109class ListValue;
[email protected]7a4de7a62010-08-17 18:38:24110class Time;
[email protected]d84e48b2010-10-21 22:04:52111class TimeDelta;
[email protected]1d14f582011-09-02 20:42:04112class TimeTicks;
[email protected]7a4de7a62010-08-17 18:38:24113struct FileDescriptor;
114}
115
initial.commit09911bf2008-07-26 23:55:29116namespace IPC {
117
[email protected]7a4de7a62010-08-17 18:38:24118struct ChannelHandle;
119
initial.commit09911bf2008-07-26 23:55:29120//-----------------------------------------------------------------------------
121// An iterator class for reading the fields contained within a Message.
122
123class MessageIterator {
124 public:
[email protected]e1981f432008-08-12 15:22:13125 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
initial.commit09911bf2008-07-26 23:55:29126 }
127 int NextInt() const {
[email protected]9422b7dc2009-12-30 20:09:02128 int val = -1;
initial.commit09911bf2008-07-26 23:55:29129 if (!msg_.ReadInt(&iter_, &val))
130 NOTREACHED();
131 return val;
132 }
initial.commit09911bf2008-07-26 23:55:29133 const std::string NextString() const {
134 std::string val;
135 if (!msg_.ReadString(&iter_, &val))
136 NOTREACHED();
137 return val;
138 }
139 const std::wstring NextWString() const {
140 std::wstring val;
141 if (!msg_.ReadWString(&iter_, &val))
142 NOTREACHED();
143 return val;
144 }
[email protected]225c8f52010-02-05 22:23:20145 void NextData(const char** data, int* length) const {
initial.commit09911bf2008-07-26 23:55:29146 if (!msg_.ReadData(&iter_, data, length)) {
147 NOTREACHED();
148 }
149 }
150 private:
151 const Message& msg_;
152 mutable void* iter_;
153};
154
155//-----------------------------------------------------------------------------
[email protected]6476c72c2011-02-11 18:46:19156// A dummy struct to place first just to allow leading commas for all
157// members in the macro-generated constructor initializer lists.
158struct NoParams {
159};
160
161//-----------------------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19162// ParamTraits specializations, etc.
163
[email protected]7d5c3ac2009-02-04 08:58:19164template <class P>
165static inline void WriteParam(Message* m, const P& p) {
[email protected]7b291f92009-08-14 05:43:53166 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53167 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
[email protected]7d5c3ac2009-02-04 08:58:19168}
169
170template <class P>
[email protected]1e86aa62009-04-24 21:22:33171static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
172 P* p) {
[email protected]7b291f92009-08-14 05:43:53173 typedef typename SimilarTypeTraits<P>::Type Type;
174 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
[email protected]7d5c3ac2009-02-04 08:58:19175}
176
177template <class P>
[email protected]252cad62010-08-18 18:33:57178static inline void LogParam(const P& p, std::string* l) {
[email protected]7b291f92009-08-14 05:43:53179 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53180 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19181}
182
183template <>
184struct ParamTraits<bool> {
185 typedef bool param_type;
186 static void Write(Message* m, const param_type& p) {
187 m->WriteBool(p);
188 }
189 static bool Read(const Message* m, void** iter, param_type* r) {
190 return m->ReadBool(iter, r);
191 }
[email protected]252cad62010-08-18 18:33:57192 static void Log(const param_type& p, std::string* l) {
193 l->append(p ? "true" : "false");
[email protected]7d5c3ac2009-02-04 08:58:19194 }
195};
196
197template <>
198struct ParamTraits<int> {
199 typedef int param_type;
200 static void Write(Message* m, const param_type& p) {
201 m->WriteInt(p);
202 }
203 static bool Read(const Message* m, void** iter, param_type* r) {
204 return m->ReadInt(iter, r);
205 }
[email protected]7c854372011-08-15 20:41:46206 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19207};
208
209template <>
[email protected]63263f92009-07-28 19:35:08210struct ParamTraits<unsigned int> {
211 typedef unsigned int param_type;
212 static void Write(Message* m, const param_type& p) {
213 m->WriteInt(p);
214 }
215 static bool Read(const Message* m, void** iter, param_type* r) {
216 return m->ReadInt(iter, reinterpret_cast<int*>(r));
217 }
[email protected]7c854372011-08-15 20:41:46218 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08219};
220
221template <>
[email protected]7d5c3ac2009-02-04 08:58:19222struct ParamTraits<long> {
223 typedef long param_type;
224 static void Write(Message* m, const param_type& p) {
225 m->WriteLong(p);
226 }
227 static bool Read(const Message* m, void** iter, param_type* r) {
228 return m->ReadLong(iter, r);
229 }
[email protected]7c854372011-08-15 20:41:46230 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19231};
232
[email protected]140c3032009-06-26 18:22:54233template <>
234struct ParamTraits<unsigned long> {
235 typedef unsigned long param_type;
236 static void Write(Message* m, const param_type& p) {
237 m->WriteLong(p);
238 }
239 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]63263f92009-07-28 19:35:08240 return m->ReadLong(iter, reinterpret_cast<long*>(r));
[email protected]140c3032009-06-26 18:22:54241 }
[email protected]7c854372011-08-15 20:41:46242 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19243};
244
245template <>
[email protected]63263f92009-07-28 19:35:08246struct ParamTraits<long long> {
247 typedef long long param_type;
[email protected]7d5c3ac2009-02-04 08:58:19248 static void Write(Message* m, const param_type& p) {
249 m->WriteInt64(static_cast<int64>(p));
250 }
251 static bool Read(const Message* m, void** iter, param_type* r) {
252 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
253 }
[email protected]7c854372011-08-15 20:41:46254 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08255};
256
257template <>
258struct ParamTraits<unsigned long long> {
259 typedef unsigned long long param_type;
260 static void Write(Message* m, const param_type& p) {
261 m->WriteInt64(p);
262 }
263 static bool Read(const Message* m, void** iter, param_type* r) {
264 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
265 }
[email protected]7c854372011-08-15 20:41:46266 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19267};
268
[email protected]43a40202010-11-12 16:25:01269template <>
[email protected]7c854372011-08-15 20:41:46270struct IPC_EXPORT ParamTraits<unsigned short> {
[email protected]43a40202010-11-12 16:25:01271 typedef unsigned short param_type;
272 static void Write(Message* m, const param_type& p);
273 static bool Read(const Message* m, void** iter, param_type* r);
274 static void Log(const param_type& p, std::string* l);
275};
276
[email protected]20199662010-06-17 03:29:26277// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
278// should be sure to check the sanity of these values after receiving them over
279// IPC.
280template <>
281struct ParamTraits<float> {
282 typedef float param_type;
283 static void Write(Message* m, const param_type& p) {
284 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
285 }
286 static bool Read(const Message* m, void** iter, param_type* r) {
287 const char *data;
288 int data_size;
289 if (!m->ReadData(iter, &data, &data_size) ||
290 data_size != sizeof(param_type)) {
291 NOTREACHED();
292 return false;
293 }
294 memcpy(r, data, sizeof(param_type));
295 return true;
296 }
[email protected]252cad62010-08-18 18:33:57297 static void Log(const param_type& p, std::string* l) {
298 l->append(StringPrintf("%e", p));
[email protected]20199662010-06-17 03:29:26299 }
300};
301
[email protected]7d5c3ac2009-02-04 08:58:19302template <>
303struct ParamTraits<double> {
304 typedef double param_type;
305 static void Write(Message* m, const param_type& p) {
306 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
307 }
308 static bool Read(const Message* m, void** iter, param_type* r) {
309 const char *data;
[email protected]20199662010-06-17 03:29:26310 int data_size;
311 if (!m->ReadData(iter, &data, &data_size) ||
312 data_size != sizeof(param_type)) {
[email protected]7d5c3ac2009-02-04 08:58:19313 NOTREACHED();
[email protected]20199662010-06-17 03:29:26314 return false;
[email protected]7d5c3ac2009-02-04 08:58:19315 }
[email protected]20199662010-06-17 03:29:26316 memcpy(r, data, sizeof(param_type));
317 return true;
[email protected]7d5c3ac2009-02-04 08:58:19318 }
[email protected]252cad62010-08-18 18:33:57319 static void Log(const param_type& p, std::string* l) {
320 l->append(StringPrintf("%e", p));
[email protected]7d5c3ac2009-02-04 08:58:19321 }
322};
323
324template <>
[email protected]7c854372011-08-15 20:41:46325struct IPC_EXPORT ParamTraits<base::Time> {
[email protected]7d5c3ac2009-02-04 08:58:19326 typedef base::Time param_type;
[email protected]7a4de7a62010-08-17 18:38:24327 static void Write(Message* m, const param_type& p);
328 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57329 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19330};
331
[email protected]d84e48b2010-10-21 22:04:52332template <>
[email protected]7c854372011-08-15 20:41:46333struct IPC_EXPORT ParamTraits<base::TimeDelta> {
[email protected]d84e48b2010-10-21 22:04:52334 typedef base::TimeDelta param_type;
335 static void Write(Message* m, const param_type& p);
336 static bool Read(const Message* m, void** iter, param_type* r);
337 static void Log(const param_type& p, std::string* l);
338};
339
[email protected]1d14f582011-09-02 20:42:04340template <>
341struct IPC_EXPORT ParamTraits<base::TimeTicks> {
342 typedef base::TimeTicks param_type;
343 static void Write(Message* m, const param_type& p);
344 static bool Read(const Message* m, void** iter, param_type* r);
345 static void Log(const param_type& p, std::string* l);
346};
347
[email protected]7d5c3ac2009-02-04 08:58:19348#if defined(OS_WIN)
349template <>
350struct ParamTraits<LOGFONT> {
351 typedef LOGFONT param_type;
352 static void Write(Message* m, const param_type& p) {
353 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
354 }
355 static bool Read(const Message* m, void** iter, param_type* r) {
356 const char *data;
357 int data_size = 0;
358 bool result = m->ReadData(iter, &data, &data_size);
359 if (result && data_size == sizeof(LOGFONT)) {
360 memcpy(r, data, sizeof(LOGFONT));
361 } else {
362 result = false;
363 NOTREACHED();
364 }
365
366 return result;
367 }
[email protected]252cad62010-08-18 18:33:57368 static void Log(const param_type& p, std::string* l) {
369 l->append(StringPrintf("<LOGFONT>"));
[email protected]7d5c3ac2009-02-04 08:58:19370 }
371};
372
373template <>
374struct ParamTraits<MSG> {
375 typedef MSG param_type;
376 static void Write(Message* m, const param_type& p) {
377 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
378 }
379 static bool Read(const Message* m, void** iter, param_type* r) {
380 const char *data;
381 int data_size = 0;
382 bool result = m->ReadData(iter, &data, &data_size);
383 if (result && data_size == sizeof(MSG)) {
384 memcpy(r, data, sizeof(MSG));
385 } else {
386 result = false;
387 NOTREACHED();
388 }
389
390 return result;
391 }
[email protected]252cad62010-08-18 18:33:57392 static void Log(const param_type& p, std::string* l) {
393 l->append("<MSG>");
[email protected]7a4de7a62010-08-17 18:38:24394 }
[email protected]7d5c3ac2009-02-04 08:58:19395};
396#endif // defined(OS_WIN)
397
398template <>
[email protected]7c854372011-08-15 20:41:46399struct IPC_EXPORT ParamTraits<base::DictionaryValue> {
[email protected]f3a1c642011-07-12 19:15:03400 typedef base::DictionaryValue param_type;
[email protected]584f2b22009-05-21 01:01:59401 static void Write(Message* m, const param_type& p);
402 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57403 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59404};
405
406template <>
[email protected]7c854372011-08-15 20:41:46407struct IPC_EXPORT ParamTraits<base::ListValue> {
[email protected]f3a1c642011-07-12 19:15:03408 typedef base::ListValue param_type;
[email protected]584f2b22009-05-21 01:01:59409 static void Write(Message* m, const param_type& p);
410 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57411 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59412};
413
414template <>
[email protected]7d5c3ac2009-02-04 08:58:19415struct ParamTraits<std::string> {
416 typedef std::string param_type;
417 static void Write(Message* m, const param_type& p) {
418 m->WriteString(p);
419 }
420 static bool Read(const Message* m, void** iter, param_type* r) {
421 return m->ReadString(iter, r);
422 }
[email protected]252cad62010-08-18 18:33:57423 static void Log(const param_type& p, std::string* l) {
424 l->append(p);
[email protected]7d5c3ac2009-02-04 08:58:19425 }
426};
427
[email protected]3dd7a7a2009-07-27 21:09:07428template<typename CharType>
[email protected]252cad62010-08-18 18:33:57429static void LogBytes(const std::vector<CharType>& data, std::string* out) {
[email protected]3dd7a7a2009-07-27 21:09:07430#if defined(OS_WIN)
431 // Windows has a GUI for logging, which can handle arbitrary binary data.
432 for (size_t i = 0; i < data.size(); ++i)
433 out->push_back(data[i]);
434#else
435 // On POSIX, we log to stdout, which we assume can display ASCII.
436 static const size_t kMaxBytesToLog = 100;
437 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
438 if (isprint(data[i]))
439 out->push_back(data[i]);
440 else
[email protected]252cad62010-08-18 18:33:57441 out->append(StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
[email protected]3dd7a7a2009-07-27 21:09:07442 }
443 if (data.size() > kMaxBytesToLog) {
444 out->append(
[email protected]252cad62010-08-18 18:33:57445 StringPrintf(" and %u more bytes",
[email protected]3dd7a7a2009-07-27 21:09:07446 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
447 }
448#endif
449}
450
[email protected]7d5c3ac2009-02-04 08:58:19451template <>
452struct ParamTraits<std::vector<unsigned char> > {
453 typedef std::vector<unsigned char> param_type;
454 static void Write(Message* m, const param_type& p) {
[email protected]f6b8ce32011-03-02 00:03:18455 if (p.empty()) {
[email protected]7d5c3ac2009-02-04 08:58:19456 m->WriteData(NULL, 0);
457 } else {
458 m->WriteData(reinterpret_cast<const char*>(&p.front()),
459 static_cast<int>(p.size()));
460 }
461 }
462 static bool Read(const Message* m, void** iter, param_type* r) {
463 const char *data;
464 int data_size = 0;
465 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
466 return false;
467 r->resize(data_size);
468 if (data_size)
469 memcpy(&r->front(), data, data_size);
470 return true;
471 }
[email protected]252cad62010-08-18 18:33:57472 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07473 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19474 }
475};
476
477template <>
478struct ParamTraits<std::vector<char> > {
479 typedef std::vector<char> param_type;
480 static void Write(Message* m, const param_type& p) {
[email protected]f6b8ce32011-03-02 00:03:18481 if (p.empty()) {
[email protected]7d5c3ac2009-02-04 08:58:19482 m->WriteData(NULL, 0);
483 } else {
484 m->WriteData(&p.front(), static_cast<int>(p.size()));
485 }
486 }
487 static bool Read(const Message* m, void** iter, param_type* r) {
488 const char *data;
489 int data_size = 0;
490 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
491 return false;
492 r->resize(data_size);
493 if (data_size)
494 memcpy(&r->front(), data, data_size);
495 return true;
496 }
[email protected]252cad62010-08-18 18:33:57497 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07498 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19499 }
500};
501
[email protected]51b63f62011-10-05 18:55:42502template <>
503struct ParamTraits<std::vector<bool> > {
504 typedef std::vector<bool> param_type;
505 static void Write(Message* m, const param_type& p) {
506 WriteParam(m, static_cast<int>(p.size()));
507 for (size_t i = 0; i < p.size(); i++)
508 WriteParam(m, p[i]);
509 }
510 static bool Read(const Message* m, void** iter, param_type* r) {
511 int size;
512 // ReadLength() checks for < 0 itself.
513 if (!m->ReadLength(iter, &size))
514 return false;
515 r->resize(size);
516 for (int i = 0; i < size; i++) {
517 bool value;
518 if (!ReadParam(m, iter, &value))
519 return false;
520 (*r)[i] = value;
521 }
522 return true;
523 }
524 static void Log(const param_type& p, std::string* l) {
525 for (size_t i = 0; i < p.size(); ++i) {
526 if (i != 0)
527 l->append(" ");
528 LogParam((p[i]), l);
529 }
530 }
531};
532
[email protected]7d5c3ac2009-02-04 08:58:19533template <class P>
534struct ParamTraits<std::vector<P> > {
535 typedef std::vector<P> param_type;
536 static void Write(Message* m, const param_type& p) {
537 WriteParam(m, static_cast<int>(p.size()));
538 for (size_t i = 0; i < p.size(); i++)
539 WriteParam(m, p[i]);
540 }
541 static bool Read(const Message* m, void** iter, param_type* r) {
542 int size;
[email protected]86440f52009-12-31 05:17:23543 // ReadLength() checks for < 0 itself.
[email protected]7d5c3ac2009-02-04 08:58:19544 if (!m->ReadLength(iter, &size))
545 return false;
546 // Resizing beforehand is not safe, see BUG 1006367 for details.
[email protected]86440f52009-12-31 05:17:23547 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
548 return false;
549 r->resize(size);
550 for (int i = 0; i < size; i++) {
551 if (!ReadParam(m, iter, &(*r)[i]))
552 return false;
[email protected]7d5c3ac2009-02-04 08:58:19553 }
554 return true;
555 }
[email protected]252cad62010-08-18 18:33:57556 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19557 for (size_t i = 0; i < p.size(); ++i) {
558 if (i != 0)
[email protected]252cad62010-08-18 18:33:57559 l->append(" ");
[email protected]7d5c3ac2009-02-04 08:58:19560 LogParam((p[i]), l);
561 }
562 }
563};
564
[email protected]96da6962010-05-13 19:10:34565template <class P>
566struct ParamTraits<std::set<P> > {
567 typedef std::set<P> param_type;
568 static void Write(Message* m, const param_type& p) {
569 WriteParam(m, static_cast<int>(p.size()));
570 typename param_type::const_iterator iter;
571 for (iter = p.begin(); iter != p.end(); ++iter)
572 WriteParam(m, *iter);
573 }
574 static bool Read(const Message* m, void** iter, param_type* r) {
575 int size;
576 if (!m->ReadLength(iter, &size))
577 return false;
578 for (int i = 0; i < size; ++i) {
579 P item;
580 if (!ReadParam(m, iter, &item))
581 return false;
582 r->insert(item);
583 }
584 return true;
585 }
[email protected]252cad62010-08-18 18:33:57586 static void Log(const param_type& p, std::string* l) {
587 l->append("<std::set>");
[email protected]96da6962010-05-13 19:10:34588 }
589};
590
591
[email protected]7d5c3ac2009-02-04 08:58:19592template <class K, class V>
593struct ParamTraits<std::map<K, V> > {
594 typedef std::map<K, V> param_type;
595 static void Write(Message* m, const param_type& p) {
596 WriteParam(m, static_cast<int>(p.size()));
597 typename param_type::const_iterator iter;
598 for (iter = p.begin(); iter != p.end(); ++iter) {
599 WriteParam(m, iter->first);
600 WriteParam(m, iter->second);
601 }
602 }
603 static bool Read(const Message* m, void** iter, param_type* r) {
604 int size;
605 if (!ReadParam(m, iter, &size) || size < 0)
606 return false;
607 for (int i = 0; i < size; ++i) {
608 K k;
609 if (!ReadParam(m, iter, &k))
610 return false;
611 V& value = (*r)[k];
612 if (!ReadParam(m, iter, &value))
613 return false;
614 }
615 return true;
616 }
[email protected]252cad62010-08-18 18:33:57617 static void Log(const param_type& p, std::string* l) {
618 l->append("<std::map>");
[email protected]7d5c3ac2009-02-04 08:58:19619 }
620};
621
[email protected]eb47a132009-03-04 00:39:56622
[email protected]7d5c3ac2009-02-04 08:58:19623template <>
624struct ParamTraits<std::wstring> {
625 typedef std::wstring param_type;
626 static void Write(Message* m, const param_type& p) {
627 m->WriteWString(p);
628 }
629 static bool Read(const Message* m, void** iter, param_type* r) {
630 return m->ReadWString(iter, r);
631 }
[email protected]7c854372011-08-15 20:41:46632 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19633};
634
[email protected]a5da6d612009-08-04 02:00:56635template <class A, class B>
636struct ParamTraits<std::pair<A, B> > {
637 typedef std::pair<A, B> param_type;
638 static void Write(Message* m, const param_type& p) {
639 WriteParam(m, p.first);
640 WriteParam(m, p.second);
641 }
642 static bool Read(const Message* m, void** iter, param_type* r) {
643 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
644 }
[email protected]252cad62010-08-18 18:33:57645 static void Log(const param_type& p, std::string* l) {
646 l->append("(");
[email protected]a5da6d612009-08-04 02:00:56647 LogParam(p.first, l);
[email protected]252cad62010-08-18 18:33:57648 l->append(", ");
[email protected]a5da6d612009-08-04 02:00:56649 LogParam(p.second, l);
[email protected]252cad62010-08-18 18:33:57650 l->append(")");
[email protected]a5da6d612009-08-04 02:00:56651 }
652};
653
[email protected]15bf8712009-08-27 00:55:02654template <>
[email protected]7c854372011-08-15 20:41:46655struct IPC_EXPORT ParamTraits<NullableString16> {
[email protected]15bf8712009-08-27 00:55:02656 typedef NullableString16 param_type;
[email protected]7a4de7a62010-08-17 18:38:24657 static void Write(Message* m, const param_type& p);
658 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57659 static void Log(const param_type& p, std::string* l);
[email protected]15bf8712009-08-27 00:55:02660};
661
[email protected]eb47a132009-03-04 00:39:56662// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
663// need this trait.
664#if !defined(WCHAR_T_IS_UTF16)
[email protected]eb47a132009-03-04 00:39:56665template <>
666struct ParamTraits<string16> {
667 typedef string16 param_type;
668 static void Write(Message* m, const param_type& p) {
[email protected]3a2a5d22009-03-04 03:36:36669 m->WriteString16(p);
[email protected]eb47a132009-03-04 00:39:56670 }
671 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]3a2a5d22009-03-04 03:36:36672 return m->ReadString16(iter, r);
[email protected]eb47a132009-03-04 00:39:56673 }
[email protected]7c854372011-08-15 20:41:46674 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]eb47a132009-03-04 00:39:56675};
[email protected]eb47a132009-03-04 00:39:56676#endif
677
[email protected]7d5c3ac2009-02-04 08:58:19678// and, a few more useful types...
679#if defined(OS_WIN)
680template <>
681struct ParamTraits<HANDLE> {
682 typedef HANDLE param_type;
683 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35684 // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
685 // bit systems.
686 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19687 }
688 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35689 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
690 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19691 }
[email protected]252cad62010-08-18 18:33:57692 static void Log(const param_type& p, std::string* l) {
693 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19694 }
695};
696
697template <>
[email protected]0a670ed2011-09-06 21:01:09698struct ParamTraits<HCURSOR> {
699 typedef HCURSOR param_type;
[email protected]7d5c3ac2009-02-04 08:58:19700 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35701 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19702 }
703 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35704 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
705 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19706 }
[email protected]252cad62010-08-18 18:33:57707 static void Log(const param_type& p, std::string* l) {
708 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19709 }
710};
711
712template <>
[email protected]7d5c3ac2009-02-04 08:58:19713struct ParamTraits<HACCEL> {
714 typedef HACCEL param_type;
715 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35716 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19717 }
718 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35719 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
720 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19721 }
722};
723
724template <>
725struct ParamTraits<POINT> {
726 typedef POINT param_type;
727 static void Write(Message* m, const param_type& p) {
728 m->WriteInt(p.x);
729 m->WriteInt(p.y);
730 }
731 static bool Read(const Message* m, void** iter, param_type* r) {
732 int x, y;
733 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
734 return false;
735 r->x = x;
736 r->y = y;
737 return true;
738 }
[email protected]252cad62010-08-18 18:33:57739 static void Log(const param_type& p, std::string* l) {
740 l->append(StringPrintf("(%d, %d)", p.x, p.y));
[email protected]7d5c3ac2009-02-04 08:58:19741 }
742};
743#endif // defined(OS_WIN)
744
745template <>
[email protected]7c854372011-08-15 20:41:46746struct IPC_EXPORT ParamTraits<FilePath> {
[email protected]7d5c3ac2009-02-04 08:58:19747 typedef FilePath param_type;
[email protected]7a4de7a62010-08-17 18:38:24748 static void Write(Message* m, const param_type& p);
749 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57750 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19751};
752
[email protected]526776c2009-02-07 00:39:26753#if defined(OS_POSIX)
[email protected]2749885f2009-03-05 21:40:11754// FileDescriptors may be serialised over IPC channels on POSIX. On the
755// receiving side, the FileDescriptor is a valid duplicate of the file
756// descriptor which was transmitted: *it is not just a copy of the integer like
757// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
758// this case, the receiving end will see a value of -1. *Zero is a valid file
759// descriptor*.
760//
761// The received file descriptor will have the |auto_close| flag set to true. The
762// code which handles the message is responsible for taking ownership of it.
763// File descriptors are OS resources and must be closed when no longer needed.
764//
765// When sending a file descriptor, the file descriptor must be valid at the time
766// of transmission. Since transmission is not synchronous, one should consider
767// dup()ing any file descriptors to be transmitted and setting the |auto_close|
768// flag, which causes the file descriptor to be closed after writing.
[email protected]526776c2009-02-07 00:39:26769template<>
[email protected]7c854372011-08-15 20:41:46770struct IPC_EXPORT ParamTraits<base::FileDescriptor> {
[email protected]5fe733de2009-02-11 18:59:20771 typedef base::FileDescriptor param_type;
[email protected]7a4de7a62010-08-17 18:38:24772 static void Write(Message* m, const param_type& p);
773 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57774 static void Log(const param_type& p, std::string* l);
[email protected]526776c2009-02-07 00:39:26775};
[email protected]379e7a52010-03-09 00:38:41776#endif // defined(OS_POSIX)
[email protected]526776c2009-02-07 00:39:26777
[email protected]d2e884d2009-06-22 20:37:52778// A ChannelHandle is basically a platform-inspecific wrapper around the
779// fact that IPC endpoints are handled specially on POSIX. See above comments
780// on FileDescriptor for more background.
781template<>
[email protected]7c854372011-08-15 20:41:46782struct IPC_EXPORT ParamTraits<IPC::ChannelHandle> {
[email protected]d2e884d2009-06-22 20:37:52783 typedef ChannelHandle param_type;
[email protected]7a4de7a62010-08-17 18:38:24784 static void Write(Message* m, const param_type& p);
785 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57786 static void Log(const param_type& p, std::string* l);
[email protected]d2e884d2009-06-22 20:37:52787};
788
[email protected]7d5c3ac2009-02-04 08:58:19789#if defined(OS_WIN)
790template <>
791struct ParamTraits<XFORM> {
792 typedef XFORM param_type;
793 static void Write(Message* m, const param_type& p) {
794 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
795 }
796 static bool Read(const Message* m, void** iter, param_type* r) {
797 const char *data;
798 int data_size = 0;
799 bool result = m->ReadData(iter, &data, &data_size);
800 if (result && data_size == sizeof(XFORM)) {
801 memcpy(r, data, sizeof(XFORM));
802 } else {
803 result = false;
804 NOTREACHED();
805 }
806
807 return result;
808 }
[email protected]252cad62010-08-18 18:33:57809 static void Log(const param_type& p, std::string* l) {
810 l->append("<XFORM>");
[email protected]7d5c3ac2009-02-04 08:58:19811 }
812};
813#endif // defined(OS_WIN)
814
[email protected]7c854372011-08-15 20:41:46815struct IPC_EXPORT LogData {
[email protected]20f0487a2010-09-30 20:06:30816 LogData();
817 ~LogData();
818
[email protected]9a3a293b2009-06-04 22:28:16819 std::string channel;
[email protected]8bef70e2009-04-14 19:11:24820 int32 routing_id;
[email protected]168ae922009-12-04 18:08:45821 uint32 type; // "User-defined" message type, from ipc_message.h.
[email protected]252cad62010-08-18 18:33:57822 std::string flags;
[email protected]7d5c3ac2009-02-04 08:58:19823 int64 sent; // Time that the message was sent (i.e. at Send()).
824 int64 receive; // Time before it was dispatched (i.e. before calling
825 // OnMessageReceived).
826 int64 dispatch; // Time after it was dispatched (i.e. after calling
827 // OnMessageReceived).
[email protected]252cad62010-08-18 18:33:57828 std::string message_name;
829 std::string params;
[email protected]7d5c3ac2009-02-04 08:58:19830};
831
832template <>
[email protected]7c854372011-08-15 20:41:46833struct IPC_EXPORT ParamTraits<LogData> {
[email protected]7d5c3ac2009-02-04 08:58:19834 typedef LogData param_type;
[email protected]20f0487a2010-09-30 20:06:30835 static void Write(Message* m, const param_type& p);
836 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57837 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19838 // Doesn't make sense to implement this!
839 }
840};
841
[email protected]eb47a132009-03-04 00:39:56842template <>
[email protected]503683f2009-02-26 09:13:01843struct ParamTraits<Message> {
844 static void Write(Message* m, const Message& p) {
[email protected]8a861402011-01-28 19:59:11845 DCHECK(p.size() <= INT_MAX);
846 int message_size = static_cast<int>(p.size());
847 m->WriteInt(message_size);
848 m->WriteData(reinterpret_cast<const char*>(p.data()), message_size);
[email protected]503683f2009-02-26 09:13:01849 }
850 static bool Read(const Message* m, void** iter, Message* r) {
851 int size;
852 if (!m->ReadInt(iter, &size))
853 return false;
854 const char* data;
855 if (!m->ReadData(iter, &data, &size))
856 return false;
857 *r = Message(data, size);
858 return true;
859 }
[email protected]252cad62010-08-18 18:33:57860 static void Log(const Message& p, std::string* l) {
861 l->append("<IPC::Message>");
[email protected]503683f2009-02-26 09:13:01862 }
863};
864
865template <>
[email protected]7d5c3ac2009-02-04 08:58:19866struct ParamTraits<Tuple0> {
867 typedef Tuple0 param_type;
868 static void Write(Message* m, const param_type& p) {
869 }
870 static bool Read(const Message* m, void** iter, param_type* r) {
871 return true;
872 }
[email protected]252cad62010-08-18 18:33:57873 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19874 }
875};
876
877template <class A>
878struct ParamTraits< Tuple1<A> > {
879 typedef Tuple1<A> param_type;
880 static void Write(Message* m, const param_type& p) {
881 WriteParam(m, p.a);
882 }
883 static bool Read(const Message* m, void** iter, param_type* r) {
884 return ReadParam(m, iter, &r->a);
885 }
[email protected]252cad62010-08-18 18:33:57886 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19887 LogParam(p.a, l);
888 }
889};
890
891template <class A, class B>
892struct ParamTraits< Tuple2<A, B> > {
893 typedef Tuple2<A, B> param_type;
894 static void Write(Message* m, const param_type& p) {
895 WriteParam(m, p.a);
896 WriteParam(m, p.b);
897 }
898 static bool Read(const Message* m, void** iter, param_type* r) {
899 return (ReadParam(m, iter, &r->a) &&
900 ReadParam(m, iter, &r->b));
901 }
[email protected]252cad62010-08-18 18:33:57902 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19903 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57904 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19905 LogParam(p.b, l);
906 }
907};
908
909template <class A, class B, class C>
910struct ParamTraits< Tuple3<A, B, C> > {
911 typedef Tuple3<A, B, C> param_type;
912 static void Write(Message* m, const param_type& p) {
913 WriteParam(m, p.a);
914 WriteParam(m, p.b);
915 WriteParam(m, p.c);
916 }
917 static bool Read(const Message* m, void** iter, param_type* r) {
918 return (ReadParam(m, iter, &r->a) &&
919 ReadParam(m, iter, &r->b) &&
920 ReadParam(m, iter, &r->c));
921 }
[email protected]252cad62010-08-18 18:33:57922 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19923 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57924 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19925 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57926 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19927 LogParam(p.c, l);
928 }
929};
930
931template <class A, class B, class C, class D>
932struct ParamTraits< Tuple4<A, B, C, D> > {
933 typedef Tuple4<A, B, C, D> param_type;
934 static void Write(Message* m, const param_type& p) {
935 WriteParam(m, p.a);
936 WriteParam(m, p.b);
937 WriteParam(m, p.c);
938 WriteParam(m, p.d);
939 }
940 static bool Read(const Message* m, void** iter, param_type* r) {
941 return (ReadParam(m, iter, &r->a) &&
942 ReadParam(m, iter, &r->b) &&
943 ReadParam(m, iter, &r->c) &&
944 ReadParam(m, iter, &r->d));
945 }
[email protected]252cad62010-08-18 18:33:57946 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19947 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57948 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19949 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57950 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19951 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57952 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19953 LogParam(p.d, l);
954 }
955};
956
957template <class A, class B, class C, class D, class E>
958struct ParamTraits< Tuple5<A, B, C, D, E> > {
959 typedef Tuple5<A, B, C, D, E> param_type;
960 static void Write(Message* m, const param_type& p) {
961 WriteParam(m, p.a);
962 WriteParam(m, p.b);
963 WriteParam(m, p.c);
964 WriteParam(m, p.d);
965 WriteParam(m, p.e);
966 }
967 static bool Read(const Message* m, void** iter, param_type* r) {
968 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 ReadParam(m, iter, &r->e));
973 }
[email protected]252cad62010-08-18 18:33:57974 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19975 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57976 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19977 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57978 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19979 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57980 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19981 LogParam(p.d, l);
[email protected]252cad62010-08-18 18:33:57982 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19983 LogParam(p.e, l);
984 }
985};
986
[email protected]7d5c3ac2009-02-04 08:58:19987//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:29988// Generic message subclasses
989
990// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:24991template <class ParamType>
[email protected]1d4ecf42011-08-26 21:27:30992class MessageSchema {
initial.commit09911bf2008-07-26 23:55:29993 public:
[email protected]81a34412009-01-05 19:17:24994 typedef ParamType Param;
[email protected]7a4de7a62010-08-17 18:38:24995 typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
[email protected]81a34412009-01-05 19:17:24996
[email protected]1d4ecf42011-08-26 21:27:30997 static void Write(Message* msg, const RefParam& p) IPC_MSG_NOINLINE;
[email protected]7a4de7a62010-08-17 18:38:24998 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:29999};
1000
[email protected]7a4de7a62010-08-17 18:38:241001// defined in ipc_logging.cc
[email protected]7c854372011-08-15 20:41:461002IPC_EXPORT void GenerateLogData(const std::string& channel,
1003 const Message& message,
[email protected]ea7744a2011-10-20 19:34:431004 LogData* data, bool get_params);
[email protected]7a4de7a62010-08-17 18:38:241005
1006
1007#if defined(IPC_MESSAGE_LOG_ENABLED)
[email protected]252cad62010-08-18 18:33:571008inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
1009 const std::string& output_params = msg->output_params();
[email protected]7a4de7a62010-08-17 18:38:241010 if (!l->empty() && !output_params.empty())
[email protected]252cad62010-08-18 18:33:571011 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:241012
1013 l->append(output_params);
1014}
1015
1016template <class ReplyParamType>
1017inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1018 const Message* msg) {
1019 if (msg->received_time() != 0) {
[email protected]252cad62010-08-18 18:33:571020 std::string output_params;
[email protected]7a4de7a62010-08-17 18:38:241021 LogParam(reply_params, &output_params);
1022 msg->set_output_params(output_params);
1023 }
1024}
1025
1026inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
1027 if (msg->sent_time()) {
1028 // Don't log the sync message after dispatch, as we don't have the
1029 // output parameters at that point. Instead, save its data and log it
1030 // with the outgoing reply message when it's sent.
1031 LogData* data = new LogData;
[email protected]ea7744a2011-10-20 19:34:431032 GenerateLogData("", *msg, data, true);
[email protected]7a4de7a62010-08-17 18:38:241033 msg->set_dont_log();
1034 reply->set_sync_log_data(data);
1035 }
1036}
1037#else
[email protected]252cad62010-08-18 18:33:571038inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
[email protected]7a4de7a62010-08-17 18:38:241039
1040template <class ReplyParamType>
1041inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1042 const Message* msg) {}
1043
1044inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1045#endif
1046
initial.commit09911bf2008-07-26 23:55:291047// This class assumes that its template argument is a RefTuple (a Tuple with
[email protected]7a4de7a62010-08-17 18:38:241048// reference elements). This would go into ipc_message_utils_impl.h, but it is
1049// also used by chrome_frame.
initial.commit09911bf2008-07-26 23:55:291050template <class RefTuple>
1051class ParamDeserializer : public MessageReplyDeserializer {
1052 public:
[email protected]e1981f432008-08-12 15:22:131053 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:291054
1055 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1056 return ReadParam(&msg, &iter, &out_);
1057 }
1058
1059 RefTuple out_;
1060};
1061
initial.commit09911bf2008-07-26 23:55:291062// Used for synchronous messages.
[email protected]75e5a872009-04-02 23:56:111063template <class SendParamType, class ReplyParamType>
[email protected]1d4ecf42011-08-26 21:27:301064class SyncMessageSchema {
initial.commit09911bf2008-07-26 23:55:291065 public:
[email protected]75e5a872009-04-02 23:56:111066 typedef SendParamType SendParam;
[email protected]7a4de7a62010-08-17 18:38:241067 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
[email protected]75e5a872009-04-02 23:56:111068 typedef ReplyParamType ReplyParam;
1069
[email protected]1d4ecf42011-08-26 21:27:301070 static void Write(Message* msg, const RefSendParam& send) IPC_MSG_NOINLINE;
[email protected]7a4de7a62010-08-17 18:38:241071 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
1072 static bool ReadReplyParam(
1073 const Message* msg,
1074 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:291075
[email protected]65412272010-12-21 20:03:241076 template<class T, class S, class Method>
[email protected]1d4ecf42011-08-26 21:27:301077 static bool DispatchWithSendParams(bool ok, const SendParam& send_params,
1078 const Message* msg, T* obj, S* sender,
1079 Method func) {
1080 Message* reply = SyncMessage::GenerateReply(msg);
1081 if (ok) {
[email protected]7a4de7a62010-08-17 18:38:241082 typename TupleTypes<ReplyParam>::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:291083 DispatchToMethod(obj, func, send_params, &reply_params);
1084 WriteParam(reply, reply_params);
[email protected]7a4de7a62010-08-17 18:38:241085 LogReplyParamsToMessage(reply_params, msg);
initial.commit09911bf2008-07-26 23:55:291086 } else {
1087 NOTREACHED() << "Error deserializing message " << msg->type();
1088 reply->set_reply_error();
initial.commit09911bf2008-07-26 23:55:291089 }
[email protected]65412272010-12-21 20:03:241090 sender->Send(reply);
[email protected]1d4ecf42011-08-26 21:27:301091 return ok;
initial.commit09911bf2008-07-26 23:55:291092 }
1093
1094 template<class T, class Method>
[email protected]1d4ecf42011-08-26 21:27:301095 static bool DispatchDelayReplyWithSendParams(bool ok,
1096 const SendParam& send_params,
1097 const Message* msg, T* obj,
1098 Method func) {
1099 Message* reply = SyncMessage::GenerateReply(msg);
1100 if (ok) {
initial.commit09911bf2008-07-26 23:55:291101 Tuple1<Message&> t = MakeRefTuple(*reply);
[email protected]7a4de7a62010-08-17 18:38:241102 ConnectMessageAndReply(msg, reply);
initial.commit09911bf2008-07-26 23:55:291103 DispatchToMethod(obj, func, send_params, &t);
initial.commit09911bf2008-07-26 23:55:291104 } else {
1105 NOTREACHED() << "Error deserializing message " << msg->type();
1106 reply->set_reply_error();
1107 obj->Send(reply);
initial.commit09911bf2008-07-26 23:55:291108 }
[email protected]1d4ecf42011-08-26 21:27:301109 return ok;
initial.commit09911bf2008-07-26 23:55:291110 }
1111
1112 template<typename TA>
1113 static void WriteReplyParams(Message* reply, TA a) {
1114 ReplyParam p(a);
1115 WriteParam(reply, p);
1116 }
1117
1118 template<typename TA, typename TB>
1119 static void WriteReplyParams(Message* reply, TA a, TB b) {
1120 ReplyParam p(a, b);
1121 WriteParam(reply, p);
1122 }
1123
1124 template<typename TA, typename TB, typename TC>
1125 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1126 ReplyParam p(a, b, c);
1127 WriteParam(reply, p);
1128 }
1129
1130 template<typename TA, typename TB, typename TC, typename TD>
1131 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1132 ReplyParam p(a, b, c, d);
1133 WriteParam(reply, p);
1134 }
1135
1136 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1137 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1138 ReplyParam p(a, b, c, d, e);
1139 WriteParam(reply, p);
1140 }
1141};
1142
[email protected]7d5c3ac2009-02-04 08:58:191143//-----------------------------------------------------------------------------
1144
[email protected]3178f4e22008-08-05 21:20:411145} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291146
[email protected]946d1b22009-07-22 23:57:211147#endif // IPC_IPC_MESSAGE_UTILS_H_