Bug 508605 - NetUtil.asyncCopy does not handle nsISafeOutputStreams correctly

This moves nsISafeOutputStream.idl into xpcom/io and makes nsAStreamCopier
handle nsISafeOutputStream correctly (calling finish instead of close).
r=bz
r=bsmedberg

--HG--
rename : netwerk/base/public/nsISafeOutputStream.idl => xpcom/io/nsISafeOutputStream.idl
This commit is contained in:
Shawn Wilsher 2009-08-06 13:34:46 -07:00
parent db59ca0328
commit 782cbb5800
5 changed files with 57 additions and 6 deletions

View File

@ -72,7 +72,6 @@ XPIDLSRCS = \
nsIAuthPromptAdapterFactory.idl \
nsIAuthPromptCallback.idl \
nsIAsyncStreamCopier.idl \
nsISafeOutputStream.idl \
nsIBufferedStreams.idl \
nsICancelable.idl \
nsICryptoHash.idl \

View File

@ -110,11 +110,48 @@ function test_async_write_file()
});
}
function test_async_write_file_nsISafeOutputStream()
{
do_test_pending();
// First, we need an output file to write to.
let file = Cc["@mozilla.org/file/directory_service;1"].
getService(Ci.nsIProperties).
get("TmpD", Ci.nsIFile);
file.append("NetUtil-async-test-file.tmp");
file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
// Then, we need an output stream to our output file.
let ostream = Cc["@mozilla.org/network/safe-file-output-stream;1"].
createInstance(Ci.nsIFileOutputStream);
ostream.init(file, -1, -1, 0);
// Finally, we need an input stream to take data from.
const TEST_DATA = "this is a test string";
let istream = Cc["@mozilla.org/io/string-input-stream;1"].
createInstance(Ci.nsIStringInputStream);
istream.setData(TEST_DATA, TEST_DATA.length);
NetUtil.asyncCopy(istream, ostream, function(aResult) {
// Make sure the copy was successful!
do_check_true(Components.isSuccessCode(aResult));
// Check the file contents.
do_check_eq(TEST_DATA, getFileContents(file));
// Remove the file, and finish the test.
file.remove(false);
do_test_finished();
run_next_test();
});
}
////////////////////////////////////////////////////////////////////////////////
//// Test Runner
let tests = [
test_async_write_file,
test_async_write_file_nsISafeOutputStream,
];
let index = 0;

View File

@ -156,6 +156,7 @@ XPIDLSRCS = \
nsIConverterInputStream.idl \
nsIConverterOutputStream.idl \
nsIIOUtil.idl \
nsISafeOutputStream.idl \
$(NULL)
ifeq ($(MOZ_WIDGET_TOOLKIT),os2)

View File

@ -41,6 +41,7 @@
#include "nsIPipe.h"
#include "nsIEventTarget.h"
#include "nsIRunnable.h"
#include "nsISafeOutputStream.h"
#include "nsAutoLock.h"
#include "nsString.h"
@ -311,12 +312,15 @@ public:
cancelStatus = mCancelStatus;
}
// ok, copy data from source to sink.
// Copy data from the source to the sink until we hit failure or have
// copied all the data.
for (;;) {
PRUint32 n;
// Note: copyFailed will be true if the source or the sink have
// reported an error, or if we failed to write any bytes
// because we have consumed all of our data.
PRBool copyFailed = PR_FALSE;
if (!canceled) {
n = DoCopy(&sourceCondition, &sinkCondition);
PRUint32 n = DoCopy(&sourceCondition, &sinkCondition);
copyFailed = NS_FAILED(sourceCondition) ||
NS_FAILED(sinkCondition) || n == 0;
@ -366,8 +370,18 @@ public:
if (mAsyncSink)
mAsyncSink->CloseWithStatus(canceled ? cancelStatus :
sourceCondition);
else
mSink->Close();
else {
// If we have an nsISafeOutputStream, and our
// sourceCondition and sinkCondition are not set to a
// failure state, finish writing.
nsCOMPtr<nsISafeOutputStream> sostream =
do_QueryInterface(mSink);
if (sostream && NS_SUCCEEDED(sourceCondition) &&
NS_SUCCEEDED(sinkCondition))
sostream->Finish();
else
mSink->Close();
}
}
mAsyncSink = nsnull;
mSink = nsnull;