From 1f1340510a2285c6f5ea1023462472ced67c50f8 Mon Sep 17 00:00:00 2001 From: "sdwilsh@shawnwilsher.com" Date: Fri, 4 Jan 2008 09:55:02 -0800 Subject: [PATCH] Bug 410131 - DM isn't buffering writes when saving a file. r=biesi, sr=bz --- .../src/nsWebBrowserPersist.cpp | 5 +++- netwerk/base/public/nsNetUtil.h | 27 +++++++++++++++++++ .../exthandler/nsExternalHelperAppService.cpp | 16 ++++++++--- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/embedding/components/webbrowserpersist/src/nsWebBrowserPersist.cpp b/embedding/components/webbrowserpersist/src/nsWebBrowserPersist.cpp index 443131eb13af..8e7d1433c8ba 100644 --- a/embedding/components/webbrowserpersist/src/nsWebBrowserPersist.cpp +++ b/embedding/components/webbrowserpersist/src/nsWebBrowserPersist.cpp @@ -121,6 +121,8 @@ #include "nsWebBrowserPersist.h" +// Buffer file writes in 32kb chunks +#define BUFFERED_OUTPUT_SIZE (1024 * 32) #define NS_SUCCESS_DONT_FIXUP NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_GENERAL, 1) @@ -2281,7 +2283,8 @@ nsWebBrowserPersist::MakeOutputStreamFromFile( rv = fileOutputStream->Init(aFile, ioFlags, -1, 0); NS_ENSURE_SUCCESS(rv, rv); - NS_ENSURE_SUCCESS(CallQueryInterface(fileOutputStream, aOutputStream), NS_ERROR_FAILURE); + *aOutputStream = NS_BufferOutputStream(fileOutputStream, + BUFFERED_OUTPUT_SIZE).get(); if (mPersistFlags & PERSIST_FLAGS_CLEANUP_ON_FAILURE) { diff --git a/netwerk/base/public/nsNetUtil.h b/netwerk/base/public/nsNetUtil.h index c651b2546b89..1e7fd650d42f 100644 --- a/netwerk/base/public/nsNetUtil.h +++ b/netwerk/base/public/nsNetUtil.h @@ -947,6 +947,33 @@ NS_NewBufferedOutputStream(nsIOutputStream **result, return rv; } +/** + * Attempts to buffer a given output stream. If this fails, it returns the + * passed-in output stream. + * + * @param aOutputStream + * The output stream we want to buffer. This cannot be null. + * @param aBufferSize + * The size of the buffer for the buffered output stream. + * @returns an nsIOutputStream that is buffered with the specified buffer size, + * or is aOutputStream if creating the new buffered stream failed. + */ +inline already_AddRefed +NS_BufferOutputStream(nsIOutputStream *aOutputStream, + PRUint32 aBufferSize) +{ + NS_ASSERTION(aOutputStream, "No output stream given!"); + + nsCOMPtr bos; + nsresult rv = NS_NewBufferedOutputStream(getter_AddRefs(bos), aOutputStream, + aBufferSize); + if (NS_SUCCEEDED(rv)) + return bos.forget(); + + NS_ADDREF(aOutputStream); + return aOutputStream; +} + // returns an input stream compatible with nsIUploadChannel::SetUploadStream() inline nsresult NS_NewPostDataStream(nsIInputStream **result, diff --git a/uriloader/exthandler/nsExternalHelperAppService.cpp b/uriloader/exthandler/nsExternalHelperAppService.cpp index 7dbef6a47864..a3a8fecd8996 100644 --- a/uriloader/exthandler/nsExternalHelperAppService.cpp +++ b/uriloader/exthandler/nsExternalHelperAppService.cpp @@ -124,6 +124,9 @@ #include "plbase64.h" #include "prmem.h" +// Buffer file writes in 32kb chunks +#define BUFFERED_OUTPUT_SIZE (1024 * 32) + #ifdef PR_LOGGING PRLogModuleInfo* nsExternalHelperAppService::mLog = nsnull; #endif @@ -1240,13 +1243,16 @@ nsresult nsExternalAppHandler::SetUpTempFile(nsIChannel * aChannel) } #endif - rv = NS_NewLocalFileOutputStream(getter_AddRefs(mOutStream), mTempFile, + nsCOMPtr outputStream; + rv = NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), mTempFile, PR_WRONLY | PR_CREATE_FILE, 0600); if (NS_FAILED(rv)) { mTempFile->Remove(PR_FALSE); return rv; } + mOutStream = NS_BufferOutputStream(outputStream, BUFFERED_OUTPUT_SIZE); + #ifdef XP_MACOSX nsCAutoString contentType; mMimeInfo->GetMIMEType(contentType); @@ -1995,8 +2001,10 @@ NS_IMETHODIMP nsExternalAppHandler::SaveToDisk(nsIFile * aNewFileLocation, PRBoo rv = mTempFile->MoveTo(dir, name); if (NS_SUCCEEDED(rv)) // if it failed, we just continue with $TEMP mTempFile = movedFile; - rv = NS_NewLocalFileOutputStream(getter_AddRefs(mOutStream), mTempFile, - PR_WRONLY | PR_APPEND, 0600); + + nsCOMPtr outputStream; + rv = NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), mTempFile, + PR_WRONLY | PR_APPEND, 0600); if (NS_FAILED(rv)) { // (Re-)opening the output stream failed. bad luck. nsAutoString path; mTempFile->GetPath(path); @@ -2004,6 +2012,8 @@ NS_IMETHODIMP nsExternalAppHandler::SaveToDisk(nsIFile * aNewFileLocation, PRBoo Cancel(rv); return NS_OK; } + + mOutStream = NS_BufferOutputStream(outputStream, BUFFERED_OUTPUT_SIZE); } }