ipc/glue/IPCMessageUtils.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim: set sw=2 ts=8 et tw=80 : */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #ifndef __IPC_GLUE_IPCMESSAGEUTILS_H__
     8 #define __IPC_GLUE_IPCMESSAGEUTILS_H__
    10 #include "base/process_util.h"
    11 #include "chrome/common/ipc_message_utils.h"
    13 #include "mozilla/ArrayUtils.h"
    14 #include "mozilla/TimeStamp.h"
    15 #ifdef XP_WIN
    16 #include "mozilla/TimeStamp_windows.h"
    17 #endif
    18 #include "mozilla/TypedEnum.h"
    19 #include "mozilla/IntegerTypeTraits.h"
    21 #include <stdint.h>
    23 #include "nsID.h"
    24 #include "nsMemory.h"
    25 #include "nsString.h"
    26 #include "nsTArray.h"
    27 #include "js/StructuredClone.h"
    28 #include "nsCSSProperty.h"
    30 #ifdef _MSC_VER
    31 #pragma warning( disable : 4800 )
    32 #endif
    34 #if !defined(OS_POSIX)
    35 // This condition must be kept in sync with the one in
    36 // ipc_message_utils.h, but this dummy definition of
    37 // base::FileDescriptor acts as a static assert that we only get one
    38 // def or the other (or neither, in which case code using
    39 // FileDescriptor fails to build)
    40 namespace base { struct FileDescriptor { }; }
    41 #endif
    43 namespace mozilla {
    45 // This is a cross-platform approximation to HANDLE, which we expect
    46 // to be typedef'd to void* or thereabouts.
    47 typedef uintptr_t WindowsHandle;
    49 // XXX there are out of place and might be generally useful.  Could
    50 // move to nscore.h or something.
    51 struct void_t {
    52   bool operator==(const void_t&) const { return true; }
    53 };
    54 struct null_t {
    55   bool operator==(const null_t&) const { return true; }
    56 };
    58 struct SerializedStructuredCloneBuffer
    59 {
    60   SerializedStructuredCloneBuffer()
    61   : data(nullptr), dataLength(0)
    62   { }
    64   SerializedStructuredCloneBuffer(const JSAutoStructuredCloneBuffer& aOther)
    65   {
    66     *this = aOther;
    67   }
    69   bool
    70   operator==(const SerializedStructuredCloneBuffer& aOther) const
    71   {
    72     return this->data == aOther.data &&
    73            this->dataLength == aOther.dataLength;
    74   }
    76   SerializedStructuredCloneBuffer&
    77   operator=(const JSAutoStructuredCloneBuffer& aOther)
    78   {
    79     data = aOther.data();
    80     dataLength = aOther.nbytes();
    81     return *this;
    82   }
    84   uint64_t* data;
    85   size_t dataLength;
    86 };
    88 } // namespace mozilla
    90 namespace IPC {
    92 /**
    93  * Generic enum serializer.
    94  *
    95  * Consider using the specializations below, such as ContiguousEnumSerializer.
    96  *
    97  * This is a generic serializer for any enum type used in IPDL.
    98  * Programmers can define ParamTraits<E> for enum type E by deriving
    99  * EnumSerializer<E, MyEnumValidator> where MyEnumValidator is a struct
   100  * that has to define a static IsLegalValue function returning whether
   101  * a given value is a legal value of the enum type at hand.
   102  *
   103  * \sa https://developer.mozilla.org/en/IPDL/Type_Serialization
   104  */
   105 template <typename E, typename EnumValidator>
   106 struct EnumSerializer {
   107   typedef E paramType;
   108   typedef typename mozilla::UnsignedStdintTypeForSize<sizeof(paramType)>::Type
   109           uintParamType;
   111   static void Write(Message* aMsg, const paramType& aValue) {
   112     MOZ_ASSERT(EnumValidator::IsLegalValue(aValue));
   113     WriteParam(aMsg, uintParamType(aValue));
   114   }
   116   static bool Read(const Message* aMsg, void** aIter, paramType* aResult) {
   117     uintParamType value;
   118     if(!ReadParam(aMsg, aIter, &value) ||
   119        !EnumValidator::IsLegalValue(paramType(value))) {
   120       return false;
   121     }
   122     *aResult = paramType(value);
   123     return true;
   124   }
   125 };
   127 template <typename E,
   128           E MinLegal,
   129           E HighBound>
   130 struct ContiguousEnumValidator
   131 {
   132   static bool IsLegalValue(E e)
   133   {
   134     return MinLegal <= e && e < HighBound;
   135   }
   136 };
   138 template <typename E,
   139           MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(E) MinLegal,
   140           MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(E) HighBound>
   141 class ContiguousTypedEnumValidator
   142 {
   143   // Silence overzealous -Wtype-limits bug in GCC fixed in GCC 4.8:
   144   // "comparison of unsigned expression >= 0 is always true"
   145   // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11856
   146   template <typename T>
   147   static bool IsLessThanOrEqual(T a, T b) { return a <= b; }
   149 public:
   150   static bool IsLegalValue(E e)
   151   {
   152     typedef MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(E) ActualEnumType;
   153     return IsLessThanOrEqual(MinLegal, ActualEnumType(e)) &&
   154            ActualEnumType(e) < HighBound;
   155   }
   156 };
   158 template <typename E,
   159           E AllBits>
   160 struct BitFlagsEnumValidator
   161 {
   162   static bool IsLegalValue(E e)
   163   {
   164     return (e & AllBits) == e;
   165   }
   166 };
   168 template <typename E,
   169           MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(E) AllBits>
   170 struct BitFlagsTypedEnumValidator
   171 {
   172   static bool IsLegalValue(E e)
   173   {
   174     return (e & AllBits) == e;
   175   }
   176 };
   178 /**
   179  * Specialization of EnumSerializer for enums with contiguous enum values.
   180  *
   181  * Provide two values: MinLegal, HighBound. An enum value x will be
   182  * considered legal if MinLegal <= x < HighBound.
   183  *
   184  * For example, following is definition of serializer for enum type FOO.
   185  * \code
   186  * enum FOO { FOO_FIRST, FOO_SECOND, FOO_LAST, NUM_FOO };
   187  *
   188  * template <>
   189  * struct ParamTraits<FOO>:
   190  *     public ContiguousEnumSerializer<FOO, FOO_FIRST, NUM_FOO> {};
   191  * \endcode
   192  * FOO_FIRST, FOO_SECOND, and FOO_LAST are valid value.
   193  */
   194 template <typename E,
   195           E MinLegal,
   196           E HighBound>
   197 struct ContiguousEnumSerializer
   198   : EnumSerializer<E,
   199                    ContiguousEnumValidator<E, MinLegal, HighBound>>
   200 {};
   202 /**
   203  * Similar to ContiguousEnumSerializer, but for MFBT typed enums
   204  * as constructed by MOZ_BEGIN_ENUM_CLASS. This can go away when
   205  * we drop MOZ_BEGIN_ENUM_CLASS and use C++11 enum classes directly.
   206  */
   207 template <typename E,
   208           MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(E) MinLegal,
   209           MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(E) HighBound>
   210 struct ContiguousTypedEnumSerializer
   211   : EnumSerializer<E,
   212                    ContiguousTypedEnumValidator<E, MinLegal, HighBound>>
   213 {};
   215 /**
   216  * Specialization of EnumSerializer for enums representing bit flags.
   217  *
   218  * Provide one value: AllBits. An enum value x will be
   219  * considered legal if (x & AllBits) == x;
   220  *
   221  * Example:
   222  * \code
   223  * enum FOO {
   224  *   FOO_FIRST =  1 << 0,
   225  *   FOO_SECOND = 1 << 1,
   226  *   FOO_LAST =   1 << 2,
   227  *   ALL_BITS =   (1 << 3) - 1
   228  * };
   229  *
   230  * template <>
   231  * struct ParamTraits<FOO>:
   232  *     public BitFlagsEnumSerializer<FOO, FOO::ALL_BITS> {};
   233  * \endcode
   234  */
   235 template <typename E,
   236           E AllBits>
   237 struct BitFlagsEnumSerializer
   238   : EnumSerializer<E,
   239                    BitFlagsEnumValidator<E, AllBits>>
   240 {};
   242 /**
   243  * Similar to BitFlagsEnumSerializer, but for MFBT typed enums
   244  * as constructed by MOZ_BEGIN_ENUM_CLASS. This can go away when
   245  * we drop MOZ_BEGIN_ENUM_CLASS and use C++11 enum classes directly.
   246  */
   247 template <typename E,
   248           MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(E) AllBits>
   249 struct BitFlagsTypedEnumSerializer
   250   : EnumSerializer<E,
   251                    BitFlagsTypedEnumValidator<E, AllBits>>
   252 {};
   254 template <>
   255 struct ParamTraits<base::ChildPrivileges>
   256   : public ContiguousEnumSerializer<base::ChildPrivileges,
   257                                     base::PRIVILEGES_DEFAULT,
   258                                     base::PRIVILEGES_LAST>
   259 { };
   261 template<>
   262 struct ParamTraits<int8_t>
   263 {
   264   typedef int8_t paramType;
   266   static void Write(Message* aMsg, const paramType& aParam)
   267   {
   268     aMsg->WriteBytes(&aParam, sizeof(aParam));
   269   }
   271   static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
   272   {
   273     const char* outp;
   274     if (!aMsg->ReadBytes(aIter, &outp, sizeof(*aResult)))
   275       return false;
   277     *aResult = *reinterpret_cast<const paramType*>(outp);
   278     return true;
   279   }
   280 };
   282 template<>
   283 struct ParamTraits<uint8_t>
   284 {
   285   typedef uint8_t paramType;
   287   static void Write(Message* aMsg, const paramType& aParam)
   288   {
   289     aMsg->WriteBytes(&aParam, sizeof(aParam));
   290   }
   292   static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
   293   {
   294     const char* outp;
   295     if (!aMsg->ReadBytes(aIter, &outp, sizeof(*aResult)))
   296       return false;
   298     *aResult = *reinterpret_cast<const paramType*>(outp);
   299     return true;
   300   }
   301 };
   303 #if !defined(OS_POSIX)
   304 // See above re: keeping definitions in sync
   305 template<>
   306 struct ParamTraits<base::FileDescriptor>
   307 {
   308   typedef base::FileDescriptor paramType;
   309   static void Write(Message* aMsg, const paramType& aParam) {
   310     NS_RUNTIMEABORT("FileDescriptor isn't meaningful on this platform");
   311   }
   312   static bool Read(const Message* aMsg, void** aIter, paramType* aResult) {
   313     NS_RUNTIMEABORT("FileDescriptor isn't meaningful on this platform");
   314     return false;
   315   }
   316 };
   317 #endif  // !defined(OS_POSIX)
   319 template <>
   320 struct ParamTraits<nsACString>
   321 {
   322   typedef nsACString paramType;
   324   static void Write(Message* aMsg, const paramType& aParam)
   325   {
   326     bool isVoid = aParam.IsVoid();
   327     aMsg->WriteBool(isVoid);
   329     if (isVoid)
   330       // represents a nullptr pointer
   331       return;
   333     uint32_t length = aParam.Length();
   334     WriteParam(aMsg, length);
   335     aMsg->WriteBytes(aParam.BeginReading(), length);
   336   }
   338   static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
   339   {
   340     bool isVoid;
   341     if (!aMsg->ReadBool(aIter, &isVoid))
   342       return false;
   344     if (isVoid) {
   345       aResult->SetIsVoid(true);
   346       return true;
   347     }
   349     uint32_t length;
   350     if (ReadParam(aMsg, aIter, &length)) {
   351       const char* buf;
   352       if (aMsg->ReadBytes(aIter, &buf, length)) {
   353         aResult->Assign(buf, length);
   354         return true;
   355       }
   356     }
   357     return false;
   358   }
   360   static void Log(const paramType& aParam, std::wstring* aLog)
   361   {
   362     if (aParam.IsVoid())
   363       aLog->append(L"(NULL)");
   364     else
   365       aLog->append(UTF8ToWide(aParam.BeginReading()));
   366   }
   367 };
   369 template <>
   370 struct ParamTraits<nsAString>
   371 {
   372   typedef nsAString paramType;
   374   static void Write(Message* aMsg, const paramType& aParam)
   375   {
   376     bool isVoid = aParam.IsVoid();
   377     aMsg->WriteBool(isVoid);
   379     if (isVoid)
   380       // represents a nullptr pointer
   381       return;
   383     uint32_t length = aParam.Length();
   384     WriteParam(aMsg, length);
   385     aMsg->WriteBytes(aParam.BeginReading(), length * sizeof(char16_t));
   386   }
   388   static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
   389   {
   390     bool isVoid;
   391     if (!aMsg->ReadBool(aIter, &isVoid))
   392       return false;
   394     if (isVoid) {
   395       aResult->SetIsVoid(true);
   396       return true;
   397     }
   399     uint32_t length;
   400     if (ReadParam(aMsg, aIter, &length)) {
   401       const char16_t* buf;
   402       if (aMsg->ReadBytes(aIter, reinterpret_cast<const char**>(&buf),
   403                        length * sizeof(char16_t))) {
   404         aResult->Assign(buf, length);
   405         return true;
   406       }
   407     }
   408     return false;
   409   }
   411   static void Log(const paramType& aParam, std::wstring* aLog)
   412   {
   413     if (aParam.IsVoid())
   414       aLog->append(L"(NULL)");
   415     else {
   416 #ifdef WCHAR_T_IS_UTF16
   417       aLog->append(reinterpret_cast<const wchar_t*>(aParam.BeginReading()));
   418 #else
   419       uint32_t length = aParam.Length();
   420       for (uint32_t index = 0; index < length; index++) {
   421         aLog->push_back(std::wstring::value_type(aParam[index]));
   422       }
   423 #endif
   424     }
   425   }
   426 };
   428 template <>
   429 struct ParamTraits<nsCString> : ParamTraits<nsACString>
   430 {
   431   typedef nsCString paramType;
   432 };
   434 template <>
   435 struct ParamTraits<nsLiteralCString> : ParamTraits<nsACString>
   436 {
   437   typedef nsLiteralCString paramType;
   438 };
   440 #ifdef MOZILLA_INTERNAL_API
   442 template<>
   443 struct ParamTraits<nsAutoCString> : ParamTraits<nsCString>
   444 {
   445   typedef nsAutoCString paramType;
   446 };
   448 #endif  // MOZILLA_INTERNAL_API
   450 template <>
   451 struct ParamTraits<nsString> : ParamTraits<nsAString>
   452 {
   453   typedef nsString paramType;
   454 };
   456 template <>
   457 struct ParamTraits<nsLiteralString> : ParamTraits<nsAString>
   458 {
   459   typedef nsLiteralString paramType;
   460 };
   462 template <typename E>
   463 struct ParamTraits<FallibleTArray<E> >
   464 {
   465   typedef FallibleTArray<E> paramType;
   467   static void Write(Message* aMsg, const paramType& aParam)
   468   {
   469     uint32_t length = aParam.Length();
   470     WriteParam(aMsg, length);
   471     for (uint32_t index = 0; index < length; index++) {
   472       WriteParam(aMsg, aParam[index]);
   473     }
   474   }
   476   static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
   477   {
   478     uint32_t length;
   479     if (!ReadParam(aMsg, aIter, &length)) {
   480       return false;
   481     }
   483     aResult->SetCapacity(length);
   484     for (uint32_t index = 0; index < length; index++) {
   485       E* element = aResult->AppendElement();
   486       if (!(element && ReadParam(aMsg, aIter, element))) {
   487         return false;
   488       }
   489     }
   491     return true;
   492   }
   494   static void Log(const paramType& aParam, std::wstring* aLog)
   495   {
   496     for (uint32_t index = 0; index < aParam.Length(); index++) {
   497       if (index) {
   498         aLog->append(L" ");
   499       }
   500       LogParam(aParam[index], aLog);
   501     }
   502   }
   503 };
   505 template<typename E>
   506 struct ParamTraits<InfallibleTArray<E> >
   507 {
   508   typedef InfallibleTArray<E> paramType;
   510   static void Write(Message* aMsg, const paramType& aParam)
   511   {
   512     WriteParam(aMsg, static_cast<const FallibleTArray<E>&>(aParam));
   513   }
   515   // deserialize the array fallibly, but return an InfallibleTArray
   516   static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
   517   {
   518     FallibleTArray<E> temp;
   519     if (!ReadParam(aMsg, aIter, &temp))
   520       return false;
   522     aResult->SwapElements(temp);
   523     return true;
   524   }
   526   static void Log(const paramType& aParam, std::wstring* aLog)
   527   {
   528     LogParam(static_cast<const FallibleTArray<E>&>(aParam), aLog);
   529   }
   530 };
   532 template<>
   533 struct ParamTraits<float>
   534 {
   535   typedef float paramType;
   537   static void Write(Message* aMsg, const paramType& aParam)
   538   {
   539     aMsg->WriteBytes(&aParam, sizeof(paramType));
   540   }
   542   static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
   543   {
   544     const char* outFloat;
   545     if (!aMsg->ReadBytes(aIter, &outFloat, sizeof(float)))
   546       return false;
   547     *aResult = *reinterpret_cast<const float*>(outFloat);
   548     return true;
   549   }
   551   static void Log(const paramType& aParam, std::wstring* aLog)
   552   {
   553     aLog->append(StringPrintf(L"%g", aParam));
   554   }
   555 };
   557 template <>
   558 struct ParamTraits<nsCSSProperty>
   559   : public ContiguousEnumSerializer<nsCSSProperty,
   560                                     eCSSProperty_UNKNOWN,
   561                                     eCSSProperty_COUNT>
   562 {};
   564 template<>
   565 struct ParamTraits<mozilla::void_t>
   566 {
   567   typedef mozilla::void_t paramType;
   568   static void Write(Message* aMsg, const paramType& aParam) { }
   569   static bool
   570   Read(const Message* aMsg, void** aIter, paramType* aResult)
   571   {
   572     *aResult = paramType();
   573     return true;
   574   }
   575 };
   577 template<>
   578 struct ParamTraits<mozilla::null_t>
   579 {
   580   typedef mozilla::null_t paramType;
   581   static void Write(Message* aMsg, const paramType& aParam) { }
   582   static bool
   583   Read(const Message* aMsg, void** aIter, paramType* aResult)
   584   {
   585     *aResult = paramType();
   586     return true;
   587   }
   588 };
   590 template<>
   591 struct ParamTraits<nsID>
   592 {
   593   typedef nsID paramType;
   595   static void Write(Message* aMsg, const paramType& aParam)
   596   {
   597     WriteParam(aMsg, aParam.m0);
   598     WriteParam(aMsg, aParam.m1);
   599     WriteParam(aMsg, aParam.m2);
   600     for (unsigned int i = 0; i < mozilla::ArrayLength(aParam.m3); i++) {
   601       WriteParam(aMsg, aParam.m3[i]);
   602     }
   603   }
   605   static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
   606   {
   607     if(!ReadParam(aMsg, aIter, &(aResult->m0)) ||
   608        !ReadParam(aMsg, aIter, &(aResult->m1)) ||
   609        !ReadParam(aMsg, aIter, &(aResult->m2)))
   610       return false;
   612     for (unsigned int i = 0; i < mozilla::ArrayLength(aResult->m3); i++)
   613       if (!ReadParam(aMsg, aIter, &(aResult->m3[i])))
   614         return false;
   616     return true;
   617   }
   619   static void Log(const paramType& aParam, std::wstring* aLog)
   620   {
   621     aLog->append(L"{");
   622     aLog->append(StringPrintf(L"%8.8X-%4.4X-%4.4X-",
   623                               aParam.m0,
   624                               aParam.m1,
   625                               aParam.m2));
   626     for (unsigned int i = 0; i < mozilla::ArrayLength(aParam.m3); i++)
   627       aLog->append(StringPrintf(L"%2.2X", aParam.m3[i]));
   628     aLog->append(L"}");
   629   }
   630 };
   632 template<>
   633 struct ParamTraits<mozilla::TimeDuration>
   634 {
   635   typedef mozilla::TimeDuration paramType;
   636   static void Write(Message* aMsg, const paramType& aParam)
   637   {
   638     WriteParam(aMsg, aParam.mValue);
   639   }
   640   static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
   641   {
   642     return ReadParam(aMsg, aIter, &aResult->mValue);
   643   };
   644 };
   646 template<>
   647 struct ParamTraits<mozilla::TimeStamp>
   648 {
   649   typedef mozilla::TimeStamp paramType;
   650   static void Write(Message* aMsg, const paramType& aParam)
   651   {
   652     WriteParam(aMsg, aParam.mValue);
   653   }
   654   static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
   655   {
   656     return ReadParam(aMsg, aIter, &aResult->mValue);
   657   };
   658 };
   660 #ifdef XP_WIN
   662 template<>
   663 struct ParamTraits<mozilla::TimeStampValue>
   664 {
   665   typedef mozilla::TimeStampValue paramType;
   666   static void Write(Message* aMsg, const paramType& aParam)
   667   {
   668     WriteParam(aMsg, aParam.mGTC);
   669     WriteParam(aMsg, aParam.mQPC);
   670     WriteParam(aMsg, aParam.mHasQPC);
   671     WriteParam(aMsg, aParam.mIsNull);
   672   }
   673   static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
   674   {
   675     return (ReadParam(aMsg, aIter, &aResult->mGTC) &&
   676             ReadParam(aMsg, aIter, &aResult->mQPC) &&
   677             ReadParam(aMsg, aIter, &aResult->mHasQPC) &&
   678             ReadParam(aMsg, aIter, &aResult->mIsNull));
   679   }
   680 };
   682 #endif
   684 template <>
   685 struct ParamTraits<mozilla::SerializedStructuredCloneBuffer>
   686 {
   687   typedef mozilla::SerializedStructuredCloneBuffer paramType;
   689   static void Write(Message* aMsg, const paramType& aParam)
   690   {
   691     WriteParam(aMsg, aParam.dataLength);
   692     if (aParam.dataLength) {
   693       // Structured clone data must be 64-bit aligned.
   694       aMsg->WriteBytes(aParam.data, aParam.dataLength, sizeof(uint64_t));
   695     }
   696   }
   698   static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
   699   {
   700     if (!ReadParam(aMsg, aIter, &aResult->dataLength)) {
   701       return false;
   702     }
   704     if (aResult->dataLength) {
   705       const char** buffer =
   706         const_cast<const char**>(reinterpret_cast<char**>(&aResult->data));
   707       // Structured clone data must be 64-bit aligned.
   708       if (!aMsg->ReadBytes(aIter, buffer, aResult->dataLength,
   709                            sizeof(uint64_t))) {
   710         return false;
   711       }
   712     } else {
   713       aResult->data = nullptr;
   714     }
   716     return true;
   717   }
   719   static void Log(const paramType& aParam, std::wstring* aLog)
   720   {
   721     LogParam(aParam.dataLength, aLog);
   722   }
   723 };
   725 } /* namespace IPC */
   727 #endif /* __IPC_GLUE_IPCMESSAGEUTILS_H__ */

mercurial