diff --git a/dom/workers/FileReaderSync.cpp b/dom/workers/FileReaderSync.cpp index 8214f81356a4..9f9a008666d0 100644 --- a/dom/workers/FileReaderSync.cpp +++ b/dom/workers/FileReaderSync.cpp @@ -182,16 +182,10 @@ FileReaderSync::ReadAsText(Blob& aBlob, } // Let's recreate the full stream using a: - // multiplexStream(stringStream + original stream) + // multiplexStream(syncStream + original stream) // In theory, we could try to see if the inputStream is a nsISeekableStream, // but this doesn't work correctly for nsPipe3 - See bug 1349570. - nsCOMPtr stringStream; - aRv = NS_NewCStringInputStream(getter_AddRefs(stringStream), sniffBuf); - if (NS_WARN_IF(aRv.Failed())) { - return; - } - nsCOMPtr multiplexStream = do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1"); if (NS_WARN_IF(!multiplexStream)) { @@ -199,12 +193,24 @@ FileReaderSync::ReadAsText(Blob& aBlob, return; } - aRv = multiplexStream->AppendStream(stringStream); + nsCOMPtr sniffStringStream; + aRv = NS_NewCStringInputStream(getter_AddRefs(sniffStringStream), sniffBuf); if (NS_WARN_IF(aRv.Failed())) { return; } - aRv = multiplexStream->AppendStream(stream); + aRv = multiplexStream->AppendStream(sniffStringStream); + if (NS_WARN_IF(aRv.Failed())) { + return; + } + + nsCOMPtr syncStream; + aRv = ConvertAsyncToSyncStream(stream, getter_AddRefs(syncStream)); + if (NS_WARN_IF(aRv.Failed())) { + return; + } + + aRv = multiplexStream->AppendStream(syncStream); if (NS_WARN_IF(aRv.Failed())) { return; } @@ -434,3 +440,44 @@ FileReaderSync::SyncRead(nsIInputStream* aStream, char* aBuffer, // Now, we can try to read again. return SyncRead(aStream, aBuffer, aBufferSize, aRead); } + +nsresult +FileReaderSync::ConvertAsyncToSyncStream(nsIInputStream* aAsyncStream, + nsIInputStream** aSyncStream) +{ + // If the stream is not async, we have nothing to do here. + nsCOMPtr asyncStream = do_QueryInterface(aAsyncStream); + if (!asyncStream) { + nsCOMPtr stream = aAsyncStream; + stream.forget(aSyncStream); + return NS_OK; + } + + uint64_t length; + nsresult rv = aAsyncStream->Available(&length); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + nsAutoCString buffer; + if (!buffer.SetLength(length, fallible)) { + return NS_ERROR_OUT_OF_MEMORY; + } + + uint32_t read; + rv = SyncRead(aAsyncStream, buffer.BeginWriting(), length, &read); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + if (read != length) { + return NS_ERROR_FAILURE; + } + + rv = NS_NewCStringInputStream(aSyncStream, buffer); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + return NS_OK; +} diff --git a/dom/workers/FileReaderSync.h b/dom/workers/FileReaderSync.h index a23877a60abc..6b61f039ee8a 100644 --- a/dom/workers/FileReaderSync.h +++ b/dom/workers/FileReaderSync.h @@ -32,6 +32,9 @@ private: nsresult ConvertStream(nsIInputStream *aStream, const char *aCharset, nsAString &aResult); + nsresult ConvertAsyncToSyncStream(nsIInputStream* aAsyncStream, + nsIInputStream** aSyncStream); + nsresult SyncRead(nsIInputStream* aStream, char* aBuffer, uint32_t aBufferSize, uint32_t* aRead);