Bug 1339710 - SlicedInputStream should be nsISeekableStream, r=smaug
☠☠ backed out by 94e98e7e3227 ☠ ☠
authorAndrea Marchesini <amarchesini@mozilla.com>
Wed, 22 Feb 2017 07:57:14 +0100
changeset 373229 cbb4e1c2aada22f98894e2fe94ef9a0e7bde4293
parent 373228 c685dca493f56fdb5c4c63405fb3b501b0365518
child 373230 7c0ec55b44dc159a6eb0c9ff65b922952e6e4f11
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 be nsISeekableStream, r=smaug
xpcom/io/SlicedInputStream.cpp
xpcom/io/SlicedInputStream.h
--- a/xpcom/io/SlicedInputStream.cpp
+++ b/xpcom/io/SlicedInputStream.cpp
@@ -15,35 +15,39 @@ 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 || !mInputStream)
   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIIPCSerializableInputStream,
                                      mWeakIPCSerializableInputStream || !mInputStream)
+  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsISeekableStream,
+                                     mWeakSeekableInputStream || !mInputStream)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIInputStream)
 NS_INTERFACE_MAP_END
 
 SlicedInputStream::SlicedInputStream(nsIInputStream* aInputStream,
                                      uint64_t aStart, uint64_t aLength)
   : mWeakCloneableInputStream(nullptr)
   , mWeakIPCSerializableInputStream(nullptr)
+  , mWeakSeekableInputStream(nullptr)
   , mStart(aStart)
   , mLength(aLength)
   , mCurPos(0)
   , mClosed(false)
 {
   MOZ_ASSERT(aInputStream);
   SetSourceStream(aInputStream);
 }
 
 SlicedInputStream::SlicedInputStream()
   : mWeakCloneableInputStream(nullptr)
   , mWeakIPCSerializableInputStream(nullptr)
+  , mWeakSeekableInputStream(nullptr)
   , mStart(0)
   , mLength(0)
   , mCurPos(0)
   , mClosed(false)
 {}
 
 SlicedInputStream::~SlicedInputStream()
 {}
@@ -63,16 +67,22 @@ SlicedInputStream::SetSourceStream(nsIIn
   }
 
   nsCOMPtr<nsIIPCSerializableInputStream> serializableStream =
     do_QueryInterface(aInputStream);
   if (serializableStream &&
       SameCOMIdentity(aInputStream, serializableStream)) {
     mWeakIPCSerializableInputStream = serializableStream;
   }
+
+  nsCOMPtr<nsISeekableStream> seekableStream =
+    do_QueryInterface(aInputStream);
+  if (seekableStream && SameCOMIdentity(aInputStream, seekableStream)) {
+    mWeakSeekableInputStream = seekableStream;
+  }
 }
 
 NS_IMETHODIMP
 SlicedInputStream::Close()
 {
   NS_ENSURE_STATE(mInputStream);
 
   mClosed = true;
@@ -320,8 +330,80 @@ mozilla::Maybe<uint64_t>
 SlicedInputStream::ExpectedSerializedLength()
 {
   if (!mInputStream || !mWeakIPCSerializableInputStream) {
     return mozilla::Nothing();
   }
 
   return mWeakIPCSerializableInputStream->ExpectedSerializedLength();
 }
+
+// nsISeekableStream
+
+NS_IMETHODIMP
+SlicedInputStream::Seek(int32_t aWhence, int64_t aOffset)
+{
+  NS_ENSURE_STATE(mInputStream);
+  NS_ENSURE_STATE(mWeakSeekableInputStream);
+
+  int64_t offset;
+  switch (aWhence) {
+    case NS_SEEK_SET:
+      offset = mStart + aOffset;
+      break;
+    case NS_SEEK_CUR:
+      offset = mStart + mCurPos + aOffset;
+      break;
+    case NS_SEEK_END:
+      offset = mStart + mLength + aOffset;
+      break;
+   default:
+     return NS_ERROR_ILLEGAL_VALUE;
+  }
+
+  if (offset < (int64_t)mStart || offset > (int64_t)(mStart + mLength)) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  nsresult rv = mWeakSeekableInputStream->Seek(NS_SEEK_SET, offset);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  mCurPos = offset - mStart;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+SlicedInputStream::Tell(int64_t *aResult)
+{
+  NS_ENSURE_STATE(mInputStream);
+  NS_ENSURE_STATE(mWeakSeekableInputStream);
+
+  int64_t tell = 0;
+
+  nsresult rv = mWeakSeekableInputStream->Tell(&tell);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  if (tell < (int64_t)mStart) {
+    *aResult = 0;
+    return NS_OK;
+  }
+
+  *aResult = tell - mStart;
+  if (*aResult > (int64_t)mLength) {
+    *aResult = mLength;
+  }
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+SlicedInputStream::SetEOF()
+{
+  NS_ENSURE_STATE(mInputStream);
+  NS_ENSURE_STATE(mWeakSeekableInputStream);
+
+  mClosed = true;
+  return mWeakSeekableInputStream->SetEOF();
+}
--- a/xpcom/io/SlicedInputStream.h
+++ b/xpcom/io/SlicedInputStream.h
@@ -6,29 +6,32 @@
 #ifndef SlicedInputStream_h
 #define SlicedInputStream_h
 
 #include "mozilla/Attributes.h"
 #include "nsCOMPtr.h"
 #include "nsIAsyncInputStream.h"
 #include "nsICloneableInputStream.h"
 #include "nsIIPCSerializableInputStream.h"
+#include "nsISeekableStream.h"
 
 // A wrapper for a slice of an underlying input stream.
 
 class SlicedInputStream final : public nsIAsyncInputStream
                               , public nsICloneableInputStream
                               , public nsIIPCSerializableInputStream
+                              , public nsISeekableStream
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIINPUTSTREAM
   NS_DECL_NSIASYNCINPUTSTREAM
   NS_DECL_NSICLONEABLEINPUTSTREAM
   NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM
+  NS_DECL_NSISEEKABLESTREAM
 
   // Create an input stream whose data comes from a slice of aInputStream.  The
   // slice begins at aStart bytes beyond aInputStream's current position, and
   // extends for a maximum of aLength bytes.  If aInputStream contains fewer
   // than aStart bytes, reading from SlicedInputStream returns no data.  If
   // aInputStream contains more than aStart bytes, but fewer than aStart +
   // aLength bytes, reading from SlicedInputStream returns as many bytes as can
   // be consumed from aInputStream after reading aLength bytes.
@@ -48,16 +51,17 @@ private:
   void
   SetSourceStream(nsIInputStream* aInputStream);
 
   nsCOMPtr<nsIInputStream> mInputStream;
 
   // Raw pointers because these are just QI of mInputStream.
   nsICloneableInputStream* mWeakCloneableInputStream;
   nsIIPCSerializableInputStream* mWeakIPCSerializableInputStream;
+  nsISeekableStream* mWeakSeekableInputStream;
 
   uint64_t mStart;
   uint64_t mLength;
   uint64_t mCurPos;
 
   bool mClosed;
 };