Bug 1432602 - Add nsIFileURLMutator.setFile() r=mayhemer
authorValentin Gosu <valentin.gosu@gmail.com>
Wed, 31 Jan 2018 22:40:45 +0100
changeset 401980 a20fbbe7b9489c90afddca712925320475083590
parent 401979 55667c8b5262b5e888a252c457b95989d38c679e
child 401981 8b075bb31f5f203dc6d49ef9391a10344a5633cc
push id33359
push usernbeleuzu@mozilla.com
push dateThu, 01 Feb 2018 10:01:45 +0000
treeherdermozilla-central@1fac52e0d5b4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmayhemer
bugs1432602
milestone60.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1432602 - Add nsIFileURLMutator.setFile() r=mayhemer MozReview-Commit-ID: EF2vVYoN8bg
dom/webbrowserpersist/nsWebBrowserPersist.cpp
netwerk/base/nsIFileURL.idl
netwerk/base/nsStandardURL.cpp
netwerk/base/nsStandardURL.h
netwerk/protocol/res/SubstitutingProtocolHandler.cpp
netwerk/protocol/res/SubstitutingProtocolHandler.h
--- a/dom/webbrowserpersist/nsWebBrowserPersist.cpp
+++ b/dom/webbrowserpersist/nsWebBrowserPersist.cpp
@@ -2108,20 +2108,20 @@ nsWebBrowserPersist::CalculateUniqueFile
 
         if (localFile)
         {
             nsAutoString filenameAsUnichar;
             CopyASCIItoUTF16(filename, filenameAsUnichar);
             localFile->SetLeafName(filenameAsUnichar);
 
             // Resync the URI with the file after the extension has been appended
-            nsresult rv;
-            nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(aURI, &rv);
-            NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
-            fileURL->SetFile(localFile);  // this should recalculate uri
+            return NS_MutateURI(aURI)
+                     .Apply<nsIFileURLMutator>(&nsIFileURLMutator::SetFile,
+                                               localFile)
+                     .Finalize(aOutURI);
         }
         else
         {
             return NS_MutateURI(url)
                      .Apply<nsIURLMutator>(&nsIURLMutator::SetFileName,
                                            filename,
                                            nullptr)
                      .Finalize(aOutURI);
@@ -2287,19 +2287,20 @@ nsWebBrowserPersist::CalculateAndAppendF
                     newFileName.Append(fileExt);
                 }
 
                 if (localFile)
                 {
                     localFile->SetLeafName(NS_ConvertUTF8toUTF16(newFileName));
 
                     // Resync the URI with the file after the extension has been appended
-                    nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(aURI, &rv);
-                    NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
-                    fileURL->SetFile(localFile);  // this should recalculate uri
+                    return NS_MutateURI(aURI)
+                             .Apply<nsIFileURLMutator>(&nsIFileURLMutator::SetFile,
+                                                   localFile)
+                             .Finalize(aOutURI);
                 }
                 else
                 {
                     return NS_MutateURI(url)
                              .Apply<nsIURLMutator>(&nsIURLMutator::SetFileName,
                                                    newFileName,
                                                    nullptr)
                              .Finalize(aOutURI);
--- a/netwerk/base/nsIFileURL.idl
+++ b/netwerk/base/nsIFileURL.idl
@@ -1,29 +1,37 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* 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/. */
 
 #include "nsIURL.idl"
 
 interface nsIFile;
+interface nsIURIMutator;
 
 /**
  * nsIFileURL provides access to the underlying nsIFile object corresponding to
  * an URL.  The URL scheme need not be file:, since other local protocols may
  * map URLs to files (e.g., resource:).
  */
 [scriptable, builtinclass, uuid(e91ac988-27c2-448b-b1a1-3822e1ef1987)]
 interface nsIFileURL : nsIURL
 {
     /**
      * Get/Set nsIFile corresponding to this URL.
      *
      *  - Getter returns a reference to an immutable object.  Callers must clone
      *    before attempting to modify the returned nsIFile object.  NOTE: this
      *    constraint might not be enforced at runtime, so beware!!
-     *
+     */
+    attribute nsIFile file;
+};
+
+[scriptable, builtinclass, uuid(a588b6f2-d2b9-4024-84c7-be3368546b57)]
+interface nsIFileURLMutator : nsISupports
+{
+    /*
      *  - Setter clones the nsIFile object (allowing the caller to safely modify
      *    the nsIFile object after setting it on this interface).
      */
-    attribute nsIFile file;
+    [must_use, noscript] void setFile(in nsIFile aFile);
 };
--- a/netwerk/base/nsStandardURL.cpp
+++ b/netwerk/base/nsStandardURL.cpp
@@ -2222,17 +2222,22 @@ nsStandardURL::SetPathQueryRef(const nsA
         mExtension.mLen = -1;
         mQuery.mLen = -1;
         mRef.mLen = -1;
     }
     return NS_OK;
 }
 
 // When updating this also update SubstitutingURL::Mutator
-NS_IMPL_ISUPPORTS(nsStandardURL::Mutator, nsIURISetters, nsIURIMutator, nsIStandardURLMutator, nsIURLMutator)
+NS_IMPL_ISUPPORTS(nsStandardURL::Mutator,
+                  nsIURISetters,
+                  nsIURIMutator,
+                  nsIStandardURLMutator,
+                  nsIURLMutator,
+                  nsIFileURLMutator)
 
 NS_IMETHODIMP
 nsStandardURL::Mutate(nsIURIMutator** aMutator)
 {
     RefPtr<nsStandardURL::Mutator> mutator = new nsStandardURL::Mutator();
     nsresult rv = mutator->InitFromURI(this);
     if (NS_FAILED(rv)) {
         return rv;
--- a/netwerk/base/nsStandardURL.h
+++ b/netwerk/base/nsStandardURL.h
@@ -317,16 +317,17 @@ public:
     // We make this implementation a template so that we can avoid writing
     // the same code for SubstitutingURL (which extends nsStandardURL)
     template<class T>
     class TemplatedMutator
         : public nsIURIMutator
         , public BaseURIMutator<T>
         , public nsIStandardURLMutator
         , public nsIURLMutator
+        , public nsIFileURLMutator
     {
         NS_FORWARD_SAFE_NSIURISETTERS_RET(BaseURIMutator<T>::mURI)
 
         MOZ_MUST_USE NS_IMETHOD
         Deserialize(const mozilla::ipc::URIParams& aParams) override
         {
             return BaseURIMutator<T>::InitFromIPCParams(aParams);
         }
@@ -425,16 +426,34 @@ public:
             }
             if (aMutator) {
                 nsCOMPtr<nsIURIMutator> mutator = this;
                 mutator.forget(aMutator);
             }
             return BaseURIMutator<T>::mURI->SetFileExtension(aFileExtension);
         }
 
+        MOZ_MUST_USE NS_IMETHOD
+        SetFile(nsIFile* aFile) override
+        {
+            RefPtr<T> uri;
+            if (BaseURIMutator<T>::mURI) {
+                // We don't need a new URI object if we already have one
+                BaseURIMutator<T>::mURI.swap(uri);
+            } else {
+                uri = new T(/* supportsFileURL = */ true);
+            }
+
+            nsresult rv = uri->SetFile(aFile);
+            if (NS_FAILED(rv)) {
+                return rv;
+            }
+            BaseURIMutator<T>::mURI = uri;
+            return NS_OK;
+        }
 
         explicit TemplatedMutator() { }
     private:
         virtual ~TemplatedMutator() { }
 
         friend T;
     };
 
--- a/netwerk/protocol/res/SubstitutingProtocolHandler.cpp
+++ b/netwerk/protocol/res/SubstitutingProtocolHandler.cpp
@@ -27,17 +27,22 @@ namespace net {
 static LazyLogModule gResLog("nsResProtocol");
 
 static NS_DEFINE_CID(kSubstitutingURLCID, NS_SUBSTITUTINGURL_CID);
 
 //---------------------------------------------------------------------------------
 // SubstitutingURL : overrides nsStandardURL::GetFile to provide nsIFile resolution
 //---------------------------------------------------------------------------------
 
-NS_IMPL_ISUPPORTS(SubstitutingURL::Mutator, nsIURISetters, nsIURIMutator, nsIStandardURLMutator, nsIURLMutator)
+NS_IMPL_ISUPPORTS(SubstitutingURL::Mutator,
+                  nsIURISetters,
+                  nsIURIMutator,
+                  nsIStandardURLMutator,
+                  nsIURLMutator,
+                  nsIFileURLMutator)
 
 nsresult
 SubstitutingURL::EnsureFile()
 {
   nsAutoCString ourScheme;
   nsresult rv = GetScheme(ourScheme);
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/netwerk/protocol/res/SubstitutingProtocolHandler.h
+++ b/netwerk/protocol/res/SubstitutingProtocolHandler.h
@@ -117,17 +117,18 @@ private:
   // we just try to enforce it on new protocols going forward.
   bool mEnforceFileOrJar;
 };
 
 // SubstitutingURL : overrides nsStandardURL::GetFile to provide nsIFile resolution
 class SubstitutingURL : public nsStandardURL
 {
 public:
-  SubstitutingURL() : nsStandardURL(true) {}
+  explicit SubstitutingURL() : nsStandardURL(true) {}
+  explicit SubstitutingURL(bool aSupportsFileURL) : nsStandardURL(true) { MOZ_ASSERT(aSupportsFileURL); }
   virtual nsStandardURL* StartClone() override;
   virtual MOZ_MUST_USE nsresult EnsureFile() override;
   NS_IMETHOD GetClassIDNoAlloc(nsCID *aCID) override;
 
   class Mutator
     : public TemplatedMutator<SubstitutingURL>
   {
     NS_DECL_ISUPPORTS