Bug 1754004 - Part 9: Remove PartiallySeekableInputStream, r=asuth,necko-reviewers,kershaw
This interface is misleading, as it doesn't allow seeking the entire type despite providing a `nsISeekableStream` interface, and is no longer necessary due to the changes in an earlier part. Differential Revision: https://phabricator.services.mozilla.com/D141046
This commit is contained in:
@@ -1,445 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 "PartiallySeekableInputStream.h"
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
#include "nsISeekableStream.h"
|
||||
#include "nsStreamUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
NS_IMPL_ADDREF(PartiallySeekableInputStream);
|
||||
NS_IMPL_RELEASE(PartiallySeekableInputStream);
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(PartiallySeekableInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISeekableStream)
|
||||
NS_INTERFACE_MAP_ENTRY(nsITellableStream)
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsICloneableInputStream,
|
||||
mWeakCloneableInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIIPCSerializableInputStream,
|
||||
mWeakIPCSerializableInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAsyncInputStream, mWeakAsyncInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIInputStreamCallback,
|
||||
mWeakAsyncInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIInputStreamLength,
|
||||
mWeakInputStreamLength)
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAsyncInputStreamLength,
|
||||
mWeakAsyncInputStreamLength)
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIInputStreamLengthCallback,
|
||||
mWeakAsyncInputStreamLength)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIInputStream)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
PartiallySeekableInputStream::PartiallySeekableInputStream(
|
||||
already_AddRefed<nsIInputStream> aInputStream, uint64_t aBufferSize)
|
||||
: mInputStream(std::move(aInputStream)),
|
||||
mWeakCloneableInputStream(nullptr),
|
||||
mWeakIPCSerializableInputStream(nullptr),
|
||||
mWeakAsyncInputStream(nullptr),
|
||||
mWeakInputStreamLength(nullptr),
|
||||
mWeakAsyncInputStreamLength(nullptr),
|
||||
mBufferSize(aBufferSize),
|
||||
mPos(0),
|
||||
mClosed(false),
|
||||
mMutex("PartiallySeekableInputStream::mMutex") {
|
||||
Init();
|
||||
}
|
||||
|
||||
PartiallySeekableInputStream::PartiallySeekableInputStream(
|
||||
already_AddRefed<nsIInputStream> aClonedBaseStream,
|
||||
PartiallySeekableInputStream* aClonedFrom)
|
||||
: mInputStream(std::move(aClonedBaseStream)),
|
||||
mWeakCloneableInputStream(nullptr),
|
||||
mWeakIPCSerializableInputStream(nullptr),
|
||||
mWeakAsyncInputStream(nullptr),
|
||||
mWeakInputStreamLength(nullptr),
|
||||
mWeakAsyncInputStreamLength(nullptr),
|
||||
mCachedBuffer(aClonedFrom->mCachedBuffer.Clone()),
|
||||
mBufferSize(aClonedFrom->mBufferSize),
|
||||
mPos(aClonedFrom->mPos),
|
||||
mClosed(aClonedFrom->mClosed),
|
||||
mMutex("PartiallySeekableInputStream::mMutex") {
|
||||
Init();
|
||||
}
|
||||
|
||||
void PartiallySeekableInputStream::Init() {
|
||||
MOZ_ASSERT(mInputStream);
|
||||
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsISeekableStream> seekableStream = do_QueryInterface(mInputStream);
|
||||
MOZ_ASSERT(!seekableStream);
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsICloneableInputStream> cloneableStream =
|
||||
do_QueryInterface(mInputStream);
|
||||
if (cloneableStream && SameCOMIdentity(mInputStream, cloneableStream)) {
|
||||
mWeakCloneableInputStream = cloneableStream;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIIPCSerializableInputStream> serializableStream =
|
||||
do_QueryInterface(mInputStream);
|
||||
if (serializableStream && SameCOMIdentity(mInputStream, serializableStream)) {
|
||||
mWeakIPCSerializableInputStream = serializableStream;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAsyncInputStream> asyncInputStream =
|
||||
do_QueryInterface(mInputStream);
|
||||
if (asyncInputStream && SameCOMIdentity(mInputStream, asyncInputStream)) {
|
||||
mWeakAsyncInputStream = asyncInputStream;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInputStreamLength> inputStreamLength =
|
||||
do_QueryInterface(mInputStream);
|
||||
if (inputStreamLength && SameCOMIdentity(mInputStream, inputStreamLength)) {
|
||||
mWeakInputStreamLength = inputStreamLength;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAsyncInputStreamLength> asyncInputStreamLength =
|
||||
do_QueryInterface(mInputStream);
|
||||
if (asyncInputStreamLength &&
|
||||
SameCOMIdentity(mInputStream, asyncInputStreamLength)) {
|
||||
mWeakAsyncInputStreamLength = asyncInputStreamLength;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PartiallySeekableInputStream::Close() {
|
||||
mInputStream->Close();
|
||||
mCachedBuffer.Clear();
|
||||
mPos = 0;
|
||||
mClosed = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIInputStream interface
|
||||
|
||||
NS_IMETHODIMP
|
||||
PartiallySeekableInputStream::Available(uint64_t* aLength) {
|
||||
if (mClosed) {
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
}
|
||||
|
||||
nsresult rv = mInputStream->Available(aLength);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (mPos < mCachedBuffer.Length()) {
|
||||
*aLength += mCachedBuffer.Length() - mPos;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PartiallySeekableInputStream::Read(char* aBuffer, uint32_t aCount,
|
||||
uint32_t* aReadCount) {
|
||||
*aReadCount = 0;
|
||||
|
||||
if (mClosed) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
uint32_t byteRead = 0;
|
||||
|
||||
if (mPos < mCachedBuffer.Length()) {
|
||||
// We are reading from the cached buffer.
|
||||
byteRead = XPCOM_MIN(mCachedBuffer.Length() - mPos, (uint64_t)aCount);
|
||||
memcpy(aBuffer, mCachedBuffer.Elements() + mPos, byteRead);
|
||||
*aReadCount = byteRead;
|
||||
mPos += byteRead;
|
||||
}
|
||||
|
||||
if (byteRead < aCount) {
|
||||
MOZ_ASSERT(mPos >= mCachedBuffer.Length());
|
||||
MOZ_ASSERT_IF(mPos > mCachedBuffer.Length(),
|
||||
mCachedBuffer.Length() == mBufferSize);
|
||||
|
||||
// We can read from the stream.
|
||||
uint32_t byteWritten;
|
||||
nsresult rv =
|
||||
mInputStream->Read(aBuffer + byteRead, aCount - byteRead, &byteWritten);
|
||||
if (NS_WARN_IF(NS_FAILED(rv)) || byteWritten == 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
*aReadCount += byteWritten;
|
||||
|
||||
// Maybe we have to cache something.
|
||||
if (mPos < mBufferSize) {
|
||||
uint32_t size = XPCOM_MIN(mPos + byteWritten, mBufferSize);
|
||||
mCachedBuffer.SetLength(size);
|
||||
memcpy(mCachedBuffer.Elements() + mPos, aBuffer + byteRead, size - mPos);
|
||||
}
|
||||
|
||||
mPos += byteWritten;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PartiallySeekableInputStream::ReadSegments(nsWriteSegmentFun aWriter,
|
||||
void* aClosure, uint32_t aCount,
|
||||
uint32_t* aResult) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PartiallySeekableInputStream::IsNonBlocking(bool* aNonBlocking) {
|
||||
return mInputStream->IsNonBlocking(aNonBlocking);
|
||||
}
|
||||
|
||||
// nsICloneableInputStream interface
|
||||
|
||||
NS_IMETHODIMP
|
||||
PartiallySeekableInputStream::GetCloneable(bool* aCloneable) {
|
||||
NS_ENSURE_STATE(mWeakCloneableInputStream);
|
||||
|
||||
return mWeakCloneableInputStream->GetCloneable(aCloneable);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PartiallySeekableInputStream::Clone(nsIInputStream** aResult) {
|
||||
NS_ENSURE_STATE(mWeakCloneableInputStream);
|
||||
|
||||
nsCOMPtr<nsIInputStream> clonedStream;
|
||||
nsresult rv = mWeakCloneableInputStream->Clone(getter_AddRefs(clonedStream));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInputStream> stream =
|
||||
new PartiallySeekableInputStream(clonedStream.forget(), this);
|
||||
|
||||
stream.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIAsyncInputStream interface
|
||||
|
||||
NS_IMETHODIMP
|
||||
PartiallySeekableInputStream::CloseWithStatus(nsresult aStatus) {
|
||||
NS_ENSURE_STATE(mWeakAsyncInputStream);
|
||||
|
||||
return mWeakAsyncInputStream->CloseWithStatus(aStatus);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PartiallySeekableInputStream::AsyncWait(nsIInputStreamCallback* aCallback,
|
||||
uint32_t aFlags,
|
||||
uint32_t aRequestedCount,
|
||||
nsIEventTarget* aEventTarget) {
|
||||
if (mClosed) {
|
||||
if (aCallback) {
|
||||
if (aEventTarget) {
|
||||
nsCOMPtr<nsIInputStreamCallback> callable = NS_NewInputStreamReadyEvent(
|
||||
"PartiallySeekableInputStream::OnInputStreamReady", aCallback,
|
||||
aEventTarget);
|
||||
callable->OnInputStreamReady(this);
|
||||
} else {
|
||||
aCallback->OnInputStreamReady(this);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
if (NS_WARN_IF(mAsyncWaitCallback && aCallback &&
|
||||
mAsyncWaitCallback != aCallback)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mAsyncWaitCallback = aCallback;
|
||||
}
|
||||
|
||||
NS_ENSURE_STATE(mWeakAsyncInputStream);
|
||||
nsCOMPtr<nsIInputStreamCallback> callback = aCallback ? this : nullptr;
|
||||
return mWeakAsyncInputStream->AsyncWait(callback, aFlags, aRequestedCount,
|
||||
aEventTarget);
|
||||
}
|
||||
|
||||
// nsIInputStreamCallback
|
||||
|
||||
NS_IMETHODIMP
|
||||
PartiallySeekableInputStream::OnInputStreamReady(nsIAsyncInputStream* aStream) {
|
||||
MOZ_ASSERT(mWeakAsyncInputStream);
|
||||
MOZ_ASSERT(mWeakAsyncInputStream == aStream);
|
||||
|
||||
nsCOMPtr<nsIInputStreamCallback> callback;
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
// We have been canceled in the meanwhile.
|
||||
if (!mAsyncWaitCallback) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
callback.swap(mAsyncWaitCallback);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(callback);
|
||||
return callback->OnInputStreamReady(this);
|
||||
}
|
||||
|
||||
// nsIIPCSerializableInputStream
|
||||
|
||||
void PartiallySeekableInputStream::SerializedComplexity(
|
||||
uint32_t aMaxSize, uint32_t* aSizeUsed, uint32_t* aPipes,
|
||||
uint32_t* aTransferables) {
|
||||
mozilla::ipc::InputStreamHelper::SerializedComplexity(
|
||||
mInputStream, aMaxSize, aSizeUsed, aPipes, aTransferables);
|
||||
}
|
||||
|
||||
void PartiallySeekableInputStream::Serialize(
|
||||
mozilla::ipc::InputStreamParams& aParams,
|
||||
FileDescriptorArray& aFileDescriptors, bool aDelayedStart,
|
||||
uint32_t aMaxSize, uint32_t* aSizeUsed,
|
||||
mozilla::ipc::ParentToChildStreamActorManager* aManager) {
|
||||
SerializeInternal(aParams, aFileDescriptors, aDelayedStart, aMaxSize,
|
||||
aSizeUsed, aManager);
|
||||
}
|
||||
|
||||
void PartiallySeekableInputStream::Serialize(
|
||||
mozilla::ipc::InputStreamParams& aParams,
|
||||
FileDescriptorArray& aFileDescriptors, bool aDelayedStart,
|
||||
uint32_t aMaxSize, uint32_t* aSizeUsed,
|
||||
mozilla::ipc::ChildToParentStreamActorManager* aManager) {
|
||||
SerializeInternal(aParams, aFileDescriptors, aDelayedStart, aMaxSize,
|
||||
aSizeUsed, aManager);
|
||||
}
|
||||
|
||||
template <typename M>
|
||||
void PartiallySeekableInputStream::SerializeInternal(
|
||||
mozilla::ipc::InputStreamParams& aParams,
|
||||
FileDescriptorArray& aFileDescriptors, bool aDelayedStart,
|
||||
uint32_t aMaxSize, uint32_t* aSizeUsed, M* aManager) {
|
||||
MOZ_ASSERT(mWeakIPCSerializableInputStream);
|
||||
MOZ_DIAGNOSTIC_ASSERT(mCachedBuffer.IsEmpty());
|
||||
mozilla::ipc::InputStreamHelper::SerializeInputStream(
|
||||
mInputStream, aParams, aFileDescriptors, aDelayedStart, aMaxSize,
|
||||
aSizeUsed, aManager);
|
||||
}
|
||||
|
||||
bool PartiallySeekableInputStream::Deserialize(
|
||||
const mozilla::ipc::InputStreamParams& aParams,
|
||||
const FileDescriptorArray& aFileDescriptors) {
|
||||
MOZ_CRASH("This method should never be called!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// nsISeekableStream
|
||||
|
||||
NS_IMETHODIMP
|
||||
PartiallySeekableInputStream::Seek(int32_t aWhence, int64_t aOffset) {
|
||||
if (mClosed) {
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
}
|
||||
|
||||
int64_t offset;
|
||||
|
||||
switch (aWhence) {
|
||||
case NS_SEEK_SET:
|
||||
offset = aOffset;
|
||||
break;
|
||||
case NS_SEEK_CUR:
|
||||
offset = mPos + aOffset;
|
||||
break;
|
||||
case NS_SEEK_END: {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
default:
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
if (offset < 0) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
if ((uint64_t)offset >= mCachedBuffer.Length() || mPos > mBufferSize) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
mPos = offset;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PartiallySeekableInputStream::Tell(int64_t* aResult) {
|
||||
if (mClosed) {
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
}
|
||||
|
||||
*aResult = mPos;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PartiallySeekableInputStream::SetEOF() { return Close(); }
|
||||
|
||||
// nsIInputStreamLength
|
||||
|
||||
NS_IMETHODIMP
|
||||
PartiallySeekableInputStream::Length(int64_t* aLength) {
|
||||
NS_ENSURE_STATE(mWeakInputStreamLength);
|
||||
return mWeakInputStreamLength->Length(aLength);
|
||||
}
|
||||
|
||||
// nsIAsyncInputStreamLength
|
||||
|
||||
NS_IMETHODIMP
|
||||
PartiallySeekableInputStream::AsyncLengthWait(
|
||||
nsIInputStreamLengthCallback* aCallback, nsIEventTarget* aEventTarget) {
|
||||
if (mClosed) {
|
||||
if (aCallback) {
|
||||
const RefPtr<PartiallySeekableInputStream> self = this;
|
||||
const nsCOMPtr<nsIInputStreamLengthCallback> callback = aCallback;
|
||||
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction(
|
||||
"PartiallySeekableInputStream::OnInputStreamLengthReady",
|
||||
[self, callback] { callback->OnInputStreamLengthReady(self, -1); });
|
||||
if (aEventTarget) {
|
||||
aEventTarget->Dispatch(runnable, NS_DISPATCH_NORMAL);
|
||||
} else {
|
||||
runnable->Run();
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ENSURE_STATE(mWeakAsyncInputStreamLength);
|
||||
|
||||
nsCOMPtr<nsIInputStreamLengthCallback> callback = aCallback ? this : nullptr;
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
mAsyncInputStreamLengthCallback = aCallback;
|
||||
}
|
||||
|
||||
return mWeakAsyncInputStreamLength->AsyncLengthWait(callback, aEventTarget);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PartiallySeekableInputStream::OnInputStreamLengthReady(
|
||||
nsIAsyncInputStreamLength* aStream, int64_t aLength) {
|
||||
nsCOMPtr<nsIInputStreamLengthCallback> callback;
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
// We have been canceled in the meanwhile.
|
||||
if (!mAsyncInputStreamLengthCallback) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
callback.swap(mAsyncInputStreamLengthCallback);
|
||||
}
|
||||
|
||||
return callback->OnInputStreamLengthReady(this, aLength);
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
@@ -1,91 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef PartiallySeekableInputStream_h
|
||||
#define PartiallySeekableInputStream_h
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIAsyncInputStream.h"
|
||||
#include "nsICloneableInputStream.h"
|
||||
#include "nsIInputStreamLength.h"
|
||||
#include "nsIIPCSerializableInputStream.h"
|
||||
#include "nsISeekableStream.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
// A wrapper for making a stream seekable for the first |aBufferSize| bytes.
|
||||
// Note that this object takes the ownership of the underlying stream.
|
||||
|
||||
class PartiallySeekableInputStream final : public nsISeekableStream,
|
||||
public nsIAsyncInputStream,
|
||||
public nsICloneableInputStream,
|
||||
public nsIIPCSerializableInputStream,
|
||||
public nsIInputStreamCallback,
|
||||
public nsIInputStreamLength,
|
||||
public nsIAsyncInputStreamLength,
|
||||
public nsIInputStreamLengthCallback {
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIINPUTSTREAM
|
||||
NS_DECL_NSISEEKABLESTREAM
|
||||
NS_DECL_NSITELLABLESTREAM
|
||||
NS_DECL_NSIASYNCINPUTSTREAM
|
||||
NS_DECL_NSICLONEABLEINPUTSTREAM
|
||||
NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM
|
||||
NS_DECL_NSIINPUTSTREAMCALLBACK
|
||||
NS_DECL_NSIINPUTSTREAMLENGTH
|
||||
NS_DECL_NSIASYNCINPUTSTREAMLENGTH
|
||||
NS_DECL_NSIINPUTSTREAMLENGTHCALLBACK
|
||||
|
||||
explicit PartiallySeekableInputStream(
|
||||
already_AddRefed<nsIInputStream> aInputStream,
|
||||
uint64_t aBufferSize = 4096);
|
||||
|
||||
private:
|
||||
PartiallySeekableInputStream(
|
||||
already_AddRefed<nsIInputStream> aClonedBaseStream,
|
||||
PartiallySeekableInputStream* aClonedFrom);
|
||||
|
||||
~PartiallySeekableInputStream() = default;
|
||||
|
||||
void Init();
|
||||
|
||||
template <typename M>
|
||||
void SerializeInternal(mozilla::ipc::InputStreamParams& aParams,
|
||||
FileDescriptorArray& aFileDescriptors,
|
||||
bool aDelayedStart, uint32_t aMaxSize,
|
||||
uint32_t* aSizeUsed, M* aManager);
|
||||
|
||||
nsCOMPtr<nsIInputStream> mInputStream;
|
||||
|
||||
// Raw pointers because these are just QI of mInputStream.
|
||||
nsICloneableInputStream* mWeakCloneableInputStream;
|
||||
nsIIPCSerializableInputStream* mWeakIPCSerializableInputStream;
|
||||
nsIAsyncInputStream* mWeakAsyncInputStream;
|
||||
nsIInputStreamLength* mWeakInputStreamLength;
|
||||
nsIAsyncInputStreamLength* mWeakAsyncInputStreamLength;
|
||||
|
||||
// Protected by mutex.
|
||||
nsCOMPtr<nsIInputStreamCallback> mAsyncWaitCallback;
|
||||
|
||||
// Protected by mutex.
|
||||
nsCOMPtr<nsIInputStreamLengthCallback> mAsyncInputStreamLengthCallback;
|
||||
|
||||
nsTArray<char> mCachedBuffer;
|
||||
|
||||
uint64_t mBufferSize;
|
||||
uint64_t mPos;
|
||||
bool mClosed;
|
||||
|
||||
Mutex mMutex MOZ_UNANNOTATED;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // PartiallySeekableInputStream_h
|
||||
@@ -162,7 +162,6 @@ EXPORTS.mozilla.net += [
|
||||
"IOActivityMonitor.h",
|
||||
"MemoryDownloader.h",
|
||||
"NetworkConnectivityService.h",
|
||||
"PartiallySeekableInputStream.h",
|
||||
"Predictor.h",
|
||||
"PrivateBrowsingChannel.h",
|
||||
"RedirectChannelRegistrar.h",
|
||||
@@ -227,7 +226,6 @@ UNIFIED_SOURCES += [
|
||||
"nsSyncStreamListener.cpp",
|
||||
"nsTransportUtils.cpp",
|
||||
"nsUDPSocket.cpp",
|
||||
"PartiallySeekableInputStream.cpp",
|
||||
"PollableEvent.cpp",
|
||||
"Predictor.cpp",
|
||||
"ProxyAutoConfig.cpp",
|
||||
|
||||
@@ -1,517 +0,0 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "Helpers.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsStreamUtils.h"
|
||||
#include "nsString.h"
|
||||
#include "nsStringStream.h"
|
||||
#include "mozilla/SpinEventLoopUntil.h"
|
||||
#include "mozilla/net/PartiallySeekableInputStream.h"
|
||||
|
||||
using mozilla::GetCurrentSerialEventTarget;
|
||||
using mozilla::MakeRefPtr;
|
||||
using mozilla::SpinEventLoopUntil;
|
||||
using mozilla::net::PartiallySeekableInputStream;
|
||||
|
||||
class NonSeekableStream final : public nsIInputStream {
|
||||
nsCOMPtr<nsIInputStream> mStream;
|
||||
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
||||
explicit NonSeekableStream(const nsACString& aBuffer) {
|
||||
NS_NewCStringInputStream(getter_AddRefs(mStream), aBuffer);
|
||||
}
|
||||
|
||||
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:
|
||||
~NonSeekableStream() = default;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(NonSeekableStream, nsIInputStream)
|
||||
|
||||
// Helper function for creating a non-seekable nsIInputStream + a
|
||||
// PartiallySeekableInputStream.
|
||||
PartiallySeekableInputStream* CreateStream(uint32_t aSize, uint64_t aStreamSize,
|
||||
nsCString& aBuffer) {
|
||||
aBuffer.SetLength(aSize);
|
||||
for (uint32_t i = 0; i < aSize; ++i) {
|
||||
aBuffer.BeginWriting()[i] = i % 10;
|
||||
}
|
||||
|
||||
RefPtr<NonSeekableStream> stream = new NonSeekableStream(aBuffer);
|
||||
return new PartiallySeekableInputStream(stream.forget(), aStreamSize);
|
||||
}
|
||||
|
||||
// Simple reading.
|
||||
TEST(TestPartiallySeekableInputStream, SimpleRead)
|
||||
{
|
||||
const size_t kBufSize = 10;
|
||||
|
||||
nsCString buf;
|
||||
RefPtr<PartiallySeekableInputStream> psi = CreateStream(kBufSize, 5, buf);
|
||||
|
||||
uint64_t length;
|
||||
ASSERT_EQ(NS_OK, psi->Available(&length));
|
||||
ASSERT_EQ((uint64_t)kBufSize, length);
|
||||
|
||||
char buf2[kBufSize];
|
||||
uint32_t count;
|
||||
ASSERT_EQ(NS_OK, psi->Read(buf2, sizeof(buf2), &count));
|
||||
ASSERT_EQ(count, buf.Length());
|
||||
ASSERT_TRUE(nsCString(buf.get(), kBufSize).Equals(nsCString(buf2, count)));
|
||||
|
||||
// At this point, after reading more than the buffer size, seek is not
|
||||
// allowed.
|
||||
ASSERT_EQ(NS_ERROR_NOT_IMPLEMENTED,
|
||||
psi->Seek(nsISeekableStream::NS_SEEK_SET, 0));
|
||||
|
||||
ASSERT_EQ(NS_ERROR_NOT_IMPLEMENTED,
|
||||
psi->Seek(nsISeekableStream::NS_SEEK_END, 0));
|
||||
|
||||
ASSERT_EQ(NS_ERROR_NOT_IMPLEMENTED,
|
||||
psi->Seek(nsISeekableStream::NS_SEEK_CUR, 0));
|
||||
|
||||
// Position is at the end of the stream.
|
||||
int64_t pos;
|
||||
ASSERT_EQ(NS_OK, psi->Tell(&pos));
|
||||
ASSERT_EQ((int64_t)kBufSize, pos);
|
||||
}
|
||||
|
||||
// Simple seek
|
||||
TEST(TestPartiallySeekableInputStream, SimpleSeek)
|
||||
{
|
||||
const size_t kBufSize = 10;
|
||||
|
||||
nsCString buf;
|
||||
RefPtr<PartiallySeekableInputStream> psi = CreateStream(kBufSize, 5, buf);
|
||||
|
||||
uint64_t length;
|
||||
ASSERT_EQ(NS_OK, psi->Available(&length));
|
||||
ASSERT_EQ((uint64_t)kBufSize, length);
|
||||
|
||||
uint32_t count;
|
||||
|
||||
{
|
||||
char buf2[3];
|
||||
ASSERT_EQ(NS_OK, psi->Read(buf2, sizeof(buf2), &count));
|
||||
ASSERT_EQ(count, sizeof(buf2));
|
||||
ASSERT_TRUE(nsCString(buf.get(), sizeof(buf2))
|
||||
.Equals(nsCString(buf2, sizeof(buf2))));
|
||||
|
||||
int64_t pos;
|
||||
ASSERT_EQ(NS_OK, psi->Tell(&pos));
|
||||
ASSERT_EQ((int64_t)sizeof(buf2), pos);
|
||||
|
||||
uint64_t length;
|
||||
ASSERT_EQ(NS_OK, psi->Available(&length));
|
||||
ASSERT_EQ((uint64_t)kBufSize - sizeof(buf2), length);
|
||||
}
|
||||
|
||||
// Let's seek back to the beginning using NS_SEEK_SET
|
||||
ASSERT_EQ(NS_OK, psi->Seek(nsISeekableStream::NS_SEEK_SET, 0));
|
||||
|
||||
{
|
||||
uint64_t length;
|
||||
ASSERT_EQ(NS_OK, psi->Available(&length));
|
||||
ASSERT_EQ((uint64_t)kBufSize, length);
|
||||
|
||||
char buf2[3];
|
||||
ASSERT_EQ(NS_OK, psi->Read(buf2, sizeof(buf2), &count));
|
||||
ASSERT_EQ(count, sizeof(buf2));
|
||||
ASSERT_TRUE(nsCString(buf.get(), sizeof(buf2))
|
||||
.Equals(nsCString(buf2, sizeof(buf2))));
|
||||
|
||||
int64_t pos;
|
||||
ASSERT_EQ(NS_OK, psi->Tell(&pos));
|
||||
ASSERT_EQ((int64_t)sizeof(buf2), pos);
|
||||
|
||||
ASSERT_EQ(NS_OK, psi->Available(&length));
|
||||
ASSERT_EQ((uint64_t)kBufSize - sizeof(buf2), length);
|
||||
}
|
||||
|
||||
// Let's seek back of 2 bytes using NS_SEEK_CUR
|
||||
ASSERT_EQ(NS_OK, psi->Seek(nsISeekableStream::NS_SEEK_CUR, -2));
|
||||
|
||||
{
|
||||
uint64_t length;
|
||||
ASSERT_EQ(NS_OK, psi->Available(&length));
|
||||
ASSERT_EQ((uint64_t)kBufSize - 1, length);
|
||||
|
||||
char buf2[3];
|
||||
ASSERT_EQ(NS_OK, psi->Read(buf2, sizeof(buf2), &count));
|
||||
ASSERT_EQ(count, sizeof(buf2));
|
||||
ASSERT_TRUE(nsCString(buf.get() + 1, sizeof(buf2))
|
||||
.Equals(nsCString(buf2, sizeof(buf2))));
|
||||
|
||||
int64_t pos;
|
||||
ASSERT_EQ(NS_OK, psi->Tell(&pos));
|
||||
ASSERT_EQ((int64_t)sizeof(buf2) + 1, pos);
|
||||
|
||||
ASSERT_EQ(NS_OK, psi->Available(&length));
|
||||
ASSERT_EQ((uint64_t)kBufSize - sizeof(buf2) - 1, length);
|
||||
}
|
||||
|
||||
// Let's seek back to the beginning using NS_SEEK_SET
|
||||
ASSERT_EQ(NS_OK, psi->Seek(nsISeekableStream::NS_SEEK_SET, 0));
|
||||
|
||||
{
|
||||
uint64_t length;
|
||||
ASSERT_EQ(NS_OK, psi->Available(&length));
|
||||
ASSERT_EQ((uint64_t)kBufSize, length);
|
||||
|
||||
char buf2[kBufSize];
|
||||
ASSERT_EQ(NS_OK, psi->Read(buf2, sizeof(buf2), &count));
|
||||
ASSERT_EQ(count, buf.Length());
|
||||
ASSERT_TRUE(nsCString(buf.get(), kBufSize).Equals(nsCString(buf2, count)));
|
||||
}
|
||||
}
|
||||
|
||||
// Full in cache
|
||||
TEST(TestPartiallySeekableInputStream, FullCachedSeek)
|
||||
{
|
||||
const size_t kBufSize = 10;
|
||||
|
||||
nsCString buf;
|
||||
RefPtr<PartiallySeekableInputStream> psi = CreateStream(kBufSize, 4096, buf);
|
||||
|
||||
uint64_t length;
|
||||
ASSERT_EQ(NS_OK, psi->Available(&length));
|
||||
ASSERT_EQ((uint64_t)kBufSize, length);
|
||||
|
||||
char buf2[kBufSize];
|
||||
uint32_t count;
|
||||
ASSERT_EQ(NS_OK, psi->Read(buf2, sizeof(buf2), &count));
|
||||
ASSERT_EQ(count, buf.Length());
|
||||
ASSERT_TRUE(nsCString(buf.get(), kBufSize).Equals(nsCString(buf2, count)));
|
||||
|
||||
ASSERT_EQ(NS_OK, psi->Available(&length));
|
||||
ASSERT_EQ((uint64_t)0, length);
|
||||
|
||||
ASSERT_EQ(NS_OK, psi->Seek(nsISeekableStream::NS_SEEK_SET, 0));
|
||||
|
||||
ASSERT_EQ(NS_OK, psi->Available(&length));
|
||||
ASSERT_EQ((uint64_t)kBufSize, length);
|
||||
|
||||
ASSERT_EQ(NS_OK, psi->Read(buf2, sizeof(buf2), &count));
|
||||
ASSERT_EQ(count, buf.Length());
|
||||
ASSERT_TRUE(nsCString(buf.get(), kBufSize).Equals(nsCString(buf2, count)));
|
||||
|
||||
ASSERT_EQ(NS_OK, psi->Available(&length));
|
||||
ASSERT_EQ((uint64_t)0, length);
|
||||
}
|
||||
|
||||
TEST(TestPartiallySeekableInputStream, QIInputStreamLength)
|
||||
{
|
||||
nsCString buf;
|
||||
buf.AssignLiteral("Hello world");
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
nsCOMPtr<nsIInputStream> psis;
|
||||
{
|
||||
RefPtr<testing::LengthInputStream> stream =
|
||||
new testing::LengthInputStream(buf, i % 2, i > 1);
|
||||
psis = new PartiallySeekableInputStream(stream.forget());
|
||||
}
|
||||
|
||||
{
|
||||
nsCOMPtr<nsIInputStreamLength> qi = do_QueryInterface(psis);
|
||||
ASSERT_EQ(!!(i % 2), !!qi);
|
||||
}
|
||||
|
||||
{
|
||||
nsCOMPtr<nsIAsyncInputStreamLength> qi = do_QueryInterface(psis);
|
||||
ASSERT_EQ(i > 1, !!qi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(TestPartiallySeekableInputStream, InputStreamLength)
|
||||
{
|
||||
nsCString buf;
|
||||
buf.AssignLiteral("Hello world");
|
||||
|
||||
nsCOMPtr<nsIInputStream> psis;
|
||||
{
|
||||
RefPtr<testing::LengthInputStream> stream =
|
||||
new testing::LengthInputStream(buf, true, false);
|
||||
psis = new PartiallySeekableInputStream(stream.forget());
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInputStreamLength> qi = do_QueryInterface(psis);
|
||||
ASSERT_TRUE(!!qi);
|
||||
|
||||
int64_t size;
|
||||
nsresult rv = qi->Length(&size);
|
||||
ASSERT_EQ(NS_OK, rv);
|
||||
ASSERT_EQ(int64_t(buf.Length()), size);
|
||||
}
|
||||
|
||||
TEST(TestPartiallySeekableInputStream, NegativeInputStreamLength)
|
||||
{
|
||||
nsCString buf;
|
||||
buf.AssignLiteral("Hello world");
|
||||
|
||||
nsCOMPtr<nsIInputStream> psis;
|
||||
{
|
||||
RefPtr<testing::LengthInputStream> stream =
|
||||
new testing::LengthInputStream(buf, true, false, NS_OK, true);
|
||||
psis = new PartiallySeekableInputStream(stream.forget());
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInputStreamLength> qi = do_QueryInterface(psis);
|
||||
ASSERT_TRUE(!!qi);
|
||||
|
||||
int64_t size;
|
||||
nsresult rv = qi->Length(&size);
|
||||
ASSERT_EQ(NS_OK, rv);
|
||||
ASSERT_EQ(-1, size);
|
||||
}
|
||||
|
||||
TEST(TestPartiallySeekableInputStream, AsyncInputStreamLength)
|
||||
{
|
||||
nsCString buf;
|
||||
buf.AssignLiteral("Hello world");
|
||||
|
||||
nsCOMPtr<nsIInputStream> psis;
|
||||
{
|
||||
RefPtr<testing::LengthInputStream> stream =
|
||||
new testing::LengthInputStream(buf, false, true);
|
||||
psis = new PartiallySeekableInputStream(stream.forget());
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAsyncInputStreamLength> qi = do_QueryInterface(psis);
|
||||
ASSERT_TRUE(!!qi);
|
||||
|
||||
RefPtr<testing::LengthCallback> callback = new testing::LengthCallback();
|
||||
|
||||
nsresult rv = qi->AsyncLengthWait(callback, GetCurrentSerialEventTarget());
|
||||
ASSERT_EQ(NS_OK, rv);
|
||||
|
||||
MOZ_ALWAYS_TRUE(SpinEventLoopUntil(
|
||||
"TEST(TestPartiallySeekableInputStream, AsyncInputStreamLength)"_ns,
|
||||
[&]() { return callback->Called(); }));
|
||||
ASSERT_EQ(int64_t(buf.Length()), callback->Size());
|
||||
}
|
||||
|
||||
TEST(TestPartiallySeekableInputStream, NegativeAsyncInputStreamLength)
|
||||
{
|
||||
nsCString buf;
|
||||
buf.AssignLiteral("Hello world");
|
||||
|
||||
nsCOMPtr<nsIInputStream> psis;
|
||||
{
|
||||
RefPtr<testing::LengthInputStream> stream =
|
||||
new testing::LengthInputStream(buf, false, true, NS_OK, true);
|
||||
psis = new PartiallySeekableInputStream(stream.forget());
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAsyncInputStreamLength> qi = do_QueryInterface(psis);
|
||||
ASSERT_TRUE(!!qi);
|
||||
|
||||
RefPtr<testing::LengthCallback> callback = new testing::LengthCallback();
|
||||
|
||||
nsresult rv = qi->AsyncLengthWait(callback, GetCurrentSerialEventTarget());
|
||||
ASSERT_EQ(NS_OK, rv);
|
||||
|
||||
MOZ_ALWAYS_TRUE(SpinEventLoopUntil(
|
||||
"TEST(TestPartiallySeekableInputStream, NegativeAsyncInputStreamLength)"_ns,
|
||||
[&]() { return callback->Called(); }));
|
||||
ASSERT_EQ(-1, callback->Size());
|
||||
}
|
||||
|
||||
TEST(TestPartiallySeekableInputStream, AbortLengthCallback)
|
||||
{
|
||||
nsCString buf;
|
||||
buf.AssignLiteral("Hello world");
|
||||
|
||||
nsCOMPtr<nsIInputStream> psis;
|
||||
{
|
||||
RefPtr<testing::LengthInputStream> stream =
|
||||
new testing::LengthInputStream(buf, false, true, NS_OK, true);
|
||||
psis = new PartiallySeekableInputStream(stream.forget());
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAsyncInputStreamLength> qi = do_QueryInterface(psis);
|
||||
ASSERT_TRUE(!!qi);
|
||||
|
||||
RefPtr<testing::LengthCallback> callback1 = new testing::LengthCallback();
|
||||
nsresult rv = qi->AsyncLengthWait(callback1, GetCurrentSerialEventTarget());
|
||||
ASSERT_EQ(NS_OK, rv);
|
||||
|
||||
RefPtr<testing::LengthCallback> callback2 = new testing::LengthCallback();
|
||||
rv = qi->AsyncLengthWait(callback2, GetCurrentSerialEventTarget());
|
||||
ASSERT_EQ(NS_OK, rv);
|
||||
|
||||
MOZ_ALWAYS_TRUE(SpinEventLoopUntil(
|
||||
"TEST(TestPartiallySeekableInputStream, AbortLengthCallback)"_ns,
|
||||
[&]() { return callback2->Called(); }));
|
||||
ASSERT_TRUE(!callback1->Called());
|
||||
ASSERT_EQ(-1, callback2->Size());
|
||||
}
|
||||
|
||||
TEST(TestPartiallySeekableInputStream, AsyncWaitAfterConsumed)
|
||||
{
|
||||
nsCString buf{"The Quick Brown Fox Jumps over the Lazy Dog"};
|
||||
const size_t bufsize = 44;
|
||||
|
||||
auto stream = MakeRefPtr<testing::AsyncStringStream>(buf);
|
||||
nsCOMPtr<nsIAsyncInputStream> psis =
|
||||
new PartiallySeekableInputStream(stream.forget(), bufsize);
|
||||
ASSERT_TRUE(psis);
|
||||
|
||||
auto callback = MakeRefPtr<testing::InputStreamCallback>();
|
||||
|
||||
nsresult rv = psis->AsyncWait(callback, 0, 0, GetCurrentSerialEventTarget());
|
||||
ASSERT_EQ(NS_OK, rv);
|
||||
|
||||
MOZ_ALWAYS_TRUE(SpinEventLoopUntil(
|
||||
"TEST(TestPartiallySeekableInputStream, AsyncWaitAfterConsumed) 1"_ns,
|
||||
[&]() { return callback->Called(); }));
|
||||
|
||||
char rdbuf[bufsize] = {'\0'};
|
||||
uint32_t count;
|
||||
ASSERT_EQ(NS_OK, psis->Read(rdbuf, sizeof(rdbuf), &count));
|
||||
ASSERT_STREQ(rdbuf, buf.Data());
|
||||
|
||||
callback = MakeRefPtr<testing::InputStreamCallback>();
|
||||
|
||||
rv = psis->AsyncWait(callback, 0, 0, GetCurrentSerialEventTarget());
|
||||
ASSERT_EQ(NS_OK, rv);
|
||||
|
||||
MOZ_ALWAYS_TRUE(SpinEventLoopUntil(
|
||||
"TEST(TestPartiallySeekableInputStream, AsyncWaitAfterConsumed) 2"_ns,
|
||||
[&]() { return callback->Called(); }));
|
||||
|
||||
memset(rdbuf, 0x0, bufsize);
|
||||
ASSERT_EQ(NS_OK, psis->Read(rdbuf, sizeof(rdbuf), &count));
|
||||
ASSERT_EQ(0U, count);
|
||||
}
|
||||
|
||||
TEST(TestPartiallySeekableInputStream, AsyncWaitAfterClosed)
|
||||
{
|
||||
nsCString buf{"The Quick Brown Fox Jumps over the Lazy Dog"};
|
||||
const size_t bufsize = 44;
|
||||
|
||||
auto stream = MakeRefPtr<testing::AsyncStringStream>(buf);
|
||||
nsCOMPtr<nsIAsyncInputStream> psis =
|
||||
new PartiallySeekableInputStream(stream.forget(), bufsize);
|
||||
ASSERT_TRUE(psis);
|
||||
|
||||
auto callback = MakeRefPtr<testing::InputStreamCallback>();
|
||||
|
||||
nsresult rv = psis->AsyncWait(callback, 0, 0, GetCurrentSerialEventTarget());
|
||||
ASSERT_EQ(NS_OK, rv);
|
||||
|
||||
MOZ_ALWAYS_TRUE(SpinEventLoopUntil(
|
||||
"TEST(TestPartiallySeekableInputStream, AsyncWaitAfterClosed) 1"_ns,
|
||||
[&]() { return callback->Called(); }));
|
||||
|
||||
ASSERT_EQ(NS_OK, psis->Close());
|
||||
|
||||
callback = MakeRefPtr<testing::InputStreamCallback>();
|
||||
|
||||
rv = psis->AsyncWait(callback, 0, 0, GetCurrentSerialEventTarget());
|
||||
ASSERT_EQ(NS_OK, rv);
|
||||
|
||||
MOZ_ALWAYS_TRUE(SpinEventLoopUntil(
|
||||
"TEST(TestPartiallySeekableInputStream, AsyncWaitAfterClosed) 2"_ns,
|
||||
[&]() { return callback->Called(); }));
|
||||
}
|
||||
|
||||
TEST(TestPartiallySeekableInputStream, AsyncLengthWaitAfterClosed)
|
||||
{
|
||||
nsCString buf{"The Quick Brown Fox Jumps over the Lazy Dog"};
|
||||
|
||||
auto stream = MakeRefPtr<testing::LengthInputStream>(buf, false, true);
|
||||
nsCOMPtr<nsIInputStream> psis =
|
||||
new PartiallySeekableInputStream(stream.forget());
|
||||
|
||||
nsCOMPtr<nsIAsyncInputStreamLength> qi = do_QueryInterface(psis);
|
||||
ASSERT_TRUE(qi);
|
||||
|
||||
auto callback = MakeRefPtr<testing::LengthCallback>();
|
||||
|
||||
nsresult rv = qi->AsyncLengthWait(callback, GetCurrentSerialEventTarget());
|
||||
ASSERT_EQ(NS_OK, rv);
|
||||
|
||||
MOZ_ALWAYS_TRUE(SpinEventLoopUntil(
|
||||
"TEST(TestPartiallySeekableInputStream, AsyncLengthWaitAfterClosed) 1"_ns,
|
||||
[&]() { return callback->Called(); }));
|
||||
ASSERT_EQ(int64_t(buf.Length()), callback->Size());
|
||||
|
||||
ASSERT_EQ(NS_OK, psis->Close());
|
||||
|
||||
callback = MakeRefPtr<testing::LengthCallback>();
|
||||
|
||||
rv = qi->AsyncLengthWait(callback, GetCurrentSerialEventTarget());
|
||||
ASSERT_EQ(NS_OK, rv);
|
||||
|
||||
MOZ_ALWAYS_TRUE(SpinEventLoopUntil(
|
||||
"TEST(TestPartiallySeekableInputStream, AsyncLengthWaitAfterClosed) 2"_ns,
|
||||
[&]() { return callback->Called(); }));
|
||||
ASSERT_EQ(-1, callback->Size());
|
||||
}
|
||||
|
||||
TEST(TestPartiallySeekableInputStream, AsyncLengthWaitAfterConsumed)
|
||||
{
|
||||
nsCString buf{"The Quick Brown Fox Jumps over the Lazy Dog"};
|
||||
const size_t bufsize = 44;
|
||||
|
||||
auto stream = MakeRefPtr<testing::LengthInputStream>(buf, false, true);
|
||||
nsCOMPtr<nsIInputStream> psis =
|
||||
new PartiallySeekableInputStream(stream.forget());
|
||||
|
||||
nsCOMPtr<nsIAsyncInputStreamLength> qi = do_QueryInterface(psis);
|
||||
ASSERT_TRUE(qi);
|
||||
|
||||
auto callback = MakeRefPtr<testing::LengthCallback>();
|
||||
|
||||
nsresult rv = qi->AsyncLengthWait(callback, GetCurrentSerialEventTarget());
|
||||
ASSERT_EQ(NS_OK, rv);
|
||||
|
||||
MOZ_ALWAYS_TRUE(SpinEventLoopUntil(
|
||||
"TEST(TestPartiallySeekableInputStream, AsyncLengthWaitAfterConsumed) 1"_ns,
|
||||
[&]() { return callback->Called(); }));
|
||||
ASSERT_EQ(int64_t(buf.Length()), callback->Size());
|
||||
|
||||
char rdbuf[bufsize] = {'\0'};
|
||||
uint32_t count;
|
||||
ASSERT_EQ(NS_OK, psis->Read(rdbuf, sizeof(rdbuf), &count));
|
||||
ASSERT_STREQ(rdbuf, buf.Data());
|
||||
|
||||
callback = MakeRefPtr<testing::LengthCallback>();
|
||||
|
||||
rv = qi->AsyncLengthWait(callback, GetCurrentSerialEventTarget());
|
||||
ASSERT_EQ(NS_OK, rv);
|
||||
|
||||
MOZ_ALWAYS_TRUE(SpinEventLoopUntil(
|
||||
"TEST(TestPartiallySeekableInputStream, AsyncLengthWaitAfterConsumed) 2"_ns,
|
||||
[&]() { return callback->Called(); }));
|
||||
ASSERT_EQ(0U, callback->Size());
|
||||
|
||||
memset(rdbuf, 0x0, bufsize);
|
||||
ASSERT_EQ(NS_OK, psis->Read(rdbuf, sizeof(rdbuf), &count));
|
||||
ASSERT_EQ(0U, count);
|
||||
}
|
||||
@@ -37,7 +37,6 @@ if CONFIG["OS_TARGET"] == "WINNT":
|
||||
if not (CONFIG["OS_TARGET"] == "WINNT" and CONFIG["CPU_ARCH"] == "aarch64"):
|
||||
UNIFIED_SOURCES += [
|
||||
"TestPACMan.cpp",
|
||||
"TestPartiallySeekableInputStream.cpp",
|
||||
"TestURIMutator.cpp",
|
||||
]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user