blob: 9d750ca1faaac4fd0b42cbf9ff86404b759a2be4 [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]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]efb5f572012-01-29 10:57:33101 ShellMsgStart,
[email protected]e503a122011-03-17 18:20:52102 LastIPCMsgStart // Must come last.
[email protected]f91cb992009-02-04 20:10:12103};
104
[email protected]7a4de7a62010-08-17 18:38:24105class FilePath;
[email protected]7a4de7a62010-08-17 18:38:24106class NullableString16;
107
108namespace base {
[email protected]f3a1c642011-07-12 19:15:03109class DictionaryValue;
110class ListValue;
[email protected]7a4de7a62010-08-17 18:38:24111class Time;
[email protected]d84e48b2010-10-21 22:04:52112class TimeDelta;
[email protected]1d14f582011-09-02 20:42:04113class TimeTicks;
[email protected]7a4de7a62010-08-17 18:38:24114struct FileDescriptor;
115}
116
initial.commit09911bf2008-07-26 23:55:29117namespace IPC {
118
[email protected]7a4de7a62010-08-17 18:38:24119struct ChannelHandle;
120
initial.commit09911bf2008-07-26 23:55:29121//-----------------------------------------------------------------------------
122// An iterator class for reading the fields contained within a Message.
123
124class MessageIterator {
125 public:
[email protected]e1981f432008-08-12 15:22:13126 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
initial.commit09911bf2008-07-26 23:55:29127 }
128 int NextInt() const {
[email protected]9422b7dc2009-12-30 20:09:02129 int val = -1;
initial.commit09911bf2008-07-26 23:55:29130 if (!msg_.ReadInt(&iter_, &val))
131 NOTREACHED();
132 return val;
133 }
initial.commit09911bf2008-07-26 23:55:29134 const std::string NextString() const {
135 std::string val;
136 if (!msg_.ReadString(&iter_, &val))
137 NOTREACHED();
138 return val;
139 }
140 const std::wstring NextWString() const {
141 std::wstring val;
142 if (!msg_.ReadWString(&iter_, &val))
143 NOTREACHED();
144 return val;
145 }
[email protected]225c8f52010-02-05 22:23:20146 void NextData(const char** data, int* length) const {
initial.commit09911bf2008-07-26 23:55:29147 if (!msg_.ReadData(&iter_, data, length)) {
148 NOTREACHED();
149 }
150 }
151 private:
152 const Message& msg_;
153 mutable void* iter_;
154};
155
156//-----------------------------------------------------------------------------
[email protected]6476c72c2011-02-11 18:46:19157// A dummy struct to place first just to allow leading commas for all
158// members in the macro-generated constructor initializer lists.
159struct NoParams {
160};
161
162//-----------------------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19163// ParamTraits specializations, etc.
164
[email protected]7d5c3ac2009-02-04 08:58:19165template <class P>
166static inline void WriteParam(Message* m, const P& p) {
[email protected]7b291f92009-08-14 05:43:53167 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53168 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
[email protected]7d5c3ac2009-02-04 08:58:19169}
170
171template <class P>
[email protected]1e86aa62009-04-24 21:22:33172static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
173 P* p) {
[email protected]7b291f92009-08-14 05:43:53174 typedef typename SimilarTypeTraits<P>::Type Type;
175 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
[email protected]7d5c3ac2009-02-04 08:58:19176}
177
178template <class P>
[email protected]252cad62010-08-18 18:33:57179static inline void LogParam(const P& p, std::string* l) {
[email protected]7b291f92009-08-14 05:43:53180 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53181 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19182}
183
184template <>
185struct ParamTraits<bool> {
186 typedef bool param_type;
187 static void Write(Message* m, const param_type& p) {
188 m->WriteBool(p);
189 }
190 static bool Read(const Message* m, void** iter, param_type* r) {
191 return m->ReadBool(iter, r);
192 }
[email protected]252cad62010-08-18 18:33:57193 static void Log(const param_type& p, std::string* l) {
194 l->append(p ? "true" : "false");
[email protected]7d5c3ac2009-02-04 08:58:19195 }
196};
197
198template <>
199struct ParamTraits<int> {
200 typedef int param_type;
201 static void Write(Message* m, const param_type& p) {
202 m->WriteInt(p);
203 }
204 static bool Read(const Message* m, void** iter, param_type* r) {
205 return m->ReadInt(iter, r);
206 }
[email protected]7c854372011-08-15 20:41:46207 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19208};
209
210template <>
[email protected]63263f92009-07-28 19:35:08211struct ParamTraits<unsigned int> {
212 typedef unsigned int param_type;
213 static void Write(Message* m, const param_type& p) {
214 m->WriteInt(p);
215 }
216 static bool Read(const Message* m, void** iter, param_type* r) {
217 return m->ReadInt(iter, reinterpret_cast<int*>(r));
218 }
[email protected]7c854372011-08-15 20:41:46219 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08220};
221
222template <>
[email protected]7d5c3ac2009-02-04 08:58:19223struct ParamTraits<long> {
224 typedef long param_type;
225 static void Write(Message* m, const param_type& p) {
226 m->WriteLong(p);
227 }
228 static bool Read(const Message* m, void** iter, param_type* r) {
229 return m->ReadLong(iter, r);
230 }
[email protected]7c854372011-08-15 20:41:46231 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19232};
233
[email protected]140c3032009-06-26 18:22:54234template <>
235struct ParamTraits<unsigned long> {
236 typedef unsigned long param_type;
237 static void Write(Message* m, const param_type& p) {
238 m->WriteLong(p);
239 }
240 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]63263f92009-07-28 19:35:08241 return m->ReadLong(iter, reinterpret_cast<long*>(r));
[email protected]140c3032009-06-26 18:22:54242 }
[email protected]7c854372011-08-15 20:41:46243 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19244};
245
246template <>
[email protected]63263f92009-07-28 19:35:08247struct ParamTraits<long long> {
248 typedef long long param_type;
[email protected]7d5c3ac2009-02-04 08:58:19249 static void Write(Message* m, const param_type& p) {
250 m->WriteInt64(static_cast<int64>(p));
251 }
252 static bool Read(const Message* m, void** iter, param_type* r) {
253 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
254 }
[email protected]7c854372011-08-15 20:41:46255 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08256};
257
258template <>
259struct ParamTraits<unsigned long long> {
260 typedef unsigned long long param_type;
261 static void Write(Message* m, const param_type& p) {
262 m->WriteInt64(p);
263 }
264 static bool Read(const Message* m, void** iter, param_type* r) {
265 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
266 }
[email protected]7c854372011-08-15 20:41:46267 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19268};
269
[email protected]43a40202010-11-12 16:25:01270template <>
[email protected]7c854372011-08-15 20:41:46271struct IPC_EXPORT ParamTraits<unsigned short> {
[email protected]43a40202010-11-12 16:25:01272 typedef unsigned short param_type;
273 static void Write(Message* m, const param_type& p);
274 static bool Read(const Message* m, void** iter, param_type* r);
275 static void Log(const param_type& p, std::string* l);
276};
277
[email protected]20199662010-06-17 03:29:26278// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
279// should be sure to check the sanity of these values after receiving them over
280// IPC.
281template <>
282struct ParamTraits<float> {
283 typedef float param_type;
284 static void Write(Message* m, const param_type& p) {
285 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
286 }
287 static bool Read(const Message* m, void** iter, param_type* r) {
288 const char *data;
289 int data_size;
290 if (!m->ReadData(iter, &data, &data_size) ||
291 data_size != sizeof(param_type)) {
292 NOTREACHED();
293 return false;
294 }
295 memcpy(r, data, sizeof(param_type));
296 return true;
297 }
[email protected]252cad62010-08-18 18:33:57298 static void Log(const param_type& p, std::string* l) {
299 l->append(StringPrintf("%e", p));
[email protected]20199662010-06-17 03:29:26300 }
301};
302
[email protected]7d5c3ac2009-02-04 08:58:19303template <>
304struct ParamTraits<double> {
305 typedef double param_type;
306 static void Write(Message* m, const param_type& p) {
307 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
308 }
309 static bool Read(const Message* m, void** iter, param_type* r) {
310 const char *data;
[email protected]20199662010-06-17 03:29:26311 int data_size;
312 if (!m->ReadData(iter, &data, &data_size) ||
313 data_size != sizeof(param_type)) {
[email protected]7d5c3ac2009-02-04 08:58:19314 NOTREACHED();
[email protected]20199662010-06-17 03:29:26315 return false;
[email protected]7d5c3ac2009-02-04 08:58:19316 }
[email protected]20199662010-06-17 03:29:26317 memcpy(r, data, sizeof(param_type));
318 return true;
[email protected]7d5c3ac2009-02-04 08:58:19319 }
[email protected]252cad62010-08-18 18:33:57320 static void Log(const param_type& p, std::string* l) {
321 l->append(StringPrintf("%e", p));
[email protected]7d5c3ac2009-02-04 08:58:19322 }
323};
324
325template <>
[email protected]7c854372011-08-15 20:41:46326struct IPC_EXPORT ParamTraits<base::Time> {
[email protected]7d5c3ac2009-02-04 08:58:19327 typedef base::Time param_type;
[email protected]7a4de7a62010-08-17 18:38:24328 static void Write(Message* m, const param_type& p);
329 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57330 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19331};
332
[email protected]d84e48b2010-10-21 22:04:52333template <>
[email protected]7c854372011-08-15 20:41:46334struct IPC_EXPORT ParamTraits<base::TimeDelta> {
[email protected]d84e48b2010-10-21 22:04:52335 typedef base::TimeDelta param_type;
336 static void Write(Message* m, const param_type& p);
337 static bool Read(const Message* m, void** iter, param_type* r);
338 static void Log(const param_type& p, std::string* l);
339};
340
[email protected]1d14f582011-09-02 20:42:04341template <>
342struct IPC_EXPORT ParamTraits<base::TimeTicks> {
343 typedef base::TimeTicks param_type;
344 static void Write(Message* m, const param_type& p);
345 static bool Read(const Message* m, void** iter, param_type* r);
346 static void Log(const param_type& p, std::string* l);
347};
348
[email protected]7d5c3ac2009-02-04 08:58:19349#if defined(OS_WIN)
350template <>
351struct ParamTraits<LOGFONT> {
352 typedef LOGFONT param_type;
353 static void Write(Message* m, const param_type& p) {
354 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
355 }
356 static bool Read(const Message* m, void** iter, param_type* r) {
357 const char *data;
358 int data_size = 0;
359 bool result = m->ReadData(iter, &data, &data_size);
360 if (result && data_size == sizeof(LOGFONT)) {
361 memcpy(r, data, sizeof(LOGFONT));
362 } else {
363 result = false;
364 NOTREACHED();
365 }
366
367 return result;
368 }
[email protected]252cad62010-08-18 18:33:57369 static void Log(const param_type& p, std::string* l) {
370 l->append(StringPrintf("<LOGFONT>"));
[email protected]7d5c3ac2009-02-04 08:58:19371 }
372};
373
374template <>
375struct ParamTraits<MSG> {
376 typedef MSG param_type;
377 static void Write(Message* m, const param_type& p) {
378 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
379 }
380 static bool Read(const Message* m, void** iter, param_type* r) {
381 const char *data;
382 int data_size = 0;
383 bool result = m->ReadData(iter, &data, &data_size);
384 if (result && data_size == sizeof(MSG)) {
385 memcpy(r, data, sizeof(MSG));
386 } else {
387 result = false;
388 NOTREACHED();
389 }
390
391 return result;
392 }
[email protected]252cad62010-08-18 18:33:57393 static void Log(const param_type& p, std::string* l) {
394 l->append("<MSG>");
[email protected]7a4de7a62010-08-17 18:38:24395 }
[email protected]7d5c3ac2009-02-04 08:58:19396};
397#endif // defined(OS_WIN)
398
399template <>
[email protected]7c854372011-08-15 20:41:46400struct IPC_EXPORT ParamTraits<base::DictionaryValue> {
[email protected]f3a1c642011-07-12 19:15:03401 typedef base::DictionaryValue param_type;
[email protected]584f2b22009-05-21 01:01:59402 static void Write(Message* m, const param_type& p);
403 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57404 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59405};
406
407template <>
[email protected]7c854372011-08-15 20:41:46408struct IPC_EXPORT ParamTraits<base::ListValue> {
[email protected]f3a1c642011-07-12 19:15:03409 typedef base::ListValue param_type;
[email protected]584f2b22009-05-21 01:01:59410 static void Write(Message* m, const param_type& p);
411 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57412 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59413};
414
415template <>
[email protected]7d5c3ac2009-02-04 08:58:19416struct ParamTraits<std::string> {
417 typedef std::string param_type;
418 static void Write(Message* m, const param_type& p) {
419 m->WriteString(p);
420 }
421 static bool Read(const Message* m, void** iter, param_type* r) {
422 return m->ReadString(iter, r);
423 }
[email protected]252cad62010-08-18 18:33:57424 static void Log(const param_type& p, std::string* l) {
425 l->append(p);
[email protected]7d5c3ac2009-02-04 08:58:19426 }
427};
428
[email protected]3dd7a7a2009-07-27 21:09:07429template<typename CharType>
[email protected]252cad62010-08-18 18:33:57430static void LogBytes(const std::vector<CharType>& data, std::string* out) {
[email protected]3dd7a7a2009-07-27 21:09:07431#if defined(OS_WIN)
432 // Windows has a GUI for logging, which can handle arbitrary binary data.
433 for (size_t i = 0; i < data.size(); ++i)
434 out->push_back(data[i]);
435#else
436 // On POSIX, we log to stdout, which we assume can display ASCII.
437 static const size_t kMaxBytesToLog = 100;
438 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
439 if (isprint(data[i]))
440 out->push_back(data[i]);
441 else
[email protected]252cad62010-08-18 18:33:57442 out->append(StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
[email protected]3dd7a7a2009-07-27 21:09:07443 }
444 if (data.size() > kMaxBytesToLog) {
445 out->append(
[email protected]252cad62010-08-18 18:33:57446 StringPrintf(" and %u more bytes",
[email protected]3dd7a7a2009-07-27 21:09:07447 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
448 }
449#endif
450}
451
[email protected]7d5c3ac2009-02-04 08:58:19452template <>
453struct ParamTraits<std::vector<unsigned char> > {
454 typedef std::vector<unsigned char> param_type;
455 static void Write(Message* m, const param_type& p) {
[email protected]f6b8ce32011-03-02 00:03:18456 if (p.empty()) {
[email protected]7d5c3ac2009-02-04 08:58:19457 m->WriteData(NULL, 0);
458 } else {
459 m->WriteData(reinterpret_cast<const char*>(&p.front()),
460 static_cast<int>(p.size()));
461 }
462 }
463 static bool Read(const Message* m, void** iter, param_type* r) {
464 const char *data;
465 int data_size = 0;
466 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
467 return false;
468 r->resize(data_size);
469 if (data_size)
470 memcpy(&r->front(), data, data_size);
471 return true;
472 }
[email protected]252cad62010-08-18 18:33:57473 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07474 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19475 }
476};
477
478template <>
479struct ParamTraits<std::vector<char> > {
480 typedef std::vector<char> param_type;
481 static void Write(Message* m, const param_type& p) {
[email protected]f6b8ce32011-03-02 00:03:18482 if (p.empty()) {
[email protected]7d5c3ac2009-02-04 08:58:19483 m->WriteData(NULL, 0);
484 } else {
485 m->WriteData(&p.front(), static_cast<int>(p.size()));
486 }
487 }
488 static bool Read(const Message* m, void** iter, param_type* r) {
489 const char *data;
490 int data_size = 0;
491 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
492 return false;
493 r->resize(data_size);
494 if (data_size)
495 memcpy(&r->front(), data, data_size);
496 return true;
497 }
[email protected]252cad62010-08-18 18:33:57498 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07499 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19500 }
501};
502
[email protected]51b63f62011-10-05 18:55:42503template <>
504struct ParamTraits<std::vector<bool> > {
505 typedef std::vector<bool> param_type;
506 static void Write(Message* m, const param_type& p) {
507 WriteParam(m, static_cast<int>(p.size()));
508 for (size_t i = 0; i < p.size(); i++)
509 WriteParam(m, p[i]);
510 }
511 static bool Read(const Message* m, void** iter, param_type* r) {
512 int size;
513 // ReadLength() checks for < 0 itself.
514 if (!m->ReadLength(iter, &size))
515 return false;
516 r->resize(size);
517 for (int i = 0; i < size; i++) {
518 bool value;
519 if (!ReadParam(m, iter, &value))
520 return false;
521 (*r)[i] = value;
522 }
523 return true;
524 }
525 static void Log(const param_type& p, std::string* l) {
526 for (size_t i = 0; i < p.size(); ++i) {
527 if (i != 0)
528 l->append(" ");
529 LogParam((p[i]), l);
530 }
531 }
532};
533
[email protected]7d5c3ac2009-02-04 08:58:19534template <class P>
535struct ParamTraits<std::vector<P> > {
536 typedef std::vector<P> param_type;
537 static void Write(Message* m, const param_type& p) {
538 WriteParam(m, static_cast<int>(p.size()));
539 for (size_t i = 0; i < p.size(); i++)
540 WriteParam(m, p[i]);
541 }
542 static bool Read(const Message* m, void** iter, param_type* r) {
543 int size;
[email protected]86440f52009-12-31 05:17:23544 // ReadLength() checks for < 0 itself.
[email protected]7d5c3ac2009-02-04 08:58:19545 if (!m->ReadLength(iter, &size))
546 return false;
547 // Resizing beforehand is not safe, see BUG 1006367 for details.
[email protected]86440f52009-12-31 05:17:23548 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
549 return false;
550 r->resize(size);
551 for (int i = 0; i < size; i++) {
552 if (!ReadParam(m, iter, &(*r)[i]))
553 return false;
[email protected]7d5c3ac2009-02-04 08:58:19554 }
555 return true;
556 }
[email protected]252cad62010-08-18 18:33:57557 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19558 for (size_t i = 0; i < p.size(); ++i) {
559 if (i != 0)
[email protected]252cad62010-08-18 18:33:57560 l->append(" ");
[email protected]7d5c3ac2009-02-04 08:58:19561 LogParam((p[i]), l);
562 }
563 }
564};
565
[email protected]96da6962010-05-13 19:10:34566template <class P>
567struct ParamTraits<std::set<P> > {
568 typedef std::set<P> param_type;
569 static void Write(Message* m, const param_type& p) {
570 WriteParam(m, static_cast<int>(p.size()));
571 typename param_type::const_iterator iter;
572 for (iter = p.begin(); iter != p.end(); ++iter)
573 WriteParam(m, *iter);
574 }
575 static bool Read(const Message* m, void** iter, param_type* r) {
576 int size;
577 if (!m->ReadLength(iter, &size))
578 return false;
579 for (int i = 0; i < size; ++i) {
580 P item;
581 if (!ReadParam(m, iter, &item))
582 return false;
583 r->insert(item);
584 }
585 return true;
586 }
[email protected]252cad62010-08-18 18:33:57587 static void Log(const param_type& p, std::string* l) {
588 l->append("<std::set>");
[email protected]96da6962010-05-13 19:10:34589 }
590};
591
592
[email protected]7d5c3ac2009-02-04 08:58:19593template <class K, class V>
594struct ParamTraits<std::map<K, V> > {
595 typedef std::map<K, V> param_type;
596 static void Write(Message* m, const param_type& p) {
597 WriteParam(m, static_cast<int>(p.size()));
598 typename param_type::const_iterator iter;
599 for (iter = p.begin(); iter != p.end(); ++iter) {
600 WriteParam(m, iter->first);
601 WriteParam(m, iter->second);
602 }
603 }
604 static bool Read(const Message* m, void** iter, param_type* r) {
605 int size;
606 if (!ReadParam(m, iter, &size) || size < 0)
607 return false;
608 for (int i = 0; i < size; ++i) {
609 K k;
610 if (!ReadParam(m, iter, &k))
611 return false;
612 V& value = (*r)[k];
613 if (!ReadParam(m, iter, &value))
614 return false;
615 }
616 return true;
617 }
[email protected]252cad62010-08-18 18:33:57618 static void Log(const param_type& p, std::string* l) {
619 l->append("<std::map>");
[email protected]7d5c3ac2009-02-04 08:58:19620 }
621};
622
[email protected]eb47a132009-03-04 00:39:56623
[email protected]7d5c3ac2009-02-04 08:58:19624template <>
625struct ParamTraits<std::wstring> {
626 typedef std::wstring param_type;
627 static void Write(Message* m, const param_type& p) {
628 m->WriteWString(p);
629 }
630 static bool Read(const Message* m, void** iter, param_type* r) {
631 return m->ReadWString(iter, r);
632 }
[email protected]7c854372011-08-15 20:41:46633 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19634};
635
[email protected]a5da6d612009-08-04 02:00:56636template <class A, class B>
637struct ParamTraits<std::pair<A, B> > {
638 typedef std::pair<A, B> param_type;
639 static void Write(Message* m, const param_type& p) {
640 WriteParam(m, p.first);
641 WriteParam(m, p.second);
642 }
643 static bool Read(const Message* m, void** iter, param_type* r) {
644 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
645 }
[email protected]252cad62010-08-18 18:33:57646 static void Log(const param_type& p, std::string* l) {
647 l->append("(");
[email protected]a5da6d612009-08-04 02:00:56648 LogParam(p.first, l);
[email protected]252cad62010-08-18 18:33:57649 l->append(", ");
[email protected]a5da6d612009-08-04 02:00:56650 LogParam(p.second, l);
[email protected]252cad62010-08-18 18:33:57651 l->append(")");
[email protected]a5da6d612009-08-04 02:00:56652 }
653};
654
[email protected]15bf8712009-08-27 00:55:02655template <>
[email protected]7c854372011-08-15 20:41:46656struct IPC_EXPORT ParamTraits<NullableString16> {
[email protected]15bf8712009-08-27 00:55:02657 typedef NullableString16 param_type;
[email protected]7a4de7a62010-08-17 18:38:24658 static void Write(Message* m, const param_type& p);
659 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57660 static void Log(const param_type& p, std::string* l);
[email protected]15bf8712009-08-27 00:55:02661};
662
[email protected]eb47a132009-03-04 00:39:56663// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
664// need this trait.
665#if !defined(WCHAR_T_IS_UTF16)
[email protected]eb47a132009-03-04 00:39:56666template <>
667struct ParamTraits<string16> {
668 typedef string16 param_type;
669 static void Write(Message* m, const param_type& p) {
[email protected]3a2a5d22009-03-04 03:36:36670 m->WriteString16(p);
[email protected]eb47a132009-03-04 00:39:56671 }
672 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]3a2a5d22009-03-04 03:36:36673 return m->ReadString16(iter, r);
[email protected]eb47a132009-03-04 00:39:56674 }
[email protected]7c854372011-08-15 20:41:46675 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]eb47a132009-03-04 00:39:56676};
[email protected]eb47a132009-03-04 00:39:56677#endif
678
[email protected]7d5c3ac2009-02-04 08:58:19679// and, a few more useful types...
680#if defined(OS_WIN)
681template <>
682struct ParamTraits<HANDLE> {
683 typedef HANDLE param_type;
684 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35685 // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
686 // bit systems.
687 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19688 }
689 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35690 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
691 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19692 }
[email protected]252cad62010-08-18 18:33:57693 static void Log(const param_type& p, std::string* l) {
694 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19695 }
696};
697
698template <>
[email protected]0a670ed2011-09-06 21:01:09699struct ParamTraits<HCURSOR> {
700 typedef HCURSOR param_type;
[email protected]7d5c3ac2009-02-04 08:58:19701 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35702 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19703 }
704 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35705 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
706 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19707 }
[email protected]252cad62010-08-18 18:33:57708 static void Log(const param_type& p, std::string* l) {
709 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19710 }
711};
712
713template <>
[email protected]7d5c3ac2009-02-04 08:58:19714struct ParamTraits<HACCEL> {
715 typedef HACCEL param_type;
716 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35717 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19718 }
719 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35720 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
721 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19722 }
723};
724
725template <>
726struct ParamTraits<POINT> {
727 typedef POINT param_type;
728 static void Write(Message* m, const param_type& p) {
729 m->WriteInt(p.x);
730 m->WriteInt(p.y);
731 }
732 static bool Read(const Message* m, void** iter, param_type* r) {
733 int x, y;
734 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
735 return false;
736 r->x = x;
737 r->y = y;
738 return true;
739 }
[email protected]252cad62010-08-18 18:33:57740 static void Log(const param_type& p, std::string* l) {
741 l->append(StringPrintf("(%d, %d)", p.x, p.y));
[email protected]7d5c3ac2009-02-04 08:58:19742 }
743};
744#endif // defined(OS_WIN)
745
746template <>
[email protected]7c854372011-08-15 20:41:46747struct IPC_EXPORT ParamTraits<FilePath> {
[email protected]7d5c3ac2009-02-04 08:58:19748 typedef FilePath param_type;
[email protected]7a4de7a62010-08-17 18:38:24749 static void Write(Message* m, const param_type& p);
750 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57751 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19752};
753
[email protected]526776c2009-02-07 00:39:26754#if defined(OS_POSIX)
[email protected]2749885f2009-03-05 21:40:11755// FileDescriptors may be serialised over IPC channels on POSIX. On the
756// receiving side, the FileDescriptor is a valid duplicate of the file
757// descriptor which was transmitted: *it is not just a copy of the integer like
758// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
759// this case, the receiving end will see a value of -1. *Zero is a valid file
760// descriptor*.
761//
762// The received file descriptor will have the |auto_close| flag set to true. The
763// code which handles the message is responsible for taking ownership of it.
764// File descriptors are OS resources and must be closed when no longer needed.
765//
766// When sending a file descriptor, the file descriptor must be valid at the time
767// of transmission. Since transmission is not synchronous, one should consider
768// dup()ing any file descriptors to be transmitted and setting the |auto_close|
769// flag, which causes the file descriptor to be closed after writing.
[email protected]526776c2009-02-07 00:39:26770template<>
[email protected]7c854372011-08-15 20:41:46771struct IPC_EXPORT ParamTraits<base::FileDescriptor> {
[email protected]5fe733de2009-02-11 18:59:20772 typedef base::FileDescriptor param_type;
[email protected]7a4de7a62010-08-17 18:38:24773 static void Write(Message* m, const param_type& p);
774 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57775 static void Log(const param_type& p, std::string* l);
[email protected]526776c2009-02-07 00:39:26776};
[email protected]379e7a52010-03-09 00:38:41777#endif // defined(OS_POSIX)
[email protected]526776c2009-02-07 00:39:26778
[email protected]d2e884d2009-06-22 20:37:52779// A ChannelHandle is basically a platform-inspecific wrapper around the
780// fact that IPC endpoints are handled specially on POSIX. See above comments
781// on FileDescriptor for more background.
782template<>
[email protected]7c854372011-08-15 20:41:46783struct IPC_EXPORT ParamTraits<IPC::ChannelHandle> {
[email protected]d2e884d2009-06-22 20:37:52784 typedef ChannelHandle param_type;
[email protected]7a4de7a62010-08-17 18:38:24785 static void Write(Message* m, const param_type& p);
786 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57787 static void Log(const param_type& p, std::string* l);
[email protected]d2e884d2009-06-22 20:37:52788};
789
[email protected]7d5c3ac2009-02-04 08:58:19790#if defined(OS_WIN)
791template <>
792struct ParamTraits<XFORM> {
793 typedef XFORM param_type;
794 static void Write(Message* m, const param_type& p) {
795 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
796 }
797 static bool Read(const Message* m, void** iter, param_type* r) {
798 const char *data;
799 int data_size = 0;
800 bool result = m->ReadData(iter, &data, &data_size);
801 if (result && data_size == sizeof(XFORM)) {
802 memcpy(r, data, sizeof(XFORM));
803 } else {
804 result = false;
805 NOTREACHED();
806 }
807
808 return result;
809 }
[email protected]252cad62010-08-18 18:33:57810 static void Log(const param_type& p, std::string* l) {
811 l->append("<XFORM>");
[email protected]7d5c3ac2009-02-04 08:58:19812 }
813};
814#endif // defined(OS_WIN)
815
[email protected]7c854372011-08-15 20:41:46816struct IPC_EXPORT LogData {
[email protected]20f0487a2010-09-30 20:06:30817 LogData();
818 ~LogData();
819
[email protected]9a3a293b2009-06-04 22:28:16820 std::string channel;
[email protected]8bef70e2009-04-14 19:11:24821 int32 routing_id;
[email protected]168ae922009-12-04 18:08:45822 uint32 type; // "User-defined" message type, from ipc_message.h.
[email protected]252cad62010-08-18 18:33:57823 std::string flags;
[email protected]7d5c3ac2009-02-04 08:58:19824 int64 sent; // Time that the message was sent (i.e. at Send()).
825 int64 receive; // Time before it was dispatched (i.e. before calling
826 // OnMessageReceived).
827 int64 dispatch; // Time after it was dispatched (i.e. after calling
828 // OnMessageReceived).
[email protected]252cad62010-08-18 18:33:57829 std::string message_name;
830 std::string params;
[email protected]7d5c3ac2009-02-04 08:58:19831};
832
833template <>
[email protected]7c854372011-08-15 20:41:46834struct IPC_EXPORT ParamTraits<LogData> {
[email protected]7d5c3ac2009-02-04 08:58:19835 typedef LogData param_type;
[email protected]20f0487a2010-09-30 20:06:30836 static void Write(Message* m, const param_type& p);
837 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57838 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19839 // Doesn't make sense to implement this!
840 }
841};
842
[email protected]eb47a132009-03-04 00:39:56843template <>
[email protected]503683f2009-02-26 09:13:01844struct ParamTraits<Message> {
845 static void Write(Message* m, const Message& p) {
[email protected]8a861402011-01-28 19:59:11846 DCHECK(p.size() <= INT_MAX);
847 int message_size = static_cast<int>(p.size());
848 m->WriteInt(message_size);
849 m->WriteData(reinterpret_cast<const char*>(p.data()), message_size);
[email protected]503683f2009-02-26 09:13:01850 }
851 static bool Read(const Message* m, void** iter, Message* r) {
852 int size;
853 if (!m->ReadInt(iter, &size))
854 return false;
855 const char* data;
856 if (!m->ReadData(iter, &data, &size))
857 return false;
858 *r = Message(data, size);
859 return true;
860 }
[email protected]252cad62010-08-18 18:33:57861 static void Log(const Message& p, std::string* l) {
862 l->append("<IPC::Message>");
[email protected]503683f2009-02-26 09:13:01863 }
864};
865
866template <>
[email protected]7d5c3ac2009-02-04 08:58:19867struct ParamTraits<Tuple0> {
868 typedef Tuple0 param_type;
869 static void Write(Message* m, const param_type& p) {
870 }
871 static bool Read(const Message* m, void** iter, param_type* r) {
872 return true;
873 }
[email protected]252cad62010-08-18 18:33:57874 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19875 }
876};
877
878template <class A>
879struct ParamTraits< Tuple1<A> > {
880 typedef Tuple1<A> param_type;
881 static void Write(Message* m, const param_type& p) {
882 WriteParam(m, p.a);
883 }
884 static bool Read(const Message* m, void** iter, param_type* r) {
885 return ReadParam(m, iter, &r->a);
886 }
[email protected]252cad62010-08-18 18:33:57887 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19888 LogParam(p.a, l);
889 }
890};
891
892template <class A, class B>
893struct ParamTraits< Tuple2<A, B> > {
894 typedef Tuple2<A, B> param_type;
895 static void Write(Message* m, const param_type& p) {
896 WriteParam(m, p.a);
897 WriteParam(m, p.b);
898 }
899 static bool Read(const Message* m, void** iter, param_type* r) {
900 return (ReadParam(m, iter, &r->a) &&
901 ReadParam(m, iter, &r->b));
902 }
[email protected]252cad62010-08-18 18:33:57903 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19904 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57905 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19906 LogParam(p.b, l);
907 }
908};
909
910template <class A, class B, class C>
911struct ParamTraits< Tuple3<A, B, C> > {
912 typedef Tuple3<A, B, C> param_type;
913 static void Write(Message* m, const param_type& p) {
914 WriteParam(m, p.a);
915 WriteParam(m, p.b);
916 WriteParam(m, p.c);
917 }
918 static bool Read(const Message* m, void** iter, param_type* r) {
919 return (ReadParam(m, iter, &r->a) &&
920 ReadParam(m, iter, &r->b) &&
921 ReadParam(m, iter, &r->c));
922 }
[email protected]252cad62010-08-18 18:33:57923 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19924 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57925 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19926 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57927 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19928 LogParam(p.c, l);
929 }
930};
931
932template <class A, class B, class C, class D>
933struct ParamTraits< Tuple4<A, B, C, D> > {
934 typedef Tuple4<A, B, C, D> param_type;
935 static void Write(Message* m, const param_type& p) {
936 WriteParam(m, p.a);
937 WriteParam(m, p.b);
938 WriteParam(m, p.c);
939 WriteParam(m, p.d);
940 }
941 static bool Read(const Message* m, void** iter, param_type* r) {
942 return (ReadParam(m, iter, &r->a) &&
943 ReadParam(m, iter, &r->b) &&
944 ReadParam(m, iter, &r->c) &&
945 ReadParam(m, iter, &r->d));
946 }
[email protected]252cad62010-08-18 18:33:57947 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19948 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57949 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19950 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57951 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19952 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57953 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19954 LogParam(p.d, l);
955 }
956};
957
958template <class A, class B, class C, class D, class E>
959struct ParamTraits< Tuple5<A, B, C, D, E> > {
960 typedef Tuple5<A, B, C, D, E> 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 WriteParam(m, p.e);
967 }
968 static bool Read(const Message* m, void** iter, param_type* r) {
969 return (ReadParam(m, iter, &r->a) &&
970 ReadParam(m, iter, &r->b) &&
971 ReadParam(m, iter, &r->c) &&
972 ReadParam(m, iter, &r->d) &&
973 ReadParam(m, iter, &r->e));
974 }
[email protected]252cad62010-08-18 18:33:57975 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19976 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57977 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19978 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57979 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19980 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57981 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19982 LogParam(p.d, l);
[email protected]252cad62010-08-18 18:33:57983 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19984 LogParam(p.e, l);
985 }
986};
987
[email protected]7d5c3ac2009-02-04 08:58:19988//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:29989// Generic message subclasses
990
991// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:24992template <class ParamType>
[email protected]1d4ecf42011-08-26 21:27:30993class MessageSchema {
initial.commit09911bf2008-07-26 23:55:29994 public:
[email protected]81a34412009-01-05 19:17:24995 typedef ParamType Param;
[email protected]7a4de7a62010-08-17 18:38:24996 typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
[email protected]81a34412009-01-05 19:17:24997
[email protected]1d4ecf42011-08-26 21:27:30998 static void Write(Message* msg, const RefParam& p) IPC_MSG_NOINLINE;
[email protected]7a4de7a62010-08-17 18:38:24999 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:291000};
1001
[email protected]7a4de7a62010-08-17 18:38:241002// defined in ipc_logging.cc
[email protected]7c854372011-08-15 20:41:461003IPC_EXPORT void GenerateLogData(const std::string& channel,
1004 const Message& message,
[email protected]ea7744a2011-10-20 19:34:431005 LogData* data, bool get_params);
[email protected]7a4de7a62010-08-17 18:38:241006
1007
1008#if defined(IPC_MESSAGE_LOG_ENABLED)
[email protected]252cad62010-08-18 18:33:571009inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
1010 const std::string& output_params = msg->output_params();
[email protected]7a4de7a62010-08-17 18:38:241011 if (!l->empty() && !output_params.empty())
[email protected]252cad62010-08-18 18:33:571012 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:241013
1014 l->append(output_params);
1015}
1016
1017template <class ReplyParamType>
1018inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1019 const Message* msg) {
1020 if (msg->received_time() != 0) {
[email protected]252cad62010-08-18 18:33:571021 std::string output_params;
[email protected]7a4de7a62010-08-17 18:38:241022 LogParam(reply_params, &output_params);
1023 msg->set_output_params(output_params);
1024 }
1025}
1026
1027inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
1028 if (msg->sent_time()) {
1029 // Don't log the sync message after dispatch, as we don't have the
1030 // output parameters at that point. Instead, save its data and log it
1031 // with the outgoing reply message when it's sent.
1032 LogData* data = new LogData;
[email protected]ea7744a2011-10-20 19:34:431033 GenerateLogData("", *msg, data, true);
[email protected]7a4de7a62010-08-17 18:38:241034 msg->set_dont_log();
1035 reply->set_sync_log_data(data);
1036 }
1037}
1038#else
[email protected]252cad62010-08-18 18:33:571039inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
[email protected]7a4de7a62010-08-17 18:38:241040
1041template <class ReplyParamType>
1042inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1043 const Message* msg) {}
1044
1045inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1046#endif
1047
initial.commit09911bf2008-07-26 23:55:291048// This class assumes that its template argument is a RefTuple (a Tuple with
[email protected]7a4de7a62010-08-17 18:38:241049// reference elements). This would go into ipc_message_utils_impl.h, but it is
1050// also used by chrome_frame.
initial.commit09911bf2008-07-26 23:55:291051template <class RefTuple>
1052class ParamDeserializer : public MessageReplyDeserializer {
1053 public:
[email protected]e1981f432008-08-12 15:22:131054 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:291055
1056 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1057 return ReadParam(&msg, &iter, &out_);
1058 }
1059
1060 RefTuple out_;
1061};
1062
initial.commit09911bf2008-07-26 23:55:291063// Used for synchronous messages.
[email protected]75e5a872009-04-02 23:56:111064template <class SendParamType, class ReplyParamType>
[email protected]1d4ecf42011-08-26 21:27:301065class SyncMessageSchema {
initial.commit09911bf2008-07-26 23:55:291066 public:
[email protected]75e5a872009-04-02 23:56:111067 typedef SendParamType SendParam;
[email protected]7a4de7a62010-08-17 18:38:241068 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
[email protected]75e5a872009-04-02 23:56:111069 typedef ReplyParamType ReplyParam;
1070
[email protected]1d4ecf42011-08-26 21:27:301071 static void Write(Message* msg, const RefSendParam& send) IPC_MSG_NOINLINE;
[email protected]7a4de7a62010-08-17 18:38:241072 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
1073 static bool ReadReplyParam(
1074 const Message* msg,
1075 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:291076
[email protected]65412272010-12-21 20:03:241077 template<class T, class S, class Method>
[email protected]1d4ecf42011-08-26 21:27:301078 static bool DispatchWithSendParams(bool ok, const SendParam& send_params,
1079 const Message* msg, T* obj, S* sender,
1080 Method func) {
1081 Message* reply = SyncMessage::GenerateReply(msg);
1082 if (ok) {
[email protected]7a4de7a62010-08-17 18:38:241083 typename TupleTypes<ReplyParam>::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:291084 DispatchToMethod(obj, func, send_params, &reply_params);
1085 WriteParam(reply, reply_params);
[email protected]7a4de7a62010-08-17 18:38:241086 LogReplyParamsToMessage(reply_params, msg);
initial.commit09911bf2008-07-26 23:55:291087 } else {
1088 NOTREACHED() << "Error deserializing message " << msg->type();
1089 reply->set_reply_error();
initial.commit09911bf2008-07-26 23:55:291090 }
[email protected]65412272010-12-21 20:03:241091 sender->Send(reply);
[email protected]1d4ecf42011-08-26 21:27:301092 return ok;
initial.commit09911bf2008-07-26 23:55:291093 }
1094
1095 template<class T, class Method>
[email protected]1d4ecf42011-08-26 21:27:301096 static bool DispatchDelayReplyWithSendParams(bool ok,
1097 const SendParam& send_params,
1098 const Message* msg, T* obj,
1099 Method func) {
1100 Message* reply = SyncMessage::GenerateReply(msg);
1101 if (ok) {
initial.commit09911bf2008-07-26 23:55:291102 Tuple1<Message&> t = MakeRefTuple(*reply);
[email protected]7a4de7a62010-08-17 18:38:241103 ConnectMessageAndReply(msg, reply);
initial.commit09911bf2008-07-26 23:55:291104 DispatchToMethod(obj, func, send_params, &t);
initial.commit09911bf2008-07-26 23:55:291105 } else {
1106 NOTREACHED() << "Error deserializing message " << msg->type();
1107 reply->set_reply_error();
1108 obj->Send(reply);
initial.commit09911bf2008-07-26 23:55:291109 }
[email protected]1d4ecf42011-08-26 21:27:301110 return ok;
initial.commit09911bf2008-07-26 23:55:291111 }
1112
1113 template<typename TA>
1114 static void WriteReplyParams(Message* reply, TA a) {
1115 ReplyParam p(a);
1116 WriteParam(reply, p);
1117 }
1118
1119 template<typename TA, typename TB>
1120 static void WriteReplyParams(Message* reply, TA a, TB b) {
1121 ReplyParam p(a, b);
1122 WriteParam(reply, p);
1123 }
1124
1125 template<typename TA, typename TB, typename TC>
1126 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1127 ReplyParam p(a, b, c);
1128 WriteParam(reply, p);
1129 }
1130
1131 template<typename TA, typename TB, typename TC, typename TD>
1132 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1133 ReplyParam p(a, b, c, d);
1134 WriteParam(reply, p);
1135 }
1136
1137 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1138 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1139 ReplyParam p(a, b, c, d, e);
1140 WriteParam(reply, p);
1141 }
1142};
1143
[email protected]7d5c3ac2009-02-04 08:58:191144//-----------------------------------------------------------------------------
1145
[email protected]3178f4e22008-08-05 21:20:411146} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291147
[email protected]946d1b22009-07-22 23:57:211148#endif // IPC_IPC_MESSAGE_UTILS_H_