Bug 1431760 - Add NS_MutateURI.Apply that allows calling methods declared in other interfaces implemented by NS_MutateURI::mMutator r=mayhemer

* The method can be chained just as the other methods on NS_MutateURI.
* In case the mutator object does not implement the interface, mStatus will be set to an error code.
* This is useful when you are constructing a new URI and the type of the mutator is known. I expect a future patch will add a MaybeApply method, that does not set mStatus to an error code if the mutator does not implement the interface.
* This patch changes nsHostObjectProtocolHandler::NewURI to use the new method and avoid a static_cast<nsHostObjectURI*>(uri)


MozReview-Commit-ID: 9kvXJX54gUP

--HG--
extra : rebase_source : 2a27778ec583251fac26c74d78125bd7266d6d87
This commit is contained in:
Valentin Gosu 2018-01-22 15:52:37 +01:00
Родитель 00db51f54b
Коммит a48c8f1ada
6 изменённых файлов: 92 добавлений и 9 удалений

Просмотреть файл

@ -892,20 +892,23 @@ nsHostObjectProtocolHandler::NewURI(const nsACString& aSpec,
DataInfo* info = GetDataInfo(aSpec);
nsCOMPtr<nsIPrincipal> principal;
RefPtr<mozilla::dom::BlobImpl> blob;
if (info && info->mObjectType == DataInfo::eBlobImpl) {
MOZ_ASSERT(info->mBlobImpl);
principal = info->mPrincipal;
blob = info->mBlobImpl;
}
nsCOMPtr<nsIURI> uri;
rv = NS_MutateURI(new nsHostObjectURI::Mutator())
.SetSpec(aSpec)
.Apply<nsIBlobURIMutator>(&nsIBlobURIMutator::SetBlobImpl, blob)
.Apply<nsIPrincipalURIMutator>(&nsIPrincipalURIMutator::SetPrincipal, principal)
.Finalize(uri);
NS_ENSURE_SUCCESS(rv, rv);
RefPtr<nsHostObjectURI> hostURI = static_cast<nsHostObjectURI*>(uri.get());
if (info && info->mObjectType == DataInfo::eBlobImpl) {
MOZ_ASSERT(info->mBlobImpl);
hostURI->mPrincipal = info->mPrincipal;
hostURI->mBlobImpl = info->mBlobImpl;
}
NS_TryToSetImmutable(hostURI);
NS_TryToSetImmutable(uri);
uri.forget(aResult);
if (info && info->mObjectType == DataInfo::eBlobImpl) {

Просмотреть файл

@ -230,7 +230,7 @@ nsHostObjectURI::EqualsInternal(nsIURI* aOther,
return NS_OK;
}
NS_IMPL_ISUPPORTS(nsHostObjectURI::Mutator, nsIURISetters, nsIURIMutator)
NS_IMPL_ISUPPORTS(nsHostObjectURI::Mutator, nsIURISetters, nsIURIMutator, nsIBlobURIMutator, nsIPrincipalURIMutator)
NS_IMETHODIMP
nsHostObjectURI::Mutate(nsIURIMutator** aMutator)

Просмотреть файл

@ -81,11 +81,33 @@ public:
class Mutator
: public nsIURIMutator
, public BaseURIMutator<nsHostObjectURI>
, public nsIBlobURIMutator
, public nsIPrincipalURIMutator
{
NS_DECL_ISUPPORTS
NS_FORWARD_SAFE_NSIURISETTERS_RET(mURI)
NS_DEFINE_NSIMUTATOR_COMMON
MOZ_MUST_USE NS_IMETHOD
SetBlobImpl(mozilla::dom::BlobImpl *aBlobImpl) override
{
if (!mURI) {
return NS_ERROR_NULL_POINTER;
}
mURI->mBlobImpl = aBlobImpl;
return NS_OK;
}
MOZ_MUST_USE NS_IMETHOD
SetPrincipal(nsIPrincipal *aPrincipal) override
{
if (!mURI) {
return NS_ERROR_NULL_POINTER;
}
mURI->mPrincipal = aPrincipal;
return NS_OK;
}
explicit Mutator() { }
private:
virtual ~Mutator() { }

Просмотреть файл

@ -369,6 +369,32 @@ public:
return *this;
}
/**
* This method allows consumers to call the methods declared in other
* interfaces implemented by the mutator object.
*
* Example:
* nsCOMPtr<nsIURI> uri;
* nsresult rv = NS_MutateURI(new URIClass::Mutator())
* .SetSpec(aSpec)
* .Apply<SomeInterface>(&SomeInterface::Method, arg1, arg2)
* .Finalize(uri);
*
* If mMutator does not implement SomeInterface, do_QueryInterface will fail
* and the method will not be called.
* If aMethod does not exist, or if there is a mismatch between argument
* types, or the number of arguments, then there will be a compile error.
*/
template <typename Interface, typename Method, typename... Args>
NS_MutateURI& Apply(Method aMethod, Args ...aArgs)
{
NS_ENSURE_SUCCESS(mStatus, *this);
nsCOMPtr<Interface> target = do_QueryInterface(mMutator, &mStatus);
NS_ENSURE_SUCCESS(mStatus, *this);
mStatus = (target->*aMethod)(aArgs...);
return *this;
}
template <class C>
MOZ_MUST_USE nsresult Finalize(nsCOMPtr<C>& aURI)
{

Просмотреть файл

@ -6,6 +6,15 @@
interface nsIURI;
%{C++
namespace mozilla {
namespace dom {
class BlobImpl;
}}
%}
[ptr] native BlobImplPtr(mozilla::dom::BlobImpl);
/**
* nsIURIWithBlobImpl is implemented by URIs which are associated with a
* specific BlobImpl.
@ -18,3 +27,14 @@ interface nsIURIWithBlobImpl : nsISupports
*/
readonly attribute nsISupports blobImpl;
};
[builtinclass, uuid(d3e8c9fa-ff07-47cc-90dc-0cc5445ddb59)]
interface nsIBlobURIMutator : nsISupports
{
/**
* Associates a blobImpl to the mutated URI.
* Would normally return nsIURIMutator, but since it only gets called
* from C++, there is no need for that.
*/
[must_use, noscript] void setBlobImpl(in BlobImplPtr blobImpl);
};

Просмотреть файл

@ -6,6 +6,7 @@
interface nsIPrincipal;
interface nsIURI;
interface nsIURIMutator;
/**
* nsIURIWithPrincipal is implemented by URIs which are associated with a
@ -25,3 +26,14 @@ interface nsIURIWithPrincipal : nsISupports
*/
readonly attribute nsIURI principalUri;
};
[builtinclass, uuid(fa138a89-c76e-4b7f-95ec-c7b56ded5ef5)]
interface nsIPrincipalURIMutator : nsISupports
{
/**
* Associates a principal to the mutated URI.
* Would normally return nsIURIMutator, but since it only gets called
* from C++, there is no need for that.
*/
[must_use, noscript] void setPrincipal(in nsIPrincipal aPrincipal);
};