Merge mozilla-central to mozilla-inbound

This commit is contained in:
Ed Morley 2012-05-23 11:03:54 +01:00
commit eb7c23a3ef
9 changed files with 489 additions and 182 deletions

View File

@ -56,6 +56,7 @@ interface nsIFileInputStream : nsIInputStream
* or more specifically, when one of the following is called:
* - Seek
* - Tell
* - SetEOF
* - Available
* - Read
* - ReadLine
@ -98,6 +99,7 @@ interface nsIFileOutputStream : nsIOutputStream
* be performed when one of the following is called:
* - Seek
* - Tell
* - SetEOF
* - Write
* - Flush
*
@ -140,3 +142,66 @@ interface nsIPartialFileInputStream : nsISupports
in unsigned long long length,
in long ioFlags, in long perm, in long behaviorFlags);
};
/**
* A stream that allows you to read from a file or stream to a file.
*/
[scriptable, uuid(82cf605a-8393-4550-83ab-43cd5578e006)]
interface nsIFileStream : nsISupports
{
/**
* @param file file to read from or stream to (must QI to
* nsILocalFile)
* @param ioFlags file open flags listed in prio.h (see
* PR_Open documentation) or -1 to open the
* file in default mode (PR_RDWR).
* @param perm file mode bits listed in prio.h or -1 to
* use the default value (0)
* @param behaviorFlags flags specifying various behaviors of the class
* (see enumerations in the class)
*/
void init(in nsIFile file, in long ioFlags, in long perm,
in long behaviorFlags);
/**
* See the same constant in nsIFileInputStream. The deferred open will
* be performed when one of the following is called:
* - Seek
* - Tell
* - SetEOF
* - Available
* - Read
* - Flush
* - Write
* - GetSize
* - GetLastModified
*
* @note Using this flag results in the file not being opened
* during the call to Init. This means that any errors that might
* happen when this flag is not set would happen during the
* first read or write. The file is not locked when Init is called,
* so it might be deleted before we try to read from it and if the
* file is to be created, then it will not appear on the disk until
* the first write.
*/
const long DEFER_OPEN = 1<<0;
};
/**
* An interface that allows you to get some metadata like file size and
* file last modified time.
*/
[scriptable, uuid(07f679e4-9601-4bd1-b510-cd3852edb881)]
interface nsIFileMetadata : nsISupports
{
/**
* File size in bytes;
*/
readonly attribute long long size;
/**
* File last modified time in milliseconds from midnight (00:00:00),
* January 1, 1970 Greenwich Mean Time (GMT).
*/
readonly attribute long long lastModified;
};

View File

@ -15,7 +15,7 @@ interface nsIOutputStream;
* into a fully asynchronous stream that can be read/written without
* blocking the main thread.
*/
[scriptable, uuid(8268D474-EFBF-494f-A152-E8A8616F4E52)]
[scriptable, uuid(51CAC889-ABC6-4948-97A3-4F135A6E7630)]
interface nsIStreamTransportService : nsISupports
{
/**
@ -65,4 +65,33 @@ interface nsIStreamTransportService : nsISupports
in long long aStartOffset,
in long long aWriteLimit,
in boolean aCloseWhenDone);
/**
* Raise the maximum number of active threads by one.
*
* Calling this method won't create any additional thread synchronously.
* It will be only created when it's needed (lazily).
*
* Used by mozilla::dom::file::FileService to increase the maximum number
* of active threads in the thread pool for asynchronous file IO.
*/
void raiseThreadLimit();
/**
* Lower the maximum number of active threads by one.
* lowerThreadLimit() should be always paired with raiseThreadLimit().
*
* Calling this method won't destroy any already running thread
* synchronously. It will be only destroyed when it's done with
* currently running event.
*
* This will never lower the maximum number of active threads beyond
* the internal limit.
*
* @throws NS_ERROR_UNEXPECTED
* When trying to lower the maximum number of active threads
* beyond the internal limit (for example in the case of badly
* nested calls)
*/
void lowerThreadLimit();
};

View File

@ -919,7 +919,7 @@ NS_NewLocalFileInputStream(nsIInputStream **result,
if (NS_SUCCEEDED(rv)) {
rv = in->Init(file, ioFlags, perm, behaviorFlags);
if (NS_SUCCEEDED(rv))
NS_ADDREF(*result = in); // cannot use nsCOMPtr::swap
in.forget(result);
}
return rv;
}
@ -957,7 +957,7 @@ NS_NewLocalFileOutputStream(nsIOutputStream **result,
if (NS_SUCCEEDED(rv)) {
rv = out->Init(file, ioFlags, perm, behaviorFlags);
if (NS_SUCCEEDED(rv))
NS_ADDREF(*result = out); // cannot use nsCOMPtr::swap
out.forget(result);
}
return rv;
}
@ -976,7 +976,25 @@ NS_NewSafeLocalFileOutputStream(nsIOutputStream **result,
if (NS_SUCCEEDED(rv)) {
rv = out->Init(file, ioFlags, perm, behaviorFlags);
if (NS_SUCCEEDED(rv))
NS_ADDREF(*result = out); // cannot use nsCOMPtr::swap
out.forget(result);
}
return rv;
}
inline nsresult
NS_NewLocalFileStream(nsIFileStream **result,
nsIFile *file,
PRInt32 ioFlags = -1,
PRInt32 perm = -1,
PRInt32 behaviorFlags = 0)
{
nsresult rv;
nsCOMPtr<nsIFileStream> stream =
do_CreateInstance(NS_LOCALFILESTREAM_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv)) {
rv = stream->Init(file, ioFlags, perm, behaviorFlags);
if (NS_SUCCEEDED(rv))
stream.forget(result);
}
return rv;
}

View File

@ -240,7 +240,7 @@ nsAsyncStreamCopier::AsyncCopy(nsIRequestObserver *observer, nsISupports *ctx)
if (NS_FAILED(rv))
Cancel(rv);
}
// we want to receive progress notifications; release happens in
// OnAsyncCopyComplete.
NS_ADDREF_THIS();

View File

@ -33,38 +33,24 @@
#define NS_NO_INPUT_BUFFERING 1 // see http://bugzilla.mozilla.org/show_bug.cgi?id=41067
////////////////////////////////////////////////////////////////////////////////
// nsFileStream
// nsFileStreamBase
nsFileStream::nsFileStream()
nsFileStreamBase::nsFileStreamBase()
: mFD(nsnull)
, mBehaviorFlags(0)
, mDeferredOpen(false)
{
}
nsFileStream::~nsFileStream()
nsFileStreamBase::~nsFileStreamBase()
{
Close();
}
NS_IMPL_THREADSAFE_ISUPPORTS1(nsFileStream, nsISeekableStream)
nsresult
nsFileStream::Close()
{
CleanUpOpen();
nsresult rv = NS_OK;
if (mFD) {
if (PR_Close(mFD) == PR_FAILURE)
rv = NS_BASE_STREAM_OSERROR;
mFD = nsnull;
}
return rv;
}
NS_IMPL_THREADSAFE_ISUPPORTS1(nsFileStreamBase, nsISeekableStream)
NS_IMETHODIMP
nsFileStream::Seek(PRInt32 whence, PRInt64 offset)
nsFileStreamBase::Seek(PRInt32 whence, PRInt64 offset)
{
nsresult rv = DoPendingOpen();
NS_ENSURE_SUCCESS(rv, rv);
@ -80,7 +66,7 @@ nsFileStream::Seek(PRInt32 whence, PRInt64 offset)
}
NS_IMETHODIMP
nsFileStream::Tell(PRInt64 *result)
nsFileStreamBase::Tell(PRInt64 *result)
{
nsresult rv = DoPendingOpen();
NS_ENSURE_SUCCESS(rv, rv);
@ -97,15 +83,18 @@ nsFileStream::Tell(PRInt64 *result)
}
NS_IMETHODIMP
nsFileStream::SetEOF()
nsFileStreamBase::SetEOF()
{
nsresult rv = DoPendingOpen();
NS_ENSURE_SUCCESS(rv, rv);
if (mFD == nsnull)
return NS_BASE_STREAM_CLOSED;
#if defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS)
// Some system calls require an EOF offset.
PRInt64 offset;
nsresult rv = Tell(&offset);
rv = Tell(&offset);
if (NS_FAILED(rv)) return rv;
#endif
@ -132,8 +121,138 @@ nsFileStream::SetEOF()
}
nsresult
nsFileStream::MaybeOpen(nsILocalFile* aFile, PRInt32 aIoFlags, PRInt32 aPerm,
bool aDeferred)
nsFileStreamBase::Close()
{
CleanUpOpen();
nsresult rv = NS_OK;
if (mFD) {
if (PR_Close(mFD) == PR_FAILURE)
rv = NS_BASE_STREAM_OSERROR;
mFD = nsnull;
}
return rv;
}
nsresult
nsFileStreamBase::Available(PRUint32* aResult)
{
nsresult rv = DoPendingOpen();
NS_ENSURE_SUCCESS(rv, rv);
if (!mFD) {
return NS_BASE_STREAM_CLOSED;
}
// PR_Available with files over 4GB returns an error, so we have to
// use the 64-bit version of PR_Available.
PRInt64 avail = PR_Available64(mFD);
if (avail == -1) {
return NS_ErrorAccordingToNSPR();
}
// If available is greater than 4GB, return 4GB
*aResult = avail > PR_UINT32_MAX ? PR_UINT32_MAX : (PRUint32)avail;
return NS_OK;
}
nsresult
nsFileStreamBase::Read(char* aBuf, PRUint32 aCount, PRUint32* aResult)
{
nsresult rv = DoPendingOpen();
NS_ENSURE_SUCCESS(rv, rv);
if (!mFD) {
*aResult = 0;
return NS_OK;
}
PRInt32 bytesRead = PR_Read(mFD, aBuf, aCount);
if (bytesRead == -1) {
return NS_ErrorAccordingToNSPR();
}
*aResult = bytesRead;
return NS_OK;
}
nsresult
nsFileStreamBase::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
PRUint32 aCount, PRUint32* aResult)
{
// ReadSegments is not implemented because it would be inefficient when
// the writer does not consume all data. If you want to call ReadSegments,
// wrap a BufferedInputStream around the file stream. That will call
// Read().
// If this is ever implemented you might need to modify
// nsPartialFileInputStream::ReadSegments
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult
nsFileStreamBase::IsNonBlocking(bool *aNonBlocking)
{
*aNonBlocking = false;
return NS_OK;
}
nsresult
nsFileStreamBase::Flush(void)
{
nsresult rv = DoPendingOpen();
NS_ENSURE_SUCCESS(rv, rv);
if (mFD == nsnull)
return NS_BASE_STREAM_CLOSED;
PRInt32 cnt = PR_Sync(mFD);
if (cnt == -1) {
return NS_ErrorAccordingToNSPR();
}
return NS_OK;
}
nsresult
nsFileStreamBase::Write(const char *buf, PRUint32 count, PRUint32 *result)
{
nsresult rv = DoPendingOpen();
NS_ENSURE_SUCCESS(rv, rv);
if (mFD == nsnull)
return NS_BASE_STREAM_CLOSED;
PRInt32 cnt = PR_Write(mFD, buf, count);
if (cnt == -1) {
return NS_ErrorAccordingToNSPR();
}
*result = cnt;
return NS_OK;
}
nsresult
nsFileStreamBase::WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval)
{
NS_NOTREACHED("WriteFrom (see source comment)");
return NS_ERROR_NOT_IMPLEMENTED;
// File streams intentionally do not support this method.
// If you need something like this, then you should wrap
// the file stream using nsIBufferedOutputStream
}
nsresult
nsFileStreamBase::WriteSegments(nsReadSegmentFun reader, void * closure, PRUint32 count, PRUint32 *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
// File streams intentionally do not support this method.
// If you need something like this, then you should wrap
// the file stream using nsIBufferedOutputStream
}
nsresult
nsFileStreamBase::MaybeOpen(nsILocalFile* aFile, PRInt32 aIoFlags,
PRInt32 aPerm, bool aDeferred)
{
mOpenParams.ioFlags = aIoFlags;
mOpenParams.perm = aPerm;
@ -157,14 +276,14 @@ nsFileStream::MaybeOpen(nsILocalFile* aFile, PRInt32 aIoFlags, PRInt32 aPerm,
}
void
nsFileStream::CleanUpOpen()
nsFileStreamBase::CleanUpOpen()
{
mOpenParams.localFile = nsnull;
mDeferredOpen = false;
}
nsresult
nsFileStream::DoOpen()
nsFileStreamBase::DoOpen()
{
NS_PRECONDITION(mOpenParams.localFile, "Must have a file to open");
@ -178,7 +297,7 @@ nsFileStream::DoOpen()
}
nsresult
nsFileStream::DoPendingOpen()
nsFileStreamBase::DoPendingOpen()
{
if (!mDeferredOpen) {
return NS_OK;
@ -190,20 +309,19 @@ nsFileStream::DoPendingOpen()
////////////////////////////////////////////////////////////////////////////////
// nsFileInputStream
NS_IMPL_ADDREF_INHERITED(nsFileInputStream, nsFileStream)
NS_IMPL_RELEASE_INHERITED(nsFileInputStream, nsFileStream)
NS_IMPL_ADDREF_INHERITED(nsFileInputStream, nsFileStreamBase)
NS_IMPL_RELEASE_INHERITED(nsFileInputStream, nsFileStreamBase)
NS_IMPL_CLASSINFO(nsFileInputStream, NULL, nsIClassInfo::THREADSAFE,
NS_LOCALFILEINPUTSTREAM_CID)
NS_INTERFACE_MAP_BEGIN(nsFileInputStream)
NS_INTERFACE_MAP_ENTRY(nsFileStream)
NS_INTERFACE_MAP_ENTRY(nsIInputStream)
NS_INTERFACE_MAP_ENTRY(nsIFileInputStream)
NS_INTERFACE_MAP_ENTRY(nsILineInputStream)
NS_INTERFACE_MAP_ENTRY(nsIIPCSerializable)
NS_IMPL_QUERY_CLASSINFO(nsFileInputStream)
NS_INTERFACE_MAP_END_INHERITING(nsFileStream)
NS_INTERFACE_MAP_END_INHERITING(nsFileStreamBase)
NS_IMPL_CI_INTERFACE_GETTER5(nsFileInputStream,
nsIInputStream,
@ -286,7 +404,7 @@ nsFileInputStream::Close()
{
// null out mLineBuffer in case Close() is called again after failing
PR_FREEIF(mLineBuffer);
nsresult rv = nsFileStream::Close();
nsresult rv = nsFileStreamBase::Close();
if (NS_FAILED(rv)) return rv;
if (mFile && (mBehaviorFlags & DELETE_ON_CLOSE)) {
rv = mFile->Remove(false);
@ -300,50 +418,16 @@ nsFileInputStream::Close()
}
NS_IMETHODIMP
nsFileInputStream::Available(PRUint32* aResult)
nsFileInputStream::Read(char* aBuf, PRUint32 aCount, PRUint32* _retval)
{
nsresult rv = DoPendingOpen();
nsresult rv = nsFileStreamBase::Read(aBuf, aCount, _retval);
NS_ENSURE_SUCCESS(rv, rv);
if (!mFD) {
return NS_BASE_STREAM_CLOSED;
}
// PR_Available with files over 4GB returns an error, so we have to
// use the 64-bit version of PR_Available.
PRInt64 avail = PR_Available64(mFD);
if (avail == -1) {
return NS_ErrorAccordingToNSPR();
}
// If available is greater than 4GB, return 4GB
*aResult = avail > PR_UINT32_MAX ? PR_UINT32_MAX : (PRUint32)avail;
return NS_OK;
}
NS_IMETHODIMP
nsFileInputStream::Read(char* aBuf, PRUint32 aCount, PRUint32* aResult)
{
nsresult rv = DoPendingOpen();
NS_ENSURE_SUCCESS(rv, rv);
if (!mFD) {
*aResult = 0;
return NS_OK;
}
PRInt32 bytesRead = PR_Read(mFD, aBuf, aCount);
if (bytesRead == -1) {
return NS_ErrorAccordingToNSPR();
}
// Check if we're at the end of file and need to close
if (mBehaviorFlags & CLOSE_ON_EOF) {
if (bytesRead == 0) {
Close();
}
if (mBehaviorFlags & CLOSE_ON_EOF && *_retval == 0) {
Close();
}
*aResult = bytesRead;
return NS_OK;
}
@ -360,28 +444,6 @@ nsFileInputStream::ReadLine(nsACString& aLine, bool* aResult)
return NS_ReadLine(this, mLineBuffer, aLine, aResult);
}
NS_IMETHODIMP
nsFileInputStream::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
PRUint32 aCount, PRUint32* aResult)
{
// ReadSegments is not implemented because it would be inefficient when
// the writer does not consume all data. If you want to call ReadSegments,
// wrap a BufferedInputStream around the file stream. That will call
// Read().
// If this is ever implemented you might need to modify
// nsPartialFileInputStream::ReadSegments
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsFileInputStream::IsNonBlocking(bool *aNonBlocking)
{
*aNonBlocking = false;
return NS_OK;
}
NS_IMETHODIMP
nsFileInputStream::Seek(PRInt32 aWhence, PRInt64 aOffset)
{
@ -400,7 +462,7 @@ nsFileInputStream::Seek(PRInt32 aWhence, PRInt64 aOffset)
}
}
return nsFileStream::Seek(aWhence, aOffset);
return nsFileStreamBase::Seek(aWhence, aOffset);
}
bool
@ -451,7 +513,7 @@ nsFileInputStream::Write(IPC::Message *aMsg)
// Don't forward to nsFileInputStream as we don't want to QI to
// nsIFileInputStream
NS_IMPL_ISUPPORTS_INHERITED3(nsPartialFileInputStream,
nsFileStream,
nsFileStreamBase,
nsIInputStream,
nsIPartialFileInputStream,
nsILineInputStream)
@ -557,8 +619,8 @@ nsPartialFileInputStream::Seek(PRInt32 aWhence, PRInt64 aOffset)
////////////////////////////////////////////////////////////////////////////////
// nsFileOutputStream
NS_IMPL_ISUPPORTS_INHERITED2(nsFileOutputStream,
nsFileStream,
NS_IMPL_ISUPPORTS_INHERITED2(nsFileOutputStream,
nsFileStreamBase,
nsIOutputStream,
nsIFileOutputStream)
@ -597,75 +659,10 @@ nsFileOutputStream::Init(nsIFile* file, PRInt32 ioFlags, PRInt32 perm,
mBehaviorFlags & nsIFileOutputStream::DEFER_OPEN);
}
NS_IMETHODIMP
nsFileOutputStream::Close()
{
return nsFileStream::Close();
}
NS_IMETHODIMP
nsFileOutputStream::Write(const char *buf, PRUint32 count, PRUint32 *result)
{
nsresult rv = DoPendingOpen();
NS_ENSURE_SUCCESS(rv, rv);
if (mFD == nsnull)
return NS_BASE_STREAM_CLOSED;
PRInt32 cnt = PR_Write(mFD, buf, count);
if (cnt == -1) {
return NS_ErrorAccordingToNSPR();
}
*result = cnt;
return NS_OK;
}
NS_IMETHODIMP
nsFileOutputStream::Flush(void)
{
nsresult rv = DoPendingOpen();
NS_ENSURE_SUCCESS(rv, rv);
if (mFD == nsnull)
return NS_BASE_STREAM_CLOSED;
PRInt32 cnt = PR_Sync(mFD);
if (cnt == -1) {
return NS_ErrorAccordingToNSPR();
}
return NS_OK;
}
NS_IMETHODIMP
nsFileOutputStream::WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval)
{
NS_NOTREACHED("WriteFrom (see source comment)");
return NS_ERROR_NOT_IMPLEMENTED;
// File streams intentionally do not support this method.
// If you need something like this, then you should wrap
// the file stream using nsIBufferedOutputStream
}
NS_IMETHODIMP
nsFileOutputStream::WriteSegments(nsReadSegmentFun reader, void * closure, PRUint32 count, PRUint32 *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
// File streams intentionally do not support this method.
// If you need something like this, then you should wrap
// the file stream using nsIBufferedOutputStream
}
NS_IMETHODIMP
nsFileOutputStream::IsNonBlocking(bool *aNonBlocking)
{
*aNonBlocking = false;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsSafeFileOutputStream
NS_IMPL_ISUPPORTS_INHERITED3(nsSafeFileOutputStream,
NS_IMPL_ISUPPORTS_INHERITED3(nsSafeFileOutputStream,
nsFileOutputStream,
nsISafeOutputStream,
nsIOutputStream,
@ -810,3 +807,80 @@ nsSafeFileOutputStream::Write(const char *buf, PRUint32 count, PRUint32 *result)
}
////////////////////////////////////////////////////////////////////////////////
// nsFileStream
NS_IMPL_ISUPPORTS_INHERITED4(nsFileStream,
nsFileStreamBase,
nsIInputStream,
nsIOutputStream,
nsIFileStream,
nsIFileMetadata)
NS_IMETHODIMP
nsFileStream::Init(nsIFile* file, PRInt32 ioFlags, PRInt32 perm,
PRInt32 behaviorFlags)
{
NS_ENSURE_TRUE(mFD == nsnull, NS_ERROR_ALREADY_INITIALIZED);
NS_ENSURE_TRUE(!mDeferredOpen, NS_ERROR_ALREADY_INITIALIZED);
mBehaviorFlags = behaviorFlags;
nsresult rv;
nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(file, &rv);
if (NS_FAILED(rv)) return rv;
if (ioFlags == -1)
ioFlags = PR_RDWR;
if (perm <= 0)
perm = 0;
return MaybeOpen(localFile, ioFlags, perm,
mBehaviorFlags & nsIFileStream::DEFER_OPEN);
}
NS_IMETHODIMP
nsFileStream::GetSize(PRInt64* _retval)
{
nsresult rv = DoPendingOpen();
NS_ENSURE_SUCCESS(rv, rv);
if (!mFD) {
return NS_BASE_STREAM_CLOSED;
}
PRFileInfo64 info;
if (PR_GetOpenFileInfo64(mFD, &info) == PR_FAILURE) {
return NS_BASE_STREAM_OSERROR;
}
*_retval = PRInt64(info.size);
return NS_OK;
}
NS_IMETHODIMP
nsFileStream::GetLastModified(PRInt64* _retval)
{
nsresult rv = DoPendingOpen();
NS_ENSURE_SUCCESS(rv, rv);
if (!mFD) {
return NS_BASE_STREAM_CLOSED;
}
PRFileInfo64 info;
if (PR_GetOpenFileInfo64(mFD, &info) == PR_FAILURE) {
return NS_BASE_STREAM_OSERROR;
}
PRInt64 modTime = PRInt64(info.modifyTime);
if (modTime == 0) {
*_retval = 0;
}
else {
*_retval = modTime / PRInt64(PR_USEC_PER_MSEC);
}
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -23,18 +23,29 @@ template<class CharType> class nsLineBuffer;
////////////////////////////////////////////////////////////////////////////////
class nsFileStream : public nsISeekableStream
class nsFileStreamBase : public nsISeekableStream
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISEEKABLESTREAM
nsFileStream();
virtual ~nsFileStream();
nsresult Close();
nsFileStreamBase();
virtual ~nsFileStreamBase();
protected:
nsresult Close();
nsresult Available(PRUint32* _retval);
nsresult Read(char* aBuf, PRUint32 aCount, PRUint32* _retval);
nsresult ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
PRUint32 aCount, PRUint32* _retval);
nsresult IsNonBlocking(bool* _retval);
nsresult Flush();
nsresult Write(const char* aBuf, PRUint32 aCount, PRUint32* _retval);
nsresult WriteFrom(nsIInputStream* aFromStream, PRUint32 aCount,
PRUint32* _retval);
nsresult WriteSegments(nsReadSegmentFun aReader, void* aClosure,
PRUint32 aCount, PRUint32* _retval);
PRFileDesc* mFD;
/**
@ -88,22 +99,38 @@ protected:
////////////////////////////////////////////////////////////////////////////////
class nsFileInputStream : public nsFileStream,
class nsFileInputStream : public nsFileStreamBase,
public nsIFileInputStream,
public nsILineInputStream,
public nsIIPCSerializable
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIINPUTSTREAM
NS_DECL_NSIFILEINPUTSTREAM
NS_DECL_NSILINEINPUTSTREAM
NS_DECL_NSIIPCSERIALIZABLE
NS_IMETHOD Close();
NS_IMETHOD Available(PRUint32* _retval)
{
return nsFileStreamBase::Available(_retval);
}
NS_IMETHOD Read(char* aBuf, PRUint32 aCount, PRUint32* _retval);
NS_IMETHOD ReadSegments(nsWriteSegmentFun aWriter, void *aClosure,
PRUint32 aCount, PRUint32* _retval)
{
return nsFileStreamBase::ReadSegments(aWriter, aClosure, aCount,
_retval);
}
NS_IMETHOD IsNonBlocking(bool* _retval)
{
return nsFileStreamBase::IsNonBlocking(_retval);
}
// Overrided from nsFileStream
// Overrided from nsFileStreamBase
NS_IMETHOD Seek(PRInt32 aWhence, PRInt64 aOffset);
nsFileInputStream() : nsFileStream()
nsFileInputStream()
{
mLineBuffer = nsnull;
}
@ -172,17 +199,19 @@ private:
////////////////////////////////////////////////////////////////////////////////
class nsFileOutputStream : public nsFileStream,
class nsFileOutputStream : public nsFileStreamBase,
public nsIFileOutputStream
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIOUTPUTSTREAM
NS_DECL_NSIFILEOUTPUTSTREAM
NS_FORWARD_NSIOUTPUTSTREAM(nsFileStreamBase::)
virtual ~nsFileOutputStream()
{
Close();
}
nsFileOutputStream() : nsFileStream() {}
virtual ~nsFileOutputStream() { nsFileOutputStream::Close(); }
static nsresult
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
};
@ -200,7 +229,10 @@ public:
mTargetFileExists(true),
mWriteResult(NS_OK) {}
virtual ~nsSafeFileOutputStream() { nsSafeFileOutputStream::Close(); }
virtual ~nsSafeFileOutputStream()
{
Close();
}
virtual nsresult DoOpen();
@ -218,4 +250,46 @@ protected:
////////////////////////////////////////////////////////////////////////////////
class nsFileStream : public nsFileStreamBase,
public nsIInputStream,
public nsIOutputStream,
public nsIFileStream,
public nsIFileMetadata
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIFILESTREAM
NS_DECL_NSIFILEMETADATA
NS_FORWARD_NSIINPUTSTREAM(nsFileStreamBase::)
// Can't use NS_FORWARD_NSIOUTPUTSTREAM due to overlapping methods
// Close() and IsNonBlocking()
NS_IMETHOD Flush()
{
return nsFileStreamBase::Flush();
}
NS_IMETHOD Write(const char* aBuf, PRUint32 aCount, PRUint32* _retval)
{
return nsFileStreamBase::Write(aBuf, aCount, _retval);
}
NS_IMETHOD WriteFrom(nsIInputStream* aFromStream, PRUint32 aCount,
PRUint32* _retval)
{
return nsFileStreamBase::WriteFrom(aFromStream, aCount, _retval);
}
NS_IMETHOD WriteSegments(nsReadSegmentFun aReader, void* aClosure,
PRUint32 aCount, PRUint32* _retval)
{
return nsFileStreamBase::WriteSegments(aReader, aClosure, aCount,
_retval);
}
virtual ~nsFileStream()
{
Close();
}
};
////////////////////////////////////////////////////////////////////////////////
#endif // nsFileStreams_h__

View File

@ -500,6 +500,35 @@ nsStreamTransportService::CreateOutputTransport(nsIOutputStream *stream,
return NS_OK;
}
NS_IMETHODIMP
nsStreamTransportService::RaiseThreadLimit()
{
NS_ENSURE_TRUE(mPool, NS_ERROR_NOT_INITIALIZED);
PRUint32 threadLimit;
nsresult rv = mPool->GetThreadLimit(&threadLimit);
NS_ENSURE_SUCCESS(rv, rv);
return mPool->SetThreadLimit(threadLimit + 1);
}
NS_IMETHODIMP
nsStreamTransportService::LowerThreadLimit()
{
NS_ENSURE_TRUE(mPool, NS_ERROR_NOT_INITIALIZED);
PRUint32 threadLimit;
nsresult rv = mPool->GetThreadLimit(&threadLimit);
NS_ENSURE_SUCCESS(rv, rv);
if (threadLimit == 4) {
NS_WARNING("Badly nested raise/lower thread limit!");
return NS_ERROR_UNEXPECTED;
}
return mPool->SetThreadLimit(threadLimit - 1);
}
NS_IMETHODIMP
nsStreamTransportService::Observe(nsISupports *subject, const char *topic,
const PRUnichar *data)

View File

@ -432,6 +432,19 @@
{0x94, 0xdb, 0xd4, 0xf8, 0x59, 0x05, 0x82, 0x15} \
}
// component implementing nsIFileStream
#define NS_LOCALFILESTREAM_CLASSNAME \
"nsFileStream"
#define NS_LOCALFILESTREAM_CONTRACTID \
"@mozilla.org/network/file-stream;1"
#define NS_LOCALFILESTREAM_CID \
{ /* f8a69bd7-176c-4a60-9a05-b6d92f8f229a */ \
0xf8a69bd7, \
0x176c, \
0x4a60, \
{0x9a, 0x05, 0xb6, 0xd9, 0x2f, 0x8f, 0x22, 0x9a} \
}
// component implementing nsIPrivateBrowsingService
#define NS_PRIVATE_BROWSING_SERVICE_CONTRACTID \
"@mozilla.org/privatebrowsing-wrapper;1"

View File

@ -87,6 +87,8 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSyncStreamListener, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSafeFileOutputStream)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsFileStream)
NS_GENERIC_AGGREGATED_CONSTRUCTOR_INIT(nsLoadGroup, Init)
#include "nsEffectiveTLDService.h"
@ -672,6 +674,7 @@ NS_DEFINE_NAMED_CID(NS_LOCALFILEINPUTSTREAM_CID);
NS_DEFINE_NAMED_CID(NS_LOCALFILEOUTPUTSTREAM_CID);
NS_DEFINE_NAMED_CID(NS_PARTIALLOCALFILEINPUTSTREAM_CID);
NS_DEFINE_NAMED_CID(NS_SAFELOCALFILEOUTPUTSTREAM_CID);
NS_DEFINE_NAMED_CID(NS_LOCALFILESTREAM_CID);
NS_DEFINE_NAMED_CID(NS_URICHECKER_CID);
NS_DEFINE_NAMED_CID(NS_INCREMENTALDOWNLOAD_CID);
NS_DEFINE_NAMED_CID(NS_STDURLPARSER_CID);
@ -806,6 +809,7 @@ static const mozilla::Module::CIDEntry kNeckoCIDs[] = {
{ &kNS_LOCALFILEOUTPUTSTREAM_CID, false, NULL, nsFileOutputStream::Create },
{ &kNS_PARTIALLOCALFILEINPUTSTREAM_CID, false, NULL, nsPartialFileInputStream::Create },
{ &kNS_SAFELOCALFILEOUTPUTSTREAM_CID, false, NULL, nsSafeFileOutputStreamConstructor },
{ &kNS_LOCALFILESTREAM_CID, false, NULL, nsFileStreamConstructor },
{ &kNS_URICHECKER_CID, false, NULL, nsURICheckerConstructor },
{ &kNS_INCREMENTALDOWNLOAD_CID, false, NULL, net_NewIncrementalDownload },
{ &kNS_STDURLPARSER_CID, false, NULL, nsStdURLParserConstructor },
@ -944,6 +948,7 @@ static const mozilla::Module::ContractIDEntry kNeckoContracts[] = {
{ NS_LOCALFILEOUTPUTSTREAM_CONTRACTID, &kNS_LOCALFILEOUTPUTSTREAM_CID },
{ NS_PARTIALLOCALFILEINPUTSTREAM_CONTRACTID, &kNS_PARTIALLOCALFILEINPUTSTREAM_CID },
{ NS_SAFELOCALFILEOUTPUTSTREAM_CONTRACTID, &kNS_SAFELOCALFILEOUTPUTSTREAM_CID },
{ NS_LOCALFILESTREAM_CONTRACTID, &kNS_LOCALFILESTREAM_CID },
{ NS_URICHECKER_CONTRACT_ID, &kNS_URICHECKER_CID },
{ NS_INCREMENTALDOWNLOAD_CONTRACTID, &kNS_INCREMENTALDOWNLOAD_CID },
{ NS_STDURLPARSER_CONTRACTID, &kNS_STDURLPARSER_CID },