blob: 1682e8108f5ef585ee4e2e32dd000796c5af05ef [file] [log] [blame]
[email protected]efb5f572012-01-29 10:57:331// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]946d1b22009-07-22 23:57:215#ifndef IPC_IPC_MESSAGE_UTILS_H_
6#define IPC_IPC_MESSAGE_UTILS_H_
[email protected]32b76ef2010-07-26 23:08:247#pragma once
initial.commit09911bf2008-07-26 23:55:298
[email protected]379e7a52010-03-09 00:38:419#include <algorithm>
initial.commit09911bf2008-07-26 23:55:2910#include <map>
[email protected]96da6962010-05-13 19:10:3411#include <set>
[email protected]663bd9e2011-03-21 01:07:0112#include <string>
13#include <vector>
initial.commit09911bf2008-07-26 23:55:2914
[email protected]dce5df52009-06-29 17:58:2515#include "base/format_macros.h"
[email protected]c410e022012-05-30 21:15:5716#include "base/platform_file.h"
[email protected]eb47a132009-03-04 00:39:5617#include "base/string16.h"
[email protected]6782f832011-05-10 04:06:0018#include "base/stringprintf.h"
[email protected]dce5df52009-06-29 17:58:2519#include "base/string_util.h"
initial.commit09911bf2008-07-26 23:55:2920#include "base/tuple.h"
[email protected]939856a2010-08-24 20:29:0221#include "ipc/ipc_param_traits.h"
[email protected]0cfe5dae2010-08-17 00:24:5422#include "ipc/ipc_sync_message.h"
[email protected]55b4e212010-08-13 20:43:5823
[email protected]7a4de7a62010-08-17 18:38:2424#if defined(COMPILER_GCC)
25// GCC "helpfully" tries to inline template methods in release mode. Except we
26// want the majority of the template junk being expanded once in the
27// implementation file (and only provide the definitions in
28// ipc_message_utils_impl.h in those files) and exported, instead of expanded
29// at every call site. Special note: GCC happily accepts the attribute before
30// the method declaration, but only acts on it if it is after.
[email protected]efafbbd2010-08-19 20:23:2531#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 40500
32// Starting in gcc 4.5, the noinline no longer implies the concept covered by
33// the introduced noclone attribute, which will create specialized versions of
34// functions/methods when certain types are constant.
35// www.gnu.org/software/gcc/gcc-4.5/changes.html
36#define IPC_MSG_NOINLINE __attribute__((noinline, noclone));
37#else
[email protected]7a4de7a62010-08-17 18:38:2438#define IPC_MSG_NOINLINE __attribute__((noinline));
[email protected]efafbbd2010-08-19 20:23:2539#endif
[email protected]7a4de7a62010-08-17 18:38:2440#elif defined(COMPILER_MSVC)
41// MSVC++ doesn't do this.
42#define IPC_MSG_NOINLINE
43#else
44#error "Please add the noinline property for your new compiler here."
45#endif
46
[email protected]f91cb992009-02-04 20:10:1247// Used by IPC_BEGIN_MESSAGES so that each message class starts from a unique
48// base. Messages have unique IDs across channels in order for the IPC logging
49// code to figure out the message class from its ID.
50enum IPCMessageStart {
[email protected]f91cb992009-02-04 20:10:1251 AutomationMsgStart = 0,
52 ViewMsgStart,
[email protected]f91cb992009-02-04 20:10:1253 PluginMsgStart,
[email protected]21fa3a12010-12-08 23:34:1654 ProfileImportMsgStart,
[email protected]f91cb992009-02-04 20:10:1255 TestMsgStart,
[email protected]21fa3a12010-12-08 23:34:1656 DevToolsMsgStart,
[email protected]eb47a132009-03-04 00:39:5657 WorkerMsgStart,
[email protected]21fa3a12010-12-08 23:34:1658 NaClMsgStart,
[email protected]60f14392009-12-15 20:46:3259 UtilityMsgStart,
[email protected]c0fc0942010-01-13 00:55:3760 GpuMsgStart,
[email protected]38fe1962010-07-31 07:57:0061 ServiceMsgStart,
[email protected]709a847e2010-11-10 01:16:1162 PpapiMsgStart,
[email protected]21fa3a12010-12-08 23:34:1663 FirefoxImporterUnittestMsgStart,
[email protected]9f547bf2010-12-13 17:00:4264 FileUtilitiesMsgStart,
65 MimeRegistryMsgStart,
[email protected]26a9acf2010-12-13 19:35:0566 DatabaseMsgStart,
[email protected]56879f932010-12-13 21:05:3767 DOMStorageMsgStart,
[email protected]2ba871b2010-12-13 21:11:0068 IndexedDBMsgStart,
[email protected]61e78f12010-12-15 21:03:5569 PepperFileMsgStart,
[email protected]c52b2892012-03-07 11:01:0270 SpeechRecognitionMsgStart,
[email protected]f0557932011-01-25 20:20:5171 PepperMsgStart,
[email protected]663bd9e2011-03-21 01:07:0172 AutofillMsgStart,
[email protected]fa685ff2011-02-17 19:47:1373 SafeBrowsingMsgStart,
[email protected]6c54e7e42011-03-02 20:52:3474 P2PMsgStart,
[email protected]db803aae2011-03-05 02:00:4275 SocketStreamMsgStart,
[email protected]94dc971d2011-03-05 19:08:3276 ResourceMsgStart,
[email protected]172f1552011-03-07 21:58:1677 FileSystemMsgStart,
[email protected]ff47b2962011-03-07 23:51:4978 ChildProcessMsgStart,
[email protected]7e3589742011-03-10 18:49:1779 ClipboardMsgStart,
[email protected]db10d8f2011-03-14 00:21:4780 BlobMsgStart,
[email protected]e93e04e2011-03-14 00:27:1081 AppCacheMsgStart,
[email protected]e7c21b812011-03-19 18:03:3082 DeviceOrientationMsgStart,
83 DesktopNotificationMsgStart,
84 GeolocationMsgStart,
[email protected]4460ee52011-03-21 19:19:2485 AudioMsgStart,
[email protected]778574e2011-03-21 22:03:5086 ChromeMsgStart,
[email protected]59f4f2fa2011-03-23 01:00:5587 DragMsgStart,
[email protected]1375e3ab2011-03-24 17:07:2288 PrintMsgStart,
[email protected]3e267192011-03-25 01:55:4589 SpellCheckMsgStart,
[email protected]44c49c92011-03-28 16:17:2390 ExtensionMsgStart,
[email protected]e1a59a22011-04-12 01:36:2591 VideoCaptureMsgStart,
[email protected]10e5cf12011-04-13 04:10:4092 QuotaMsgStart,
[email protected]ae4efe42011-04-18 21:28:0593 IconMsgStart,
[email protected]d4cff272011-05-02 15:46:0194 TextInputClientMsgStart,
[email protected]373c1062011-06-09 21:11:5195 ChromeUtilityMsgStart,
[email protected]47126542011-06-28 12:10:2096 MediaStreamMsgStart,
[email protected]6f08af82011-09-15 01:19:0397 ChromeBenchmarkingMsgStart,
[email protected]1ef93132011-09-16 18:33:4798 IntentsMsgStart,
[email protected]7f3c7af2011-10-20 22:52:5199 JavaBridgeMsgStart,
[email protected]7f5969d2011-10-28 18:42:42100 GamepadMsgStart,
[email protected]efb5f572012-01-29 10:57:33101 ShellMsgStart,
[email protected]68d53322012-02-13 21:29:01102 AccessibilityMsgStart,
[email protected]a0358d72012-03-09 14:06:50103 PrerenderMsgStart,
[email protected]c2b374402012-03-12 19:23:07104 ChromotingMsgStart,
[email protected]8dd709fb2012-04-06 00:49:06105 BrowserPluginMsgStart,
[email protected]e503a122011-03-17 18:20:52106 LastIPCMsgStart // Must come last.
[email protected]f91cb992009-02-04 20:10:12107};
108
[email protected]7a4de7a62010-08-17 18:38:24109class FilePath;
[email protected]7a4de7a62010-08-17 18:38:24110class NullableString16;
111
112namespace base {
[email protected]f3a1c642011-07-12 19:15:03113class DictionaryValue;
114class ListValue;
[email protected]7a4de7a62010-08-17 18:38:24115class Time;
[email protected]d84e48b2010-10-21 22:04:52116class TimeDelta;
[email protected]1d14f582011-09-02 20:42:04117class TimeTicks;
[email protected]7a4de7a62010-08-17 18:38:24118struct FileDescriptor;
119}
120
initial.commit09911bf2008-07-26 23:55:29121namespace IPC {
122
[email protected]7a4de7a62010-08-17 18:38:24123struct ChannelHandle;
124
initial.commit09911bf2008-07-26 23:55:29125//-----------------------------------------------------------------------------
126// An iterator class for reading the fields contained within a Message.
[email protected]bf5aedf02012-06-04 21:18:25127class IPC_EXPORT MessageIterator {
initial.commit09911bf2008-07-26 23:55:29128 public:
[email protected]bf5aedf02012-06-04 21:18:25129 explicit MessageIterator(const Message& m);
130
131 int NextInt() const;
132 const std::string NextString() const;
133
initial.commit09911bf2008-07-26 23:55:29134 private:
[email protected]ce208f872012-03-07 20:42:56135 mutable PickleIterator iter_;
initial.commit09911bf2008-07-26 23:55:29136};
137
[email protected]bf5aedf02012-06-04 21:18:25138// -----------------------------------------------------------------------------
139// How we send IPC message logs across channels.
140struct IPC_EXPORT LogData {
141 LogData();
142 ~LogData();
143
144 std::string channel;
145 int32 routing_id;
146 uint32 type; // "User-defined" message type, from ipc_message.h.
147 std::string flags;
148 int64 sent; // Time that the message was sent (i.e. at Send()).
149 int64 receive; // Time before it was dispatched (i.e. before calling
150 // OnMessageReceived).
151 int64 dispatch; // Time after it was dispatched (i.e. after calling
152 // OnMessageReceived).
153 std::string message_name;
154 std::string params;
155};
156
157
initial.commit09911bf2008-07-26 23:55:29158//-----------------------------------------------------------------------------
[email protected]6476c72c2011-02-11 18:46:19159// A dummy struct to place first just to allow leading commas for all
160// members in the macro-generated constructor initializer lists.
161struct NoParams {
162};
163
[email protected]7d5c3ac2009-02-04 08:58:19164template <class P>
165static inline void WriteParam(Message* m, const P& p) {
[email protected]7b291f92009-08-14 05:43:53166 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53167 ParamTraits<Type>::Write(m, static_cast<const Type& >(p));
[email protected]7d5c3ac2009-02-04 08:58:19168}
169
170template <class P>
[email protected]ce208f872012-03-07 20:42:56171static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m,
172 PickleIterator* iter,
[email protected]1e86aa62009-04-24 21:22:33173 P* p) {
[email protected]7b291f92009-08-14 05:43:53174 typedef typename SimilarTypeTraits<P>::Type Type;
175 return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p));
[email protected]7d5c3ac2009-02-04 08:58:19176}
177
178template <class P>
[email protected]252cad62010-08-18 18:33:57179static inline void LogParam(const P& p, std::string* l) {
[email protected]7b291f92009-08-14 05:43:53180 typedef typename SimilarTypeTraits<P>::Type Type;
[email protected]46ce5b562010-06-16 18:39:53181 ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
[email protected]7d5c3ac2009-02-04 08:58:19182}
183
[email protected]bf5aedf02012-06-04 21:18:25184// Primitive ParamTraits -------------------------------------------------------
185
[email protected]7d5c3ac2009-02-04 08:58:19186template <>
187struct ParamTraits<bool> {
188 typedef bool param_type;
189 static void Write(Message* m, const param_type& p) {
190 m->WriteBool(p);
191 }
[email protected]bf5aedf02012-06-04 21:18:25192 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19193 return m->ReadBool(iter, r);
194 }
[email protected]bf5aedf02012-06-04 21:18:25195 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19196};
197
198template <>
199struct ParamTraits<int> {
200 typedef int param_type;
201 static void Write(Message* m, const param_type& p) {
202 m->WriteInt(p);
203 }
[email protected]bf5aedf02012-06-04 21:18:25204 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19205 return m->ReadInt(iter, r);
206 }
[email protected]7c854372011-08-15 20:41:46207 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19208};
209
210template <>
[email protected]63263f92009-07-28 19:35:08211struct ParamTraits<unsigned int> {
212 typedef unsigned int param_type;
213 static void Write(Message* m, const param_type& p) {
214 m->WriteInt(p);
215 }
[email protected]bf5aedf02012-06-04 21:18:25216 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]63263f92009-07-28 19:35:08217 return m->ReadInt(iter, reinterpret_cast<int*>(r));
218 }
[email protected]7c854372011-08-15 20:41:46219 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08220};
221
222template <>
[email protected]7d5c3ac2009-02-04 08:58:19223struct ParamTraits<long> {
224 typedef long param_type;
225 static void Write(Message* m, const param_type& p) {
[email protected]c272d082012-03-23 00:03:10226 m->WriteLongUsingDangerousNonPortableLessPersistableForm(p);
[email protected]7d5c3ac2009-02-04 08:58:19227 }
[email protected]bf5aedf02012-06-04 21:18:25228 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19229 return m->ReadLong(iter, r);
230 }
[email protected]7c854372011-08-15 20:41:46231 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19232};
233
[email protected]140c3032009-06-26 18:22:54234template <>
235struct ParamTraits<unsigned long> {
236 typedef unsigned long param_type;
237 static void Write(Message* m, const param_type& p) {
[email protected]c272d082012-03-23 00:03:10238 m->WriteLongUsingDangerousNonPortableLessPersistableForm(p);
[email protected]140c3032009-06-26 18:22:54239 }
[email protected]bf5aedf02012-06-04 21:18:25240 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]63263f92009-07-28 19:35:08241 return m->ReadLong(iter, reinterpret_cast<long*>(r));
[email protected]140c3032009-06-26 18:22:54242 }
[email protected]7c854372011-08-15 20:41:46243 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19244};
245
246template <>
[email protected]63263f92009-07-28 19:35:08247struct ParamTraits<long long> {
248 typedef long long param_type;
[email protected]7d5c3ac2009-02-04 08:58:19249 static void Write(Message* m, const param_type& p) {
250 m->WriteInt64(static_cast<int64>(p));
251 }
[email protected]ce208f872012-03-07 20:42:56252 static bool Read(const Message* m, PickleIterator* iter,
253 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19254 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
255 }
[email protected]7c854372011-08-15 20:41:46256 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]63263f92009-07-28 19:35:08257};
258
259template <>
260struct ParamTraits<unsigned long long> {
261 typedef unsigned long long param_type;
262 static void Write(Message* m, const param_type& p) {
263 m->WriteInt64(p);
264 }
[email protected]ce208f872012-03-07 20:42:56265 static bool Read(const Message* m, PickleIterator* iter,
266 param_type* r) {
[email protected]63263f92009-07-28 19:35:08267 return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
268 }
[email protected]7c854372011-08-15 20:41:46269 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19270};
271
[email protected]43a40202010-11-12 16:25:01272template <>
[email protected]7c854372011-08-15 20:41:46273struct IPC_EXPORT ParamTraits<unsigned short> {
[email protected]43a40202010-11-12 16:25:01274 typedef unsigned short param_type;
275 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56276 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]43a40202010-11-12 16:25:01277 static void Log(const param_type& p, std::string* l);
278};
279
[email protected]20199662010-06-17 03:29:26280// Note that the IPC layer doesn't sanitize NaNs and +/- INF values. Clients
281// should be sure to check the sanity of these values after receiving them over
282// IPC.
283template <>
[email protected]bf5aedf02012-06-04 21:18:25284struct IPC_EXPORT ParamTraits<float> {
[email protected]20199662010-06-17 03:29:26285 typedef float param_type;
[email protected]bf5aedf02012-06-04 21:18:25286 static void Write(Message* m, const param_type& p);
287 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
288 static void Log(const param_type& p, std::string* l);
[email protected]20199662010-06-17 03:29:26289};
290
[email protected]7d5c3ac2009-02-04 08:58:19291template <>
[email protected]bf5aedf02012-06-04 21:18:25292struct IPC_EXPORT ParamTraits<double> {
[email protected]7d5c3ac2009-02-04 08:58:19293 typedef double param_type;
[email protected]c410e022012-05-30 21:15:57294 static void Write(Message* m, const param_type& p);
295 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
296 static void Log(const param_type& p, std::string* l);
297};
298
[email protected]bf5aedf02012-06-04 21:18:25299// STL ParamTraits -------------------------------------------------------------
[email protected]584f2b22009-05-21 01:01:59300
301template <>
[email protected]7d5c3ac2009-02-04 08:58:19302struct ParamTraits<std::string> {
303 typedef std::string param_type;
304 static void Write(Message* m, const param_type& p) {
305 m->WriteString(p);
306 }
[email protected]ce208f872012-03-07 20:42:56307 static bool Read(const Message* m, PickleIterator* iter,
308 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19309 return m->ReadString(iter, r);
310 }
[email protected]bf5aedf02012-06-04 21:18:25311 IPC_EXPORT static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19312};
313
[email protected]bf5aedf02012-06-04 21:18:25314template <>
315struct ParamTraits<std::wstring> {
316 typedef std::wstring param_type;
317 static void Write(Message* m, const param_type& p) {
318 m->WriteWString(p);
[email protected]3dd7a7a2009-07-27 21:09:07319 }
[email protected]bf5aedf02012-06-04 21:18:25320 static bool Read(const Message* m, PickleIterator* iter,
321 param_type* r) {
322 return m->ReadWString(iter, r);
[email protected]3dd7a7a2009-07-27 21:09:07323 }
[email protected]bf5aedf02012-06-04 21:18:25324 IPC_EXPORT static void Log(const param_type& p, std::string* l);
325};
326
327// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
328// need this trait.
329#if !defined(WCHAR_T_IS_UTF16)
330template <>
331struct ParamTraits<string16> {
332 typedef string16 param_type;
333 static void Write(Message* m, const param_type& p) {
334 m->WriteString16(p);
335 }
336 static bool Read(const Message* m, PickleIterator* iter,
337 param_type* r) {
338 return m->ReadString16(iter, r);
339 }
340 IPC_EXPORT static void Log(const param_type& p, std::string* l);
341};
[email protected]3dd7a7a2009-07-27 21:09:07342#endif
[email protected]3dd7a7a2009-07-27 21:09:07343
[email protected]7d5c3ac2009-02-04 08:58:19344template <>
[email protected]bf5aedf02012-06-04 21:18:25345struct IPC_EXPORT ParamTraits<std::vector<char> > {
[email protected]7d5c3ac2009-02-04 08:58:19346 typedef std::vector<char> param_type;
[email protected]bf5aedf02012-06-04 21:18:25347 static void Write(Message* m, const param_type& p);
348 static bool Read(const Message*, PickleIterator* iter, param_type* r);
349 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19350};
351
[email protected]51b63f62011-10-05 18:55:42352template <>
[email protected]bf5aedf02012-06-04 21:18:25353struct IPC_EXPORT ParamTraits<std::vector<unsigned char> > {
354 typedef std::vector<unsigned char> param_type;
355 static void Write(Message* m, const param_type& p);
356 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
357 static void Log(const param_type& p, std::string* l);
358};
359
360template <>
361struct IPC_EXPORT ParamTraits<std::vector<bool> > {
[email protected]51b63f62011-10-05 18:55:42362 typedef std::vector<bool> param_type;
[email protected]bf5aedf02012-06-04 21:18:25363 static void Write(Message* m, const param_type& p);
364 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
365 static void Log(const param_type& p, std::string* l);
[email protected]51b63f62011-10-05 18:55:42366};
367
[email protected]7d5c3ac2009-02-04 08:58:19368template <class P>
369struct ParamTraits<std::vector<P> > {
370 typedef std::vector<P> param_type;
371 static void Write(Message* m, const param_type& p) {
372 WriteParam(m, static_cast<int>(p.size()));
373 for (size_t i = 0; i < p.size(); i++)
374 WriteParam(m, p[i]);
375 }
[email protected]ce208f872012-03-07 20:42:56376 static bool Read(const Message* m, PickleIterator* iter,
377 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19378 int size;
[email protected]86440f52009-12-31 05:17:23379 // ReadLength() checks for < 0 itself.
[email protected]7d5c3ac2009-02-04 08:58:19380 if (!m->ReadLength(iter, &size))
381 return false;
382 // Resizing beforehand is not safe, see BUG 1006367 for details.
[email protected]86440f52009-12-31 05:17:23383 if (INT_MAX / sizeof(P) <= static_cast<size_t>(size))
384 return false;
385 r->resize(size);
386 for (int i = 0; i < size; i++) {
387 if (!ReadParam(m, iter, &(*r)[i]))
388 return false;
[email protected]7d5c3ac2009-02-04 08:58:19389 }
390 return true;
391 }
[email protected]252cad62010-08-18 18:33:57392 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19393 for (size_t i = 0; i < p.size(); ++i) {
394 if (i != 0)
[email protected]252cad62010-08-18 18:33:57395 l->append(" ");
[email protected]7d5c3ac2009-02-04 08:58:19396 LogParam((p[i]), l);
397 }
398 }
399};
400
[email protected]96da6962010-05-13 19:10:34401template <class P>
402struct ParamTraits<std::set<P> > {
403 typedef std::set<P> param_type;
404 static void Write(Message* m, const param_type& p) {
405 WriteParam(m, static_cast<int>(p.size()));
406 typename param_type::const_iterator iter;
407 for (iter = p.begin(); iter != p.end(); ++iter)
408 WriteParam(m, *iter);
409 }
[email protected]ce208f872012-03-07 20:42:56410 static bool Read(const Message* m, PickleIterator* iter,
411 param_type* r) {
[email protected]96da6962010-05-13 19:10:34412 int size;
413 if (!m->ReadLength(iter, &size))
414 return false;
415 for (int i = 0; i < size; ++i) {
416 P item;
417 if (!ReadParam(m, iter, &item))
418 return false;
419 r->insert(item);
420 }
421 return true;
422 }
[email protected]252cad62010-08-18 18:33:57423 static void Log(const param_type& p, std::string* l) {
424 l->append("<std::set>");
[email protected]96da6962010-05-13 19:10:34425 }
426};
427
[email protected]7d5c3ac2009-02-04 08:58:19428template <class K, class V>
429struct ParamTraits<std::map<K, V> > {
430 typedef std::map<K, V> param_type;
431 static void Write(Message* m, const param_type& p) {
432 WriteParam(m, static_cast<int>(p.size()));
433 typename param_type::const_iterator iter;
434 for (iter = p.begin(); iter != p.end(); ++iter) {
435 WriteParam(m, iter->first);
436 WriteParam(m, iter->second);
437 }
438 }
[email protected]ce208f872012-03-07 20:42:56439 static bool Read(const Message* m, PickleIterator* iter,
440 param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19441 int size;
442 if (!ReadParam(m, iter, &size) || size < 0)
443 return false;
444 for (int i = 0; i < size; ++i) {
445 K k;
446 if (!ReadParam(m, iter, &k))
447 return false;
448 V& value = (*r)[k];
449 if (!ReadParam(m, iter, &value))
450 return false;
451 }
452 return true;
453 }
[email protected]252cad62010-08-18 18:33:57454 static void Log(const param_type& p, std::string* l) {
455 l->append("<std::map>");
[email protected]7d5c3ac2009-02-04 08:58:19456 }
457};
458
[email protected]a5da6d612009-08-04 02:00:56459template <class A, class B>
460struct ParamTraits<std::pair<A, B> > {
461 typedef std::pair<A, B> param_type;
462 static void Write(Message* m, const param_type& p) {
463 WriteParam(m, p.first);
464 WriteParam(m, p.second);
465 }
[email protected]ce208f872012-03-07 20:42:56466 static bool Read(const Message* m, PickleIterator* iter,
467 param_type* r) {
[email protected]a5da6d612009-08-04 02:00:56468 return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second);
469 }
[email protected]252cad62010-08-18 18:33:57470 static void Log(const param_type& p, std::string* l) {
471 l->append("(");
[email protected]a5da6d612009-08-04 02:00:56472 LogParam(p.first, l);
[email protected]252cad62010-08-18 18:33:57473 l->append(", ");
[email protected]a5da6d612009-08-04 02:00:56474 LogParam(p.second, l);
[email protected]252cad62010-08-18 18:33:57475 l->append(")");
[email protected]a5da6d612009-08-04 02:00:56476 }
477};
478
[email protected]bf5aedf02012-06-04 21:18:25479// Base ParamTraits ------------------------------------------------------------
[email protected]7d5c3ac2009-02-04 08:58:19480
481template <>
[email protected]bf5aedf02012-06-04 21:18:25482struct IPC_EXPORT ParamTraits<base::DictionaryValue> {
483 typedef base::DictionaryValue param_type;
[email protected]7a4de7a62010-08-17 18:38:24484 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56485 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57486 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19487};
488
[email protected]526776c2009-02-07 00:39:26489#if defined(OS_POSIX)
[email protected]2749885f2009-03-05 21:40:11490// FileDescriptors may be serialised over IPC channels on POSIX. On the
491// receiving side, the FileDescriptor is a valid duplicate of the file
492// descriptor which was transmitted: *it is not just a copy of the integer like
493// HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
494// this case, the receiving end will see a value of -1. *Zero is a valid file
495// descriptor*.
496//
497// The received file descriptor will have the |auto_close| flag set to true. The
498// code which handles the message is responsible for taking ownership of it.
499// File descriptors are OS resources and must be closed when no longer needed.
500//
501// When sending a file descriptor, the file descriptor must be valid at the time
502// of transmission. Since transmission is not synchronous, one should consider
503// dup()ing any file descriptors to be transmitted and setting the |auto_close|
504// flag, which causes the file descriptor to be closed after writing.
[email protected]526776c2009-02-07 00:39:26505template<>
[email protected]7c854372011-08-15 20:41:46506struct IPC_EXPORT ParamTraits<base::FileDescriptor> {
[email protected]5fe733de2009-02-11 18:59:20507 typedef base::FileDescriptor param_type;
[email protected]7a4de7a62010-08-17 18:38:24508 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56509 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57510 static void Log(const param_type& p, std::string* l);
[email protected]526776c2009-02-07 00:39:26511};
[email protected]379e7a52010-03-09 00:38:41512#endif // defined(OS_POSIX)
[email protected]526776c2009-02-07 00:39:26513
[email protected]bf5aedf02012-06-04 21:18:25514template <>
515struct IPC_EXPORT ParamTraits<FilePath> {
516 typedef FilePath param_type;
[email protected]7a4de7a62010-08-17 18:38:24517 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56518 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]252cad62010-08-18 18:33:57519 static void Log(const param_type& p, std::string* l);
[email protected]d2e884d2009-06-22 20:37:52520};
521
[email protected]7d5c3ac2009-02-04 08:58:19522template <>
[email protected]bf5aedf02012-06-04 21:18:25523struct IPC_EXPORT ParamTraits<base::ListValue> {
524 typedef base::ListValue param_type;
[email protected]20f0487a2010-09-30 20:06:30525 static void Write(Message* m, const param_type& p);
[email protected]ce208f872012-03-07 20:42:56526 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
[email protected]bf5aedf02012-06-04 21:18:25527 static void Log(const param_type& p, std::string* l);
[email protected]7d5c3ac2009-02-04 08:58:19528};
529
[email protected]eb47a132009-03-04 00:39:56530template <>
[email protected]bf5aedf02012-06-04 21:18:25531struct IPC_EXPORT ParamTraits<NullableString16> {
532 typedef NullableString16 param_type;
533 static void Write(Message* m, const param_type& p);
534 static bool Read(const Message* m, PickleIterator* iter,
535 param_type* r);
536 static void Log(const param_type& p, std::string* l);
537};
538
539template <>
540struct IPC_EXPORT ParamTraits<base::PlatformFileInfo> {
541 typedef base::PlatformFileInfo param_type;
542 static void Write(Message* m, const param_type& p);
543 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
544 static void Log(const param_type& p, std::string* l);
545};
546
547template <>
548struct SimilarTypeTraits<base::PlatformFileError> {
549 typedef int Type;
550};
551
552template <>
553struct IPC_EXPORT ParamTraits<base::Time> {
554 typedef base::Time param_type;
555 static void Write(Message* m, const param_type& p);
556 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
557 static void Log(const param_type& p, std::string* l);
558};
559
560template <>
561struct IPC_EXPORT ParamTraits<base::TimeDelta> {
562 typedef base::TimeDelta param_type;
563 static void Write(Message* m, const param_type& p);
564 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
565 static void Log(const param_type& p, std::string* l);
566};
567
568template <>
569struct IPC_EXPORT ParamTraits<base::TimeTicks> {
570 typedef base::TimeTicks param_type;
571 static void Write(Message* m, const param_type& p);
572 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
573 static void Log(const param_type& p, std::string* l);
[email protected]503683f2009-02-26 09:13:01574};
575
576template <>
[email protected]7d5c3ac2009-02-04 08:58:19577struct ParamTraits<Tuple0> {
578 typedef Tuple0 param_type;
579 static void Write(Message* m, const param_type& p) {
580 }
[email protected]ce208f872012-03-07 20:42:56581 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19582 return true;
583 }
[email protected]252cad62010-08-18 18:33:57584 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19585 }
586};
587
588template <class A>
589struct ParamTraits< Tuple1<A> > {
590 typedef Tuple1<A> param_type;
591 static void Write(Message* m, const param_type& p) {
592 WriteParam(m, p.a);
593 }
[email protected]ce208f872012-03-07 20:42:56594 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19595 return ReadParam(m, iter, &r->a);
596 }
[email protected]252cad62010-08-18 18:33:57597 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19598 LogParam(p.a, l);
599 }
600};
601
602template <class A, class B>
603struct ParamTraits< Tuple2<A, B> > {
604 typedef Tuple2<A, B> param_type;
605 static void Write(Message* m, const param_type& p) {
606 WriteParam(m, p.a);
607 WriteParam(m, p.b);
608 }
[email protected]ce208f872012-03-07 20:42:56609 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19610 return (ReadParam(m, iter, &r->a) &&
611 ReadParam(m, iter, &r->b));
612 }
[email protected]252cad62010-08-18 18:33:57613 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19614 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57615 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19616 LogParam(p.b, l);
617 }
618};
619
620template <class A, class B, class C>
621struct ParamTraits< Tuple3<A, B, C> > {
622 typedef Tuple3<A, B, C> param_type;
623 static void Write(Message* m, const param_type& p) {
624 WriteParam(m, p.a);
625 WriteParam(m, p.b);
626 WriteParam(m, p.c);
627 }
[email protected]ce208f872012-03-07 20:42:56628 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19629 return (ReadParam(m, iter, &r->a) &&
630 ReadParam(m, iter, &r->b) &&
631 ReadParam(m, iter, &r->c));
632 }
[email protected]252cad62010-08-18 18:33:57633 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19634 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57635 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19636 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57637 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19638 LogParam(p.c, l);
639 }
640};
641
642template <class A, class B, class C, class D>
643struct ParamTraits< Tuple4<A, B, C, D> > {
644 typedef Tuple4<A, B, C, D> param_type;
645 static void Write(Message* m, const param_type& p) {
646 WriteParam(m, p.a);
647 WriteParam(m, p.b);
648 WriteParam(m, p.c);
649 WriteParam(m, p.d);
650 }
[email protected]ce208f872012-03-07 20:42:56651 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19652 return (ReadParam(m, iter, &r->a) &&
653 ReadParam(m, iter, &r->b) &&
654 ReadParam(m, iter, &r->c) &&
655 ReadParam(m, iter, &r->d));
656 }
[email protected]252cad62010-08-18 18:33:57657 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19658 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57659 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19660 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57661 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19662 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57663 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19664 LogParam(p.d, l);
665 }
666};
667
668template <class A, class B, class C, class D, class E>
669struct ParamTraits< Tuple5<A, B, C, D, E> > {
670 typedef Tuple5<A, B, C, D, E> param_type;
671 static void Write(Message* m, const param_type& p) {
672 WriteParam(m, p.a);
673 WriteParam(m, p.b);
674 WriteParam(m, p.c);
675 WriteParam(m, p.d);
676 WriteParam(m, p.e);
677 }
[email protected]ce208f872012-03-07 20:42:56678 static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
[email protected]7d5c3ac2009-02-04 08:58:19679 return (ReadParam(m, iter, &r->a) &&
680 ReadParam(m, iter, &r->b) &&
681 ReadParam(m, iter, &r->c) &&
682 ReadParam(m, iter, &r->d) &&
683 ReadParam(m, iter, &r->e));
684 }
[email protected]252cad62010-08-18 18:33:57685 static void Log(const param_type& p, std::string* l) {
[email protected]7d5c3ac2009-02-04 08:58:19686 LogParam(p.a, l);
[email protected]252cad62010-08-18 18:33:57687 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19688 LogParam(p.b, l);
[email protected]252cad62010-08-18 18:33:57689 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19690 LogParam(p.c, l);
[email protected]252cad62010-08-18 18:33:57691 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19692 LogParam(p.d, l);
[email protected]252cad62010-08-18 18:33:57693 l->append(", ");
[email protected]7d5c3ac2009-02-04 08:58:19694 LogParam(p.e, l);
695 }
696};
697
[email protected]bf5aedf02012-06-04 21:18:25698// IPC types ParamTraits -------------------------------------------------------
699
700// A ChannelHandle is basically a platform-inspecific wrapper around the
701// fact that IPC endpoints are handled specially on POSIX. See above comments
702// on FileDescriptor for more background.
703template<>
704struct IPC_EXPORT ParamTraits<IPC::ChannelHandle> {
705 typedef ChannelHandle param_type;
706 static void Write(Message* m, const param_type& p);
707 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
708 static void Log(const param_type& p, std::string* l);
709};
710
711template <>
712struct IPC_EXPORT ParamTraits<LogData> {
713 typedef LogData param_type;
714 static void Write(Message* m, const param_type& p);
715 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
716 static void Log(const param_type& p, std::string* l);
717};
718
719template <>
720struct IPC_EXPORT ParamTraits<Message> {
721 static void Write(Message* m, const Message& p);
722 static bool Read(const Message* m, PickleIterator* iter, Message* r);
723 static void Log(const Message& p, std::string* l);
724};
725
726// Windows ParamTraits ---------------------------------------------------------
727
728#if defined(OS_WIN)
729template <>
730struct IPC_EXPORT ParamTraits<HANDLE> {
731 typedef HANDLE param_type;
732 static void Write(Message* m, const param_type& p);
733 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
734 static void Log(const param_type& p, std::string* l);
735};
736
737template <>
738struct IPC_EXPORT ParamTraits<LOGFONT> {
739 typedef LOGFONT param_type;
740 static void Write(Message* m, const param_type& p);
741 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
742 static void Log(const param_type& p, std::string* l);
743};
744
745template <>
746struct IPC_EXPORT ParamTraits<MSG> {
747 typedef MSG param_type;
748 static void Write(Message* m, const param_type& p);
749 static bool Read(const Message* m, PickleIterator* iter, param_type* r);
750 static void Log(const param_type& p, std::string* l);
751};
752#endif // defined(OS_WIN)
753
[email protected]7d5c3ac2009-02-04 08:58:19754//-----------------------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:29755// Generic message subclasses
756
757// Used for asynchronous messages.
[email protected]81a34412009-01-05 19:17:24758template <class ParamType>
[email protected]1d4ecf42011-08-26 21:27:30759class MessageSchema {
initial.commit09911bf2008-07-26 23:55:29760 public:
[email protected]81a34412009-01-05 19:17:24761 typedef ParamType Param;
[email protected]7a4de7a62010-08-17 18:38:24762 typedef typename TupleTypes<ParamType>::ParamTuple RefParam;
[email protected]81a34412009-01-05 19:17:24763
[email protected]1d4ecf42011-08-26 21:27:30764 static void Write(Message* msg, const RefParam& p) IPC_MSG_NOINLINE;
[email protected]7a4de7a62010-08-17 18:38:24765 static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:29766};
767
[email protected]7a4de7a62010-08-17 18:38:24768// defined in ipc_logging.cc
[email protected]7c854372011-08-15 20:41:46769IPC_EXPORT void GenerateLogData(const std::string& channel,
770 const Message& message,
[email protected]ea7744a2011-10-20 19:34:43771 LogData* data, bool get_params);
[email protected]7a4de7a62010-08-17 18:38:24772
773
774#if defined(IPC_MESSAGE_LOG_ENABLED)
[email protected]252cad62010-08-18 18:33:57775inline void AddOutputParamsToLog(const Message* msg, std::string* l) {
776 const std::string& output_params = msg->output_params();
[email protected]7a4de7a62010-08-17 18:38:24777 if (!l->empty() && !output_params.empty())
[email protected]252cad62010-08-18 18:33:57778 l->append(", ");
[email protected]7a4de7a62010-08-17 18:38:24779
780 l->append(output_params);
781}
782
783template <class ReplyParamType>
784inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
785 const Message* msg) {
786 if (msg->received_time() != 0) {
[email protected]252cad62010-08-18 18:33:57787 std::string output_params;
[email protected]7a4de7a62010-08-17 18:38:24788 LogParam(reply_params, &output_params);
789 msg->set_output_params(output_params);
790 }
791}
792
793inline void ConnectMessageAndReply(const Message* msg, Message* reply) {
794 if (msg->sent_time()) {
795 // Don't log the sync message after dispatch, as we don't have the
796 // output parameters at that point. Instead, save its data and log it
797 // with the outgoing reply message when it's sent.
798 LogData* data = new LogData;
[email protected]ea7744a2011-10-20 19:34:43799 GenerateLogData("", *msg, data, true);
[email protected]7a4de7a62010-08-17 18:38:24800 msg->set_dont_log();
801 reply->set_sync_log_data(data);
802 }
803}
804#else
[email protected]252cad62010-08-18 18:33:57805inline void AddOutputParamsToLog(const Message* msg, std::string* l) {}
[email protected]7a4de7a62010-08-17 18:38:24806
807template <class ReplyParamType>
808inline void LogReplyParamsToMessage(const ReplyParamType& reply_params,
809 const Message* msg) {}
810
811inline void ConnectMessageAndReply(const Message* msg, Message* reply) {}
812#endif
813
initial.commit09911bf2008-07-26 23:55:29814// This class assumes that its template argument is a RefTuple (a Tuple with
[email protected]7a4de7a62010-08-17 18:38:24815// reference elements). This would go into ipc_message_utils_impl.h, but it is
816// also used by chrome_frame.
initial.commit09911bf2008-07-26 23:55:29817template <class RefTuple>
818class ParamDeserializer : public MessageReplyDeserializer {
819 public:
[email protected]e1981f432008-08-12 15:22:13820 explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
initial.commit09911bf2008-07-26 23:55:29821
[email protected]ce208f872012-03-07 20:42:56822 bool SerializeOutputParameters(const IPC::Message& msg, PickleIterator iter) {
initial.commit09911bf2008-07-26 23:55:29823 return ReadParam(&msg, &iter, &out_);
824 }
825
826 RefTuple out_;
827};
828
initial.commit09911bf2008-07-26 23:55:29829// Used for synchronous messages.
[email protected]75e5a872009-04-02 23:56:11830template <class SendParamType, class ReplyParamType>
[email protected]1d4ecf42011-08-26 21:27:30831class SyncMessageSchema {
initial.commit09911bf2008-07-26 23:55:29832 public:
[email protected]75e5a872009-04-02 23:56:11833 typedef SendParamType SendParam;
[email protected]7a4de7a62010-08-17 18:38:24834 typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam;
[email protected]75e5a872009-04-02 23:56:11835 typedef ReplyParamType ReplyParam;
836
[email protected]1d4ecf42011-08-26 21:27:30837 static void Write(Message* msg, const RefSendParam& send) IPC_MSG_NOINLINE;
[email protected]7a4de7a62010-08-17 18:38:24838 static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE;
839 static bool ReadReplyParam(
840 const Message* msg,
841 typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE;
initial.commit09911bf2008-07-26 23:55:29842
[email protected]65412272010-12-21 20:03:24843 template<class T, class S, class Method>
[email protected]1d4ecf42011-08-26 21:27:30844 static bool DispatchWithSendParams(bool ok, const SendParam& send_params,
845 const Message* msg, T* obj, S* sender,
846 Method func) {
847 Message* reply = SyncMessage::GenerateReply(msg);
848 if (ok) {
[email protected]7a4de7a62010-08-17 18:38:24849 typename TupleTypes<ReplyParam>::ValueTuple reply_params;
initial.commit09911bf2008-07-26 23:55:29850 DispatchToMethod(obj, func, send_params, &reply_params);
851 WriteParam(reply, reply_params);
[email protected]7a4de7a62010-08-17 18:38:24852 LogReplyParamsToMessage(reply_params, msg);
initial.commit09911bf2008-07-26 23:55:29853 } else {
854 NOTREACHED() << "Error deserializing message " << msg->type();
855 reply->set_reply_error();
initial.commit09911bf2008-07-26 23:55:29856 }
[email protected]65412272010-12-21 20:03:24857 sender->Send(reply);
[email protected]1d4ecf42011-08-26 21:27:30858 return ok;
initial.commit09911bf2008-07-26 23:55:29859 }
860
861 template<class T, class Method>
[email protected]1d4ecf42011-08-26 21:27:30862 static bool DispatchDelayReplyWithSendParams(bool ok,
863 const SendParam& send_params,
864 const Message* msg, T* obj,
865 Method func) {
866 Message* reply = SyncMessage::GenerateReply(msg);
867 if (ok) {
initial.commit09911bf2008-07-26 23:55:29868 Tuple1<Message&> t = MakeRefTuple(*reply);
[email protected]7a4de7a62010-08-17 18:38:24869 ConnectMessageAndReply(msg, reply);
initial.commit09911bf2008-07-26 23:55:29870 DispatchToMethod(obj, func, send_params, &t);
initial.commit09911bf2008-07-26 23:55:29871 } else {
872 NOTREACHED() << "Error deserializing message " << msg->type();
873 reply->set_reply_error();
874 obj->Send(reply);
initial.commit09911bf2008-07-26 23:55:29875 }
[email protected]1d4ecf42011-08-26 21:27:30876 return ok;
initial.commit09911bf2008-07-26 23:55:29877 }
878
879 template<typename TA>
880 static void WriteReplyParams(Message* reply, TA a) {
881 ReplyParam p(a);
882 WriteParam(reply, p);
883 }
884
885 template<typename TA, typename TB>
886 static void WriteReplyParams(Message* reply, TA a, TB b) {
887 ReplyParam p(a, b);
888 WriteParam(reply, p);
889 }
890
891 template<typename TA, typename TB, typename TC>
892 static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
893 ReplyParam p(a, b, c);
894 WriteParam(reply, p);
895 }
896
897 template<typename TA, typename TB, typename TC, typename TD>
898 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
899 ReplyParam p(a, b, c, d);
900 WriteParam(reply, p);
901 }
902
903 template<typename TA, typename TB, typename TC, typename TD, typename TE>
904 static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
905 ReplyParam p(a, b, c, d, e);
906 WriteParam(reply, p);
907 }
908};
909
[email protected]3178f4e22008-08-05 21:20:41910} // namespace IPC
initial.commit09911bf2008-07-26 23:55:29911
[email protected]946d1b22009-07-22 23:57:21912#endif // IPC_IPC_MESSAGE_UTILS_H_