Fix for bug 86474 and bug 79983. Truncate files used by nsFileTransport
and eliminate trailing garbage from updated cache files. r=gagan, sr=darin git-svn-id: svn://10.0.0.236/trunk@99853 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -47,6 +47,9 @@ interface nsISeekableStream : nsISupports
|
||||
|
||||
void seek(in long whence, in long offset);
|
||||
unsigned long tell();
|
||||
|
||||
// truncate stream to the current offset
|
||||
void setEOF();
|
||||
};
|
||||
|
||||
[scriptable, uuid(616f5b48-da09-11d3-8cda-0060b0fc14a3)]
|
||||
|
||||
@@ -138,6 +138,19 @@ nsBufferedStream::Tell(PRUint32 *result)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBufferedStream::SetEOF()
|
||||
{
|
||||
if (mStream == nsnull)
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsISeekableStream> ras = do_QueryInterface(mStream, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
return ras->SetEOF();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsBufferedInputStream
|
||||
|
||||
|
||||
@@ -20,6 +20,24 @@
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
// file truncation support
|
||||
#if defined(__linux)
|
||||
#define _BSD_SOURCE 1
|
||||
#include <unistd.h>
|
||||
#elif defined(XP_MAC)
|
||||
#include <Files.h>
|
||||
#elif defined(XP_WIN)
|
||||
#include <windows.h>
|
||||
#else
|
||||
// XXX add necessary include file for ftruncate (or equivalent)
|
||||
#endif
|
||||
|
||||
#if defined(XP_MAC)
|
||||
#include "pprio.h"
|
||||
#else
|
||||
#include "private/pprio.h"
|
||||
#endif
|
||||
|
||||
#include "nsFileStreams.h"
|
||||
#include "nsILocalFile.h"
|
||||
#include "nsXPIDLString.h"
|
||||
@@ -345,6 +363,46 @@ nsFileStream::Tell(PRUint32 *result)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileStream::SetEOF()
|
||||
{
|
||||
if (mFD == nsnull)
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
|
||||
#if defined(__linux) || defined(XP_MAC) || defined(XP_OS2)
|
||||
// Some system calls require an EOF offset.
|
||||
PRUint32 offset;
|
||||
nsresult rv = Tell(&offset);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
#endif
|
||||
|
||||
#if defined(__linux)
|
||||
if (ftruncate(PR_FileDesc2NativeHandle(mFD), offset) != 0) {
|
||||
NS_ERROR("ftruncate failed");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
#elif defined(XP_MAC)
|
||||
if (::SetEOF(PR_FileDesc2NativeHandle(mFD), offset) != 0) {
|
||||
NS_ERROR("SetEOF failed");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
#elif defined(XP_WIN)
|
||||
if (!SetEndOfFile((HANDLE) PR_FileDesc2NativeHandle(mFD))) {
|
||||
NS_ERROR("SetEndOfFile failed");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
#elif defined(XP_OS2)
|
||||
if (DosSetFileSize((HFILE) PR_FileDesc2NativeHandle(mFD), offset) != NO_ERROR) {
|
||||
NS_ERROR("DosSetFileSize failed");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
#else
|
||||
// XXX not implemented
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsFileInputStream
|
||||
|
||||
|
||||
@@ -474,12 +474,19 @@ nsFileTransport::OpenOutputStream(PRUint32 aTransferOffset,
|
||||
NS_ASSERTION(aTransferCount == PRUint32(-1), "need to wrap output stream in one that truncates");
|
||||
|
||||
nsresult rv = mStreamIO->GetOutputStream(aResult);
|
||||
if (NS_SUCCEEDED(rv) && aTransferOffset) {
|
||||
nsCOMPtr<nsISeekableStream> seekable(do_QueryInterface(*aResult, &rv));
|
||||
if (NS_SUCCEEDED(rv) && seekable) {
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsISeekableStream> seekable(do_QueryInterface(*aResult, &rv));
|
||||
if (seekable) {
|
||||
if (aTransferOffset)
|
||||
rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET, aTransferOffset);
|
||||
}
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = seekable->SetEOF();
|
||||
}
|
||||
// a stream need not support nsISeekableStream unless a transfer offset
|
||||
// greater than zero was requested.
|
||||
else if (aTransferOffset == 0)
|
||||
rv = NS_OK;
|
||||
|
||||
return rv;
|
||||
}
|
||||
@@ -673,14 +680,12 @@ nsFileTransport::Process(void)
|
||||
if (mOffset > 0) {
|
||||
// if we need to set a starting offset, QI for the nsISeekableStream
|
||||
// and set it
|
||||
nsCOMPtr<nsISeekableStream> ras = do_QueryInterface(source, &mStatus);
|
||||
if (NS_FAILED(mStatus)) {
|
||||
mXferState = END_READ;
|
||||
return;
|
||||
nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(source, &mStatus);
|
||||
if (NS_SUCCEEDED(mStatus)) {
|
||||
// for now, assume the offset is always relative to the start of the
|
||||
// file (position 0) so use PR_SEEK_SET
|
||||
mStatus = seekable->Seek(PR_SEEK_SET, mOffset);
|
||||
}
|
||||
// for now, assume the offset is always relative to the start of the
|
||||
// file (position 0) so use PR_SEEK_SET
|
||||
mStatus = ras->Seek(PR_SEEK_SET, mOffset);
|
||||
if (NS_FAILED(mStatus)) {
|
||||
mXferState = END_READ;
|
||||
return;
|
||||
@@ -866,23 +871,24 @@ nsFileTransport::Process(void)
|
||||
return;
|
||||
}
|
||||
|
||||
if (mOffset > 0) {
|
||||
// If we need to set a starting offset, QI for the nsISeekableStream
|
||||
// and set it.
|
||||
nsCOMPtr<nsISeekableStream> ras = do_QueryInterface(mSink, &mStatus);
|
||||
if (NS_FAILED(mStatus)) {
|
||||
mXferState = END_WRITE;
|
||||
return;
|
||||
}
|
||||
// For now, assume the offset is always relative to the start of the
|
||||
// file (position 0) so use PR_SEEK_SET.
|
||||
mStatus = ras->Seek(PR_SEEK_SET, mOffset);
|
||||
if (NS_FAILED(mStatus)) {
|
||||
mXferState = END_WRITE;
|
||||
return;
|
||||
}
|
||||
mOffset = 0;
|
||||
// QI to a seekable stream so we can set EOF and Seek (if required)
|
||||
nsCOMPtr<nsISeekableStream> seekable(do_QueryInterface(mSink, &mStatus));
|
||||
if (seekable) {
|
||||
if (mOffset)
|
||||
mStatus = seekable->Seek(nsISeekableStream::NS_SEEK_SET, mOffset);
|
||||
if (NS_SUCCEEDED(mStatus))
|
||||
mStatus = seekable->SetEOF();
|
||||
}
|
||||
// a stream need not support nsISeekableStream unless a transfer offset
|
||||
// greater than zero was requested.
|
||||
else if (mOffset == 0)
|
||||
mStatus = NS_OK;
|
||||
|
||||
if (NS_FAILED(mStatus)) {
|
||||
mXferState = END_WRITE;
|
||||
return;
|
||||
}
|
||||
mOffset = 0;
|
||||
|
||||
if (!mSinkWrapper) {
|
||||
//
|
||||
|
||||
@@ -2329,6 +2329,12 @@ nsSocketIS::Tell(PRUint32 *offset)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSocketIS::SetEOF()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsSocketOS
|
||||
@@ -2456,6 +2462,12 @@ nsSocketOS::Tell(PRUint32 *offset)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSocketOS::SetEOF()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsSocketRequest
|
||||
|
||||
Reference in New Issue
Block a user