blob: e7bbe344624295b22ae0481b13e31013f32ac1f5 [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]e503a122011-03-17 18:20:5297 LastIPCMsgStart // Must come last.
[email protected]f91cb992009-02-04 20:10:1298};
99
[email protected]7a4de7a62010-08-17 18:38:24100class FilePath;
[email protected]7a4de7a62010-08-17 18:38:24101class NullableString16;
102
103namespace base {
[email protected]f3a1c642011-07-12 19:15:03104class DictionaryValue;
105class ListValue;
[email protected]7a4de7a62010-08-17 18:38:24106class Time;
[email protected]d84e48b2010-10-21 22:04:52107class TimeDelta;
[email protected]7a4de7a62010-08-17 18:38:24108struct FileDescriptor;
109}
110
initial.commit09911bf2008-07-26 23:55:29111namespace IPC {
112
[email protected]7a4de7a62010-08-17 18:38:24113struct ChannelHandle;
114
initial.commit09911bf2008-07-26 23:55:29115//-----------------------------------------------------------------------------
116// An iterator class for reading the fields contained within a Message.
117
118class MessageIterator {
119 public:
[email protected]e1981f432008-08-12 15:22:13120 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
initial.commit09911bf2008-07-26 23:55:29121 }
122 int NextInt() const {
[email protected]9422b7dc2009-12-30 20:09:02123 int val = -1;
initial.commit09911bf2008-07-26 23:55:29124 if (!msg_.ReadInt(&iter_, &val))
125 NOTREACHED();
126 return val;
127 }
initial.commit09911bf2008-07-26 23:55:29128 const std::string NextString() const {
129 std::string val;
130 if (!msg_.ReadString(&iter_, &val))
131 NOTREACHED();
132 return val;
133 }
134 const std::wstring NextWString() const {
135 std::wstring val;
136 if (!msg_.ReadWString(&iter_, &val))
137 NOTREACHED();
138 return val;
139 }
[email protected]225c8f52010-02-05 22:23:20140 void NextData(const char** data, int* length) const {
initial.commit09911bf2008-07-26 23:55:29141 if (!msg_.ReadData(&iter_, data, length)) {
142 NOTREACHED();
143 }
144 }
145 private:
146 const Message& msg_;
147 mutable void* iter_;
148};
149
150//-----------------------------------------------------------------------------
[email protected]6476c72c2011-02-11 18:46:19151// A dummy struct to place first just to allow leading commas for all
152// members in the macro-generated constructor initializer lists.
153struct NoParams {
154};
155
156//-----------------------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19157// ParamTraits specializations, etc.
158
[email protected]7d5c3ac2009-02-04 08:58:19159template <class P>
160static inline void WriteParam(Message* m, const P& p) {
[email protected]7b291f92009-08-14 05:43:53161 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53162 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
[email protected]7d5c3ac2009-02-04 08:58:19163}
164
165template <class P>
[email protected]1e86aa62009-04-24 21:22:33166static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
167 P* p) {
[email protected]7b291f92009-08-14 05:43:53168 typedef typename SimilarTypeTraits<P>::Type Type;
169 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
[email protected]7d5c3ac2009-02-04 08:58:19170}
171
172template <class P>
[email protected]252cad62010-08-18 18:33:57173static inline void LogParam(const P& p, std::string* l) {
[email protected]7b291f92009-08-14 05:43:53174 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53175 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19176}
177
178template <>
179struct ParamTraits<bool> {
180 typedef bool param_type;
181 static void Write(Message* m, const param_type& p) {
182 m->WriteBool(p);
183 }
184 static bool Read(const Message* m, void** iter, param_type* r) {
185 return m->ReadBool(iter, r);
186 }
[email protected]252cad62010-08-18 18:33:57187 static void Log(const param_type& p, std::string* l) {
188 l->append(p ? "true" : "false");
[email protected]7d5c3ac2009-02-04 08:58:19189 }
190};
191
192template <>
193struct ParamTraits<int> {
194 typedef int param_type;
195 static void Write(Message* m, const param_type& p) {
196 m->WriteInt(p);
197 }
198 static bool Read(const Message* m, void** iter, param_type* r) {
199 return m->ReadInt(iter, r);
200 }
[email protected]7c854372011-08-15 20:41:46201 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19202};
203
204template <>
[email protected]63263f92009-07-28 19:35:08205struct ParamTraits<unsigned int> {
206 typedef unsigned int param_type;
207 static void Write(Message* m, const param_type& p) {
208 m->WriteInt(p);
209 }
210 static bool Read(const Message* m, void** iter, param_type* r) {
211 return m->ReadInt(iter, reinterpret_cast<int*>(r));
212 }
[email protected]7c854372011-08-15 20:41:46213 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08214};
215
216template <>
[email protected]7d5c3ac2009-02-04 08:58:19217struct ParamTraits<long> {
218 typedef long param_type;
219 static void Write(Message* m, const param_type& p) {
220 m->WriteLong(p);
221 }
222 static bool Read(const Message* m, void** iter, param_type* r) {
223 return m->ReadLong(iter, r);
224 }
[email protected]7c854372011-08-15 20:41:46225 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19226};
227
[email protected]140c3032009-06-26 18:22:54228template <>
229struct ParamTraits<unsigned long> {
230 typedef unsigned long param_type;
231 static void Write(Message* m, const param_type& p) {
232 m->WriteLong(p);
233 }
234 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]63263f92009-07-28 19:35:08235 return m->ReadLong(iter, reinterpret_cast<long*>(r));
[email protected]140c3032009-06-26 18:22:54236 }
[email protected]7c854372011-08-15 20:41:46237 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19238};
239
240template <>
[email protected]63263f92009-07-28 19:35:08241struct ParamTraits<long long> {
242 typedef long long param_type;
[email protected]7d5c3ac2009-02-04 08:58:19243 static void Write(Message* m, const param_type& p) {
244 m->WriteInt64(static_cast<int64>(p));
245 }
246 static bool Read(const Message* m, void** iter, param_type* r) {
247 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
248 }
[email protected]7c854372011-08-15 20:41:46249 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08250};
251
252template <>
253struct ParamTraits<unsigned long long> {
254 typedef unsigned long long param_type;
255 static void Write(Message* m, const param_type& p) {
256 m->WriteInt64(p);
257 }
258 static bool Read(const Message* m, void** iter, param_type* r) {
259 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
260 }
[email protected]7c854372011-08-15 20:41:46261 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19262};
263
[email protected]43a40202010-11-12 16:25:01264template <>
[email protected]7c854372011-08-15 20:41:46265struct IPC_EXPORT ParamTraits<unsigned short> {
[email protected]43a40202010-11-12 16:25:01266 typedef unsigned short param_type;
267 static void Write(Message* m, const param_type& p);
268 static bool Read(const Message* m, void** iter, param_type* r);
269 static void Log(const param_type& p, std::string* l);
270};
271
[email protected]20199662010-06-17 03:29:26272// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
273// should be sure to check the sanity of these values after receiving them over
274// IPC.
275template <>
276struct ParamTraits<float> {
277 typedef float param_type;
278 static void Write(Message* m, const param_type& p) {
279 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
280 }
281 static bool Read(const Message* m, void** iter, param_type* r) {
282 const char *data;
283 int data_size;
284 if (!m->ReadData(iter, &data, &data_size) ||
285 data_size != sizeof(param_type)) {
286 NOTREACHED();
287 return false;
288 }
289 memcpy(r, data, sizeof(param_type));
290 return true;
291 }
[email protected]252cad62010-08-18 18:33:57292 static void Log(const param_type& p, std::string* l) {
293 l->append(StringPrintf("%e", p));
[email protected]20199662010-06-17 03:29:26294 }
295};
296
[email protected]7d5c3ac2009-02-04 08:58:19297template <>
298struct ParamTraits<double> {
299 typedef double param_type;
300 static void Write(Message* m, const param_type& p) {
301 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
302 }
303 static bool Read(const Message* m, void** iter, param_type* r) {
304 const char *data;
[email protected]20199662010-06-17 03:29:26305 int data_size;
306 if (!m->ReadData(iter, &data, &data_size) ||
307 data_size != sizeof(param_type)) {
[email protected]7d5c3ac2009-02-04 08:58:19308 NOTREACHED();
[email protected]20199662010-06-17 03:29:26309 return false;
[email protected]7d5c3ac2009-02-04 08:58:19310 }
[email protected]20199662010-06-17 03:29:26311 memcpy(r, data, sizeof(param_type));
312 return true;
[email protected]7d5c3ac2009-02-04 08:58:19313 }
[email protected]252cad62010-08-18 18:33:57314 static void Log(const param_type& p, std::string* l) {
315 l->append(StringPrintf("%e", p));
[email protected]7d5c3ac2009-02-04 08:58:19316 }
317};
318
319template <>
[email protected]7c854372011-08-15 20:41:46320struct IPC_EXPORT ParamTraits<base::Time> {
[email protected]7d5c3ac2009-02-04 08:58:19321 typedef base::Time param_type;
[email protected]7a4de7a62010-08-17 18:38:24322 static void Write(Message* m, const param_type& p);
323 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57324 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19325};
326
[email protected]d84e48b2010-10-21 22:04:52327template <>
[email protected]7c854372011-08-15 20:41:46328struct IPC_EXPORT ParamTraits<base::TimeDelta> {
[email protected]d84e48b2010-10-21 22:04:52329 typedef base::TimeDelta param_type;
330 static void Write(Message* m, const param_type& p);
331 static bool Read(const Message* m, void** iter, param_type* r);
332 static void Log(const param_type& p, std::string* l);
333};
334
[email protected]7d5c3ac2009-02-04 08:58:19335#if defined(OS_WIN)
336template <>
337struct ParamTraits<LOGFONT> {
338 typedef LOGFONT param_type;
339 static void Write(Message* m, const param_type& p) {
340 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
341 }
342 static bool Read(const Message* m, void** iter, param_type* r) {
343 const char *data;
344 int data_size = 0;
345 bool result = m->ReadData(iter, &data, &data_size);
346 if (result && data_size == sizeof(LOGFONT)) {
347 memcpy(r, data, sizeof(LOGFONT));
348 } else {
349 result = false;
350 NOTREACHED();
351 }
352
353 return result;
354 }
[email protected]252cad62010-08-18 18:33:57355 static void Log(const param_type& p, std::string* l) {
356 l->append(StringPrintf("<LOGFONT>"));
[email protected]7d5c3ac2009-02-04 08:58:19357 }
358};
359
360template <>
361struct ParamTraits<MSG> {
362 typedef MSG param_type;
363 static void Write(Message* m, const param_type& p) {
364 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
365 }
366 static bool Read(const Message* m, void** iter, param_type* r) {
367 const char *data;
368 int data_size = 0;
369 bool result = m->ReadData(iter, &data, &data_size);
370 if (result && data_size == sizeof(MSG)) {
371 memcpy(r, data, sizeof(MSG));
372 } else {
373 result = false;
374 NOTREACHED();
375 }
376
377 return result;
378 }
[email protected]252cad62010-08-18 18:33:57379 static void Log(const param_type& p, std::string* l) {
380 l->append("<MSG>");
[email protected]7a4de7a62010-08-17 18:38:24381 }
[email protected]7d5c3ac2009-02-04 08:58:19382};
383#endif // defined(OS_WIN)
384
385template <>
[email protected]7c854372011-08-15 20:41:46386struct IPC_EXPORT ParamTraits<base::DictionaryValue> {
[email protected]f3a1c642011-07-12 19:15:03387 typedef base::DictionaryValue param_type;
[email protected]584f2b22009-05-21 01:01:59388 static void Write(Message* m, const param_type& p);
389 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57390 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59391};
392
393template <>
[email protected]7c854372011-08-15 20:41:46394struct IPC_EXPORT ParamTraits<base::ListValue> {
[email protected]f3a1c642011-07-12 19:15:03395 typedef base::ListValue param_type;
[email protected]584f2b22009-05-21 01:01:59396 static void Write(Message* m, const param_type& p);
397 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57398 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59399};
400
401template <>
[email protected]7d5c3ac2009-02-04 08:58:19402struct ParamTraits<std::string> {
403 typedef std::string param_type;
404 static void Write(Message* m, const param_type& p) {
405 m->WriteString(p);
406 }
407 static bool Read(const Message* m, void** iter, param_type* r) {
408 return m->ReadString(iter, r);
409 }
[email protected]252cad62010-08-18 18:33:57410 static void Log(const param_type& p, std::string* l) {
411 l->append(p);
[email protected]7d5c3ac2009-02-04 08:58:19412 }
413};
414
[email protected]3dd7a7a2009-07-27 21:09:07415template<typename CharType>
[email protected]252cad62010-08-18 18:33:57416static void LogBytes(const std::vector<CharType>& data, std::string* out) {
[email protected]3dd7a7a2009-07-27 21:09:07417#if defined(OS_WIN)
418 // Windows has a GUI for logging, which can handle arbitrary binary data.
419 for (size_t i = 0; i < data.size(); ++i)
420 out->push_back(data[i]);
421#else
422 // On POSIX, we log to stdout, which we assume can display ASCII.
423 static const size_t kMaxBytesToLog = 100;
424 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
425 if (isprint(data[i]))
426 out->push_back(data[i]);
427 else
[email protected]252cad62010-08-18 18:33:57428 out->append(StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
[email protected]3dd7a7a2009-07-27 21:09:07429 }
430 if (data.size() > kMaxBytesToLog) {
431 out->append(
[email protected]252cad62010-08-18 18:33:57432 StringPrintf(" and %u more bytes",
[email protected]3dd7a7a2009-07-27 21:09:07433 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
434 }
435#endif
436}
437
[email protected]7d5c3ac2009-02-04 08:58:19438template <>
439struct ParamTraits<std::vector<unsigned char> > {
440 typedef std::vector<unsigned char> param_type;
441 static void Write(Message* m, const param_type& p) {
[email protected]f6b8ce32011-03-02 00:03:18442 if (p.empty()) {
[email protected]7d5c3ac2009-02-04 08:58:19443 m->WriteData(NULL, 0);
444 } else {
445 m->WriteData(reinterpret_cast<const char*>(&p.front()),
446 static_cast<int>(p.size()));
447 }
448 }
449 static bool Read(const Message* m, void** iter, param_type* r) {
450 const char *data;
451 int data_size = 0;
452 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
453 return false;
454 r->resize(data_size);
455 if (data_size)
456 memcpy(&r->front(), data, data_size);
457 return true;
458 }
[email protected]252cad62010-08-18 18:33:57459 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07460 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19461 }
462};
463
464template <>
465struct ParamTraits<std::vector<char> > {
466 typedef std::vector<char> param_type;
467 static void Write(Message* m, const param_type& p) {
[email protected]f6b8ce32011-03-02 00:03:18468 if (p.empty()) {
[email protected]7d5c3ac2009-02-04 08:58:19469 m->WriteData(NULL, 0);
470 } else {
471 m->WriteData(&p.front(), static_cast<int>(p.size()));
472 }
473 }
474 static bool Read(const Message* m, void** iter, param_type* r) {
475 const char *data;
476 int data_size = 0;
477 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
478 return false;
479 r->resize(data_size);
480 if (data_size)
481 memcpy(&r->front(), data, data_size);
482 return true;
483 }
[email protected]252cad62010-08-18 18:33:57484 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07485 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19486 }
487};
488
489template <class P>
490struct ParamTraits<std::vector<P> > {
491 typedef std::vector<P> param_type;
492 static void Write(Message* m, const param_type& p) {
493 WriteParam(m, static_cast<int>(p.size()));
494 for (size_t i = 0; i < p.size(); i++)
495 WriteParam(m, p[i]);
496 }
497 static bool Read(const Message* m, void** iter, param_type* r) {
498 int size;
[email protected]86440f52009-12-31 05:17:23499 // ReadLength() checks for < 0 itself.
[email protected]7d5c3ac2009-02-04 08:58:19500 if (!m->ReadLength(iter, &size))
501 return false;
502 // Resizing beforehand is not safe, see BUG 1006367 for details.
[email protected]86440f52009-12-31 05:17:23503 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
504 return false;
505 r->resize(size);
506 for (int i = 0; i < size; i++) {
507 if (!ReadParam(m, iter, &(*r)[i]))
508 return false;
[email protected]7d5c3ac2009-02-04 08:58:19509 }
510 return true;
511 }
[email protected]252cad62010-08-18 18:33:57512 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19513 for (size_t i = 0; i < p.size(); ++i) {
514 if (i != 0)
[email protected]252cad62010-08-18 18:33:57515 l->append(" ");
[email protected]7d5c3ac2009-02-04 08:58:19516 LogParam((p[i]), l);
517 }
518 }
519};
520
[email protected]96da6962010-05-13 19:10:34521template <class P>
522struct ParamTraits<std::set<P> > {
523 typedef std::set<P> param_type;
524 static void Write(Message* m, const param_type& p) {
525 WriteParam(m, static_cast<int>(p.size()));
526 typename param_type::const_iterator iter;
527 for (iter = p.begin(); iter != p.end(); ++iter)
528 WriteParam(m, *iter);
529 }
530 static bool Read(const Message* m, void** iter, param_type* r) {
531 int size;
532 if (!m->ReadLength(iter, &size))
533 return false;
534 for (int i = 0; i < size; ++i) {
535 P item;
536 if (!ReadParam(m, iter, &item))
537 return false;
538 r->insert(item);
539 }
540 return true;
541 }
[email protected]252cad62010-08-18 18:33:57542 static void Log(const param_type& p, std::string* l) {
543 l->append("<std::set>");
[email protected]96da6962010-05-13 19:10:34544 }
545};
546
547
[email protected]7d5c3ac2009-02-04 08:58:19548template <class K, class V>
549struct ParamTraits<std::map<K, V> > {
550 typedef std::map<K, V> param_type;
551 static void Write(Message* m, const param_type& p) {
552 WriteParam(m, static_cast<int>(p.size()));
553 typename param_type::const_iterator iter;
554 for (iter = p.begin(); iter != p.end(); ++iter) {
555 WriteParam(m, iter->first);
556 WriteParam(m, iter->second);
557 }
558 }
559 static bool Read(const Message* m, void** iter, param_type* r) {
560 int size;
561 if (!ReadParam(m, iter, &size) || size < 0)
562 return false;
563 for (int i = 0; i < size; ++i) {
564 K k;
565 if (!ReadParam(m, iter, &k))
566 return false;
567 V& value = (*r)[k];
568 if (!ReadParam(m, iter, &value))
569 return false;
570 }
571 return true;
572 }
[email protected]252cad62010-08-18 18:33:57573 static void Log(const param_type& p, std::string* l) {
574 l->append("<std::map>");
[email protected]7d5c3ac2009-02-04 08:58:19575 }
576};
577
[email protected]eb47a132009-03-04 00:39:56578
[email protected]7d5c3ac2009-02-04 08:58:19579template <>
580struct ParamTraits<std::wstring> {
581 typedef std::wstring param_type;
582 static void Write(Message* m, const param_type& p) {
583 m->WriteWString(p);
584 }
585 static bool Read(const Message* m, void** iter, param_type* r) {
586 return m->ReadWString(iter, r);
587 }
[email protected]7c854372011-08-15 20:41:46588 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19589};
590
[email protected]a5da6d612009-08-04 02:00:56591template <class A, class B>
592struct ParamTraits<std::pair<A, B> > {
593 typedef std::pair<A, B> param_type;
594 static void Write(Message* m, const param_type& p) {
595 WriteParam(m, p.first);
596 WriteParam(m, p.second);
597 }
598 static bool Read(const Message* m, void** iter, param_type* r) {
599 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
600 }
[email protected]252cad62010-08-18 18:33:57601 static void Log(const param_type& p, std::string* l) {
602 l->append("(");
[email protected]a5da6d612009-08-04 02:00:56603 LogParam(p.first, l);
[email protected]252cad62010-08-18 18:33:57604 l->append(", ");
[email protected]a5da6d612009-08-04 02:00:56605 LogParam(p.second, l);
[email protected]252cad62010-08-18 18:33:57606 l->append(")");
[email protected]a5da6d612009-08-04 02:00:56607 }
608};
609
[email protected]15bf8712009-08-27 00:55:02610template <>
[email protected]7c854372011-08-15 20:41:46611struct IPC_EXPORT ParamTraits<NullableString16> {
[email protected]15bf8712009-08-27 00:55:02612 typedef NullableString16 param_type;
[email protected]7a4de7a62010-08-17 18:38:24613 static void Write(Message* m, const param_type& p);
614 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57615 static void Log(const param_type& p, std::string* l);
[email protected]15bf8712009-08-27 00:55:02616};
617
[email protected]eb47a132009-03-04 00:39:56618// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
619// need this trait.
620#if !defined(WCHAR_T_IS_UTF16)
[email protected]eb47a132009-03-04 00:39:56621template <>
622struct ParamTraits<string16> {
623 typedef string16 param_type;
624 static void Write(Message* m, const param_type& p) {
[email protected]3a2a5d22009-03-04 03:36:36625 m->WriteString16(p);
[email protected]eb47a132009-03-04 00:39:56626 }
627 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]3a2a5d22009-03-04 03:36:36628 return m->ReadString16(iter, r);
[email protected]eb47a132009-03-04 00:39:56629 }
[email protected]7c854372011-08-15 20:41:46630 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]eb47a132009-03-04 00:39:56631};
[email protected]eb47a132009-03-04 00:39:56632#endif
633
[email protected]7d5c3ac2009-02-04 08:58:19634// and, a few more useful types...
635#if defined(OS_WIN)
636template <>
637struct ParamTraits<HANDLE> {
638 typedef HANDLE param_type;
639 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35640 // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
641 // bit systems.
642 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19643 }
644 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35645 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
646 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19647 }
[email protected]252cad62010-08-18 18:33:57648 static void Log(const param_type& p, std::string* l) {
649 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19650 }
651};
652
653template <>
654struct ParamTraits<HCURSOR> {
655 typedef HCURSOR param_type;
656 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35657 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19658 }
659 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35660 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
661 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19662 }
[email protected]252cad62010-08-18 18:33:57663 static void Log(const param_type& p, std::string* l) {
664 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19665 }
666};
667
668template <>
[email protected]7d5c3ac2009-02-04 08:58:19669struct ParamTraits<HACCEL> {
670 typedef HACCEL param_type;
671 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35672 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19673 }
674 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35675 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
676 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19677 }
678};
679
680template <>
681struct ParamTraits<POINT> {
682 typedef POINT param_type;
683 static void Write(Message* m, const param_type& p) {
684 m->WriteInt(p.x);
685 m->WriteInt(p.y);
686 }
687 static bool Read(const Message* m, void** iter, param_type* r) {
688 int x, y;
689 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
690 return false;
691 r->x = x;
692 r->y = y;
693 return true;
694 }
[email protected]252cad62010-08-18 18:33:57695 static void Log(const param_type& p, std::string* l) {
696 l->append(StringPrintf("(%d, %d)", p.x, p.y));
[email protected]7d5c3ac2009-02-04 08:58:19697 }
698};
699#endif // defined(OS_WIN)
700
701template <>
[email protected]7c854372011-08-15 20:41:46702struct IPC_EXPORT ParamTraits<FilePath> {
[email protected]7d5c3ac2009-02-04 08:58:19703 typedef FilePath param_type;
[email protected]7a4de7a62010-08-17 18:38:24704 static void Write(Message* m, const param_type& p);
705 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57706 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19707};
708
[email protected]526776c2009-02-07 00:39:26709#if defined(OS_POSIX)
[email protected]2749885f2009-03-05 21:40:11710// FileDescriptors may be serialised over IPC channels on POSIX. On the
711// receiving side, the FileDescriptor is a valid duplicate of the file
712// descriptor which was transmitted: *it is not just a copy of the integer like
713// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
714// this case, the receiving end will see a value of -1. *Zero is a valid file
715// descriptor*.
716//
717// The received file descriptor will have the |auto_close| flag set to true. The
718// code which handles the message is responsible for taking ownership of it.
719// File descriptors are OS resources and must be closed when no longer needed.
720//
721// When sending a file descriptor, the file descriptor must be valid at the time
722// of transmission. Since transmission is not synchronous, one should consider
723// dup()ing any file descriptors to be transmitted and setting the |auto_close|
724// flag, which causes the file descriptor to be closed after writing.
[email protected]526776c2009-02-07 00:39:26725template<>
[email protected]7c854372011-08-15 20:41:46726struct IPC_EXPORT ParamTraits<base::FileDescriptor> {
[email protected]5fe733de2009-02-11 18:59:20727 typedef base::FileDescriptor param_type;
[email protected]7a4de7a62010-08-17 18:38:24728 static void Write(Message* m, const param_type& p);
729 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57730 static void Log(const param_type& p, std::string* l);
[email protected]526776c2009-02-07 00:39:26731};
[email protected]379e7a52010-03-09 00:38:41732#endif // defined(OS_POSIX)
[email protected]526776c2009-02-07 00:39:26733
[email protected]d2e884d2009-06-22 20:37:52734// A ChannelHandle is basically a platform-inspecific wrapper around the
735// fact that IPC endpoints are handled specially on POSIX. See above comments
736// on FileDescriptor for more background.
737template<>
[email protected]7c854372011-08-15 20:41:46738struct IPC_EXPORT ParamTraits<IPC::ChannelHandle> {
[email protected]d2e884d2009-06-22 20:37:52739 typedef ChannelHandle param_type;
[email protected]7a4de7a62010-08-17 18:38:24740 static void Write(Message* m, const param_type& p);
741 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57742 static void Log(const param_type& p, std::string* l);
[email protected]d2e884d2009-06-22 20:37:52743};
744
[email protected]7d5c3ac2009-02-04 08:58:19745#if defined(OS_WIN)
746template <>
747struct ParamTraits<XFORM> {
748 typedef XFORM param_type;
749 static void Write(Message* m, const param_type& p) {
750 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
751 }
752 static bool Read(const Message* m, void** iter, param_type* r) {
753 const char *data;
754 int data_size = 0;
755 bool result = m->ReadData(iter, &data, &data_size);
756 if (result && data_size == sizeof(XFORM)) {
757 memcpy(r, data, sizeof(XFORM));
758 } else {
759 result = false;
760 NOTREACHED();
761 }
762
763 return result;
764 }
[email protected]252cad62010-08-18 18:33:57765 static void Log(const param_type& p, std::string* l) {
766 l->append("<XFORM>");
[email protected]7d5c3ac2009-02-04 08:58:19767 }
768};
769#endif // defined(OS_WIN)
770
[email protected]7c854372011-08-15 20:41:46771struct IPC_EXPORT LogData {
[email protected]20f0487a2010-09-30 20:06:30772 LogData();
773 ~LogData();
774
[email protected]9a3a293b2009-06-04 22:28:16775 std::string channel;
[email protected]8bef70e2009-04-14 19:11:24776 int32 routing_id;
[email protected]168ae922009-12-04 18:08:45777 uint32 type; // "User-defined" message type, from ipc_message.h.
[email protected]252cad62010-08-18 18:33:57778 std::string flags;
[email protected]7d5c3ac2009-02-04 08:58:19779 int64 sent; // Time that the message was sent (i.e. at Send()).
780 int64 receive; // Time before it was dispatched (i.e. before calling
781 // OnMessageReceived).
782 int64 dispatch; // Time after it was dispatched (i.e. after calling
783 // OnMessageReceived).
[email protected]252cad62010-08-18 18:33:57784 std::string message_name;
785 std::string params;
[email protected]7d5c3ac2009-02-04 08:58:19786};
787
788template <>
[email protected]7c854372011-08-15 20:41:46789struct IPC_EXPORT ParamTraits<LogData> {
[email protected]7d5c3ac2009-02-04 08:58:19790 typedef LogData param_type;
[email protected]20f0487a2010-09-30 20:06:30791 static void Write(Message* m, const param_type& p);
792 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57793 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19794 // Doesn't make sense to implement this!
795 }
796};
797
[email protected]eb47a132009-03-04 00:39:56798template <>
[email protected]503683f2009-02-26 09:13:01799struct ParamTraits<Message> {
800 static void Write(Message* m, const Message& p) {
[email protected]8a861402011-01-28 19:59:11801 DCHECK(p.size() <= INT_MAX);
802 int message_size = static_cast<int>(p.size());
803 m->WriteInt(message_size);
804 m->WriteData(reinterpret_cast<const char*>(p.data()), message_size);
[email protected]503683f2009-02-26 09:13:01805 }
806 static bool Read(const Message* m, void** iter, Message* r) {
807 int size;
808 if (!m->ReadInt(iter, &size))
809 return false;
810 const char* data;
811 if (!m->ReadData(iter, &data, &size))
812 return false;
813 *r = Message(data, size);
814 return true;
815 }
[email protected]252cad62010-08-18 18:33:57816 static void Log(const Message& p, std::string* l) {
817 l->append("<IPC::Message>");
[email protected]503683f2009-02-26 09:13:01818 }
819};
820
821template <>
[email protected]7d5c3ac2009-02-04 08:58:19822struct ParamTraits<Tuple0> {
823 typedef Tuple0 param_type;
824 static void Write(Message* m, const param_type& p) {
825 }
826 static bool Read(const Message* m, void** iter, param_type* r) {
827 return true;
828 }
[email protected]252cad62010-08-18 18:33:57829 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19830 }
831};
832
833template <class A>
834struct ParamTraits< Tuple1<A> > {
835 typedef Tuple1<A> param_type;
836 static void Write(Message* m, const param_type& p) {
837 WriteParam(m, p.a);
838 }
839 static bool Read(const Message* m, void** iter, param_type* r) {
840 return ReadParam(m, iter, &r->a);
841 }
[email protected]252cad62010-08-18 18:33:57842 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19843 LogParam(p.a, l);
844 }
845};
846
847template <class A, class B>
848struct ParamTraits< Tuple2<A, B> > {
849 typedef Tuple2<A, B> param_type;
850 static void Write(Message* m, const param_type& p) {
851 WriteParam(m, p.a);
852 WriteParam(m, p.b);
853 }
854 static bool Read(const Message* m, void** iter, param_type* r) {
855 return (ReadParam(m, iter, &r->a) &&
856 ReadParam(m, iter, &r->b));
857 }
[email protected]252cad62010-08-18 18:33:57858 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19859 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57860 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19861 LogParam(p.b, l);
862 }
863};
864
865template <class A, class B, class C>
866struct ParamTraits< Tuple3<A, B, C> > {
867 typedef Tuple3<A, B, C> param_type;
868 static void Write(Message* m, const param_type& p) {
869 WriteParam(m, p.a);
870 WriteParam(m, p.b);
871 WriteParam(m, p.c);
872 }
873 static bool Read(const Message* m, void** iter, param_type* r) {
874 return (ReadParam(m, iter, &r->a) &&
875 ReadParam(m, iter, &r->b) &&
876 ReadParam(m, iter, &r->c));
877 }
[email protected]252cad62010-08-18 18:33:57878 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19879 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57880 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19881 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57882 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19883 LogParam(p.c, l);
884 }
885};
886
887template <class A, class B, class C, class D>
888struct ParamTraits< Tuple4<A, B, C, D> > {
889 typedef Tuple4<A, B, C, D> param_type;
890 static void Write(Message* m, const param_type& p) {
891 WriteParam(m, p.a);
892 WriteParam(m, p.b);
893 WriteParam(m, p.c);
894 WriteParam(m, p.d);
895 }
896 static bool Read(const Message* m, void** iter, param_type* r) {
897 return (ReadParam(m, iter, &r->a) &&
898 ReadParam(m, iter, &r->b) &&
899 ReadParam(m, iter, &r->c) &&
900 ReadParam(m, iter, &r->d));
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);
[email protected]252cad62010-08-18 18:33:57906 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19907 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57908 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19909 LogParam(p.d, l);
910 }
911};
912
913template <class A, class B, class C, class D, class E>
914struct ParamTraits< Tuple5<A, B, C, D, E> > {
915 typedef Tuple5<A, B, C, D, E> param_type;
916 static void Write(Message* m, const param_type& p) {
917 WriteParam(m, p.a);
918 WriteParam(m, p.b);
919 WriteParam(m, p.c);
920 WriteParam(m, p.d);
921 WriteParam(m, p.e);
922 }
923 static bool Read(const Message* m, void** iter, param_type* r) {
924 return (ReadParam(m, iter, &r->a) &&
925 ReadParam(m, iter, &r->b) &&
926 ReadParam(m, iter, &r->c) &&
927 ReadParam(m, iter, &r->d) &&
928 ReadParam(m, iter, &r->e));
929 }
[email protected]252cad62010-08-18 18:33:57930 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19931 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57932 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19933 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57934 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19935 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57936 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19937 LogParam(p.d, l);
[email protected]252cad62010-08-18 18:33:57938 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19939 LogParam(p.e, l);
940 }
941};
942
[email protected]7d5c3ac2009-02-04 08:58:19943//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:29944// Generic message subclasses
945
946// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:24947template <class ParamType>
[email protected]1d4ecf42011-08-26 21:27:30948class MessageSchema {
initial.commit09911bf2008-07-26 23:55:29949 public:
[email protected]81a34412009-01-05 19:17:24950 typedef ParamType Param;
[email protected]7a4de7a62010-08-17 18:38:24951 typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
[email protected]81a34412009-01-05 19:17:24952
[email protected]1d4ecf42011-08-26 21:27:30953 static void Write(Message* msg, const RefParam& p) IPC_MSG_NOINLINE;
[email protected]7a4de7a62010-08-17 18:38:24954 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:29955};
956
[email protected]7a4de7a62010-08-17 18:38:24957// defined in ipc_logging.cc
[email protected]7c854372011-08-15 20:41:46958IPC_EXPORT void GenerateLogData(const std::string& channel,
959 const Message& message,
960 LogData* data);
[email protected]7a4de7a62010-08-17 18:38:24961
962
963#if defined(IPC_MESSAGE_LOG_ENABLED)
[email protected]252cad62010-08-18 18:33:57964inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
965 const std::string& output_params = msg->output_params();
[email protected]7a4de7a62010-08-17 18:38:24966 if (!l->empty() && !output_params.empty())
[email protected]252cad62010-08-18 18:33:57967 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:24968
969 l->append(output_params);
970}
971
972template <class ReplyParamType>
973inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
974 const Message* msg) {
975 if (msg->received_time() != 0) {
[email protected]252cad62010-08-18 18:33:57976 std::string output_params;
[email protected]7a4de7a62010-08-17 18:38:24977 LogParam(reply_params, &output_params);
978 msg->set_output_params(output_params);
979 }
980}
981
982inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
983 if (msg->sent_time()) {
984 // Don't log the sync message after dispatch, as we don't have the
985 // output parameters at that point. Instead, save its data and log it
986 // with the outgoing reply message when it's sent.
987 LogData* data = new LogData;
988 GenerateLogData("", *msg, data);
989 msg->set_dont_log();
990 reply->set_sync_log_data(data);
991 }
992}
993#else
[email protected]252cad62010-08-18 18:33:57994inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
[email protected]7a4de7a62010-08-17 18:38:24995
996template <class ReplyParamType>
997inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
998 const Message* msg) {}
999
1000inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1001#endif
1002
initial.commit09911bf2008-07-26 23:55:291003// This class assumes that its template argument is a RefTuple (a Tuple with
[email protected]7a4de7a62010-08-17 18:38:241004// reference elements). This would go into ipc_message_utils_impl.h, but it is
1005// also used by chrome_frame.
initial.commit09911bf2008-07-26 23:55:291006template <class RefTuple>
1007class ParamDeserializer : public MessageReplyDeserializer {
1008 public:
[email protected]e1981f432008-08-12 15:22:131009 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:291010
1011 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1012 return ReadParam(&msg, &iter, &out_);
1013 }
1014
1015 RefTuple out_;
1016};
1017
initial.commit09911bf2008-07-26 23:55:291018// Used for synchronous messages.
[email protected]75e5a872009-04-02 23:56:111019template <class SendParamType, class ReplyParamType>
[email protected]1d4ecf42011-08-26 21:27:301020class SyncMessageSchema {
initial.commit09911bf2008-07-26 23:55:291021 public:
[email protected]75e5a872009-04-02 23:56:111022 typedef SendParamType SendParam;
[email protected]7a4de7a62010-08-17 18:38:241023 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
[email protected]75e5a872009-04-02 23:56:111024 typedef ReplyParamType ReplyParam;
1025
[email protected]1d4ecf42011-08-26 21:27:301026 static void Write(Message* msg, const RefSendParam& send) IPC_MSG_NOINLINE;
[email protected]7a4de7a62010-08-17 18:38:241027 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
1028 static bool ReadReplyParam(
1029 const Message* msg,
1030 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:291031
[email protected]65412272010-12-21 20:03:241032 template<class T, class S, class Method>
[email protected]1d4ecf42011-08-26 21:27:301033 static bool DispatchWithSendParams(bool ok, const SendParam& send_params,
1034 const Message* msg, T* obj, S* sender,
1035 Method func) {
1036 Message* reply = SyncMessage::GenerateReply(msg);
1037 if (ok) {
[email protected]7a4de7a62010-08-17 18:38:241038 typename TupleTypes<ReplyParam>::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:291039 DispatchToMethod(obj, func, send_params, &reply_params);
1040 WriteParam(reply, reply_params);
[email protected]7a4de7a62010-08-17 18:38:241041 LogReplyParamsToMessage(reply_params, msg);
initial.commit09911bf2008-07-26 23:55:291042 } else {
1043 NOTREACHED() << "Error deserializing message " << msg->type();
1044 reply->set_reply_error();
initial.commit09911bf2008-07-26 23:55:291045 }
[email protected]65412272010-12-21 20:03:241046 sender->Send(reply);
[email protected]1d4ecf42011-08-26 21:27:301047 return ok;
initial.commit09911bf2008-07-26 23:55:291048 }
1049
1050 template<class T, class Method>
[email protected]1d4ecf42011-08-26 21:27:301051 static bool DispatchDelayReplyWithSendParams(bool ok,
1052 const SendParam& send_params,
1053 const Message* msg, T* obj,
1054 Method func) {
1055 Message* reply = SyncMessage::GenerateReply(msg);
1056 if (ok) {
initial.commit09911bf2008-07-26 23:55:291057 Tuple1<Message&> t = MakeRefTuple(*reply);
[email protected]7a4de7a62010-08-17 18:38:241058 ConnectMessageAndReply(msg, reply);
initial.commit09911bf2008-07-26 23:55:291059 DispatchToMethod(obj, func, send_params, &t);
initial.commit09911bf2008-07-26 23:55:291060 } else {
1061 NOTREACHED() << "Error deserializing message " << msg->type();
1062 reply->set_reply_error();
1063 obj->Send(reply);
initial.commit09911bf2008-07-26 23:55:291064 }
[email protected]1d4ecf42011-08-26 21:27:301065 return ok;
initial.commit09911bf2008-07-26 23:55:291066 }
1067
1068 template<typename TA>
1069 static void WriteReplyParams(Message* reply, TA a) {
1070 ReplyParam p(a);
1071 WriteParam(reply, p);
1072 }
1073
1074 template<typename TA, typename TB>
1075 static void WriteReplyParams(Message* reply, TA a, TB b) {
1076 ReplyParam p(a, b);
1077 WriteParam(reply, p);
1078 }
1079
1080 template<typename TA, typename TB, typename TC>
1081 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1082 ReplyParam p(a, b, c);
1083 WriteParam(reply, p);
1084 }
1085
1086 template<typename TA, typename TB, typename TC, typename TD>
1087 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1088 ReplyParam p(a, b, c, d);
1089 WriteParam(reply, p);
1090 }
1091
1092 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1093 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1094 ReplyParam p(a, b, c, d, e);
1095 WriteParam(reply, p);
1096 }
1097};
1098
[email protected]7d5c3ac2009-02-04 08:58:191099//-----------------------------------------------------------------------------
1100
[email protected]3178f4e22008-08-05 21:20:411101} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291102
[email protected]946d1b22009-07-22 23:57:211103#endif // IPC_IPC_MESSAGE_UTILS_H_