Loading netwerk/base/nsBufferedStreams.cpp +52 −0 Original line number Diff line number Diff line Loading @@ -293,6 +293,7 @@ NS_INTERFACE_MAP_BEGIN(nsBufferedInputStream) NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIIPCSerializableInputStream, IsIPCSerializable()) NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAsyncInputStream, IsAsyncInputStream()) NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIInputStreamCallback, IsAsyncInputStream()) NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsICloneableInputStream, IsCloneableInputStream()) NS_IMPL_QUERY_CLASSINFO(nsBufferedInputStream) NS_INTERFACE_MAP_END_INHERITING(nsBufferedStream) Loading Loading @@ -641,6 +642,13 @@ nsBufferedInputStream::IsAsyncInputStream() const return !!stream; } bool nsBufferedInputStream::IsCloneableInputStream() const { nsCOMPtr<nsICloneableInputStream> stream = do_QueryInterface(mStream); return !!stream; } NS_IMETHODIMP nsBufferedInputStream::CloseWithStatus(nsresult aStatus) { Loading Loading @@ -695,6 +703,50 @@ nsBufferedInputStream::GetData(nsIInputStream **aResult) return NS_OK; } // nsICloneableInputStream interface NS_IMETHODIMP nsBufferedInputStream::GetCloneable(bool* aCloneable) { *aCloneable = false; // If we don't have the buffer, the inputStream has been already closed. // If mBufferStartOffset is not 0, the stream has been seeked or read. // In both case the cloning is not supported. if (!mBuffer || mBufferStartOffset) { return NS_OK; } nsCOMPtr<nsICloneableInputStream> stream = do_QueryInterface(mStream); // GetCloneable is infallible. NS_ENSURE_TRUE(stream, NS_OK); return stream->GetCloneable(aCloneable); } NS_IMETHODIMP nsBufferedInputStream::Clone(nsIInputStream** aResult) { if (!mBuffer || mBufferStartOffset) { return NS_ERROR_FAILURE; } nsCOMPtr<nsICloneableInputStream> stream = do_QueryInterface(mStream); NS_ENSURE_TRUE(stream, NS_ERROR_FAILURE); nsCOMPtr<nsIInputStream> clonedStream; nsresult rv = stream->Clone(getter_AddRefs(clonedStream)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIBufferedInputStream> bis = new nsBufferedInputStream(); rv = bis->Init(clonedStream, mBufferSize); NS_ENSURE_SUCCESS(rv, rv); bis.forget(aResult); return NS_OK; } //////////////////////////////////////////////////////////////////////////////// // nsBufferedOutputStream Loading netwerk/base/nsBufferedStreams.h +5 −1 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ #include "nsCOMPtr.h" #include "nsIIPCSerializableInputStream.h" #include "nsIAsyncInputStream.h" #include "nsICloneableInputStream.h" //////////////////////////////////////////////////////////////////////////////// Loading Loading @@ -65,7 +66,8 @@ class nsBufferedInputStream : public nsBufferedStream, public nsIStreamBufferAccess, public nsIIPCSerializableInputStream, public nsIAsyncInputStream, public nsIInputStreamCallback public nsIInputStreamCallback, public nsICloneableInputStream { public: NS_DECL_ISUPPORTS_INHERITED Loading @@ -75,6 +77,7 @@ public: NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM NS_DECL_NSIASYNCINPUTSTREAM NS_DECL_NSIINPUTSTREAMCALLBACK NS_DECL_NSICLONEABLEINPUTSTREAM nsBufferedInputStream() : nsBufferedStream() {} Loading @@ -90,6 +93,7 @@ protected: bool IsIPCSerializable() const; bool IsAsyncInputStream() const; bool IsCloneableInputStream() const; NS_IMETHOD Fill() override; NS_IMETHOD Flush() override { return NS_OK; } // no-op for input streams Loading xpcom/tests/gtest/TestCloneInputStream.cpp +50 −12 Original line number Diff line number Diff line Loading @@ -40,6 +40,54 @@ TEST(CloneInputStream, CloneableInput) testing::ConsumeAndValidateStream(clone, inputString); } class NonCloneableInputStream final : public nsIInputStream { public: NS_DECL_THREADSAFE_ISUPPORTS explicit NonCloneableInputStream(already_AddRefed<nsIInputStream> aInputStream) : mStream(aInputStream) {} NS_IMETHOD Available(uint64_t* aLength) override { return mStream->Available(aLength); } NS_IMETHOD Read(char* aBuffer, uint32_t aCount, uint32_t* aReadCount) override { return mStream->Read(aBuffer, aCount, aReadCount); } NS_IMETHOD ReadSegments(nsWriteSegmentFun aWriter, void* aClosure, uint32_t aCount, uint32_t *aResult) override { return mStream->ReadSegments(aWriter, aClosure, aCount, aResult); } NS_IMETHOD Close() override { return mStream->Close(); } NS_IMETHOD IsNonBlocking(bool* aNonBlocking) override { return mStream->IsNonBlocking(aNonBlocking); } private: ~NonCloneableInputStream() = default; nsCOMPtr<nsIInputStream> mStream; }; NS_IMPL_ISUPPORTS(NonCloneableInputStream, nsIInputStream) TEST(CloneInputStream, NonCloneableInput_NoFallback) { nsTArray<char> inputData; Loading @@ -50,12 +98,7 @@ TEST(CloneInputStream, NonCloneableInput_NoFallback) nsresult rv = NS_NewCStringInputStream(getter_AddRefs(base), inputString); ASSERT_TRUE(NS_SUCCEEDED(rv)); // Take advantage of nsBufferedInputStream being non-cloneable right // now. If this changes in the future, then we need a different stream // type in this test. nsCOMPtr<nsIInputStream> stream; rv = NS_NewBufferedInputStream(getter_AddRefs(stream), base.forget(), 4096); ASSERT_TRUE(NS_SUCCEEDED(rv)); nsCOMPtr<nsIInputStream> stream = new NonCloneableInputStream(base.forget()); nsCOMPtr<nsICloneableInputStream> cloneable = do_QueryInterface(stream); ASSERT_TRUE(cloneable == nullptr); Loading @@ -78,12 +121,7 @@ TEST(CloneInputStream, NonCloneableInput_Fallback) nsresult rv = NS_NewCStringInputStream(getter_AddRefs(base), inputString); ASSERT_TRUE(NS_SUCCEEDED(rv)); // Take advantage of nsBufferedInputStream being non-cloneable right // now. If this changes in the future, then we need a different stream // type in this test. nsCOMPtr<nsIInputStream> stream; rv = NS_NewBufferedInputStream(getter_AddRefs(stream), base.forget(), 4096); ASSERT_TRUE(NS_SUCCEEDED(rv)); nsCOMPtr<nsIInputStream> stream = new NonCloneableInputStream(base.forget()); nsCOMPtr<nsICloneableInputStream> cloneable = do_QueryInterface(stream); ASSERT_TRUE(cloneable == nullptr); Loading Loading
netwerk/base/nsBufferedStreams.cpp +52 −0 Original line number Diff line number Diff line Loading @@ -293,6 +293,7 @@ NS_INTERFACE_MAP_BEGIN(nsBufferedInputStream) NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIIPCSerializableInputStream, IsIPCSerializable()) NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAsyncInputStream, IsAsyncInputStream()) NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIInputStreamCallback, IsAsyncInputStream()) NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsICloneableInputStream, IsCloneableInputStream()) NS_IMPL_QUERY_CLASSINFO(nsBufferedInputStream) NS_INTERFACE_MAP_END_INHERITING(nsBufferedStream) Loading Loading @@ -641,6 +642,13 @@ nsBufferedInputStream::IsAsyncInputStream() const return !!stream; } bool nsBufferedInputStream::IsCloneableInputStream() const { nsCOMPtr<nsICloneableInputStream> stream = do_QueryInterface(mStream); return !!stream; } NS_IMETHODIMP nsBufferedInputStream::CloseWithStatus(nsresult aStatus) { Loading Loading @@ -695,6 +703,50 @@ nsBufferedInputStream::GetData(nsIInputStream **aResult) return NS_OK; } // nsICloneableInputStream interface NS_IMETHODIMP nsBufferedInputStream::GetCloneable(bool* aCloneable) { *aCloneable = false; // If we don't have the buffer, the inputStream has been already closed. // If mBufferStartOffset is not 0, the stream has been seeked or read. // In both case the cloning is not supported. if (!mBuffer || mBufferStartOffset) { return NS_OK; } nsCOMPtr<nsICloneableInputStream> stream = do_QueryInterface(mStream); // GetCloneable is infallible. NS_ENSURE_TRUE(stream, NS_OK); return stream->GetCloneable(aCloneable); } NS_IMETHODIMP nsBufferedInputStream::Clone(nsIInputStream** aResult) { if (!mBuffer || mBufferStartOffset) { return NS_ERROR_FAILURE; } nsCOMPtr<nsICloneableInputStream> stream = do_QueryInterface(mStream); NS_ENSURE_TRUE(stream, NS_ERROR_FAILURE); nsCOMPtr<nsIInputStream> clonedStream; nsresult rv = stream->Clone(getter_AddRefs(clonedStream)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIBufferedInputStream> bis = new nsBufferedInputStream(); rv = bis->Init(clonedStream, mBufferSize); NS_ENSURE_SUCCESS(rv, rv); bis.forget(aResult); return NS_OK; } //////////////////////////////////////////////////////////////////////////////// // nsBufferedOutputStream Loading
netwerk/base/nsBufferedStreams.h +5 −1 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ #include "nsCOMPtr.h" #include "nsIIPCSerializableInputStream.h" #include "nsIAsyncInputStream.h" #include "nsICloneableInputStream.h" //////////////////////////////////////////////////////////////////////////////// Loading Loading @@ -65,7 +66,8 @@ class nsBufferedInputStream : public nsBufferedStream, public nsIStreamBufferAccess, public nsIIPCSerializableInputStream, public nsIAsyncInputStream, public nsIInputStreamCallback public nsIInputStreamCallback, public nsICloneableInputStream { public: NS_DECL_ISUPPORTS_INHERITED Loading @@ -75,6 +77,7 @@ public: NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM NS_DECL_NSIASYNCINPUTSTREAM NS_DECL_NSIINPUTSTREAMCALLBACK NS_DECL_NSICLONEABLEINPUTSTREAM nsBufferedInputStream() : nsBufferedStream() {} Loading @@ -90,6 +93,7 @@ protected: bool IsIPCSerializable() const; bool IsAsyncInputStream() const; bool IsCloneableInputStream() const; NS_IMETHOD Fill() override; NS_IMETHOD Flush() override { return NS_OK; } // no-op for input streams Loading
xpcom/tests/gtest/TestCloneInputStream.cpp +50 −12 Original line number Diff line number Diff line Loading @@ -40,6 +40,54 @@ TEST(CloneInputStream, CloneableInput) testing::ConsumeAndValidateStream(clone, inputString); } class NonCloneableInputStream final : public nsIInputStream { public: NS_DECL_THREADSAFE_ISUPPORTS explicit NonCloneableInputStream(already_AddRefed<nsIInputStream> aInputStream) : mStream(aInputStream) {} NS_IMETHOD Available(uint64_t* aLength) override { return mStream->Available(aLength); } NS_IMETHOD Read(char* aBuffer, uint32_t aCount, uint32_t* aReadCount) override { return mStream->Read(aBuffer, aCount, aReadCount); } NS_IMETHOD ReadSegments(nsWriteSegmentFun aWriter, void* aClosure, uint32_t aCount, uint32_t *aResult) override { return mStream->ReadSegments(aWriter, aClosure, aCount, aResult); } NS_IMETHOD Close() override { return mStream->Close(); } NS_IMETHOD IsNonBlocking(bool* aNonBlocking) override { return mStream->IsNonBlocking(aNonBlocking); } private: ~NonCloneableInputStream() = default; nsCOMPtr<nsIInputStream> mStream; }; NS_IMPL_ISUPPORTS(NonCloneableInputStream, nsIInputStream) TEST(CloneInputStream, NonCloneableInput_NoFallback) { nsTArray<char> inputData; Loading @@ -50,12 +98,7 @@ TEST(CloneInputStream, NonCloneableInput_NoFallback) nsresult rv = NS_NewCStringInputStream(getter_AddRefs(base), inputString); ASSERT_TRUE(NS_SUCCEEDED(rv)); // Take advantage of nsBufferedInputStream being non-cloneable right // now. If this changes in the future, then we need a different stream // type in this test. nsCOMPtr<nsIInputStream> stream; rv = NS_NewBufferedInputStream(getter_AddRefs(stream), base.forget(), 4096); ASSERT_TRUE(NS_SUCCEEDED(rv)); nsCOMPtr<nsIInputStream> stream = new NonCloneableInputStream(base.forget()); nsCOMPtr<nsICloneableInputStream> cloneable = do_QueryInterface(stream); ASSERT_TRUE(cloneable == nullptr); Loading @@ -78,12 +121,7 @@ TEST(CloneInputStream, NonCloneableInput_Fallback) nsresult rv = NS_NewCStringInputStream(getter_AddRefs(base), inputString); ASSERT_TRUE(NS_SUCCEEDED(rv)); // Take advantage of nsBufferedInputStream being non-cloneable right // now. If this changes in the future, then we need a different stream // type in this test. nsCOMPtr<nsIInputStream> stream; rv = NS_NewBufferedInputStream(getter_AddRefs(stream), base.forget(), 4096); ASSERT_TRUE(NS_SUCCEEDED(rv)); nsCOMPtr<nsIInputStream> stream = new NonCloneableInputStream(base.forget()); nsCOMPtr<nsICloneableInputStream> cloneable = do_QueryInterface(stream); ASSERT_TRUE(cloneable == nullptr); Loading