diff --git a/dom/plugins/ipc/IpdlTuple.h b/dom/plugins/ipc/IpdlTuple.h new file mode 100644 index 000000000000..175289e0c4bd --- /dev/null +++ b/dom/plugins/ipc/IpdlTuple.h @@ -0,0 +1,184 @@ +#ifndef dom_plugins_ipc_ipdltuple_h +#define dom_plugins_ipc_ipdltuple_h + +#include "mozilla/plugins/FunctionBrokerIPCUtils.h" +#include "mozilla/Variant.h" + +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 + EltType* Element(uint32_t index) + { + if ((index >= mTupleElements.Length()) || + !mTupleElements[index].GetVariant().is()) { + return nullptr; + } + return &mTupleElements[index].GetVariant().as(); + } + + template + const EltType* Element(uint32_t index) const + { + return const_cast(this)->Element(index); + } + + template + void AddElement(const EltType& aElt) + { + IpdlTupleElement* newEntry = mTupleElements.AppendElement(); + newEntry->Set(aElt); + } + +private: + struct InvalidType {}; + + // Like Variant but with a default constructor. + template + struct MaybeVariant + { + public: + MaybeVariant() : mValue(InvalidType()) {} + MaybeVariant(MaybeVariant&& o) : mValue(Move(o.mValue)) {} + + template void Set(const Param& aParam) + { + mValue = mozilla::AsVariant(aParam); + } + + typedef mozilla::Variant MaybeVariantType; + MaybeVariantType& GetVariant() { return mValue; } + const MaybeVariantType& GetVariant() const { return mValue; } + + private: + MaybeVariantType mValue; + }; + +#if defined(XP_WIN) + typedef MaybeVariant IpdlTupleElement; +#else + typedef MaybeVariant IpdlTupleElement; +#endif // defined(XP_WIN) + + friend struct IPC::ParamTraits; + friend struct IPC::ParamTraits; + friend struct IPC::ParamTraits; + + nsTArray mTupleElements; +}; + +template <> template<> +inline void IpdlTuple::IpdlTupleElement::Set(const nsDependentCSubstring& aParam) +{ + mValue = MaybeVariantType(mozilla::VariantType(), aParam); +} + +} // namespace plugins +} // namespace mozilla + +namespace IPC { + +using namespace mozilla::plugins; + +template <> +struct ParamTraits +{ + 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 +{ + typedef IpdlTuple::IpdlTupleElement paramType; + + static void Write(Message* aMsg, const paramType& aParam) + { + MOZ_RELEASE_ASSERT(!aParam.GetVariant().is()); + 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()); + return ret; + } + + struct LogMatcher + { + explicit LogMatcher(std::wstring* aLog) : mLog(aLog) {} + + template + void match(const EntryType& aParam) + { + LogParam(aParam, mLog); + } + + private: + std::wstring* mLog; + }; + + static void Log(const paramType& aParam, std::wstring* aLog) + { + aParam.GetVariant().match(LogMatcher(aLog)); + } +}; + +template<> +struct ParamTraits +{ + 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""); + } +}; + +} // namespace IPC + +#endif /* dom_plugins_ipc_ipdltuple_h */