LCOV - code coverage report
Current view: directory - ipc/chromium/src/chrome/common - ipc_message_utils.h (source / functions) Found Hit Coverage
Test: app.info Lines: 128 0 0.0 %
Date: 2012-06-02 Functions: 249 0 0.0 %

       1                 : // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
       2                 : // Use of this source code is governed by a BSD-style license that can be
       3                 : // found in the LICENSE file.
       4                 : 
       5                 : #ifndef CHROME_COMMON_IPC_MESSAGE_UTILS_H_
       6                 : #define CHROME_COMMON_IPC_MESSAGE_UTILS_H_
       7                 : 
       8                 : #include <string>
       9                 : #include <vector>
      10                 : #include <map>
      11                 : 
      12                 : #include "base/file_path.h"
      13                 : #include "base/string_util.h"
      14                 : #include "base/string16.h"
      15                 : #include "base/tuple.h"
      16                 : 
      17                 : #if defined(OS_POSIX)
      18                 : #include "chrome/common/file_descriptor_set_posix.h"
      19                 : #endif
      20                 : #include "chrome/common/ipc_sync_message.h"
      21                 : #include "chrome/common/thumbnail_score.h"
      22                 : #include "chrome/common/transport_dib.h"
      23                 : 
      24                 : namespace IPC {
      25                 : 
      26                 : //-----------------------------------------------------------------------------
      27                 : // An iterator class for reading the fields contained within a Message.
      28                 : 
      29                 : class MessageIterator {
      30                 :  public:
      31               0 :   explicit MessageIterator(const Message& m) : msg_(m), iter_(NULL) {
      32               0 :   }
      33               0 :   int NextInt() const {
      34                 :     int val;
      35               0 :     if (!msg_.ReadInt(&iter_, &val))
      36               0 :       NOTREACHED();
      37               0 :     return val;
      38                 :   }
      39                 :   intptr_t NextIntPtr() const {
      40                 :     intptr_t val;
      41                 :     if (!msg_.ReadIntPtr(&iter_, &val))
      42                 :       NOTREACHED();
      43                 :     return val;
      44                 :   }
      45                 :   const std::string NextString() const {
      46                 :     std::string val;
      47                 :     if (!msg_.ReadString(&iter_, &val))
      48                 :       NOTREACHED();
      49                 :     return val;
      50                 :   }
      51                 :   const std::wstring NextWString() const {
      52                 :     std::wstring val;
      53                 :     if (!msg_.ReadWString(&iter_, &val))
      54                 :       NOTREACHED();
      55                 :     return val;
      56                 :   }
      57                 :   const void NextData(const char** data, int* length) const {
      58                 :     if (!msg_.ReadData(&iter_, data, length)) {
      59                 :       NOTREACHED();
      60                 :     }
      61                 :   }
      62                 :  private:
      63                 :   const Message& msg_;
      64                 :   mutable void* iter_;
      65                 : };
      66                 : 
      67                 : //-----------------------------------------------------------------------------
      68                 : // ParamTraits specializations, etc.
      69                 : 
      70                 : template <class P> struct ParamTraits {};
      71                 : 
      72                 : template <class P>
      73               0 : static inline void WriteParam(Message* m, const P& p) {
      74               0 :   ParamTraits<P>::Write(m, p);
      75               0 : }
      76                 : 
      77                 : template <class P>
      78               0 : static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, void** iter,
      79                 :                                                 P* p) {
      80               0 :   return ParamTraits<P>::Read(m, iter, p);
      81                 : }
      82                 : 
      83                 : template <class P>
      84                 : static inline void LogParam(const P& p, std::wstring* l) {
      85                 :   ParamTraits<P>::Log(p, l);
      86                 : }
      87                 : 
      88                 : template <>
      89                 : struct ParamTraits<bool> {
      90                 :   typedef bool param_type;
      91               0 :   static void Write(Message* m, const param_type& p) {
      92               0 :     m->WriteBool(p);
      93               0 :   }
      94               0 :   static bool Read(const Message* m, void** iter, param_type* r) {
      95               0 :     return m->ReadBool(iter, r);
      96                 :   }
      97                 :   static void Log(const param_type& p, std::wstring* l) {
      98                 :     l->append(p ? L"true" : L"false");
      99                 :   }
     100                 : };
     101                 : 
     102                 : template <>
     103                 : struct ParamTraits<int16> {
     104                 :   typedef int16 param_type;
     105               0 :   static void Write(Message* m, const param_type& p) {
     106               0 :     m->WriteInt(p);
     107               0 :   }
     108               0 :   static bool Read(const Message* m, void** iter, param_type* r) {
     109               0 :     return m->ReadInt16(iter, r);
     110                 :   }
     111                 :   static void Log(const param_type& p, std::wstring* l) {
     112                 :     l->append(StringPrintf(L"%hd", p));
     113                 :   }
     114                 : };
     115                 : 
     116                 : template <>
     117                 : struct ParamTraits<uint16> {
     118                 :   typedef uint16 param_type;
     119               0 :   static void Write(Message* m, const param_type& p) {
     120               0 :     m->WriteInt(p);
     121               0 :   }
     122               0 :   static bool Read(const Message* m, void** iter, param_type* r) {
     123               0 :     return m->ReadUInt16(iter, r);
     124                 :   }
     125                 :   static void Log(const param_type& p, std::wstring* l) {
     126                 :     l->append(StringPrintf(L"%hu", p));
     127                 :   }
     128                 : };
     129                 : 
     130                 : template <>
     131                 : struct ParamTraits<int> {
     132                 :   typedef int param_type;
     133               0 :   static void Write(Message* m, const param_type& p) {
     134               0 :     m->WriteInt(p);
     135               0 :   }
     136               0 :   static bool Read(const Message* m, void** iter, param_type* r) {
     137               0 :     return m->ReadInt(iter, r);
     138                 :   }
     139                 :   static void Log(const param_type& p, std::wstring* l) {
     140                 :     l->append(StringPrintf(L"%d", p));
     141                 :   }
     142                 : };
     143                 : 
     144                 : template <>
     145                 : struct ParamTraits<long> {
     146                 :   typedef long param_type;
     147               0 :   static void Write(Message* m, const param_type& p) {
     148               0 :     m->WriteLong(p);
     149               0 :   }
     150               0 :   static bool Read(const Message* m, void** iter, param_type* r) {
     151               0 :     return m->ReadLong(iter, r);
     152                 :   }
     153                 :   static void Log(const param_type& p, std::wstring* l) {
     154                 :     l->append(StringPrintf(L"%l", p));
     155                 :   }
     156                 : };
     157                 : 
     158                 : template <>
     159                 : struct ParamTraits<unsigned long> {
     160                 :   typedef unsigned long param_type;
     161               0 :   static void Write(Message* m, const param_type& p) {
     162               0 :     m->WriteULong(p);
     163               0 :   }
     164               0 :   static bool Read(const Message* m, void** iter, param_type* r) {
     165               0 :     return m->ReadULong(iter, r);
     166                 :   }
     167                 :   static void Log(const param_type& p, std::wstring* l) {
     168                 :     l->append(StringPrintf(L"%ul", p));
     169                 :   }
     170                 : };
     171                 : #if (defined(OS_OPENBSD) && defined(ARCH_CPU_64_BITS))
     172                 : // On OpenBSD, uint64_t is unsigned long long
     173                 : // see https://bugzilla.mozilla.org/show_bug.cgi?id=648735#c27
     174                 : template <>
     175                 : struct ParamTraits<unsigned long long> {
     176                 :   typedef unsigned long long param_type;
     177                 :   static void Write(Message* m, const param_type& p) {
     178                 :     m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
     179                 :  }
     180                 :   static bool Read(const Message* m, void** iter, param_type* r) {
     181                 :     const char *data;
     182                 :     int data_size = 0;
     183                 :     bool result = m->ReadData(iter, &data, &data_size);
     184                 :     if (result && data_size == sizeof(param_type)) {
     185                 :       memcpy(r, data, sizeof(param_type));
     186                 :     } else {
     187                 :       result = false;
     188                 :       NOTREACHED();
     189                 :     }
     190                 :     return result;
     191                 :   }
     192                 :   static void Log(const param_type& p, std::wstring* l) {
     193                 :     l->append(StringPrintf(L"%ull", p));
     194                 :   }
     195                 : };
     196                 : #endif
     197                 : 
     198                 : #if !(defined(OS_MACOSX) || defined(OS_OPENBSD) || defined(OS_WIN) || (defined(OS_LINUX) && defined(ARCH_CPU_64_BITS)) || defined(ARCH_CPU_S390))
     199                 : // There size_t is a synonym for |unsigned long| ...
     200                 : template <>
     201                 : struct ParamTraits<size_t> {
     202                 :   typedef size_t param_type;
     203               0 :   static void Write(Message* m, const param_type& p) {
     204               0 :     m->WriteSize(p);
     205               0 :   }
     206               0 :   static bool Read(const Message* m, void** iter, param_type* r) {
     207               0 :     return m->ReadSize(iter, r);
     208                 :   }
     209                 :   static void Log(const param_type& p, std::wstring* l) {
     210                 :     l->append(StringPrintf(L"%u", p));
     211                 :   }
     212                 : };
     213                 : 
     214                 : #elif !defined(OS_MACOSX)
     215                 : // ... so we need to define traits for |unsigned int|.
     216                 : // XXX duplicating OS_MACOSX version below so as not to conflict
     217                 : template <>
     218                 : struct ParamTraits<uint32> {
     219                 :   typedef uint32 param_type;
     220                 :   static void Write(Message* m, const param_type& p) {
     221                 :     m->WriteUInt32(p);
     222                 :   }
     223                 :   static bool Read(const Message* m, void** iter, param_type* r) {
     224                 :     return m->ReadUInt32(iter, r);
     225                 :   }
     226                 :   static void Log(const param_type& p, std::wstring* l) {
     227                 :     l->append(StringPrintf(L"%u", p));
     228                 :   }
     229                 : };
     230                 : 
     231                 : #endif // if !(defined(OS_LINUX) && defined(ARCH_CPU_64_BITS))
     232                 : 
     233                 : #if defined(OS_MACOSX)
     234                 : // On Linux size_t & uint32 can be the same type.
     235                 : // TODO(playmobil): Fix compilation if this is not the case.
     236                 : template <>
     237                 : struct ParamTraits<uint32> {
     238                 :   typedef uint32 param_type;
     239                 :   static void Write(Message* m, const param_type& p) {
     240                 :     m->WriteUInt32(p);
     241                 :   }
     242                 :   static bool Read(const Message* m, void** iter, param_type* r) {
     243                 :     return m->ReadUInt32(iter, r);
     244                 :   }
     245                 :   static void Log(const param_type& p, std::wstring* l) {
     246                 :     l->append(StringPrintf(L"%u", p));
     247                 :   }
     248                 : };
     249                 : #endif  // defined(OS_MACOSX)
     250                 : 
     251                 : #if !(defined(OS_LINUX) && defined(ARCH_CPU_64_BITS))
     252                 : // int64 is |long int| on 64-bit systems, uint64 is |unsigned long|
     253                 : template <>
     254                 : struct ParamTraits<int64> {
     255                 :   typedef int64 param_type;
     256               0 :   static void Write(Message* m, const param_type& p) {
     257               0 :     m->WriteInt64(p);
     258               0 :   }
     259               0 :   static bool Read(const Message* m, void** iter, param_type* r) {
     260               0 :     return m->ReadInt64(iter, r);
     261                 :   }
     262                 :   static void Log(const param_type& p, std::wstring* l) {
     263                 :     l->append(StringPrintf(L"%" PRId64L, p));
     264                 :   }
     265                 : };
     266                 : 
     267                 : template <>
     268                 : struct ParamTraits<uint64> {
     269                 :   typedef uint64 param_type;
     270               0 :   static void Write(Message* m, const param_type& p) {
     271               0 :     m->WriteInt64(static_cast<int64>(p));
     272               0 :   }
     273               0 :   static bool Read(const Message* m, void** iter, param_type* r) {
     274               0 :     return m->ReadInt64(iter, reinterpret_cast<int64*>(r));
     275                 :   }
     276                 :   static void Log(const param_type& p, std::wstring* l) {
     277                 :     l->append(StringPrintf(L"%" PRIu64L, p));
     278                 :   }
     279                 : };
     280                 : #endif // if !(defined(OS_LINUX) && defined(ARCH_CPU_64_BITS))
     281                 : 
     282                 : template <>
     283                 : struct ParamTraits<double> {
     284                 :   typedef double param_type;
     285               0 :   static void Write(Message* m, const param_type& p) {
     286               0 :     m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
     287               0 :   }
     288               0 :   static bool Read(const Message* m, void** iter, param_type* r) {
     289                 :     const char *data;
     290               0 :     int data_size = 0;
     291               0 :     bool result = m->ReadData(iter, &data, &data_size);
     292               0 :     if (result && data_size == sizeof(param_type)) {
     293               0 :       memcpy(r, data, sizeof(param_type));
     294                 :     } else {
     295               0 :       result = false;
     296               0 :       NOTREACHED();
     297                 :     }
     298                 : 
     299               0 :     return result;
     300                 :   }
     301                 :   static void Log(const param_type& p, std::wstring* l) {
     302                 :     l->append(StringPrintf(L"e", p));
     303                 :   }
     304                 : };
     305                 : 
     306                 : template <>
     307                 : struct ParamTraits<base::Time> {
     308                 :   typedef base::Time param_type;
     309                 :   static void Write(Message* m, const param_type& p) {
     310                 :     ParamTraits<int64>::Write(m, p.ToInternalValue());
     311                 :   }
     312                 :   static bool Read(const Message* m, void** iter, param_type* r) {
     313                 :     int64 value;
     314                 :     if (!ParamTraits<int64>::Read(m, iter, &value))
     315                 :       return false;
     316                 :     *r = base::Time::FromInternalValue(value);
     317                 :     return true;
     318                 :   }
     319                 :   static void Log(const param_type& p, std::wstring* l) {
     320                 :     ParamTraits<int64>::Log(p.ToInternalValue(), l);
     321                 :   }
     322                 : };
     323                 : 
     324                 : #if defined(OS_WIN)
     325                 : template <>
     326                 : struct ParamTraits<LOGFONT> {
     327                 :   typedef LOGFONT param_type;
     328                 :   static void Write(Message* m, const param_type& p) {
     329                 :     m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
     330                 :   }
     331                 :   static bool Read(const Message* m, void** iter, param_type* r) {
     332                 :     const char *data;
     333                 :     int data_size = 0;
     334                 :     bool result = m->ReadData(iter, &data, &data_size);
     335                 :     if (result && data_size == sizeof(LOGFONT)) {
     336                 :       memcpy(r, data, sizeof(LOGFONT));
     337                 :     } else {
     338                 :       result = false;
     339                 :       NOTREACHED();
     340                 :     }
     341                 : 
     342                 :     return result;
     343                 :   }
     344                 :   static void Log(const param_type& p, std::wstring* l) {
     345                 :     l->append(StringPrintf(L"<LOGFONT>"));
     346                 :   }
     347                 : };
     348                 : 
     349                 : template <>
     350                 : struct ParamTraits<MSG> {
     351                 :   typedef MSG param_type;
     352                 :   static void Write(Message* m, const param_type& p) {
     353                 :     m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
     354                 :   }
     355                 :   static bool Read(const Message* m, void** iter, param_type* r) {
     356                 :     const char *data;
     357                 :     int data_size = 0;
     358                 :     bool result = m->ReadData(iter, &data, &data_size);
     359                 :     if (result && data_size == sizeof(MSG)) {
     360                 :       memcpy(r, data, sizeof(MSG));
     361                 :     } else {
     362                 :       result = false;
     363                 :       NOTREACHED();
     364                 :     }
     365                 : 
     366                 :     return result;
     367                 :   }
     368                 : };
     369                 : #endif  // defined(OS_WIN)
     370                 : 
     371                 : template <>
     372                 : struct ParamTraits<std::string> {
     373                 :   typedef std::string param_type;
     374                 :   static void Write(Message* m, const param_type& p) {
     375                 :     m->WriteString(p);
     376                 :   }
     377                 :   static bool Read(const Message* m, void** iter, param_type* r) {
     378                 :     return m->ReadString(iter, r);
     379                 :   }
     380                 :   static void Log(const param_type& p, std::wstring* l) {
     381                 :     l->append(UTF8ToWide(p));
     382                 :   }
     383                 : };
     384                 : 
     385                 : template <>
     386                 : struct ParamTraits<std::vector<unsigned char> > {
     387                 :   typedef std::vector<unsigned char> param_type;
     388                 :   static void Write(Message* m, const param_type& p) {
     389                 :     if (p.size() == 0) {
     390                 :       m->WriteData(NULL, 0);
     391                 :     } else {
     392                 :       m->WriteData(reinterpret_cast<const char*>(&p.front()),
     393                 :                    static_cast<int>(p.size()));
     394                 :     }
     395                 :   }
     396                 :   static bool Read(const Message* m, void** iter, param_type* r) {
     397                 :     const char *data;
     398                 :     int data_size = 0;
     399                 :     if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
     400                 :       return false;
     401                 :     r->resize(data_size);
     402                 :     if (data_size)
     403                 :       memcpy(&r->front(), data, data_size);
     404                 :     return true;
     405                 :   }
     406                 :   static void Log(const param_type& p, std::wstring* l) {
     407                 :     for (size_t i = 0; i < p.size(); ++i)
     408                 :       l->push_back(p[i]);
     409                 :   }
     410                 : };
     411                 : 
     412                 : template <>
     413                 : struct ParamTraits<std::vector<char> > {
     414                 :   typedef std::vector<char> param_type;
     415                 :   static void Write(Message* m, const param_type& p) {
     416                 :     if (p.size() == 0) {
     417                 :       m->WriteData(NULL, 0);
     418                 :     } else {
     419                 :       m->WriteData(&p.front(), static_cast<int>(p.size()));
     420                 :     }
     421                 :   }
     422                 :   static bool Read(const Message* m, void** iter, param_type* r) {
     423                 :     const char *data;
     424                 :     int data_size = 0;
     425                 :     if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
     426                 :       return false;
     427                 :     r->resize(data_size);
     428                 :     if (data_size)
     429                 :       memcpy(&r->front(), data, data_size);
     430                 :     return true;
     431                 :   }
     432                 :   static void Log(const param_type& p, std::wstring* l) {
     433                 :     for (size_t i = 0; i < p.size(); ++i)
     434                 :       l->push_back(p[i]);
     435                 :   }
     436                 : };
     437                 : 
     438                 : template <class P>
     439                 : struct ParamTraits<std::vector<P> > {
     440                 :   typedef std::vector<P> param_type;
     441               0 :   static void Write(Message* m, const param_type& p) {
     442               0 :     WriteParam(m, static_cast<int>(p.size()));
     443               0 :     for (size_t i = 0; i < p.size(); i++)
     444               0 :       WriteParam(m, p[i]);
     445               0 :   }
     446               0 :   static bool Read(const Message* m, void** iter, param_type* r) {
     447                 :     int size;
     448               0 :     if (!m->ReadLength(iter, &size))
     449               0 :       return false;
     450                 :     // Resizing beforehand is not safe, see BUG 1006367 for details.
     451               0 :     if (m->IteratorHasRoomFor(*iter, size * sizeof(P))) {
     452               0 :       r->resize(size);
     453               0 :       for (int i = 0; i < size; i++) {
     454               0 :         if (!ReadParam(m, iter, &(*r)[i]))
     455               0 :           return false;
     456                 :       }
     457                 :     } else {
     458               0 :       for (int i = 0; i < size; i++) {
     459               0 :         P element;
     460               0 :         if (!ReadParam(m, iter, &element))
     461               0 :           return false;
     462               0 :         r->push_back(element);
     463                 :       }
     464                 :     }
     465               0 :     return true;
     466                 :   }
     467                 :   static void Log(const param_type& p, std::wstring* l) {
     468                 :     for (size_t i = 0; i < p.size(); ++i) {
     469                 :       if (i != 0)
     470                 :         l->append(L" ");
     471                 : 
     472                 :       LogParam((p[i]), l);
     473                 :     }
     474                 :   }
     475                 : };
     476                 : 
     477                 : template <class K, class V>
     478                 : struct ParamTraits<std::map<K, V> > {
     479                 :   typedef std::map<K, V> param_type;
     480                 :   static void Write(Message* m, const param_type& p) {
     481                 :     WriteParam(m, static_cast<int>(p.size()));
     482                 :     typename param_type::const_iterator iter;
     483                 :     for (iter = p.begin(); iter != p.end(); ++iter) {
     484                 :       WriteParam(m, iter->first);
     485                 :       WriteParam(m, iter->second);
     486                 :     }
     487                 :   }
     488                 :   static bool Read(const Message* m, void** iter, param_type* r) {
     489                 :     int size;
     490                 :     if (!ReadParam(m, iter, &size) || size < 0)
     491                 :       return false;
     492                 :     for (int i = 0; i < size; ++i) {
     493                 :       K k;
     494                 :       if (!ReadParam(m, iter, &k))
     495                 :         return false;
     496                 :       V& value = (*r)[k];
     497                 :       if (!ReadParam(m, iter, &value))
     498                 :         return false;
     499                 :     }
     500                 :     return true;
     501                 :   }
     502                 :   static void Log(const param_type& p, std::wstring* l) {
     503                 :     l->append(L"<std::map>");
     504                 :   }
     505                 : };
     506                 : 
     507                 : 
     508                 : template <>
     509                 : struct ParamTraits<std::wstring> {
     510                 :   typedef std::wstring param_type;
     511               0 :   static void Write(Message* m, const param_type& p) {
     512               0 :     m->WriteWString(p);
     513               0 :   }
     514               0 :   static bool Read(const Message* m, void** iter, param_type* r) {
     515               0 :     return m->ReadWString(iter, r);
     516                 :   }
     517                 :   static void Log(const param_type& p, std::wstring* l) {
     518                 :     l->append(p);
     519                 :   }
     520                 : };
     521                 : 
     522                 : // If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
     523                 : // need this trait.
     524                 : #if !defined(WCHAR_T_IS_UTF16)
     525                 : template <>
     526                 : struct ParamTraits<string16> {
     527                 :   typedef string16 param_type;
     528                 :   static void Write(Message* m, const param_type& p) {
     529                 :     m->WriteString16(p);
     530                 :   }
     531                 :   static bool Read(const Message* m, void** iter, param_type* r) {
     532                 :     return m->ReadString16(iter, r);
     533                 :   }
     534                 :   static void Log(const param_type& p, std::wstring* l) {
     535                 :     l->append(UTF16ToWide(p));
     536                 :   }
     537                 : };
     538                 : #endif
     539                 : 
     540                 : // and, a few more useful types...
     541                 : #if defined(OS_WIN)
     542                 : template <>
     543                 : struct ParamTraits<HANDLE> {
     544                 :   typedef HANDLE param_type;
     545                 :   static void Write(Message* m, const param_type& p) {
     546                 :     m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
     547                 :   }
     548                 :   static bool Read(const Message* m, void** iter, param_type* r) {
     549                 :     DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
     550                 :     return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
     551                 :   }
     552                 :   static void Log(const param_type& p, std::wstring* l) {
     553                 :     l->append(StringPrintf(L"0x%X", p));
     554                 :   }
     555                 : };
     556                 : 
     557                 : template <>
     558                 : struct ParamTraits<HCURSOR> {
     559                 :   typedef HCURSOR param_type;
     560                 :   static void Write(Message* m, const param_type& p) {
     561                 :     m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
     562                 :   }
     563                 :   static bool Read(const Message* m, void** iter, param_type* r) {
     564                 :     DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
     565                 :     return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
     566                 :   }
     567                 :   static void Log(const param_type& p, std::wstring* l) {
     568                 :     l->append(StringPrintf(L"0x%X", p));
     569                 :   }
     570                 : };
     571                 : 
     572                 : template <>
     573                 : struct ParamTraits<HWND> {
     574                 :   typedef HWND param_type;
     575                 :   static void Write(Message* m, const param_type& p) {
     576                 :     m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
     577                 :   }
     578                 :   static bool Read(const Message* m, void** iter, param_type* r) {
     579                 :     DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
     580                 :     return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
     581                 :   }
     582                 :   static void Log(const param_type& p, std::wstring* l) {
     583                 :     l->append(StringPrintf(L"0x%X", p));
     584                 :   }
     585                 : };
     586                 : 
     587                 : template <>
     588                 : struct ParamTraits<HACCEL> {
     589                 :   typedef HACCEL param_type;
     590                 :   static void Write(Message* m, const param_type& p) {
     591                 :     m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
     592                 :   }
     593                 :   static bool Read(const Message* m, void** iter, param_type* r) {
     594                 :     DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
     595                 :     return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
     596                 :   }
     597                 : };
     598                 : 
     599                 : template <>
     600                 : struct ParamTraits<POINT> {
     601                 :   typedef POINT param_type;
     602                 :   static void Write(Message* m, const param_type& p) {
     603                 :     m->WriteInt(p.x);
     604                 :     m->WriteInt(p.y);
     605                 :   }
     606                 :   static bool Read(const Message* m, void** iter, param_type* r) {
     607                 :     int x, y;
     608                 :     if (!m->ReadInt(iter, &x) || !m->ReadInt(iter, &y))
     609                 :       return false;
     610                 :     r->x = x;
     611                 :     r->y = y;
     612                 :     return true;
     613                 :   }
     614                 :   static void Log(const param_type& p, std::wstring* l) {
     615                 :     l->append(StringPrintf(L"(%d, %d)", p.x, p.y));
     616                 :   }
     617                 : };
     618                 : #endif  // defined(OS_WIN)
     619                 : 
     620                 : template <>
     621                 : struct ParamTraits<FilePath> {
     622                 :   typedef FilePath param_type;
     623                 :   static void Write(Message* m, const param_type& p) {
     624                 :     ParamTraits<FilePath::StringType>::Write(m, p.value());
     625                 :   }
     626                 :   static bool Read(const Message* m, void** iter, param_type* r) {
     627                 :     FilePath::StringType value;
     628                 :     if (!ParamTraits<FilePath::StringType>::Read(m, iter, &value))
     629                 :       return false;
     630                 :     *r = FilePath(value);
     631                 :     return true;
     632                 :   }
     633                 :   static void Log(const param_type& p, std::wstring* l) {
     634                 :     ParamTraits<FilePath::StringType>::Log(p.value(), l);
     635                 :   }
     636                 : };
     637                 : 
     638                 : #if defined(OS_POSIX)
     639                 : // FileDescriptors may be serialised over IPC channels on POSIX. On the
     640                 : // receiving side, the FileDescriptor is a valid duplicate of the file
     641                 : // descriptor which was transmitted: *it is not just a copy of the integer like
     642                 : // HANDLEs on Windows*. The only exception is if the file descriptor is < 0. In
     643                 : // this case, the receiving end will see a value of -1. *Zero is a valid file
     644                 : // descriptor*.
     645                 : //
     646                 : // The received file descriptor will have the |auto_close| flag set to true. The
     647                 : // code which handles the message is responsible for taking ownership of it.
     648                 : // File descriptors are OS resources and must be closed when no longer needed.
     649                 : //
     650                 : // When sending a file descriptor, the file descriptor must be valid at the time
     651                 : // of transmission. Since transmission is not synchronous, one should consider
     652                 : // dup()ing any file descriptors to be transmitted and setting the |auto_close|
     653                 : // flag, which causes the file descriptor to be closed after writing.
     654                 : template<>
     655                 : struct ParamTraits<base::FileDescriptor> {
     656                 :   typedef base::FileDescriptor param_type;
     657               0 :   static void Write(Message* m, const param_type& p) {
     658               0 :     const bool valid = p.fd >= 0;
     659               0 :     WriteParam(m, valid);
     660                 : 
     661               0 :     if (valid) {
     662               0 :       if (!m->WriteFileDescriptor(p))
     663               0 :         NOTREACHED();
     664                 :     }
     665               0 :   }
     666               0 :   static bool Read(const Message* m, void** iter, param_type* r) {
     667                 :     bool valid;
     668               0 :     if (!ReadParam(m, iter, &valid))
     669               0 :       return false;
     670                 : 
     671               0 :     if (!valid) {
     672               0 :       r->fd = -1;
     673               0 :       r->auto_close = false;
     674               0 :       return true;
     675                 :     }
     676                 : 
     677               0 :     return m->ReadFileDescriptor(iter, r);
     678                 :   }
     679                 :   static void Log(const param_type& p, std::wstring* l) {
     680                 :     if (p.auto_close) {
     681                 :       l->append(StringPrintf(L"FD(%d auto-close)", p.fd));
     682                 :     } else {
     683                 :       l->append(StringPrintf(L"FD(%d)", p.fd));
     684                 :     }
     685                 :   }
     686                 : };
     687                 : #endif // defined(OS_POSIX)
     688                 : 
     689                 : template<>
     690                 : struct ParamTraits<ThumbnailScore> {
     691                 :   typedef ThumbnailScore param_type;
     692                 :   static void Write(Message* m, const param_type& p) {
     693                 :     IPC::ParamTraits<double>::Write(m, p.boring_score);
     694                 :     IPC::ParamTraits<bool>::Write(m, p.good_clipping);
     695                 :     IPC::ParamTraits<bool>::Write(m, p.at_top);
     696                 :     IPC::ParamTraits<base::Time>::Write(m, p.time_at_snapshot);
     697                 :   }
     698                 :   static bool Read(const Message* m, void** iter, param_type* r) {
     699                 :     double boring_score;
     700                 :     bool good_clipping, at_top;
     701                 :     base::Time time_at_snapshot;
     702                 :     if (!IPC::ParamTraits<double>::Read(m, iter, &boring_score) ||
     703                 :         !IPC::ParamTraits<bool>::Read(m, iter, &good_clipping) ||
     704                 :         !IPC::ParamTraits<bool>::Read(m, iter, &at_top) ||
     705                 :         !IPC::ParamTraits<base::Time>::Read(m, iter, &time_at_snapshot))
     706                 :       return false;
     707                 : 
     708                 :     r->boring_score = boring_score;
     709                 :     r->good_clipping = good_clipping;
     710                 :     r->at_top = at_top;
     711                 :     r->time_at_snapshot = time_at_snapshot;
     712                 :     return true;
     713                 :   }
     714                 :   static void Log(const param_type& p, std::wstring* l) {
     715                 :     l->append(StringPrintf(L"(%f, %d, %d)",
     716                 :                            p.boring_score, p.good_clipping, p.at_top));
     717                 :   }
     718                 : };
     719                 : 
     720                 : #if defined(OS_WIN)
     721                 : template <>
     722                 : struct ParamTraits<XFORM> {
     723                 :   typedef XFORM param_type;
     724                 :   static void Write(Message* m, const param_type& p) {
     725                 :     m->WriteData(reinterpret_cast<const char*>(&p), sizeof(XFORM));
     726                 :   }
     727                 :   static bool Read(const Message* m, void** iter, param_type* r) {
     728                 :     const char *data;
     729                 :     int data_size = 0;
     730                 :     bool result = m->ReadData(iter, &data, &data_size);
     731                 :     if (result && data_size == sizeof(XFORM)) {
     732                 :       memcpy(r, data, sizeof(XFORM));
     733                 :     } else {
     734                 :       result = false;
     735                 :       NOTREACHED();
     736                 :     }
     737                 : 
     738                 :     return result;
     739                 :   }
     740                 :   static void Log(const param_type& p, std::wstring* l) {
     741                 :     l->append(L"<XFORM>");
     742                 :   }
     743                 : };
     744                 : #endif  // defined(OS_WIN)
     745                 : 
     746               0 : struct LogData {
     747                 :   std::wstring channel;
     748                 :   int32 routing_id;
     749                 :   uint16 type;
     750                 :   std::wstring flags;
     751                 :   int64 sent;  // Time that the message was sent (i.e. at Send()).
     752                 :   int64 receive;  // Time before it was dispatched (i.e. before calling
     753                 :                   // OnMessageReceived).
     754                 :   int64 dispatch;  // Time after it was dispatched (i.e. after calling
     755                 :                    // OnMessageReceived).
     756                 :   std::wstring message_name;
     757                 :   std::wstring params;
     758                 : };
     759                 : 
     760                 : template <>
     761                 : struct ParamTraits<LogData> {
     762                 :   typedef LogData param_type;
     763               0 :   static void Write(Message* m, const param_type& p) {
     764               0 :     WriteParam(m, p.channel);
     765               0 :     WriteParam(m, p.routing_id);
     766               0 :     WriteParam(m, static_cast<int>(p.type));
     767               0 :     WriteParam(m, p.flags);
     768               0 :     WriteParam(m, p.sent);
     769               0 :     WriteParam(m, p.receive);
     770               0 :     WriteParam(m, p.dispatch);
     771               0 :     WriteParam(m, p.params);
     772               0 :   }
     773               0 :   static bool Read(const Message* m, void** iter, param_type* r) {
     774                 :     int type;
     775                 :     bool result =
     776               0 :       ReadParam(m, iter, &r->channel) &&
     777               0 :       ReadParam(m, iter, &r->routing_id) &&
     778               0 :       ReadParam(m, iter, &type) &&
     779               0 :       ReadParam(m, iter, &r->flags) &&
     780               0 :       ReadParam(m, iter, &r->sent) &&
     781               0 :       ReadParam(m, iter, &r->receive) &&
     782               0 :       ReadParam(m, iter, &r->dispatch) &&
     783               0 :       ReadParam(m, iter, &r->params);
     784               0 :     r->type = static_cast<uint16>(type);
     785               0 :     return result;
     786                 :   }
     787                 :   static void Log(const param_type& p, std::wstring* l) {
     788                 :     // Doesn't make sense to implement this!
     789                 :   }
     790                 : };
     791                 : 
     792                 : #if defined(OS_WIN)
     793                 : template<>
     794                 : struct ParamTraits<TransportDIB::Id> {
     795                 :   typedef TransportDIB::Id param_type;
     796                 :   static void Write(Message* m, const param_type& p) {
     797                 :     WriteParam(m, p.handle);
     798                 :     WriteParam(m, p.sequence_num);
     799                 :   }
     800                 :   static bool Read(const Message* m, void** iter, param_type* r) {
     801                 :     return (ReadParam(m, iter, &r->handle) &&
     802                 :             ReadParam(m, iter, &r->sequence_num));
     803                 :   }
     804                 :   static void Log(const param_type& p, std::wstring* l) {
     805                 :     l->append(L"TransportDIB(");
     806                 :     LogParam(p.handle, l);
     807                 :     l->append(L", ");
     808                 :     LogParam(p.sequence_num, l);
     809                 :     l->append(L")");
     810                 :   }
     811                 : };
     812                 : #endif
     813                 : 
     814                 : template <>
     815                 : struct ParamTraits<Message> {
     816                 :   static void Write(Message* m, const Message& p) {
     817                 :     m->WriteInt(p.size());
     818                 :     m->WriteData(reinterpret_cast<const char*>(p.data()), p.size());
     819                 :   }
     820                 :   static bool Read(const Message* m, void** iter, Message* r) {
     821                 :     int size;
     822                 :     if (!m->ReadInt(iter, &size))
     823                 :       return false;
     824                 :     const char* data;
     825                 :     if (!m->ReadData(iter, &data, &size))
     826                 :       return false;
     827                 :     *r = Message(data, size);
     828                 :     return true;
     829                 :   }
     830                 :   static void Log(const Message& p, std::wstring* l) {
     831                 :     l->append(L"<IPC::Message>");
     832                 :   }
     833                 : };
     834                 : 
     835                 : template <>
     836                 : struct ParamTraits<Tuple0> {
     837                 :   typedef Tuple0 param_type;
     838                 :   static void Write(Message* m, const param_type& p) {
     839                 :   }
     840                 :   static bool Read(const Message* m, void** iter, param_type* r) {
     841                 :     return true;
     842                 :   }
     843                 :   static void Log(const param_type& p, std::wstring* l) {
     844                 :   }
     845                 : };
     846                 : 
     847                 : template <class A>
     848                 : struct ParamTraits< Tuple1<A> > {
     849                 :   typedef Tuple1<A> param_type;
     850                 :   static void Write(Message* m, const param_type& p) {
     851                 :     WriteParam(m, p.a);
     852                 :   }
     853                 :   static bool Read(const Message* m, void** iter, param_type* r) {
     854                 :     return ReadParam(m, iter, &r->a);
     855                 :   }
     856                 :   static void Log(const param_type& p, std::wstring* l) {
     857                 :     LogParam(p.a, l);
     858                 :   }
     859                 : };
     860                 : 
     861                 : template <class A, class B>
     862                 : struct ParamTraits< Tuple2<A, B> > {
     863                 :   typedef Tuple2<A, B> param_type;
     864                 :   static void Write(Message* m, const param_type& p) {
     865                 :     WriteParam(m, p.a);
     866                 :     WriteParam(m, p.b);
     867                 :   }
     868                 :   static bool Read(const Message* m, void** iter, param_type* r) {
     869                 :     return (ReadParam(m, iter, &r->a) &&
     870                 :             ReadParam(m, iter, &r->b));
     871                 :   }
     872                 :   static void Log(const param_type& p, std::wstring* l) {
     873                 :     LogParam(p.a, l);
     874                 :     l->append(L", ");
     875                 :     LogParam(p.b, l);
     876                 :   }
     877                 : };
     878                 : 
     879                 : template <class A, class B, class C>
     880                 : struct ParamTraits< Tuple3<A, B, C> > {
     881                 :   typedef Tuple3<A, B, C> param_type;
     882                 :   static void Write(Message* m, const param_type& p) {
     883                 :     WriteParam(m, p.a);
     884                 :     WriteParam(m, p.b);
     885                 :     WriteParam(m, p.c);
     886                 :   }
     887                 :   static bool Read(const Message* m, void** iter, param_type* r) {
     888                 :     return (ReadParam(m, iter, &r->a) &&
     889                 :             ReadParam(m, iter, &r->b) &&
     890                 :             ReadParam(m, iter, &r->c));
     891                 :   }
     892                 :   static void Log(const param_type& p, std::wstring* l) {
     893                 :     LogParam(p.a, l);
     894                 :     l->append(L", ");
     895                 :     LogParam(p.b, l);
     896                 :     l->append(L", ");
     897                 :     LogParam(p.c, l);
     898                 :   }
     899                 : };
     900                 : 
     901                 : template <class A, class B, class C, class D>
     902                 : struct ParamTraits< Tuple4<A, B, C, D> > {
     903                 :   typedef Tuple4<A, B, C, D> param_type;
     904                 :   static void Write(Message* m, const param_type& p) {
     905                 :     WriteParam(m, p.a);
     906                 :     WriteParam(m, p.b);
     907                 :     WriteParam(m, p.c);
     908                 :     WriteParam(m, p.d);
     909                 :   }
     910                 :   static bool Read(const Message* m, void** iter, param_type* r) {
     911                 :     return (ReadParam(m, iter, &r->a) &&
     912                 :             ReadParam(m, iter, &r->b) &&
     913                 :             ReadParam(m, iter, &r->c) &&
     914                 :             ReadParam(m, iter, &r->d));
     915                 :   }
     916                 :   static void Log(const param_type& p, std::wstring* l) {
     917                 :     LogParam(p.a, l);
     918                 :     l->append(L", ");
     919                 :     LogParam(p.b, l);
     920                 :     l->append(L", ");
     921                 :     LogParam(p.c, l);
     922                 :     l->append(L", ");
     923                 :     LogParam(p.d, l);
     924                 :   }
     925                 : };
     926                 : 
     927                 : template <class A, class B, class C, class D, class E>
     928                 : struct ParamTraits< Tuple5<A, B, C, D, E> > {
     929                 :   typedef Tuple5<A, B, C, D, E> param_type;
     930                 :   static void Write(Message* m, const param_type& p) {
     931                 :     WriteParam(m, p.a);
     932                 :     WriteParam(m, p.b);
     933                 :     WriteParam(m, p.c);
     934                 :     WriteParam(m, p.d);
     935                 :     WriteParam(m, p.e);
     936                 :   }
     937                 :   static bool Read(const Message* m, void** iter, param_type* r) {
     938                 :     return (ReadParam(m, iter, &r->a) &&
     939                 :             ReadParam(m, iter, &r->b) &&
     940                 :             ReadParam(m, iter, &r->c) &&
     941                 :             ReadParam(m, iter, &r->d) &&
     942                 :             ReadParam(m, iter, &r->e));
     943                 :   }
     944                 :   static void Log(const param_type& p, std::wstring* l) {
     945                 :     LogParam(p.a, l);
     946                 :     l->append(L", ");
     947                 :     LogParam(p.b, l);
     948                 :     l->append(L", ");
     949                 :     LogParam(p.c, l);
     950                 :     l->append(L", ");
     951                 :     LogParam(p.d, l);
     952                 :     l->append(L", ");
     953                 :     LogParam(p.e, l);
     954                 :   }
     955                 : };
     956                 : 
     957                 : template <class A, class B, class C, class D, class E, class F>
     958                 : struct ParamTraits< Tuple6<A, B, C, D, E, F> > {
     959                 :   typedef Tuple6<A, B, C, D, E, F> param_type;
     960                 :   static void Write(Message* m, const param_type& p) {
     961                 :     WriteParam(m, p.a);
     962                 :     WriteParam(m, p.b);
     963                 :     WriteParam(m, p.c);
     964                 :     WriteParam(m, p.d);
     965                 :     WriteParam(m, p.e);
     966                 :     WriteParam(m, p.f);
     967                 :   }
     968                 :   static bool Read(const Message* m, void** iter, param_type* r) {
     969                 :     return (ReadParam(m, iter, &r->a) &&
     970                 :             ReadParam(m, iter, &r->b) &&
     971                 :             ReadParam(m, iter, &r->c) &&
     972                 :             ReadParam(m, iter, &r->d) &&
     973                 :             ReadParam(m, iter, &r->e) &&
     974                 :             ReadParam(m, iter, &r->f));
     975                 :   }
     976                 :   static void Log(const param_type& p, std::wstring* l) {
     977                 :     LogParam(p.a, l);
     978                 :     l->append(L", ");
     979                 :     LogParam(p.b, l);
     980                 :     l->append(L", ");
     981                 :     LogParam(p.c, l);
     982                 :     l->append(L", ");
     983                 :     LogParam(p.d, l);
     984                 :     l->append(L", ");
     985                 :     LogParam(p.e, l);
     986                 :     l->append(L", ");
     987                 :     LogParam(p.f, l);
     988                 :   }
     989                 : };
     990                 : 
     991                 : 
     992                 : 
     993                 : //-----------------------------------------------------------------------------
     994                 : // Generic message subclasses
     995                 : 
     996                 : // Used for asynchronous messages.
     997                 : template <class ParamType>
     998                 : class MessageWithTuple : public Message {
     999                 :  public:
    1000                 :   typedef ParamType Param;
    1001                 : 
    1002                 :   MessageWithTuple(int32 routing_id, uint16 type, const Param& p)
    1003                 :       : Message(routing_id, type, PRIORITY_NORMAL) {
    1004                 :     WriteParam(this, p);
    1005                 :   }
    1006                 : 
    1007                 :   static bool Read(const Message* msg, Param* p) {
    1008                 :     void* iter = NULL;
    1009                 :     bool rv = ReadParam(msg, &iter, p);
    1010                 :     DCHECK(rv) << "Error deserializing message " << msg->type();
    1011                 :     return rv;
    1012                 :   }
    1013                 : 
    1014                 :   // Generic dispatcher.  Should cover most cases.
    1015                 :   template<class T, class Method>
    1016                 :   static bool Dispatch(const Message* msg, T* obj, Method func) {
    1017                 :     Param p;
    1018                 :     if (Read(msg, &p)) {
    1019                 :       DispatchToMethod(obj, func, p);
    1020                 :       return true;
    1021                 :     }
    1022                 :     return false;
    1023                 :   }
    1024                 : 
    1025                 :   // The following dispatchers exist for the case where the callback function
    1026                 :   // needs the message as well.  They assume that "Param" is a type of Tuple
    1027                 :   // (except the one arg case, as there is no Tuple1).
    1028                 :   template<class T, typename TA>
    1029                 :   static bool Dispatch(const Message* msg, T* obj,
    1030                 :                        void (T::*func)(const Message&, TA)) {
    1031                 :     Param p;
    1032                 :     if (Read(msg, &p)) {
    1033                 :       (obj->*func)(*msg, p);
    1034                 :       return true;
    1035                 :     }
    1036                 :     return false;
    1037                 :   }
    1038                 : 
    1039                 :   template<class T, typename TA, typename TB>
    1040                 :   static bool Dispatch(const Message* msg, T* obj,
    1041                 :                        void (T::*func)(const Message&, TA, TB)) {
    1042                 :     Param p;
    1043                 :     if (Read(msg, &p)) {
    1044                 :       (obj->*func)(*msg, p.a, p.b);
    1045                 :       return true;
    1046                 :     }
    1047                 :     return false;
    1048                 :   }
    1049                 : 
    1050                 :   template<class T, typename TA, typename TB, typename TC>
    1051                 :   static bool Dispatch(const Message* msg, T* obj,
    1052                 :                        void (T::*func)(const Message&, TA, TB, TC)) {
    1053                 :     Param p;
    1054                 :     if (Read(msg, &p)) {
    1055                 :       (obj->*func)(*msg, p.a, p.b, p.c);
    1056                 :       return true;
    1057                 :     }
    1058                 :     return false;
    1059                 :   }
    1060                 : 
    1061                 :   template<class T, typename TA, typename TB, typename TC, typename TD>
    1062                 :   static bool Dispatch(const Message* msg, T* obj,
    1063                 :                        void (T::*func)(const Message&, TA, TB, TC, TD)) {
    1064                 :     Param p;
    1065                 :     if (Read(msg, &p)) {
    1066                 :       (obj->*func)(*msg, p.a, p.b, p.c, p.d);
    1067                 :       return true;
    1068                 :     }
    1069                 :     return false;
    1070                 :   }
    1071                 : 
    1072                 :   template<class T, typename TA, typename TB, typename TC, typename TD,
    1073                 :            typename TE>
    1074                 :   static bool Dispatch(const Message* msg, T* obj,
    1075                 :                        void (T::*func)(const Message&, TA, TB, TC, TD, TE)) {
    1076                 :     Param p;
    1077                 :     if (Read(msg, &p)) {
    1078                 :       (obj->*func)(*msg, p.a, p.b, p.c, p.d, p.e);
    1079                 :       return true;
    1080                 :     }
    1081                 :     return false;
    1082                 :   }
    1083                 : 
    1084                 :   static void Log(const Message* msg, std::wstring* l) {
    1085                 :     Param p;
    1086                 :     if (Read(msg, &p))
    1087                 :       LogParam(p, l);
    1088                 :   }
    1089                 : 
    1090                 :   // Functions used to do manual unpacking.  Only used by the automation code,
    1091                 :   // these should go away once that code uses SyncChannel.
    1092                 :   template<typename TA, typename TB>
    1093                 :   static bool Read(const IPC::Message* msg, TA* a, TB* b) {
    1094                 :     ParamType params;
    1095                 :     if (!Read(msg, &params))
    1096                 :       return false;
    1097                 :     *a = params.a;
    1098                 :     *b = params.b;
    1099                 :     return true;
    1100                 :   }
    1101                 : 
    1102                 :   template<typename TA, typename TB, typename TC>
    1103                 :   static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c) {
    1104                 :     ParamType params;
    1105                 :     if (!Read(msg, &params))
    1106                 :       return false;
    1107                 :     *a = params.a;
    1108                 :     *b = params.b;
    1109                 :     *c = params.c;
    1110                 :     return true;
    1111                 :   }
    1112                 : 
    1113                 :   template<typename TA, typename TB, typename TC, typename TD>
    1114                 :   static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d) {
    1115                 :     ParamType params;
    1116                 :     if (!Read(msg, &params))
    1117                 :       return false;
    1118                 :     *a = params.a;
    1119                 :     *b = params.b;
    1120                 :     *c = params.c;
    1121                 :     *d = params.d;
    1122                 :     return true;
    1123                 :   }
    1124                 : 
    1125                 :   template<typename TA, typename TB, typename TC, typename TD, typename TE>
    1126                 :   static bool Read(const IPC::Message* msg, TA* a, TB* b, TC* c, TD* d, TE* e) {
    1127                 :     ParamType params;
    1128                 :     if (!Read(msg, &params))
    1129                 :       return false;
    1130                 :     *a = params.a;
    1131                 :     *b = params.b;
    1132                 :     *c = params.c;
    1133                 :     *d = params.d;
    1134                 :     *e = params.e;
    1135                 :     return true;
    1136                 :   }
    1137                 : };
    1138                 : 
    1139                 : // This class assumes that its template argument is a RefTuple (a Tuple with
    1140                 : // reference elements).
    1141                 : template <class RefTuple>
    1142                 : class ParamDeserializer : public MessageReplyDeserializer {
    1143                 :  public:
    1144                 :   explicit ParamDeserializer(const RefTuple& out) : out_(out) { }
    1145                 : 
    1146                 :   bool SerializeOutputParameters(const IPC::Message& msg, void* iter) {
    1147                 :     return ReadParam(&msg, &iter, &out_);
    1148                 :   }
    1149                 : 
    1150                 :   RefTuple out_;
    1151                 : };
    1152                 : 
    1153                 : // defined in ipc_logging.cc
    1154                 : void GenerateLogData(const std::wstring& channel, const Message& message,
    1155                 :                      LogData* data);
    1156                 : 
    1157                 : // Used for synchronous messages.
    1158                 : template <class SendParamType, class ReplyParamType>
    1159                 : class MessageWithReply : public SyncMessage {
    1160                 :  public:
    1161                 :   typedef SendParamType SendParam;
    1162                 :   typedef ReplyParamType ReplyParam;
    1163                 : 
    1164                 :   MessageWithReply(int32 routing_id, uint16 type,
    1165                 :                    const SendParam& send, const ReplyParam& reply)
    1166                 :       : SyncMessage(routing_id, type, PRIORITY_NORMAL,
    1167                 :                     new ParamDeserializer<ReplyParam>(reply)) {
    1168                 :     WriteParam(this, send);
    1169                 :   }
    1170                 : 
    1171                 :   static void Log(const Message* msg, std::wstring* l) {
    1172                 :     if (msg->is_sync()) {
    1173                 :       SendParam p;
    1174                 :       void* iter = SyncMessage::GetDataIterator(msg);
    1175                 :       if (ReadParam(msg, &iter, &p))
    1176                 :         LogParam(p, l);
    1177                 : 
    1178                 : #if defined(IPC_MESSAGE_LOG_ENABLED)
    1179                 :       const std::wstring& output_params = msg->output_params();
    1180                 :       if (!l->empty() && !output_params.empty())
    1181                 :         l->append(L", ");
    1182                 : 
    1183                 :       l->append(output_params);
    1184                 : #endif
    1185                 :     } else {
    1186                 :       // This is an outgoing reply.  Now that we have the output parameters, we
    1187                 :       // can finally log the message.
    1188                 :       typename ReplyParam::ValueTuple p;
    1189                 :       void* iter = SyncMessage::GetDataIterator(msg);
    1190                 :       if (ReadParam(msg, &iter, &p))
    1191                 :         LogParam(p, l);
    1192                 :     }
    1193                 :   }
    1194                 : 
    1195                 :   template<class T, class Method>
    1196                 :   static bool Dispatch(const Message* msg, T* obj, Method func) {
    1197                 :     SendParam send_params;
    1198                 :     void* iter = GetDataIterator(msg);
    1199                 :     Message* reply = GenerateReply(msg);
    1200                 :     bool error;
    1201                 :     if (ReadParam(msg, &iter, &send_params)) {
    1202                 :       typename ReplyParam::ValueTuple reply_params;
    1203                 :       DispatchToMethod(obj, func, send_params, &reply_params);
    1204                 :       WriteParam(reply, reply_params);
    1205                 :       error = false;
    1206                 : #ifdef IPC_MESSAGE_LOG_ENABLED
    1207                 :       if (msg->received_time() != 0) {
    1208                 :         std::wstring output_params;
    1209                 :         LogParam(reply_params, &output_params);
    1210                 :         msg->set_output_params(output_params);
    1211                 :       }
    1212                 : #endif
    1213                 :     } else {
    1214                 :       NOTREACHED() << "Error deserializing message " << msg->type();
    1215                 :       reply->set_reply_error();
    1216                 :       error = true;
    1217                 :     }
    1218                 : 
    1219                 :     obj->Send(reply);
    1220                 :     return !error;
    1221                 :   }
    1222                 : 
    1223                 :   template<class T, class Method>
    1224                 :   static bool DispatchDelayReply(const Message* msg, T* obj, Method func) {
    1225                 :     SendParam send_params;
    1226                 :     void* iter = GetDataIterator(msg);
    1227                 :     Message* reply = GenerateReply(msg);
    1228                 :     bool error;
    1229                 :     if (ReadParam(msg, &iter, &send_params)) {
    1230                 :       Tuple1<Message&> t = MakeRefTuple(*reply);
    1231                 : 
    1232                 : #ifdef IPC_MESSAGE_LOG_ENABLED
    1233                 :       if (msg->sent_time()) {
    1234                 :         // Don't log the sync message after dispatch, as we don't have the
    1235                 :         // output parameters at that point.  Instead, save its data and log it
    1236                 :         // with the outgoing reply message when it's sent.
    1237                 :         LogData* data = new LogData;
    1238                 :         GenerateLogData(L"", *msg, data);
    1239                 :         msg->set_dont_log();
    1240                 :         reply->set_sync_log_data(data);
    1241                 :       }
    1242                 : #endif
    1243                 :       DispatchToMethod(obj, func, send_params, &t);
    1244                 :       error = false;
    1245                 :     } else {
    1246                 :       NOTREACHED() << "Error deserializing message " << msg->type();
    1247                 :       reply->set_reply_error();
    1248                 :       obj->Send(reply);
    1249                 :       error = true;
    1250                 :     }
    1251                 :     return !error;
    1252                 :   }
    1253                 : 
    1254                 :   template<typename TA>
    1255                 :   static void WriteReplyParams(Message* reply, TA a) {
    1256                 :     ReplyParam p(a);
    1257                 :     WriteParam(reply, p);
    1258                 :   }
    1259                 : 
    1260                 :   template<typename TA, typename TB>
    1261                 :   static void WriteReplyParams(Message* reply, TA a, TB b) {
    1262                 :     ReplyParam p(a, b);
    1263                 :     WriteParam(reply, p);
    1264                 :   }
    1265                 : 
    1266                 :   template<typename TA, typename TB, typename TC>
    1267                 :   static void WriteReplyParams(Message* reply, TA a, TB b, TC c) {
    1268                 :     ReplyParam p(a, b, c);
    1269                 :     WriteParam(reply, p);
    1270                 :   }
    1271                 : 
    1272                 :   template<typename TA, typename TB, typename TC, typename TD>
    1273                 :   static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d) {
    1274                 :     ReplyParam p(a, b, c, d);
    1275                 :     WriteParam(reply, p);
    1276                 :   }
    1277                 : 
    1278                 :   template<typename TA, typename TB, typename TC, typename TD, typename TE>
    1279                 :   static void WriteReplyParams(Message* reply, TA a, TB b, TC c, TD d, TE e) {
    1280                 :     ReplyParam p(a, b, c, d, e);
    1281                 :     WriteParam(reply, p);
    1282                 :   }
    1283                 : };
    1284                 : 
    1285                 : //-----------------------------------------------------------------------------
    1286                 : 
    1287                 : }  // namespace IPC
    1288                 : 
    1289                 : #endif  // CHROME_COMMON_IPC_MESSAGE_UTILS_H_

Generated by: LCOV version 1.7