DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (b6d82b1a6b02)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef _WEBRTC_IPC_TRAITS_H_
#define _WEBRTC_IPC_TRAITS_H_

#include "ipc/IPCMessageUtils.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/RTCConfigurationBinding.h"
#include "mozilla/media/webrtc/WebrtcGlobal.h"
#include "mozilla/dom/CandidateInfo.h"
#include "mozilla/MacroForEach.h"
#include "mtransport/transportlayerdtls.h"
#include <vector>

namespace mozilla {
typedef std::vector<std::string> StringVector;
}

namespace IPC {

template <typename T>
struct ParamTraits<std::vector<T>> {
  typedef std::vector<T> paramType;

  static void Write(Message* aMsg, const paramType& aParam) {
    aMsg->WriteUInt32(aParam.size());
    for (const T& elem : aParam) {
      WriteParam(aMsg, elem);
    }
  }

  static bool Read(const Message* aMsg, PickleIterator* aIter,
                   paramType* aResult) {
    uint32_t size;
    if (!aMsg->ReadUInt32(aIter, &size)) {
      return false;
    }
    while (size--) {
      // Only works when T is movable. Meh.
      T elem;
      if (!ReadParam(aMsg, aIter, &elem)) {
        return false;
      }
      aResult->emplace_back(std::move(elem));
    }

    return true;
  }
};

template <>
struct ParamTraits<mozilla::dom::OwningStringOrStringSequence> {
  typedef mozilla::dom::OwningStringOrStringSequence paramType;

  // Ugh. OwningStringOrStringSequence already has this enum, but it is
  // private generated code. So we have to re-create it.
  enum Type { kUninitialized, kString, kStringSequence };

  static void Write(Message* aMsg, const paramType& aParam) {
    if (aParam.IsString()) {
      aMsg->WriteInt16(kString);
      WriteParam(aMsg, aParam.GetAsString());
    } else if (aParam.IsStringSequence()) {
      aMsg->WriteInt16(kStringSequence);
      WriteParam(aMsg, aParam.GetAsStringSequence());
    } else {
      aMsg->WriteInt16(kUninitialized);
    }
  }

  static bool Read(const Message* aMsg, PickleIterator* aIter,
                   paramType* aResult) {
    int16_t type;
    if (!aMsg->ReadInt16(aIter, &type)) {
      return false;
    }

    switch (type) {
      case kUninitialized:
        aResult->Uninit();
        return true;
      case kString:
        return ReadParam(aMsg, aIter, &aResult->SetAsString());
      case kStringSequence:
        return ReadParam(aMsg, aIter, &aResult->SetAsStringSequence());
    }

    return false;
  }
};

template <typename T>
struct WebidlEnumSerializer
    : public ContiguousEnumSerializer<T, T(0), T::EndGuard_> {};

template <>
struct ParamTraits<mozilla::dom::RTCIceCredentialType>
    : public WebidlEnumSerializer<mozilla::dom::RTCIceCredentialType> {};

template <>
struct ParamTraits<mozilla::dom::RTCIceTransportPolicy>
    : public WebidlEnumSerializer<mozilla::dom::RTCIceTransportPolicy> {};

// A couple of recursive helper functions, allows syntax like:
// WriteParams(aMsg, aParam.foo, aParam.bar, aParam.baz)
// ReadParams(aMsg, aIter, aParam.foo, aParam.bar, aParam.baz)

// Base case
static void WriteParams(Message* aMsg) {}

template <typename T0, typename... Tn>
static void WriteParams(Message* aMsg, const T0& aArg,
                        const Tn&... aRemainingArgs) {
  WriteParam(aMsg, aArg);                // Write first arg
  WriteParams(aMsg, aRemainingArgs...);  // Recurse for the rest
}

// Base case
static bool ReadParams(const Message* aMsg, PickleIterator* aIter) {
  return true;
}

template <typename T0, typename... Tn>
static bool ReadParams(const Message* aMsg, PickleIterator* aIter, T0& aArg,
                       Tn&... aRemainingArgs) {
  return ReadParam(aMsg, aIter, &aArg) &&             // Read first arg
         ReadParams(aMsg, aIter, aRemainingArgs...);  // Recurse for the rest
}

// Macros that allow syntax like:
// DEFINE_IPC_SERIALIZER_WITH_FIELDS(SomeType, member1, member2, member3)
// Makes sure that serialize/deserialize code do the same members in the same
// order.
#define ACCESS_PARAM_FIELD(Field) aParam.Field

#define DEFINE_IPC_SERIALIZER_WITH_FIELDS(Type, ...)                         \
  template <>                                                                \
  struct ParamTraits<Type> {                                                 \
    typedef Type paramType;                                                  \
    static void Write(Message* aMsg, const paramType& aParam) {              \
      WriteParams(aMsg, MOZ_FOR_EACH_SEPARATED(ACCESS_PARAM_FIELD, (, ), (), \
                                               (__VA_ARGS__)));              \
    }                                                                        \
                                                                             \
    static bool Read(const Message* aMsg, PickleIterator* aIter,             \
                     paramType* aResult) {                                   \
      paramType& aParam = *aResult;                                          \
      return ReadParams(aMsg, aIter,                                         \
                        MOZ_FOR_EACH_SEPARATED(ACCESS_PARAM_FIELD, (, ), (), \
                                               (__VA_ARGS__)));              \
    }                                                                        \
  };

DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::dom::RTCIceServer, mCredential,
                                  mCredentialType, mUrl, mUrls, mUsername)

DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::CandidateInfo, mCandidate, mUfrag,
                                  mDefaultHostRtp, mDefaultPortRtp,
                                  mDefaultHostRtcp, mDefaultPortRtcp,
                                  mMDNSAddress, mActualAddress)

DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::DtlsDigest, algorithm_, value_)

}  // namespace IPC

#endif  // _WEBRTC_IPC_TRAITS_H_