Bug 1339710 - SlicedInputStream should not be nsICloneableInputStream if the source stream is not, r=smaug
☠☠ backed out by 94e98e7e3227 ☠ ☠
authorAndrea Marchesini <amarchesini@mozilla.com>
Wed, 22 Feb 2017 07:54:46 +0100
changeset 373226 7561692c1bc7ae4e4f7d968412e65015c611050f
parent 373225 bf67ad546e37a4dd2c1e0317b290d46f95d02688
child 373227 4761a15d45fdbe24993fdafa38f7bd457300dcf3
push id10863
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 23:02:23 +0000
treeherdermozilla-aurora@0931190cd725 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1339710
milestone54.0a1
Bug 1339710 - SlicedInputStream should not be nsICloneableInputStream if the source stream is not, r=smaug
xpcom/io/SlicedInputStream.cpp
xpcom/io/SlicedInputStream.h
--- a/xpcom/io/SlicedInputStream.cpp
+++ b/xpcom/io/SlicedInputStream.cpp
@@ -2,33 +2,56 @@
 /* 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 "SlicedInputStream.h"
 #include "nsISeekableStream.h"
 #include "nsStreamUtils.h"
 
-NS_IMPL_ISUPPORTS(SlicedInputStream, nsIInputStream,
-                  nsICloneableInputStream, nsIAsyncInputStream)
+NS_IMPL_ADDREF(SlicedInputStream);
+NS_IMPL_RELEASE(SlicedInputStream);
+
+NS_INTERFACE_MAP_BEGIN(SlicedInputStream)
+  NS_INTERFACE_MAP_ENTRY(nsIInputStream)
+  NS_INTERFACE_MAP_ENTRY(nsIAsyncInputStream)
+  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsICloneableInputStream,
+                                     mWeakCloneableInputStream)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIInputStream)
+NS_INTERFACE_MAP_END
 
 SlicedInputStream::SlicedInputStream(nsIInputStream* aInputStream,
                                      uint64_t aStart, uint64_t aLength)
-  : mInputStream(aInputStream)
+  : mWeakCloneableInputStream(nullptr)
   , mStart(aStart)
   , mLength(aLength)
   , mCurPos(0)
   , mClosed(false)
 {
   MOZ_ASSERT(aInputStream);
+  SetSourceStream(aInputStream);
 }
 
 SlicedInputStream::~SlicedInputStream()
 {}
 
+void
+SlicedInputStream::SetSourceStream(nsIInputStream* aInputStream)
+{
+  MOZ_ASSERT(aInputStream);
+
+  mInputStream = aInputStream;
+
+  nsCOMPtr<nsICloneableInputStream> cloneableStream =
+    do_QueryInterface(aInputStream);
+  if (cloneableStream && SameCOMIdentity(aInputStream, cloneableStream)) {
+    mWeakCloneableInputStream = cloneableStream;
+  }
+}
+
 NS_IMETHODIMP
 SlicedInputStream::Close()
 {
   mClosed = true;
   return NS_OK;
 }
 
 // nsIInputStream interface
@@ -146,36 +169,32 @@ SlicedInputStream::IsNonBlocking(bool* a
   return mInputStream->IsNonBlocking(aNonBlocking);
 }
 
 // nsICloneableInputStream interface
 
 NS_IMETHODIMP
 SlicedInputStream::GetCloneable(bool* aCloneable)
 {
+  MOZ_ASSERT(mWeakCloneableInputStream);
   *aCloneable = true;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 SlicedInputStream::Clone(nsIInputStream** aResult)
 {
-  nsCOMPtr<nsIInputStream> clonedStream;
-  nsCOMPtr<nsIInputStream> replacementStream;
+  MOZ_ASSERT(mWeakCloneableInputStream);
 
-  nsresult rv = NS_CloneInputStream(mInputStream, getter_AddRefs(clonedStream),
-                                    getter_AddRefs(replacementStream));
+  nsCOMPtr<nsIInputStream> clonedStream;
+  nsresult rv = mWeakCloneableInputStream->Clone(getter_AddRefs(clonedStream));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-  if (replacementStream) {
-    mInputStream = replacementStream.forget();
-  }
-
   nsCOMPtr<nsIInputStream> sis =
     new SlicedInputStream(clonedStream, mStart, mLength);
 
   sis.forget(aResult);
   return NS_OK;
 }
 
 // nsIAsyncInputStream interface
--- a/xpcom/io/SlicedInputStream.h
+++ b/xpcom/io/SlicedInputStream.h
@@ -34,17 +34,24 @@ public:
   // SlicedInputStream wrapper around it.
 
   SlicedInputStream(nsIInputStream* aInputStream,
                     uint64_t aStart, uint64_t aLength);
 
 private:
   ~SlicedInputStream();
 
+  void
+  SetSourceStream(nsIInputStream* aInputStream);
+
   nsCOMPtr<nsIInputStream> mInputStream;
+
+  // Raw pointer because this is just QI of mInputStream.
+  nsICloneableInputStream* mWeakCloneableInputStream;
+
   uint64_t mStart;
   uint64_t mLength;
   uint64_t mCurPos;
 
   bool mClosed;
 };
 
 #endif // SlicedInputStream_h