tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

IPCMessageUtils.h (8397B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 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/. */
      6 
      7 #ifndef __IPC_GLUE_IPCMESSAGEUTILS_H__
      8 #define __IPC_GLUE_IPCMESSAGEUTILS_H__
      9 
     10 #include <cstdint>
     11 #include "chrome/common/ipc_message.h"
     12 #include "chrome/common/ipc_message_utils.h"
     13 #include "mozilla/ipc/IPCCore.h"
     14 #include "mozilla/MacroForEach.h"
     15 
     16 class PickleIterator;
     17 
     18 // XXX Things that are not necessary if moving implementations to the cpp file
     19 #include "base/string_util.h"
     20 
     21 #ifdef _MSC_VER
     22 #  pragma warning(disable : 4800)
     23 #endif
     24 
     25 #if !defined(XP_UNIX)
     26 // This condition must be kept in sync with the one in
     27 // ipc_message_utils.h, but this dummy definition of
     28 // base::FileDescriptor acts as a static assert that we only get one
     29 // def or the other (or neither, in which case code using
     30 // FileDescriptor fails to build)
     31 namespace base {
     32 struct FileDescriptor {};
     33 }  // namespace base
     34 #endif
     35 
     36 namespace mozilla {
     37 template <typename...>
     38 class Variant;
     39 
     40 namespace detail {
     41 template <typename...>
     42 struct VariantTag;
     43 }
     44 }  // namespace mozilla
     45 
     46 namespace IPC {
     47 
     48 /**
     49 * A helper class for serializing empty structs. Since the struct is empty there
     50 * is nothing to write, and a priori we know the result of the read.
     51 */
     52 template <typename T>
     53 struct EmptyStructSerializer {
     54  typedef T paramType;
     55 
     56  static void Write(MessageWriter* aWriter, const paramType& aParam) {}
     57 
     58  static bool Read(MessageReader* aReader, paramType* aResult) {
     59    *aResult = {};
     60    return true;
     61  }
     62 };
     63 
     64 template <>
     65 struct ParamTraits<int8_t> {
     66  typedef int8_t paramType;
     67 
     68  static void Write(MessageWriter* aWriter, const paramType& aParam) {
     69    aWriter->WriteBytes(&aParam, sizeof(aParam));
     70  }
     71 
     72  static bool Read(MessageReader* aReader, paramType* aResult) {
     73    return aReader->ReadBytesInto(aResult, sizeof(*aResult));
     74  }
     75 };
     76 
     77 template <>
     78 struct ParamTraits<uint8_t> {
     79  typedef uint8_t paramType;
     80 
     81  static void Write(MessageWriter* aWriter, const paramType& aParam) {
     82    aWriter->WriteBytes(&aParam, sizeof(aParam));
     83  }
     84 
     85  static bool Read(MessageReader* aReader, paramType* aResult) {
     86    return aReader->ReadBytesInto(aResult, sizeof(*aResult));
     87  }
     88 };
     89 
     90 #if !defined(XP_UNIX)
     91 // See above re: keeping definitions in sync
     92 template <>
     93 struct ParamTraits<base::FileDescriptor> {
     94  typedef base::FileDescriptor paramType;
     95  static void Write(MessageWriter* aWriter, const paramType& aParam) {
     96    MOZ_CRASH("FileDescriptor isn't meaningful on this platform");
     97  }
     98  static bool Read(MessageReader* aReader, paramType* aResult) {
     99    MOZ_CRASH("FileDescriptor isn't meaningful on this platform");
    100    return false;
    101  }
    102 };
    103 #endif  // !defined(XP_UNIX)
    104 
    105 template <>
    106 struct ParamTraits<mozilla::void_t> {
    107  typedef mozilla::void_t paramType;
    108  static void Write(MessageWriter* aWriter, const paramType& aParam) {}
    109  static bool Read(MessageReader* aReader, paramType* aResult) {
    110    *aResult = paramType();
    111    return true;
    112  }
    113 };
    114 
    115 template <>
    116 struct ParamTraits<mozilla::null_t> {
    117  typedef mozilla::null_t paramType;
    118  static void Write(MessageWriter* aWriter, const paramType& aParam) {}
    119  static bool Read(MessageReader* aReader, paramType* aResult) {
    120    *aResult = paramType();
    121    return true;
    122  }
    123 };
    124 
    125 // Helper class for reading bitfields.
    126 // If T has bitfields members, derive ParamTraits<T> from BitfieldHelper<T>.
    127 template <typename ParamType>
    128 struct BitfieldHelper {
    129  // We need this helper because we can't get the address of a bitfield to
    130  // pass directly to ReadParam. So instead we read it into a temporary bool
    131  // and set the bitfield using a setter function
    132  static bool ReadBoolForBitfield(MessageReader* aReader, ParamType* aResult,
    133                                  void (ParamType::*aSetter)(bool)) {
    134    bool value;
    135    if (ReadParam(aReader, &value)) {
    136      (aResult->*aSetter)(value);
    137      return true;
    138    }
    139    return false;
    140  }
    141 };
    142 
    143 // A couple of recursive helper functions, allows syntax like:
    144 // WriteParams(aMsg, aParam.foo, aParam.bar, aParam.baz)
    145 // ReadParams(aMsg, aIter, aParam.foo, aParam.bar, aParam.baz)
    146 
    147 template <typename... Ts>
    148 static void WriteParams(MessageWriter* aWriter, const Ts&... aArgs) {
    149  (WriteParam(aWriter, aArgs), ...);
    150 }
    151 
    152 template <typename... Ts>
    153 static bool ReadParams(MessageReader* aReader, Ts&... aArgs) {
    154  return (ReadParam(aReader, &aArgs) && ...);
    155 }
    156 
    157 // Macros that allow syntax like:
    158 // DEFINE_IPC_SERIALIZER_WITH_FIELDS(SomeType, member1, member2, member3)
    159 // Makes sure that serialize/deserialize code do the same members in the same
    160 // order.
    161 #define ACCESS_PARAM_FIELD(Field) aParam.Field
    162 
    163 #define DEFINE_IPC_SERIALIZER_WITH_FIELDS(Type, ...)                         \
    164  template <>                                                                \
    165  struct ParamTraits<Type> {                                                 \
    166    typedef Type paramType;                                                  \
    167    static void Write(MessageWriter* aWriter, const paramType& aParam) {     \
    168      WriteParams(aWriter, MOZ_FOR_EACH_SEPARATED(ACCESS_PARAM_FIELD, (, ),  \
    169                                                  (), (__VA_ARGS__)));       \
    170    }                                                                        \
    171                                                                             \
    172    static bool Read(MessageReader* aReader, paramType* aResult) {           \
    173      paramType& aParam = *aResult;                                          \
    174      return ReadParams(aReader,                                             \
    175                        MOZ_FOR_EACH_SEPARATED(ACCESS_PARAM_FIELD, (, ), (), \
    176                                               (__VA_ARGS__)));              \
    177    }                                                                        \
    178  };
    179 
    180 #define DEFINE_IPC_SERIALIZER_WITHOUT_FIELDS(Type) \
    181  template <>                                      \
    182  struct ParamTraits<Type> : public EmptyStructSerializer<Type> {};
    183 
    184 } /* namespace IPC */
    185 
    186 #define DEFINE_IPC_SERIALIZER_WITH_SUPER_CLASS(Type, Super)              \
    187  template <>                                                            \
    188  struct ParamTraits<Type> {                                             \
    189    typedef Type paramType;                                              \
    190    static void Write(MessageWriter* aWriter, const paramType& aParam) { \
    191      WriteParam(aWriter, static_cast<const Super&>(aParam));            \
    192    }                                                                    \
    193                                                                         \
    194    static bool Read(MessageReader* aReader, paramType* aResult) {       \
    195      return ReadParam(aReader, static_cast<Super*>(aResult));           \
    196    }                                                                    \
    197  };
    198 
    199 #define DEFINE_IPC_SERIALIZER_WITH_SUPER_CLASS_AND_FIELDS(Type, Super, ...)  \
    200  template <>                                                                \
    201  struct ParamTraits<Type> {                                                 \
    202    typedef Type paramType;                                                  \
    203    static void Write(MessageWriter* aWriter, const paramType& aParam) {     \
    204      WriteParam(aWriter, static_cast<const Super&>(aParam));                \
    205      WriteParams(aWriter, MOZ_FOR_EACH_SEPARATED(ACCESS_PARAM_FIELD, (, ),  \
    206                                                  (), (__VA_ARGS__)));       \
    207    }                                                                        \
    208                                                                             \
    209    static bool Read(MessageReader* aReader, paramType* aResult) {           \
    210      paramType& aParam = *aResult;                                          \
    211      return ReadParam(aReader, static_cast<Super*>(aResult)) &&             \
    212             ReadParams(aReader,                                             \
    213                        MOZ_FOR_EACH_SEPARATED(ACCESS_PARAM_FIELD, (, ), (), \
    214                                               (__VA_ARGS__)));              \
    215    }                                                                        \
    216  };
    217 
    218 #endif /* __IPC_GLUE_IPCMESSAGEUTILS_H__ */