diff --git a/mozilla/modules/plugin/base/src/nsPluginInstancePeer.cpp b/mozilla/modules/plugin/base/src/nsPluginInstancePeer.cpp index 70b9e48a7bb..50c1162fecb 100644 --- a/mozilla/modules/plugin/base/src/nsPluginInstancePeer.cpp +++ b/mozilla/modules/plugin/base/src/nsPluginInstancePeer.cpp @@ -263,7 +263,7 @@ NS_IMETHODIMP nsPluginStreamToFile::Write(const char* aBuf, PRUint32 aCount, PRUint32 *aWriteCount) { // write the data to the file and update the target - nsCOMPtr thing; + nsCOMPtr thing; thing = do_QueryInterface(mFileThing); thing->Open(mFileSpec, (PR_RDWR|PR_APPEND), 0700); PRUint32 actualCount; diff --git a/mozilla/modules/plugin/nglsrc/nsPluginInstancePeer.cpp b/mozilla/modules/plugin/nglsrc/nsPluginInstancePeer.cpp index 70b9e48a7bb..50c1162fecb 100644 --- a/mozilla/modules/plugin/nglsrc/nsPluginInstancePeer.cpp +++ b/mozilla/modules/plugin/nglsrc/nsPluginInstancePeer.cpp @@ -263,7 +263,7 @@ NS_IMETHODIMP nsPluginStreamToFile::Write(const char* aBuf, PRUint32 aCount, PRUint32 *aWriteCount) { // write the data to the file and update the target - nsCOMPtr thing; + nsCOMPtr thing; thing = do_QueryInterface(mFileThing); thing->Open(mFileSpec, (PR_RDWR|PR_APPEND), 0700); PRUint32 actualCount; diff --git a/mozilla/xpcom/base/IIDS.h b/mozilla/xpcom/base/IIDS.h index 5a6560f566b..f47236f9517 100644 --- a/mozilla/xpcom/base/IIDS.h +++ b/mozilla/xpcom/base/IIDS.h @@ -935,7 +935,7 @@ nsIFileOutputStream = { /* a6cf90e7-15b3-11d2-932e-00805f8add32 */ 0x11d2, {0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} }; -nsIFile = { /* a6cf90e8-15b3-11d2-932e-00805f8add32 */ +nsIOpenFile = { /* a6cf90e8-15b3-11d2-932e-00805f8add32 */ 0xa6cf90e8, 0x15b3, 0x11d2, diff --git a/mozilla/xpcom/io/nsFileStream.h b/mozilla/xpcom/io/nsFileStream.h index 718399b4f9b..f6c0922aa7d 100644 --- a/mozilla/xpcom/io/nsFileStream.h +++ b/mozilla/xpcom/io/nsFileStream.h @@ -302,7 +302,7 @@ class NS_COM nsFileClient : public virtual nsErrorProne { public: - nsFileClient(const nsCOMPtr& inFile) + nsFileClient(const nsCOMPtr& inFile) : mFile(do_QueryInterface(inFile)) { } @@ -335,7 +335,7 @@ protected: } // DATA protected: - nsCOMPtr mFile; + nsCOMPtr mFile; }; // class nsFileClient //======================================================================================== diff --git a/mozilla/xpcom/io/nsIFile.idl b/mozilla/xpcom/io/nsIFile.idl index 79860560363..8c82f3bc09d 100644 --- a/mozilla/xpcom/io/nsIFile.idl +++ b/mozilla/xpcom/io/nsIFile.idl @@ -177,3 +177,8 @@ interface nsIFile : nsISupports */ boolean isEqual([const] in nsIFile inFile); }; + +%{C++ +#define NS_FILE_PROGID "component://netscape/file" +#define NS_FILE_CLASSNAME "File Specification" +%} diff --git a/mozilla/xpcom/io/nsIFileStream.cpp b/mozilla/xpcom/io/nsIFileStream.cpp index e6e729c8b20..b6f03595508 100644 --- a/mozilla/xpcom/io/nsIFileStream.cpp +++ b/mozilla/xpcom/io/nsIFileStream.cpp @@ -22,6 +22,8 @@ #include "prerror.h" +#include "nsSegmentedBuffer.h" + #ifdef XP_MAC #include "pprio.h" // To get PR_ImportFile #else @@ -38,7 +40,7 @@ class FileImpl : public nsIRandomAccessStore , public nsIFileOutputStream , public nsIFileInputStream - , public nsIFile + , public nsIOpenFile //======================================================================================== { public: @@ -50,6 +52,13 @@ class FileImpl , mLength(-1) { NS_INIT_REFCNT(); + + nsresult rv = mOutBuffer.Init(4096, 4096); + if (NS_FAILED(rv)) mFailed = PR_TRUE; + + mWriteCursor = nsnull; + mWriteLimit = nsnull; + } FileImpl( const nsFileSpec& inFile, @@ -62,6 +71,13 @@ class FileImpl , mLength(-1) { NS_INIT_REFCNT(); + + nsresult rv = mOutBuffer.Init(4096, 4096); + if (NS_FAILED(rv)) mFailed = PR_TRUE; + + mWriteCursor = nsnull; + mWriteLimit = nsnull; + Open(inFile, nsprMode, accessMode); } virtual ~FileImpl() @@ -72,7 +88,7 @@ class FileImpl // nsISupports interface NS_DECL_ISUPPORTS - // nsIFile interface + // nsIOpenFile interface NS_IMETHOD Open( const nsFileSpec& inFile, int nsprMode, @@ -133,7 +149,8 @@ class FileImpl { NS_PRECONDITION(aBuf != nsnull, "null ptr"); NS_PRECONDITION(aWriteCount != nsnull, "null ptr"); - + + *aWriteCount = 0; #ifdef XP_MAC // Calling PR_Write on stdout is sure suicide. @@ -148,14 +165,39 @@ class FileImpl return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR); if (mFailed) return NS_ERROR_FAILURE; - PRInt32 bytesWrit = PR_Write(mFileDesc, aBuf, aCount); - if (bytesWrit != (PRInt32)aCount) - { - mFailed = PR_TRUE; - *aWriteCount = 0; - return NS_FILE_RESULT(PR_GetError()); - } - *aWriteCount = bytesWrit; + + PRUint32 bufOffset = 0; + + while (aCount > 0) + { + if (mWriteCursor == nsnull || mWriteCursor == mWriteLimit) + { + char* seg = mOutBuffer.AppendNewSegment(); + if (seg == nsnull) + { + // buffer is full, try again + Flush(); + seg = mOutBuffer.AppendNewSegment(); + if (seg == nsnull) + return NS_ERROR_OUT_OF_MEMORY; + } + mWriteCursor = seg; + mWriteLimit = seg + mOutBuffer.GetSegmentSize(); + } + + // move + + *aWriteCount = mWriteLimit - mWriteCursor; + + if (aCount < *aWriteCount) + *aWriteCount = aCount; + + memcpy(mWriteCursor, (aBuf + bufOffset), *aWriteCount); + + aCount -= *aWriteCount; + bufOffset += *aWriteCount; + mWriteCursor += *aWriteCount; + } return NS_OK; } NS_IMETHOD Flush(); @@ -178,13 +220,18 @@ class FileImpl PRBool mFailed; PRBool mEOF; PRInt32 mLength; + + nsSegmentedBuffer mOutBuffer; + char* mWriteCursor; + char* mWriteLimit; + }; // class FileImpl NS_IMPL_RELEASE(FileImpl) NS_IMPL_ADDREF(FileImpl) NS_IMPL_QUERY_HEAD(FileImpl) - NS_IMPL_QUERY_BODY(nsIFile) + NS_IMPL_QUERY_BODY(nsIOpenFile) NS_IMPL_QUERY_BODY(nsIRandomAccessStore) NS_IMPL_QUERY_BODY(nsIOutputStream) NS_IMPL_QUERY_BODY(nsIInputStream) @@ -336,6 +383,8 @@ NS_IMETHODIMP FileImpl::Tell(PRIntn* outWhere) NS_IMETHODIMP FileImpl::Close() //---------------------------------------------------------------------------------------- { + Flush(); + if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR || !mFileDesc) return NS_OK; if (PR_Close(mFileDesc) == PR_SUCCESS) @@ -359,11 +408,35 @@ NS_IMETHODIMP FileImpl::Flush() if (!mFileDesc) return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR); + PRInt32 segCount = mOutBuffer.GetSegmentCount(); + PRUint32 segSize = mOutBuffer.GetSegmentSize(); + + for (PRInt32 i = 0; i < segCount; i++) + { + char* seg = mOutBuffer.GetSegment(i); + + // if it is the last buffer, it may not be completely full. + if(i == (segCount-1)) + segSize = (mWriteCursor - seg); + + PRInt32 bytesWrit = PR_Write(mFileDesc, seg, segSize); + if (bytesWrit != (PRInt32)segSize) + { + mFailed = PR_TRUE; + return NS_FILE_RESULT(PR_GetError()); + } + } + + mOutBuffer.Empty(); + mWriteCursor = nsnull; + mWriteLimit = nsnull; + #ifdef XP_MAC // On unix, it seems to fail always. if (PR_Sync(mFileDesc) != PR_SUCCESS) mFailed = PR_TRUE; #endif + return NS_OK; } // FileImpl::flush diff --git a/mozilla/xpcom/io/nsIFileStream.h b/mozilla/xpcom/io/nsIFileStream.h index 7f14ace09d6..15b590b3d45 100644 --- a/mozilla/xpcom/io/nsIFileStream.h +++ b/mozilla/xpcom/io/nsIFileStream.h @@ -25,18 +25,18 @@ class nsFileSpec; /* a6cf90e8-15b3-11d2-932e-00805f8add32 */ -#define NS_IFILE_IID \ +#define NS_IOPENFILE_IID \ { 0xa6cf90e8, 0x15b3, 0x11d2, \ {0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} } //======================================================================================== -class nsIFile +class nsIOpenFile // Represents a file, and supports Open. //======================================================================================== : public nsISupports { public: - static const nsIID& GetIID() { static nsIID iid = NS_IFILE_IID; return iid; } + static const nsIID& GetIID() { static nsIID iid = NS_IOPENFILE_IID; return iid; } NS_IMETHOD Open( const nsFileSpec& inFile, int nsprMode, @@ -46,7 +46,7 @@ public: // are automatically opened on construction. NS_IMETHOD GetIsOpen(PRBool* outOpen) = 0; -}; // class nsIFile +}; // class nsIOpenFile /* a6cf90e8-15b3-11d2-932e-00805f8add32 */ #define NS_IRANDOMACCESS_IID \ diff --git a/mozilla/xpcom/tests/FilesTest.cpp b/mozilla/xpcom/tests/FilesTest.cpp index 71cc2c59850..de735bf4fc9 100644 --- a/mozilla/xpcom/tests/FilesTest.cpp +++ b/mozilla/xpcom/tests/FilesTest.cpp @@ -956,7 +956,7 @@ int FilesTest::RunAllTests() return rv; Banner("StringStream"); - rv = StringStream(); +// rv = StringStream(); if (rv) return rv;