Bug 1359087 - Use IPCBlob in FileHandle - part 3 - Changes in IndexedDB StreamWrapper, r=janv

This commit is contained in:
Andrea Marchesini 2017-05-09 22:35:42 +02:00
Родитель 13532cc30e
Коммит 018dbb6ceb
1 изменённых файлов: 134 добавлений и 19 удалений

Просмотреть файл

@ -8,6 +8,8 @@
#include "IDBFileHandle.h"
#include "mozilla/Assertions.h"
#include "nsIAsyncInputStream.h"
#include "nsICloneableInputStream.h"
#include "nsIIPCSerializableInputStream.h"
namespace mozilla {
@ -19,7 +21,9 @@ using namespace mozilla::ipc;
namespace {
class StreamWrapper final
: public nsIInputStream
: public nsIAsyncInputStream
, public nsIInputStreamCallback
, public nsICloneableInputStream
, public nsIIPCSerializableInputStream
{
class CloseRunnable;
@ -29,6 +33,9 @@ class StreamWrapper final
RefPtr<IDBFileHandle> mFileHandle;
bool mFinished;
// This is needed to call OnInputStreamReady() with the correct inputStream.
nsCOMPtr<nsIInputStreamCallback> mAsyncWaitCallback;
public:
StreamWrapper(nsIInputStream* aInputStream,
IDBFileHandle* aFileHandle)
@ -95,8 +102,34 @@ private:
NS_DISPATCH_NORMAL));
}
bool
IsCloneableInputStream() const
{
nsCOMPtr<nsICloneableInputStream> stream =
do_QueryInterface(mInputStream);
return !!stream;
}
bool
IsIPCSerializableInputStream() const
{
nsCOMPtr<nsIIPCSerializableInputStream> stream =
do_QueryInterface(mInputStream);
return !!stream;
}
bool
IsAsyncInputStream() const
{
nsCOMPtr<nsIAsyncInputStream> stream = do_QueryInterface(mInputStream);
return !!stream;
}
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIINPUTSTREAM
NS_DECL_NSIASYNCINPUTSTREAM
NS_DECL_NSIINPUTSTREAMCALLBACK
NS_DECL_NSICLONEABLEINPUTSTREAM
NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM
};
@ -211,15 +244,23 @@ StreamWrapper::~StreamWrapper()
NS_IMPL_ADDREF(StreamWrapper)
NS_IMPL_RELEASE_WITH_DESTROY(StreamWrapper, Destroy())
NS_IMPL_QUERY_INTERFACE(StreamWrapper,
nsIInputStream,
nsIIPCSerializableInputStream)
NS_INTERFACE_MAP_BEGIN(StreamWrapper)
NS_INTERFACE_MAP_ENTRY(nsIInputStream)
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAsyncInputStream,
IsAsyncInputStream())
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIInputStreamCallback,
IsAsyncInputStream())
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsICloneableInputStream,
IsCloneableInputStream())
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIIPCSerializableInputStream,
IsIPCSerializableInputStream())
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIInputStream)
NS_INTERFACE_MAP_END
NS_IMETHODIMP
StreamWrapper::Close()
{
MOZ_ASSERT(!IsOnOwningThread());
RefPtr<CloseRunnable> closeRunnable = new CloseRunnable(this);
MOZ_ALWAYS_SUCCEEDS(mOwningThread->Dispatch(closeRunnable,
@ -231,17 +272,12 @@ StreamWrapper::Close()
NS_IMETHODIMP
StreamWrapper::Available(uint64_t* _retval)
{
// Can't assert here, this method is sometimes called on the owning thread
// (nsInputStreamChannel::OpenContentStream calls Available before setting
// the content length property).
return mInputStream->Available(_retval);
}
NS_IMETHODIMP
StreamWrapper::Read(char* aBuf, uint32_t aCount, uint32_t* _retval)
{
MOZ_ASSERT(!IsOnOwningThread());
return mInputStream->Read(aBuf, aCount, _retval);
}
@ -249,7 +285,6 @@ NS_IMETHODIMP
StreamWrapper::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
uint32_t aCount, uint32_t* _retval)
{
MOZ_ASSERT(!IsOnOwningThread());
return mInputStream->ReadSegments(aWriter, aClosure, aCount, _retval);
}
@ -275,13 +310,7 @@ bool
StreamWrapper::Deserialize(const InputStreamParams& aParams,
const FileDescriptorArray& aFileDescriptors)
{
nsCOMPtr<nsIIPCSerializableInputStream> stream =
do_QueryInterface(mInputStream);
if (stream) {
return stream->Deserialize(aParams, aFileDescriptors);
}
MOZ_CRASH("This method should never be called");
return false;
}
@ -297,6 +326,92 @@ StreamWrapper::ExpectedSerializedLength()
return Nothing();
}
NS_IMETHODIMP
StreamWrapper::CloseWithStatus(nsresult aStatus)
{
nsCOMPtr<nsIAsyncInputStream> stream = do_QueryInterface(mInputStream);
if (!stream) {
return NS_ERROR_NO_INTERFACE;
}
nsresult rv = stream->CloseWithStatus(aStatus);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return Close();
}
NS_IMETHODIMP
StreamWrapper::AsyncWait(nsIInputStreamCallback* aCallback,
uint32_t aFlags,
uint32_t aRequestedCount,
nsIEventTarget* aEventTarget)
{
nsCOMPtr<nsIAsyncInputStream> stream = do_QueryInterface(mInputStream);
if (!stream) {
return NS_ERROR_NO_INTERFACE;
}
if (mAsyncWaitCallback && aCallback) {
return NS_ERROR_FAILURE;
}
mAsyncWaitCallback = aCallback;
if (!mAsyncWaitCallback) {
return NS_OK;
}
return stream->AsyncWait(this, aFlags, aRequestedCount, aEventTarget);
}
// nsIInputStreamCallback
NS_IMETHODIMP
StreamWrapper::OnInputStreamReady(nsIAsyncInputStream* aStream)
{
nsCOMPtr<nsIAsyncInputStream> stream = do_QueryInterface(mInputStream);
if (!stream) {
return NS_ERROR_NO_INTERFACE;
}
// We have been canceled in the meanwhile.
if (!mAsyncWaitCallback) {
return NS_OK;
}
nsCOMPtr<nsIInputStreamCallback> callback;
callback.swap(mAsyncWaitCallback);
return callback->OnInputStreamReady(this);
}
// nsICloneableInputStream
NS_IMETHODIMP
StreamWrapper::GetCloneable(bool* aCloneable)
{
nsCOMPtr<nsICloneableInputStream> stream = do_QueryInterface(mInputStream);
if (!stream) {
*aCloneable = false;
return NS_ERROR_NO_INTERFACE;
}
return stream->GetCloneable(aCloneable);
}
NS_IMETHODIMP
StreamWrapper::Clone(nsIInputStream** aResult)
{
nsCOMPtr<nsICloneableInputStream> stream = do_QueryInterface(mInputStream);
if (!stream) {
return NS_ERROR_NO_INTERFACE;
}
return stream->Clone(aResult);
}
NS_IMPL_ISUPPORTS_INHERITED0(StreamWrapper::CloseRunnable,
Runnable)