summaryrefslogtreecommitdiffstats
path: root/dom/plugins/ipc/IpdlTuple.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/plugins/ipc/IpdlTuple.h')
-rw-r--r--dom/plugins/ipc/IpdlTuple.h186
1 files changed, 186 insertions, 0 deletions
diff --git a/dom/plugins/ipc/IpdlTuple.h b/dom/plugins/ipc/IpdlTuple.h
new file mode 100644
index 0000000000..06db9bfddb
--- /dev/null
+++ b/dom/plugins/ipc/IpdlTuple.h
@@ -0,0 +1,186 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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 dom_plugins_ipc_ipdltuple_h
+#define dom_plugins_ipc_ipdltuple_h
+
+#include "ipc/IPCMessageUtilsSpecializations.h"
+#include "mozilla/plugins/FunctionBrokerIPCUtils.h"
+#include "mozilla/Variant.h"
+
+namespace mozilla {
+namespace plugins {
+
+// The stuff in this "internal" namespace used to be inside the IpdlTuple
+// class, but that prevented the MOZ_DECLARE_RELOCATE_USING_MOVE_CONSTRUCTOR
+// that is needed on the IpdlTupleElement struct. Without this, nsTArray can end
+// up using a move constructor on this struct, which is not memmovable on
+// Windows.
+namespace internal {
+
+struct InvalidType {};
+
+// Like Variant but with a default constructor.
+template <typename... Types>
+struct MaybeVariant {
+ public:
+ MaybeVariant() : mValue(InvalidType()) {}
+ MaybeVariant(MaybeVariant&& o) : mValue(std::move(o.mValue)) {}
+
+ template <typename Param>
+ void Set(const Param& aParam) {
+ mValue = mozilla::AsVariant(aParam);
+ }
+
+ typedef mozilla::Variant<InvalidType, Types...> MaybeVariantType;
+ MaybeVariantType& GetVariant() { return mValue; }
+ const MaybeVariantType& GetVariant() const { return mValue; }
+
+ private:
+ MaybeVariantType mValue;
+};
+
+#if defined(XP_WIN)
+typedef MaybeVariant<int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t,
+ int64_t, uint64_t, nsCString, nsString, bool,
+ OpenFileNameIPC, OpenFileNameRetIPC, NativeWindowHandle,
+ IPCSchannelCred, IPCInternetBuffers, StringArray,
+ IPCPrintDlg>
+ IpdlTupleElement;
+#else
+typedef MaybeVariant<int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t,
+ int64_t, uint64_t, nsCString, nsString, bool>
+ IpdlTupleElement;
+#endif // defined(XP_WIN)
+
+} // namespace internal
+} // namespace plugins
+} // namespace mozilla
+
+MOZ_DECLARE_RELOCATE_USING_MOVE_CONSTRUCTOR(
+ mozilla::plugins::internal::IpdlTupleElement)
+
+namespace mozilla {
+namespace plugins {
+
+/**
+ * IpdlTuple is used by automatic function brokering to pass parameter
+ * lists for brokered functions. It supports a limited set of types
+ * (see IpdlTuple::IpdlTupleElement).
+ */
+class IpdlTuple {
+ public:
+ uint32_t NumElements() const { return mTupleElements.Length(); }
+
+ template <typename EltType>
+ EltType* Element(uint32_t index) {
+ if ((index >= mTupleElements.Length()) ||
+ !mTupleElements[index].GetVariant().is<EltType>()) {
+ return nullptr;
+ }
+ return &mTupleElements[index].GetVariant().as<EltType>();
+ }
+
+ template <typename EltType>
+ const EltType* Element(uint32_t index) const {
+ return const_cast<IpdlTuple*>(this)->Element<EltType>(index);
+ }
+
+ template <typename EltType>
+ void AddElement(const EltType& aElt) {
+ IpdlTupleElement* newEntry = mTupleElements.AppendElement();
+ newEntry->Set(aElt);
+ }
+
+ private:
+ typedef mozilla::plugins::internal::InvalidType InvalidType;
+ typedef mozilla::plugins::internal::IpdlTupleElement IpdlTupleElement;
+
+ friend struct IPC::ParamTraits<IpdlTuple>;
+ friend struct IPC::ParamTraits<IpdlTuple::IpdlTupleElement>;
+ friend struct IPC::ParamTraits<IpdlTuple::InvalidType>;
+
+ nsTArray<IpdlTupleElement> mTupleElements;
+};
+
+namespace internal {
+template <>
+template <>
+inline void IpdlTupleElement::Set<nsDependentCSubstring>(
+ const nsDependentCSubstring& aParam) {
+ mValue = MaybeVariantType(mozilla::VariantType<nsCString>(), aParam);
+}
+} // namespace internal
+
+} // namespace plugins
+} // namespace mozilla
+
+namespace IPC {
+
+using namespace mozilla::plugins;
+
+template <>
+struct ParamTraits<IpdlTuple> {
+ typedef IpdlTuple paramType;
+
+ static void Write(Message* aMsg, const paramType& aParam) {
+ WriteParam(aMsg, aParam.mTupleElements);
+ }
+
+ static bool Read(const Message* aMsg, PickleIterator* aIter,
+ paramType* aParam) {
+ return ReadParam(aMsg, aIter, &aParam->mTupleElements);
+ }
+
+ static void Log(const paramType& aParam, std::wstring* aLog) {
+ LogParam(aParam.mTupleElements, aLog);
+ }
+};
+
+template <>
+struct ParamTraits<IpdlTuple::IpdlTupleElement> {
+ typedef IpdlTuple::IpdlTupleElement paramType;
+
+ static void Write(Message* aMsg, const paramType& aParam) {
+ MOZ_RELEASE_ASSERT(!aParam.GetVariant().is<IpdlTuple::InvalidType>());
+ WriteParam(aMsg, aParam.GetVariant());
+ }
+
+ static bool Read(const Message* aMsg, PickleIterator* aIter,
+ paramType* aParam) {
+ bool ret = ReadParam(aMsg, aIter, &aParam->GetVariant());
+ MOZ_RELEASE_ASSERT(!aParam->GetVariant().is<IpdlTuple::InvalidType>());
+ return ret;
+ }
+
+ static void Log(const paramType& aParam, std::wstring* aLog) {
+ aParam.GetVariant().match(
+ [aLog](const auto& aParam) { LogParam(aParam, aLog); });
+ }
+};
+
+template <>
+struct ParamTraits<IpdlTuple::InvalidType> {
+ typedef IpdlTuple::InvalidType paramType;
+
+ static void Write(Message* aMsg, const paramType& aParam) {
+ MOZ_ASSERT_UNREACHABLE("Attempt to serialize an invalid tuple element");
+ }
+
+ static bool Read(const Message* aMsg, PickleIterator* aIter,
+ paramType* aParam) {
+ MOZ_ASSERT_UNREACHABLE("Attempt to deserialize an invalid tuple element");
+ return false;
+ }
+
+ static void Log(const paramType& aParam, std::wstring* aLog) {
+ aLog->append(L"<Invalid Tuple Entry>");
+ }
+};
+
+} // namespace IPC
+
+#endif /* dom_plugins_ipc_ipdltuple_h */