blob: ae7490cb34d0f91f0b8c3ea3a965821954a88b1e [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]e503a122011-03-17 18:20:5296 LastIPCMsgStart // Must come last.
[email protected]f91cb992009-02-04 20:10:1297};
98
[email protected]7a4de7a62010-08-17 18:38:2499class FilePath;
[email protected]7a4de7a62010-08-17 18:38:24100class NullableString16;
101
102namespace base {
[email protected]f3a1c642011-07-12 19:15:03103class DictionaryValue;
104class ListValue;
[email protected]7a4de7a62010-08-17 18:38:24105class Time;
[email protected]d84e48b2010-10-21 22:04:52106class TimeDelta;
[email protected]7a4de7a62010-08-17 18:38:24107struct FileDescriptor;
108}
109
initial.commit09911bf2008-07-26 23:55:29110namespace IPC {
111
[email protected]7a4de7a62010-08-17 18:38:24112struct ChannelHandle;
113
initial.commit09911bf2008-07-26 23:55:29114//-----------------------------------------------------------------------------
115// An iterator class for reading the fields contained within a Message.
116
117class MessageIterator {
118 public:
[email protected]e1981f432008-08-12 15:22:13119 explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
initial.commit09911bf2008-07-26 23:55:29120 }
121 int NextInt() const {
[email protected]9422b7dc2009-12-30 20:09:02122 int val = -1;
initial.commit09911bf2008-07-26 23:55:29123 if (!msg_.ReadInt(&iter_, &val))
124 NOTREACHED();
125 return val;
126 }
initial.commit09911bf2008-07-26 23:55:29127 const std::string NextString() const {
128 std::string val;
129 if (!msg_.ReadString(&iter_, &val))
130 NOTREACHED();
131 return val;
132 }
133 const std::wstring NextWString() const {
134 std::wstring val;
135 if (!msg_.ReadWString(&iter_, &val))
136 NOTREACHED();
137 return val;
138 }
[email protected]225c8f52010-02-05 22:23:20139 void NextData(const char** data, int* length) const {
initial.commit09911bf2008-07-26 23:55:29140 if (!msg_.ReadData(&iter_, data, length)) {
141 NOTREACHED();
142 }
143 }
144 private:
145 const Message& msg_;
146 mutable void* iter_;
147};
148
149//-----------------------------------------------------------------------------
[email protected]6476c72c2011-02-11 18:46:19150// A dummy struct to place first just to allow leading commas for all
151// members in the macro-generated constructor initializer lists.
152struct NoParams {
153};
154
155//-----------------------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19156// ParamTraits specializations, etc.
157
[email protected]7d5c3ac2009-02-04 08:58:19158template <class P>
159static inline void WriteParam(Message* m, const P& p) {
[email protected]7b291f92009-08-14 05:43:53160 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53161 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
[email protected]7d5c3ac2009-02-04 08:58:19162}
163
164template <class P>
[email protected]1e86aa62009-04-24 21:22:33165static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
166 P* p) {
[email protected]7b291f92009-08-14 05:43:53167 typedef typename SimilarTypeTraits<P>::Type Type;
168 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
[email protected]7d5c3ac2009-02-04 08:58:19169}
170
171template <class P>
[email protected]252cad62010-08-18 18:33:57172static inline void LogParam(const P& p, std::string* l) {
[email protected]7b291f92009-08-14 05:43:53173 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53174 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19175}
176
177template <>
178struct ParamTraits<bool> {
179 typedef bool param_type;
180 static void Write(Message* m, const param_type& p) {
181 m->WriteBool(p);
182 }
183 static bool Read(const Message* m, void** iter, param_type* r) {
184 return m->ReadBool(iter, r);
185 }
[email protected]252cad62010-08-18 18:33:57186 static void Log(const param_type& p, std::string* l) {
187 l->append(p ? "true" : "false");
[email protected]7d5c3ac2009-02-04 08:58:19188 }
189};
190
191template <>
192struct ParamTraits<int> {
193 typedef int param_type;
194 static void Write(Message* m, const param_type& p) {
195 m->WriteInt(p);
196 }
197 static bool Read(const Message* m, void** iter, param_type* r) {
198 return m->ReadInt(iter, r);
199 }
[email protected]7c854372011-08-15 20:41:46200 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19201};
202
203template <>
[email protected]63263f92009-07-28 19:35:08204struct ParamTraits<unsigned int> {
205 typedef unsigned int param_type;
206 static void Write(Message* m, const param_type& p) {
207 m->WriteInt(p);
208 }
209 static bool Read(const Message* m, void** iter, param_type* r) {
210 return m->ReadInt(iter, reinterpret_cast<int*>(r));
211 }
[email protected]7c854372011-08-15 20:41:46212 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08213};
214
215template <>
[email protected]7d5c3ac2009-02-04 08:58:19216struct ParamTraits<long> {
217 typedef long param_type;
218 static void Write(Message* m, const param_type& p) {
219 m->WriteLong(p);
220 }
221 static bool Read(const Message* m, void** iter, param_type* r) {
222 return m->ReadLong(iter, r);
223 }
[email protected]7c854372011-08-15 20:41:46224 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19225};
226
[email protected]140c3032009-06-26 18:22:54227template <>
228struct ParamTraits<unsigned long> {
229 typedef unsigned long param_type;
230 static void Write(Message* m, const param_type& p) {
231 m->WriteLong(p);
232 }
233 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]63263f92009-07-28 19:35:08234 return m->ReadLong(iter, reinterpret_cast<long*>(r));
[email protected]140c3032009-06-26 18:22:54235 }
[email protected]7c854372011-08-15 20:41:46236 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19237};
238
239template <>
[email protected]63263f92009-07-28 19:35:08240struct ParamTraits<long long> {
241 typedef long long param_type;
[email protected]7d5c3ac2009-02-04 08:58:19242 static void Write(Message* m, const param_type& p) {
243 m->WriteInt64(static_cast<int64>(p));
244 }
245 static bool Read(const Message* m, void** iter, param_type* r) {
246 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
247 }
[email protected]7c854372011-08-15 20:41:46248 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08249};
250
251template <>
252struct ParamTraits<unsigned long long> {
253 typedef unsigned long long param_type;
254 static void Write(Message* m, const param_type& p) {
255 m->WriteInt64(p);
256 }
257 static bool Read(const Message* m, void** iter, param_type* r) {
258 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
259 }
[email protected]7c854372011-08-15 20:41:46260 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19261};
262
[email protected]43a40202010-11-12 16:25:01263template <>
[email protected]7c854372011-08-15 20:41:46264struct IPC_EXPORT ParamTraits<unsigned short> {
[email protected]43a40202010-11-12 16:25:01265 typedef unsigned short param_type;
266 static void Write(Message* m, const param_type& p);
267 static bool Read(const Message* m, void** iter, param_type* r);
268 static void Log(const param_type& p, std::string* l);
269};
270
[email protected]20199662010-06-17 03:29:26271// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
272// should be sure to check the sanity of these values after receiving them over
273// IPC.
274template <>
275struct ParamTraits<float> {
276 typedef float param_type;
277 static void Write(Message* m, const param_type& p) {
278 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
279 }
280 static bool Read(const Message* m, void** iter, param_type* r) {
281 const char *data;
282 int data_size;
283 if (!m->ReadData(iter, &data, &data_size) ||
284 data_size != sizeof(param_type)) {
285 NOTREACHED();
286 return false;
287 }
288 memcpy(r, data, sizeof(param_type));
289 return true;
290 }
[email protected]252cad62010-08-18 18:33:57291 static void Log(const param_type& p, std::string* l) {
292 l->append(StringPrintf("%e", p));
[email protected]20199662010-06-17 03:29:26293 }
294};
295
[email protected]7d5c3ac2009-02-04 08:58:19296template <>
297struct ParamTraits<double> {
298 typedef double param_type;
299 static void Write(Message* m, const param_type& p) {
300 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
301 }
302 static bool Read(const Message* m, void** iter, param_type* r) {
303 const char *data;
[email protected]20199662010-06-17 03:29:26304 int data_size;
305 if (!m->ReadData(iter, &data, &data_size) ||
306 data_size != sizeof(param_type)) {
[email protected]7d5c3ac2009-02-04 08:58:19307 NOTREACHED();
[email protected]20199662010-06-17 03:29:26308 return false;
[email protected]7d5c3ac2009-02-04 08:58:19309 }
[email protected]20199662010-06-17 03:29:26310 memcpy(r, data, sizeof(param_type));
311 return true;
[email protected]7d5c3ac2009-02-04 08:58:19312 }
[email protected]252cad62010-08-18 18:33:57313 static void Log(const param_type& p, std::string* l) {
314 l->append(StringPrintf("%e", p));
[email protected]7d5c3ac2009-02-04 08:58:19315 }
316};
317
318template <>
[email protected]7c854372011-08-15 20:41:46319struct IPC_EXPORT ParamTraits<base::Time> {
[email protected]7d5c3ac2009-02-04 08:58:19320 typedef base::Time param_type;
[email protected]7a4de7a62010-08-17 18:38:24321 static void Write(Message* m, const param_type& p);
322 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57323 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19324};
325
[email protected]d84e48b2010-10-21 22:04:52326template <>
[email protected]7c854372011-08-15 20:41:46327struct IPC_EXPORT ParamTraits<base::TimeDelta> {
[email protected]d84e48b2010-10-21 22:04:52328 typedef base::TimeDelta param_type;
329 static void Write(Message* m, const param_type& p);
330 static bool Read(const Message* m, void** iter, param_type* r);
331 static void Log(const param_type& p, std::string* l);
332};
333
[email protected]7d5c3ac2009-02-04 08:58:19334#if defined(OS_WIN)
335template <>
336struct ParamTraits<LOGFONT> {
337 typedef LOGFONT param_type;
338 static void Write(Message* m, const param_type& p) {
339 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
340 }
341 static bool Read(const Message* m, void** iter, param_type* r) {
342 const char *data;
343 int data_size = 0;
344 bool result = m->ReadData(iter, &data, &data_size);
345 if (result && data_size == sizeof(LOGFONT)) {
346 memcpy(r, data, sizeof(LOGFONT));
347 } else {
348 result = false;
349 NOTREACHED();
350 }
351
352 return result;
353 }
[email protected]252cad62010-08-18 18:33:57354 static void Log(const param_type& p, std::string* l) {
355 l->append(StringPrintf("<LOGFONT>"));
[email protected]7d5c3ac2009-02-04 08:58:19356 }
357};
358
359template <>
360struct ParamTraits<MSG> {
361 typedef MSG param_type;
362 static void Write(Message* m, const param_type& p) {
363 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
364 }
365 static bool Read(const Message* m, void** iter, param_type* r) {
366 const char *data;
367 int data_size = 0;
368 bool result = m->ReadData(iter, &data, &data_size);
369 if (result && data_size == sizeof(MSG)) {
370 memcpy(r, data, sizeof(MSG));
371 } else {
372 result = false;
373 NOTREACHED();
374 }
375
376 return result;
377 }
[email protected]252cad62010-08-18 18:33:57378 static void Log(const param_type& p, std::string* l) {
379 l->append("<MSG>");
[email protected]7a4de7a62010-08-17 18:38:24380 }
[email protected]7d5c3ac2009-02-04 08:58:19381};
382#endif // defined(OS_WIN)
383
384template <>
[email protected]7c854372011-08-15 20:41:46385struct IPC_EXPORT ParamTraits<base::DictionaryValue> {
[email protected]f3a1c642011-07-12 19:15:03386 typedef base::DictionaryValue param_type;
[email protected]584f2b22009-05-21 01:01:59387 static void Write(Message* m, const param_type& p);
388 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57389 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59390};
391
392template <>
[email protected]7c854372011-08-15 20:41:46393struct IPC_EXPORT ParamTraits<base::ListValue> {
[email protected]f3a1c642011-07-12 19:15:03394 typedef base::ListValue param_type;
[email protected]584f2b22009-05-21 01:01:59395 static void Write(Message* m, const param_type& p);
396 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57397 static void Log(const param_type& p, std::string* l);
[email protected]584f2b22009-05-21 01:01:59398};
399
400template <>
[email protected]7d5c3ac2009-02-04 08:58:19401struct ParamTraits<std::string> {
402 typedef std::string param_type;
403 static void Write(Message* m, const param_type& p) {
404 m->WriteString(p);
405 }
406 static bool Read(const Message* m, void** iter, param_type* r) {
407 return m->ReadString(iter, r);
408 }
[email protected]252cad62010-08-18 18:33:57409 static void Log(const param_type& p, std::string* l) {
410 l->append(p);
[email protected]7d5c3ac2009-02-04 08:58:19411 }
412};
413
[email protected]3dd7a7a2009-07-27 21:09:07414template<typename CharType>
[email protected]252cad62010-08-18 18:33:57415static void LogBytes(const std::vector<CharType>& data, std::string* out) {
[email protected]3dd7a7a2009-07-27 21:09:07416#if defined(OS_WIN)
417 // Windows has a GUI for logging, which can handle arbitrary binary data.
418 for (size_t i = 0; i < data.size(); ++i)
419 out->push_back(data[i]);
420#else
421 // On POSIX, we log to stdout, which we assume can display ASCII.
422 static const size_t kMaxBytesToLog = 100;
423 for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
424 if (isprint(data[i]))
425 out->push_back(data[i]);
426 else
[email protected]252cad62010-08-18 18:33:57427 out->append(StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
[email protected]3dd7a7a2009-07-27 21:09:07428 }
429 if (data.size() > kMaxBytesToLog) {
430 out->append(
[email protected]252cad62010-08-18 18:33:57431 StringPrintf(" and %u more bytes",
[email protected]3dd7a7a2009-07-27 21:09:07432 static_cast<unsigned>(data.size() - kMaxBytesToLog)));
433 }
434#endif
435}
436
[email protected]7d5c3ac2009-02-04 08:58:19437template <>
438struct ParamTraits<std::vector<unsigned char> > {
439 typedef std::vector<unsigned char> param_type;
440 static void Write(Message* m, const param_type& p) {
[email protected]f6b8ce32011-03-02 00:03:18441 if (p.empty()) {
[email protected]7d5c3ac2009-02-04 08:58:19442 m->WriteData(NULL, 0);
443 } else {
444 m->WriteData(reinterpret_cast<const char*>(&p.front()),
445 static_cast<int>(p.size()));
446 }
447 }
448 static bool Read(const Message* m, void** iter, param_type* r) {
449 const char *data;
450 int data_size = 0;
451 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
452 return false;
453 r->resize(data_size);
454 if (data_size)
455 memcpy(&r->front(), data, data_size);
456 return true;
457 }
[email protected]252cad62010-08-18 18:33:57458 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07459 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19460 }
461};
462
463template <>
464struct ParamTraits<std::vector<char> > {
465 typedef std::vector<char> param_type;
466 static void Write(Message* m, const param_type& p) {
[email protected]f6b8ce32011-03-02 00:03:18467 if (p.empty()) {
[email protected]7d5c3ac2009-02-04 08:58:19468 m->WriteData(NULL, 0);
469 } else {
470 m->WriteData(&p.front(), static_cast<int>(p.size()));
471 }
472 }
473 static bool Read(const Message* m, void** iter, param_type* r) {
474 const char *data;
475 int data_size = 0;
476 if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
477 return false;
478 r->resize(data_size);
479 if (data_size)
480 memcpy(&r->front(), data, data_size);
481 return true;
482 }
[email protected]252cad62010-08-18 18:33:57483 static void Log(const param_type& p, std::string* l) {
[email protected]3dd7a7a2009-07-27 21:09:07484 LogBytes(p, l);
[email protected]7d5c3ac2009-02-04 08:58:19485 }
486};
487
488template <class P>
489struct ParamTraits<std::vector<P> > {
490 typedef std::vector<P> param_type;
491 static void Write(Message* m, const param_type& p) {
492 WriteParam(m, static_cast<int>(p.size()));
493 for (size_t i = 0; i < p.size(); i++)
494 WriteParam(m, p[i]);
495 }
496 static bool Read(const Message* m, void** iter, param_type* r) {
497 int size;
[email protected]86440f52009-12-31 05:17:23498 // ReadLength() checks for < 0 itself.
[email protected]7d5c3ac2009-02-04 08:58:19499 if (!m->ReadLength(iter, &size))
500 return false;
501 // Resizing beforehand is not safe, see BUG 1006367 for details.
[email protected]86440f52009-12-31 05:17:23502 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
503 return false;
504 r->resize(size);
505 for (int i = 0; i < size; i++) {
506 if (!ReadParam(m, iter, &(*r)[i]))
507 return false;
[email protected]7d5c3ac2009-02-04 08:58:19508 }
509 return true;
510 }
[email protected]252cad62010-08-18 18:33:57511 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19512 for (size_t i = 0; i < p.size(); ++i) {
513 if (i != 0)
[email protected]252cad62010-08-18 18:33:57514 l->append(" ");
[email protected]7d5c3ac2009-02-04 08:58:19515 LogParam((p[i]), l);
516 }
517 }
518};
519
[email protected]96da6962010-05-13 19:10:34520template <class P>
521struct ParamTraits<std::set<P> > {
522 typedef std::set<P> param_type;
523 static void Write(Message* m, const param_type& p) {
524 WriteParam(m, static_cast<int>(p.size()));
525 typename param_type::const_iterator iter;
526 for (iter = p.begin(); iter != p.end(); ++iter)
527 WriteParam(m, *iter);
528 }
529 static bool Read(const Message* m, void** iter, param_type* r) {
530 int size;
531 if (!m->ReadLength(iter, &size))
532 return false;
533 for (int i = 0; i < size; ++i) {
534 P item;
535 if (!ReadParam(m, iter, &item))
536 return false;
537 r->insert(item);
538 }
539 return true;
540 }
[email protected]252cad62010-08-18 18:33:57541 static void Log(const param_type& p, std::string* l) {
542 l->append("<std::set>");
[email protected]96da6962010-05-13 19:10:34543 }
544};
545
546
[email protected]7d5c3ac2009-02-04 08:58:19547template <class K, class V>
548struct ParamTraits<std::map<K, V> > {
549 typedef std::map<K, V> param_type;
550 static void Write(Message* m, const param_type& p) {
551 WriteParam(m, static_cast<int>(p.size()));
552 typename param_type::const_iterator iter;
553 for (iter = p.begin(); iter != p.end(); ++iter) {
554 WriteParam(m, iter->first);
555 WriteParam(m, iter->second);
556 }
557 }
558 static bool Read(const Message* m, void** iter, param_type* r) {
559 int size;
560 if (!ReadParam(m, iter, &size) || size < 0)
561 return false;
562 for (int i = 0; i < size; ++i) {
563 K k;
564 if (!ReadParam(m, iter, &k))
565 return false;
566 V& value = (*r)[k];
567 if (!ReadParam(m, iter, &value))
568 return false;
569 }
570 return true;
571 }
[email protected]252cad62010-08-18 18:33:57572 static void Log(const param_type& p, std::string* l) {
573 l->append("<std::map>");
[email protected]7d5c3ac2009-02-04 08:58:19574 }
575};
576
[email protected]eb47a132009-03-04 00:39:56577
[email protected]7d5c3ac2009-02-04 08:58:19578template <>
579struct ParamTraits<std::wstring> {
580 typedef std::wstring param_type;
581 static void Write(Message* m, const param_type& p) {
582 m->WriteWString(p);
583 }
584 static bool Read(const Message* m, void** iter, param_type* r) {
585 return m->ReadWString(iter, r);
586 }
[email protected]7c854372011-08-15 20:41:46587 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19588};
589
[email protected]a5da6d612009-08-04 02:00:56590template <class A, class B>
591struct ParamTraits<std::pair<A, B> > {
592 typedef std::pair<A, B> param_type;
593 static void Write(Message* m, const param_type& p) {
594 WriteParam(m, p.first);
595 WriteParam(m, p.second);
596 }
597 static bool Read(const Message* m, void** iter, param_type* r) {
598 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
599 }
[email protected]252cad62010-08-18 18:33:57600 static void Log(const param_type& p, std::string* l) {
601 l->append("(");
[email protected]a5da6d612009-08-04 02:00:56602 LogParam(p.first, l);
[email protected]252cad62010-08-18 18:33:57603 l->append(", ");
[email protected]a5da6d612009-08-04 02:00:56604 LogParam(p.second, l);
[email protected]252cad62010-08-18 18:33:57605 l->append(")");
[email protected]a5da6d612009-08-04 02:00:56606 }
607};
608
[email protected]15bf8712009-08-27 00:55:02609template <>
[email protected]7c854372011-08-15 20:41:46610struct IPC_EXPORT ParamTraits<NullableString16> {
[email protected]15bf8712009-08-27 00:55:02611 typedef NullableString16 param_type;
[email protected]7a4de7a62010-08-17 18:38:24612 static void Write(Message* m, const param_type& p);
613 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57614 static void Log(const param_type& p, std::string* l);
[email protected]15bf8712009-08-27 00:55:02615};
616
[email protected]eb47a132009-03-04 00:39:56617// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
618// need this trait.
619#if !defined(WCHAR_T_IS_UTF16)
[email protected]eb47a132009-03-04 00:39:56620template <>
621struct ParamTraits<string16> {
622 typedef string16 param_type;
623 static void Write(Message* m, const param_type& p) {
[email protected]3a2a5d22009-03-04 03:36:36624 m->WriteString16(p);
[email protected]eb47a132009-03-04 00:39:56625 }
626 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]3a2a5d22009-03-04 03:36:36627 return m->ReadString16(iter, r);
[email protected]eb47a132009-03-04 00:39:56628 }
[email protected]7c854372011-08-15 20:41:46629 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]eb47a132009-03-04 00:39:56630};
[email protected]eb47a132009-03-04 00:39:56631#endif
632
[email protected]7d5c3ac2009-02-04 08:58:19633// and, a few more useful types...
634#if defined(OS_WIN)
635template <>
636struct ParamTraits<HANDLE> {
637 typedef HANDLE param_type;
638 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35639 // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
640 // bit systems.
641 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19642 }
643 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35644 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
645 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19646 }
[email protected]252cad62010-08-18 18:33:57647 static void Log(const param_type& p, std::string* l) {
648 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19649 }
650};
651
652template <>
653struct ParamTraits<HCURSOR> {
654 typedef HCURSOR param_type;
655 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35656 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19657 }
658 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35659 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
660 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19661 }
[email protected]252cad62010-08-18 18:33:57662 static void Log(const param_type& p, std::string* l) {
663 l->append(StringPrintf("0x%X", p));
[email protected]7d5c3ac2009-02-04 08:58:19664 }
665};
666
667template <>
[email protected]7d5c3ac2009-02-04 08:58:19668struct ParamTraits<HACCEL> {
669 typedef HACCEL param_type;
670 static void Write(Message* m, const param_type& p) {
[email protected]37477912010-02-09 08:06:35671 m->WriteUInt32(reinterpret_cast<uint32>(p));
[email protected]7d5c3ac2009-02-04 08:58:19672 }
673 static bool Read(const Message* m, void** iter, param_type* r) {
[email protected]37477912010-02-09 08:06:35674 DCHECK_EQ(sizeof(param_type), sizeof(uint32));
675 return m->ReadUInt32(iter, reinterpret_cast<uint32*>(r));
[email protected]7d5c3ac2009-02-04 08:58:19676 }
677};
678
679template <>
680struct ParamTraits<POINT> {
681 typedef POINT param_type;
682 static void Write(Message* m, const param_type& p) {
683 m->WriteInt(p.x);
684 m->WriteInt(p.y);
685 }
686 static bool Read(const Message* m, void** iter, param_type* r) {
687 int x, y;
688 if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
689 return false;
690 r->x = x;
691 r->y = y;
692 return true;
693 }
[email protected]252cad62010-08-18 18:33:57694 static void Log(const param_type& p, std::string* l) {
695 l->append(StringPrintf("(%d, %d)", p.x, p.y));
[email protected]7d5c3ac2009-02-04 08:58:19696 }
697};
698#endif // defined(OS_WIN)
699
700template <>
[email protected]7c854372011-08-15 20:41:46701struct IPC_EXPORT ParamTraits<FilePath> {
[email protected]7d5c3ac2009-02-04 08:58:19702 typedef FilePath param_type;
[email protected]7a4de7a62010-08-17 18:38:24703 static void Write(Message* m, const param_type& p);
704 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57705 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19706};
707
[email protected]526776c2009-02-07 00:39:26708#if defined(OS_POSIX)
[email protected]2749885f2009-03-05 21:40:11709// FileDescriptors may be serialised over IPC channels on POSIX. On the
710// receiving side, the FileDescriptor is a valid duplicate of the file
711// descriptor which was transmitted: *it is not just a copy of the integer like
712// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
713// this case, the receiving end will see a value of -1. *Zero is a valid file
714// descriptor*.
715//
716// The received file descriptor will have the |auto_close| flag set to true. The
717// code which handles the message is responsible for taking ownership of it.
718// File descriptors are OS resources and must be closed when no longer needed.
719//
720// When sending a file descriptor, the file descriptor must be valid at the time
721// of transmission. Since transmission is not synchronous, one should consider
722// dup()ing any file descriptors to be transmitted and setting the |auto_close|
723// flag, which causes the file descriptor to be closed after writing.
[email protected]526776c2009-02-07 00:39:26724template<>
[email protected]7c854372011-08-15 20:41:46725struct IPC_EXPORT ParamTraits<base::FileDescriptor> {
[email protected]5fe733de2009-02-11 18:59:20726 typedef base::FileDescriptor param_type;
[email protected]7a4de7a62010-08-17 18:38:24727 static void Write(Message* m, const param_type& p);
728 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57729 static void Log(const param_type& p, std::string* l);
[email protected]526776c2009-02-07 00:39:26730};
[email protected]379e7a52010-03-09 00:38:41731#endif // defined(OS_POSIX)
[email protected]526776c2009-02-07 00:39:26732
[email protected]d2e884d2009-06-22 20:37:52733// A ChannelHandle is basically a platform-inspecific wrapper around the
734// fact that IPC endpoints are handled specially on POSIX. See above comments
735// on FileDescriptor for more background.
736template<>
[email protected]7c854372011-08-15 20:41:46737struct IPC_EXPORT ParamTraits<IPC::ChannelHandle> {
[email protected]d2e884d2009-06-22 20:37:52738 typedef ChannelHandle param_type;
[email protected]7a4de7a62010-08-17 18:38:24739 static void Write(Message* m, const param_type& p);
740 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57741 static void Log(const param_type& p, std::string* l);
[email protected]d2e884d2009-06-22 20:37:52742};
743
[email protected]7d5c3ac2009-02-04 08:58:19744#if defined(OS_WIN)
745template <>
746struct ParamTraits<XFORM> {
747 typedef XFORM param_type;
748 static void Write(Message* m, const param_type& p) {
749 m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
750 }
751 static bool Read(const Message* m, void** iter, param_type* r) {
752 const char *data;
753 int data_size = 0;
754 bool result = m->ReadData(iter, &data, &data_size);
755 if (result && data_size == sizeof(XFORM)) {
756 memcpy(r, data, sizeof(XFORM));
757 } else {
758 result = false;
759 NOTREACHED();
760 }
761
762 return result;
763 }
[email protected]252cad62010-08-18 18:33:57764 static void Log(const param_type& p, std::string* l) {
765 l->append("<XFORM>");
[email protected]7d5c3ac2009-02-04 08:58:19766 }
767};
768#endif // defined(OS_WIN)
769
[email protected]7c854372011-08-15 20:41:46770struct IPC_EXPORT LogData {
[email protected]20f0487a2010-09-30 20:06:30771 LogData();
772 ~LogData();
773
[email protected]9a3a293b2009-06-04 22:28:16774 std::string channel;
[email protected]8bef70e2009-04-14 19:11:24775 int32 routing_id;
[email protected]168ae922009-12-04 18:08:45776 uint32 type; // "User-defined" message type, from ipc_message.h.
[email protected]252cad62010-08-18 18:33:57777 std::string flags;
[email protected]7d5c3ac2009-02-04 08:58:19778 int64 sent; // Time that the message was sent (i.e. at Send()).
779 int64 receive; // Time before it was dispatched (i.e. before calling
780 // OnMessageReceived).
781 int64 dispatch; // Time after it was dispatched (i.e. after calling
782 // OnMessageReceived).
[email protected]252cad62010-08-18 18:33:57783 std::string message_name;
784 std::string params;
[email protected]7d5c3ac2009-02-04 08:58:19785};
786
787template <>
[email protected]7c854372011-08-15 20:41:46788struct IPC_EXPORT ParamTraits<LogData> {
[email protected]7d5c3ac2009-02-04 08:58:19789 typedef LogData param_type;
[email protected]20f0487a2010-09-30 20:06:30790 static void Write(Message* m, const param_type& p);
791 static bool Read(const Message* m, void** iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57792 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19793 // Doesn't make sense to implement this!
794 }
795};
796
[email protected]eb47a132009-03-04 00:39:56797template <>
[email protected]503683f2009-02-26 09:13:01798struct ParamTraits<Message> {
799 static void Write(Message* m, const Message& p) {
[email protected]8a861402011-01-28 19:59:11800 DCHECK(p.size() <= INT_MAX);
801 int message_size = static_cast<int>(p.size());
802 m->WriteInt(message_size);
803 m->WriteData(reinterpret_cast<const char*>(p.data()), message_size);
[email protected]503683f2009-02-26 09:13:01804 }
805 static bool Read(const Message* m, void** iter, Message* r) {
806 int size;
807 if (!m->ReadInt(iter, &size))
808 return false;
809 const char* data;
810 if (!m->ReadData(iter, &data, &size))
811 return false;
812 *r = Message(data, size);
813 return true;
814 }
[email protected]252cad62010-08-18 18:33:57815 static void Log(const Message& p, std::string* l) {
816 l->append("<IPC::Message>");
[email protected]503683f2009-02-26 09:13:01817 }
818};
819
820template <>
[email protected]7d5c3ac2009-02-04 08:58:19821struct ParamTraits<Tuple0> {
822 typedef Tuple0 param_type;
823 static void Write(Message* m, const param_type& p) {
824 }
825 static bool Read(const Message* m, void** iter, param_type* r) {
826 return true;
827 }
[email protected]252cad62010-08-18 18:33:57828 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19829 }
830};
831
832template <class A>
833struct ParamTraits< Tuple1<A> > {
834 typedef Tuple1<A> param_type;
835 static void Write(Message* m, const param_type& p) {
836 WriteParam(m, p.a);
837 }
838 static bool Read(const Message* m, void** iter, param_type* r) {
839 return ReadParam(m, iter, &r->a);
840 }
[email protected]252cad62010-08-18 18:33:57841 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19842 LogParam(p.a, l);
843 }
844};
845
846template <class A, class B>
847struct ParamTraits< Tuple2<A, B> > {
848 typedef Tuple2<A, B> param_type;
849 static void Write(Message* m, const param_type& p) {
850 WriteParam(m, p.a);
851 WriteParam(m, p.b);
852 }
853 static bool Read(const Message* m, void** iter, param_type* r) {
854 return (ReadParam(m, iter, &r->a) &&
855 ReadParam(m, iter, &r->b));
856 }
[email protected]252cad62010-08-18 18:33:57857 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19858 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57859 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19860 LogParam(p.b, l);
861 }
862};
863
864template <class A, class B, class C>
865struct ParamTraits< Tuple3<A, B, C> > {
866 typedef Tuple3<A, B, C> param_type;
867 static void Write(Message* m, const param_type& p) {
868 WriteParam(m, p.a);
869 WriteParam(m, p.b);
870 WriteParam(m, p.c);
871 }
872 static bool Read(const Message* m, void** iter, param_type* r) {
873 return (ReadParam(m, iter, &r->a) &&
874 ReadParam(m, iter, &r->b) &&
875 ReadParam(m, iter, &r->c));
876 }
[email protected]252cad62010-08-18 18:33:57877 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19878 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57879 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19880 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57881 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19882 LogParam(p.c, l);
883 }
884};
885
886template <class A, class B, class C, class D>
887struct ParamTraits< Tuple4<A, B, C, D> > {
888 typedef Tuple4<A, B, C, D> param_type;
889 static void Write(Message* m, const param_type& p) {
890 WriteParam(m, p.a);
891 WriteParam(m, p.b);
892 WriteParam(m, p.c);
893 WriteParam(m, p.d);
894 }
895 static bool Read(const Message* m, void** iter, param_type* r) {
896 return (ReadParam(m, iter, &r->a) &&
897 ReadParam(m, iter, &r->b) &&
898 ReadParam(m, iter, &r->c) &&
899 ReadParam(m, iter, &r->d));
900 }
[email protected]252cad62010-08-18 18:33:57901 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19902 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57903 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19904 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57905 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19906 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57907 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19908 LogParam(p.d, l);
909 }
910};
911
912template <class A, class B, class C, class D, class E>
913struct ParamTraits< Tuple5<A, B, C, D, E> > {
914 typedef Tuple5<A, B, C, D, E> param_type;
915 static void Write(Message* m, const param_type& p) {
916 WriteParam(m, p.a);
917 WriteParam(m, p.b);
918 WriteParam(m, p.c);
919 WriteParam(m, p.d);
920 WriteParam(m, p.e);
921 }
922 static bool Read(const Message* m, void** iter, param_type* r) {
923 return (ReadParam(m, iter, &r->a) &&
924 ReadParam(m, iter, &r->b) &&
925 ReadParam(m, iter, &r->c) &&
926 ReadParam(m, iter, &r->d) &&
927 ReadParam(m, iter, &r->e));
928 }
[email protected]252cad62010-08-18 18:33:57929 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19930 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57931 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19932 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57933 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19934 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57935 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19936 LogParam(p.d, l);
[email protected]252cad62010-08-18 18:33:57937 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19938 LogParam(p.e, l);
939 }
940};
941
[email protected]7d5c3ac2009-02-04 08:58:19942//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:29943// Generic message subclasses
944
945// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:24946template <class ParamType>
initial.commit09911bf2008-07-26 23:55:29947class MessageWithTuple : public Message {
948 public:
[email protected]81a34412009-01-05 19:17:24949 typedef ParamType Param;
[email protected]7a4de7a62010-08-17 18:38:24950 typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
[email protected]81a34412009-01-05 19:17:24951
[email protected]7a4de7a62010-08-17 18:38:24952 // The constructor and the Read() method's templated implementations are in
953 // ipc_message_utils_impl.h. The subclass constructor and Log() methods call
954 // the templated versions of these and make sure there are instantiations in
955 // those translation units.
956 MessageWithTuple(int32 routing_id, uint32 type, const RefParam& p);
[email protected]071b4b92010-08-09 16:06:58957
[email protected]7a4de7a62010-08-17 18:38:24958 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:29959
960 // Generic dispatcher. Should cover most cases.
[email protected]65412272010-12-21 20:03:24961 template<class T, class S, class Method>
962 static bool Dispatch(const Message* msg, T* obj, S* sender, Method func) {
initial.commit09911bf2008-07-26 23:55:29963 Param p;
964 if (Read(msg, &p)) {
965 DispatchToMethod(obj, func, p);
966 return true;
967 }
968 return false;
969 }
970
971 // The following dispatchers exist for the case where the callback function
972 // needs the message as well. They assume that "Param" is a type of Tuple
973 // (except the one arg case, as there is no Tuple1).
[email protected]65412272010-12-21 20:03:24974 template<class T, class S, typename TA>
975 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29976 void (T::*func)(const Message&, TA)) {
977 Param p;
978 if (Read(msg, &p)) {
[email protected]c2fe31542009-05-20 18:24:14979 (obj->*func)(*msg, p.a);
initial.commit09911bf2008-07-26 23:55:29980 return true;
981 }
982 return false;
983 }
984
[email protected]65412272010-12-21 20:03:24985 template<class T, class S, typename TA, typename TB>
986 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29987 void (T::*func)(const Message&, TA, TB)) {
988 Param p;
989 if (Read(msg, &p)) {
990 (obj->*func)(*msg, p.a, p.b);
991 return true;
992 }
993 return false;
994 }
995
[email protected]65412272010-12-21 20:03:24996 template<class T, class S, typename TA, typename TB, typename TC>
997 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:29998 void (T::*func)(const Message&, TA, TB, TC)) {
999 Param p;
1000 if (Read(msg, &p)) {
1001 (obj->*func)(*msg, p.a, p.b, p.c);
1002 return true;
1003 }
1004 return false;
1005 }
1006
[email protected]65412272010-12-21 20:03:241007 template<class T, class S, typename TA, typename TB, typename TC, typename TD>
1008 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:291009 void (T::*func)(const Message&, TA, TB, TC, TD)) {
1010 Param p;
1011 if (Read(msg, &p)) {
1012 (obj->*func)(*msg, p.a, p.b, p.c, p.d);
1013 return true;
1014 }
1015 return false;
1016 }
1017
[email protected]65412272010-12-21 20:03:241018 template<class T, class S, typename TA, typename TB, typename TC, typename TD,
initial.commit09911bf2008-07-26 23:55:291019 typename TE>
[email protected]65412272010-12-21 20:03:241020 static bool Dispatch(const Message* msg, T* obj, S* sender,
initial.commit09911bf2008-07-26 23:55:291021 void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
1022 Param p;
1023 if (Read(msg, &p)) {
1024 (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
1025 return true;
1026 }
1027 return false;
1028 }
1029
[email protected]deb57402009-02-06 01:35:301030 // Functions used to do manual unpacking. Only used by the automation code,
1031 // these should go away once that code uses SyncChannel.
1032 template<typename TA, typename TB>
1033 static bool Read(const IPC::Message* msg, TA* a, TB* b) {
1034 ParamType params;
1035 if (!Read(msg, &params))
1036 return false;
1037 *a = params.a;
1038 *b = params.b;
1039 return true;
1040 }
1041
1042 template<typename TA, typename TB, typename TC>
1043 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
1044 ParamType params;
1045 if (!Read(msg, &params))
1046 return false;
1047 *a = params.a;
1048 *b = params.b;
1049 *c = params.c;
1050 return true;
1051 }
1052
1053 template<typename TA, typename TB, typename TC, typename TD>
1054 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) {
1055 ParamType params;
1056 if (!Read(msg, &params))
1057 return false;
1058 *a = params.a;
1059 *b = params.b;
1060 *c = params.c;
1061 *d = params.d;
1062 return true;
1063 }
1064
1065 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1066 static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) {
1067 ParamType params;
1068 if (!Read(msg, &params))
1069 return false;
1070 *a = params.a;
1071 *b = params.b;
1072 *c = params.c;
1073 *d = params.d;
1074 *e = params.e;
1075 return true;
1076 }
initial.commit09911bf2008-07-26 23:55:291077};
1078
[email protected]7a4de7a62010-08-17 18:38:241079// defined in ipc_logging.cc
[email protected]7c854372011-08-15 20:41:461080IPC_EXPORT void GenerateLogData(const std::string& channel,
1081 const Message& message,
1082 LogData* data);
[email protected]7a4de7a62010-08-17 18:38:241083
1084
1085#if defined(IPC_MESSAGE_LOG_ENABLED)
[email protected]252cad62010-08-18 18:33:571086inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
1087 const std::string& output_params = msg->output_params();
[email protected]7a4de7a62010-08-17 18:38:241088 if (!l->empty() && !output_params.empty())
[email protected]252cad62010-08-18 18:33:571089 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:241090
1091 l->append(output_params);
1092}
1093
1094template <class ReplyParamType>
1095inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1096 const Message* msg) {
1097 if (msg->received_time() != 0) {
[email protected]252cad62010-08-18 18:33:571098 std::string output_params;
[email protected]7a4de7a62010-08-17 18:38:241099 LogParam(reply_params, &output_params);
1100 msg->set_output_params(output_params);
1101 }
1102}
1103
1104inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
1105 if (msg->sent_time()) {
1106 // Don't log the sync message after dispatch, as we don't have the
1107 // output parameters at that point. Instead, save its data and log it
1108 // with the outgoing reply message when it's sent.
1109 LogData* data = new LogData;
1110 GenerateLogData("", *msg, data);
1111 msg->set_dont_log();
1112 reply->set_sync_log_data(data);
1113 }
1114}
1115#else
[email protected]252cad62010-08-18 18:33:571116inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
[email protected]7a4de7a62010-08-17 18:38:241117
1118template <class ReplyParamType>
1119inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
1120 const Message* msg) {}
1121
1122inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
1123#endif
1124
initial.commit09911bf2008-07-26 23:55:291125// This class assumes that its template argument is a RefTuple (a Tuple with
[email protected]7a4de7a62010-08-17 18:38:241126// reference elements). This would go into ipc_message_utils_impl.h, but it is
1127// also used by chrome_frame.
initial.commit09911bf2008-07-26 23:55:291128template <class RefTuple>
1129class ParamDeserializer : public MessageReplyDeserializer {
1130 public:
[email protected]e1981f432008-08-12 15:22:131131 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:291132
1133 bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
1134 return ReadParam(&msg, &iter, &out_);
1135 }
1136
1137 RefTuple out_;
1138};
1139
initial.commit09911bf2008-07-26 23:55:291140// Used for synchronous messages.
[email protected]75e5a872009-04-02 23:56:111141template <class SendParamType, class ReplyParamType>
initial.commit09911bf2008-07-26 23:55:291142class MessageWithReply : public SyncMessage {
1143 public:
[email protected]75e5a872009-04-02 23:56:111144 typedef SendParamType SendParam;
[email protected]7a4de7a62010-08-17 18:38:241145 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
[email protected]75e5a872009-04-02 23:56:111146 typedef ReplyParamType ReplyParam;
1147
[email protected]168ae922009-12-04 18:08:451148 MessageWithReply(int32 routing_id, uint32 type,
[email protected]7a4de7a62010-08-17 18:38:241149 const RefSendParam& send, const ReplyParam& reply);
1150 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
1151 static bool ReadReplyParam(
1152 const Message* msg,
1153 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:291154
[email protected]65412272010-12-21 20:03:241155 template<class T, class S, class Method>
1156 static bool Dispatch(const Message* msg, T* obj, S* sender, Method func) {
initial.commit09911bf2008-07-26 23:55:291157 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291158 Message* reply = GenerateReply(msg);
1159 bool error;
[email protected]7a4de7a62010-08-17 18:38:241160 if (ReadSendParam(msg, &send_params)) {
1161 typename TupleTypes<ReplyParam>::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:291162 DispatchToMethod(obj, func, send_params, &reply_params);
1163 WriteParam(reply, reply_params);
1164 error = false;
[email protected]7a4de7a62010-08-17 18:38:241165 LogReplyParamsToMessage(reply_params, msg);
initial.commit09911bf2008-07-26 23:55:291166 } else {
1167 NOTREACHED() << "Error deserializing message " << msg->type();
1168 reply->set_reply_error();
1169 error = true;
1170 }
1171
[email protected]65412272010-12-21 20:03:241172 sender->Send(reply);
initial.commit09911bf2008-07-26 23:55:291173 return !error;
1174 }
1175
1176 template<class T, class Method>
[email protected]7d5c3ac2009-02-04 08:58:191177 static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
initial.commit09911bf2008-07-26 23:55:291178 SendParam send_params;
initial.commit09911bf2008-07-26 23:55:291179 Message* reply = GenerateReply(msg);
1180 bool error;
[email protected]7a4de7a62010-08-17 18:38:241181 if (ReadSendParam(msg, &send_params)) {
initial.commit09911bf2008-07-26 23:55:291182 Tuple1<Message&> t = MakeRefTuple(*reply);
[email protected]7a4de7a62010-08-17 18:38:241183 ConnectMessageAndReply(msg, reply);
initial.commit09911bf2008-07-26 23:55:291184 DispatchToMethod(obj, func, send_params, &t);
1185 error = false;
1186 } else {
1187 NOTREACHED() << "Error deserializing message " << msg->type();
1188 reply->set_reply_error();
1189 obj->Send(reply);
1190 error = true;
1191 }
1192 return !error;
1193 }
1194
1195 template<typename TA>
1196 static void WriteReplyParams(Message* reply, TA a) {
1197 ReplyParam p(a);
1198 WriteParam(reply, p);
1199 }
1200
1201 template<typename TA, typename TB>
1202 static void WriteReplyParams(Message* reply, TA a, TB b) {
1203 ReplyParam p(a, b);
1204 WriteParam(reply, p);
1205 }
1206
1207 template<typename TA, typename TB, typename TC>
1208 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
1209 ReplyParam p(a, b, c);
1210 WriteParam(reply, p);
1211 }
1212
1213 template<typename TA, typename TB, typename TC, typename TD>
1214 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
1215 ReplyParam p(a, b, c, d);
1216 WriteParam(reply, p);
1217 }
1218
1219 template<typename TA, typename TB, typename TC, typename TD, typename TE>
1220 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
1221 ReplyParam p(a, b, c, d, e);
1222 WriteParam(reply, p);
1223 }
1224};
1225
[email protected]7d5c3ac2009-02-04 08:58:191226//-----------------------------------------------------------------------------
1227
[email protected]3178f4e22008-08-05 21:20:411228} // namespace IPC
initial.commit09911bf2008-07-26 23:55:291229
[email protected]946d1b22009-07-22 23:57:211230#endif // IPC_IPC_MESSAGE_UTILS_H_