michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * vim: sw=2 ts=2 et : michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef dom_plugins_PluginIdentifierChild_h michael@0: #define dom_plugins_PluginIdentifierChild_h michael@0: michael@0: #include "mozilla/plugins/PPluginIdentifierChild.h" michael@0: #include "npapi.h" michael@0: #include "npruntime.h" michael@0: michael@0: #include "nsString.h" michael@0: michael@0: namespace mozilla { michael@0: namespace plugins { michael@0: michael@0: class PluginModuleChild; michael@0: michael@0: /** michael@0: * Plugin identifiers may be "temporary", see the comment on the michael@0: * PPluginIdentifier constructor for details. This means that any IPDL method michael@0: * which receives a PPluginIdentifierChild* parameter must use StackIdentifier michael@0: * to track it. michael@0: */ michael@0: class PluginIdentifierChild : public PPluginIdentifierChild michael@0: { michael@0: friend class PluginModuleChild; michael@0: public: michael@0: bool IsString() michael@0: { michael@0: return mIsString; michael@0: } michael@0: michael@0: NPIdentifier ToNPIdentifier() michael@0: { michael@0: if (mCanonicalIdentifier) { michael@0: return mCanonicalIdentifier; michael@0: } michael@0: michael@0: NS_ASSERTION(mHashed, "Handing out an unhashed identifier?"); michael@0: return this; michael@0: } michael@0: michael@0: void MakePermanent(); michael@0: michael@0: class MOZ_STACK_CLASS StackIdentifier michael@0: { michael@0: public: michael@0: StackIdentifier(PPluginIdentifierChild* actor) michael@0: : mIdentifier(static_cast(actor)) michael@0: { michael@0: if (mIdentifier) michael@0: mIdentifier->StartTemporary(); michael@0: } michael@0: michael@0: ~StackIdentifier() { michael@0: if (mIdentifier) michael@0: mIdentifier->FinishTemporary(); michael@0: } michael@0: michael@0: PluginIdentifierChild* operator->() { return mIdentifier; } michael@0: michael@0: private: michael@0: PluginIdentifierChild* mIdentifier; michael@0: }; michael@0: michael@0: protected: michael@0: PluginIdentifierChild(bool aIsString) michael@0: : mCanonicalIdentifier(nullptr) michael@0: , mHashed(false) michael@0: , mTemporaryRefs(0) michael@0: , mIsString(aIsString) michael@0: { michael@0: MOZ_COUNT_CTOR(PluginIdentifierChild); michael@0: } michael@0: michael@0: virtual ~PluginIdentifierChild() michael@0: { michael@0: MOZ_COUNT_DTOR(PluginIdentifierChild); michael@0: } michael@0: michael@0: // The following functions are implemented by the subclasses for their michael@0: // identifier maps. michael@0: virtual PluginIdentifierChild* GetCanonical() = 0; michael@0: virtual void Hash() = 0; michael@0: virtual void Unhash() = 0; michael@0: michael@0: private: michael@0: void StartTemporary(); michael@0: void FinishTemporary(); michael@0: michael@0: // There's a possibility that we already have an actor that wraps the same michael@0: // string or int because we do all this identifier construction michael@0: // asynchronously. In this case we need to hand out the canonical version michael@0: // created by the child side. michael@0: // michael@0: // In order to deal with temporary identifiers which appear on the stack, michael@0: // identifiers use the following state invariants: michael@0: // michael@0: // * mCanonicalIdentifier is non-nullptr: this is a duplicate identifier, no michael@0: // further information is necessary. michael@0: // * mHashed is false: this identifier is a newborn, non-permanent identifier michael@0: // * mHashed is true, mTemporaryRefs is 0: this identifier is permanent michael@0: // * mHashed is true, mTemporaryRefs is non-0: this identifier is temporary; michael@0: // if NPN_GetFooIdentifier is called for it, we need to retain it. If michael@0: // all stack references are lost, unhash it because it will soon be michael@0: // deleted. michael@0: michael@0: PluginIdentifierChild* mCanonicalIdentifier; michael@0: bool mHashed; michael@0: unsigned int mTemporaryRefs; michael@0: bool mIsString; michael@0: }; michael@0: michael@0: class PluginIdentifierChildString : public PluginIdentifierChild michael@0: { michael@0: friend class PluginModuleChild; michael@0: public: michael@0: NPUTF8* ToString() michael@0: { michael@0: return ToNewCString(mString); michael@0: } michael@0: michael@0: protected: michael@0: PluginIdentifierChildString(const nsCString& aString) michael@0: : PluginIdentifierChild(true), michael@0: mString(aString) michael@0: { } michael@0: michael@0: virtual PluginIdentifierChild* GetCanonical(); michael@0: virtual void Hash(); michael@0: virtual void Unhash(); michael@0: michael@0: nsCString mString; michael@0: }; michael@0: michael@0: class PluginIdentifierChildInt : public PluginIdentifierChild michael@0: { michael@0: friend class PluginModuleChild; michael@0: public: michael@0: int32_t ToInt() michael@0: { michael@0: return mInt; michael@0: } michael@0: michael@0: protected: michael@0: PluginIdentifierChildInt(int32_t aInt) michael@0: : PluginIdentifierChild(false), michael@0: mInt(aInt) michael@0: { } michael@0: michael@0: virtual PluginIdentifierChild* GetCanonical(); michael@0: virtual void Hash(); michael@0: virtual void Unhash(); michael@0: michael@0: int32_t mInt; michael@0: }; michael@0: michael@0: } // namespace plugins michael@0: } // namespace mozilla michael@0: michael@0: #endif // dom_plugins_PluginIdentifierChild_h