summaryrefslogtreecommitdiffstats
path: root/src/libs/xpcom18a4/xpcom/obsolete/nsIFileStream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/xpcom18a4/xpcom/obsolete/nsIFileStream.cpp')
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/nsIFileStream.cpp727
1 files changed, 727 insertions, 0 deletions
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/nsIFileStream.cpp b/src/libs/xpcom18a4/xpcom/obsolete/nsIFileStream.cpp
new file mode 100644
index 00000000..011bcdaa
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/nsIFileStream.cpp
@@ -0,0 +1,727 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Pierre Phaneuf <pp@ludusdesign.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsIFileStream.h"
+#include "nsFileSpec.h"
+#include "nsCOMPtr.h"
+
+#include "prerror.h"
+
+#include "nsSegmentedBuffer.h"
+#include "nsInt64.h"
+
+#ifdef XP_MAC
+#include "pprio.h" // To get PR_ImportFile
+#else
+#include "prio.h"
+#endif
+
+#ifdef XP_MAC
+#include <Errors.h>
+#include <iostream>
+#endif
+
+//========================================================================================
+class FileImpl
+ : public nsIRandomAccessStore
+ , public nsIFileSpecOutputStream
+ , public nsIFileSpecInputStream
+ , public nsIOpenFile
+//========================================================================================
+{
+ public:
+ FileImpl(PRFileDesc* inDesc);
+ FileImpl(const nsFileSpec& inFile, int nsprMode, PRIntn accessMode);
+
+ // nsISupports interface
+ NS_DECL_ISUPPORTS
+
+ // nsIOpenFile interface
+ NS_IMETHOD Open(const nsFileSpec& inFile, int nsprMode, PRIntn accessMode);
+ NS_IMETHOD Close();
+ NS_IMETHOD GetIsOpen(PRBool* outOpen);
+
+ // nsIInputStream interface
+ NS_IMETHOD Available(PRUint32 *aLength);
+ NS_IMETHOD Read(char* aBuf, PRUint32 aCount, PRUint32 *aReadCount);
+ NS_IMETHOD ReadSegments(nsWriteSegmentFun writer, void * closure, PRUint32 count, PRUint32 *_retval);
+ NS_IMETHOD IsNonBlocking(PRBool *aNonBlocking);
+
+ // nsIOutputStream interface
+ NS_IMETHOD Write(const char* aBuf, PRUint32 aCount, PRUint32 *aWriteCount);
+ NS_IMETHOD Flush();
+ NS_IMETHOD WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval);
+ NS_IMETHOD WriteSegments(nsReadSegmentFun reader, void * closure, PRUint32 count, PRUint32 *_retval);
+
+ // nsIRandomAccessStore interface
+ NS_DECL_NSISEEKABLESTREAM
+ NS_IMETHOD GetAtEOF(PRBool* outAtEOF);
+ NS_IMETHOD SetAtEOF(PRBool inAtEOF);
+
+ private:
+
+ ~FileImpl();
+
+ protected:
+
+ enum {
+ kOuputBufferSegmentSize = 4096,
+ kOuputBufferMaxSize = 4096
+ };
+
+ nsresult InternalFlush(PRBool syncFile);
+ nsresult AllocateBuffers(PRUint32 segmentSize, PRUint32 maxSize);
+
+ PRFileDesc* mFileDesc;
+ int mNSPRMode;
+ PRBool mFailed;
+ PRBool mEOF;
+ PRInt32 mLength;
+
+ PRBool mGotBuffers;
+ 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(nsIOpenFile)
+ NS_IMPL_QUERY_BODY(nsISeekableStream)
+ NS_IMPL_QUERY_BODY(nsIRandomAccessStore)
+ NS_IMPL_QUERY_BODY(nsIOutputStream)
+ NS_IMPL_QUERY_BODY(nsIInputStream)
+ NS_IMPL_QUERY_BODY(nsIFileSpecInputStream)
+ NS_IMPL_QUERY_BODY(nsIFileSpecOutputStream)
+NS_IMPL_QUERY_TAIL(nsIOutputStream)
+
+
+//----------------------------------------------------------------------------------------
+FileImpl::FileImpl(PRFileDesc* inDesc)
+//----------------------------------------------------------------------------------------
+: mFileDesc(inDesc)
+, mNSPRMode(0)
+, mFailed(PR_FALSE)
+, mEOF(PR_FALSE)
+, mLength(-1)
+, mGotBuffers(PR_FALSE)
+{
+ mWriteCursor = nsnull;
+ mWriteLimit = nsnull;
+}
+
+
+//----------------------------------------------------------------------------------------
+FileImpl::FileImpl(const nsFileSpec& inFile, int nsprMode, PRIntn accessMode)
+//----------------------------------------------------------------------------------------
+: mFileDesc(nsnull)
+, mNSPRMode(-1)
+, mEOF(PR_FALSE)
+, mLength(-1)
+, mGotBuffers(PR_FALSE)
+{
+ mWriteCursor = nsnull;
+ mWriteLimit = nsnull;
+
+ nsresult rv = Open(inFile, nsprMode, accessMode); // this sets nsprMode
+
+ if (NS_FAILED(rv))
+ {
+ mFailed = PR_TRUE;
+#if DEBUG
+ char *fileName = inFile.GetLeafName();
+ printf("Opening file %s failed\n", fileName);
+ nsCRT::free(fileName);
+#endif
+ }
+ else
+ {
+ mFailed = PR_FALSE;
+ }
+}
+
+//----------------------------------------------------------------------------------------
+FileImpl::~FileImpl()
+//----------------------------------------------------------------------------------------
+{
+ nsresult rv = Close();
+ NS_ASSERTION(NS_SUCCEEDED(rv), "Close failed");
+}
+
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP FileImpl::Open(
+ const nsFileSpec& inFile,
+ int nsprMode,
+ PRIntn accessMode)
+//----------------------------------------------------------------------------------------
+{
+ if (mFileDesc)
+ if ((nsprMode & mNSPRMode) == nsprMode)
+ return NS_OK;
+ else
+ return NS_FILE_RESULT(PR_ILLEGAL_ACCESS_ERROR);
+
+ const int nspr_modes[]={
+ PR_WRONLY | PR_CREATE_FILE,
+ PR_WRONLY | PR_CREATE_FILE | PR_APPEND,
+ PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
+ PR_RDONLY,
+ PR_RDONLY | PR_APPEND,
+ PR_RDWR | PR_CREATE_FILE,
+ PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE,
+// "wb",
+// "ab",
+// "wb",
+// "rb",
+// "r+b",
+// "w+b",
+ 0 };
+ const int* currentLegalMode = nspr_modes;
+ while (*currentLegalMode && nsprMode != *currentLegalMode)
+ ++currentLegalMode;
+ if (!*currentLegalMode)
+ return NS_FILE_RESULT(PR_ILLEGAL_ACCESS_ERROR);
+
+#ifdef XP_MAC
+ // Use the file spec to open the file, because one path can be common to
+ // several files on the Macintosh (you can have several volumes with the
+ // same name, see).
+ mFileDesc = 0;
+ OSErr err = inFile.Error();
+ if (err != noErr)
+ if (err != fnfErr || !(nsprMode & PR_CREATE_FILE))
+ return NS_FILE_RESULT(inFile.Error());
+ err = noErr;
+#if DEBUG
+ const OSType kCreator = 'CWIE';
+#else
+ const OSType kCreator = 'MOSS';
+#endif
+ // Resolve the alias to the original file.
+ nsFileSpec original = inFile;
+ PRBool ignoredResult;
+ original.ResolveSymlink(ignoredResult);
+ const FSSpec& spec = original.operator const FSSpec&();
+ if (nsprMode & PR_CREATE_FILE) {
+ // In order to get the right file type/creator, do it with an nsILocalFileMac
+ // Don't propagate any errors in doing this. If any error, just use FSpCreate.
+ FSSpec nonConstSpec = spec;
+ nsCOMPtr<nsILocalFileMac> macFile;
+ nsresult res = NS_NewLocalFileWithFSSpec(&nonConstSpec, PR_FALSE, getter_AddRefs(macFile));
+ if (NS_SUCCEEDED(res)) {
+ nsCOMPtr<nsIFile> asFile(do_QueryInterface(macFile, &res));
+ if (NS_SUCCEEDED(res)) {
+ res = asFile->Create(nsIFile::NORMAL_FILE_TYPE, 0);
+ if (res == NS_ERROR_FILE_ALREADY_EXISTS)
+ res = NS_OK;
+ }
+ }
+ if (NS_FAILED(res))
+ err = FSpCreate(&spec, kCreator, 'TEXT', 0);
+ }
+
+ if (err == dupFNErr)
+ err = noErr;
+ if (err != noErr)
+ return NS_FILE_RESULT(err);
+
+ SInt8 perm;
+ if (nsprMode & PR_RDWR)
+ perm = fsRdWrPerm;
+ else if (nsprMode & PR_WRONLY)
+ perm = fsWrPerm;
+ else
+ perm = fsRdPerm;
+
+ short refnum;
+ err = FSpOpenDF(&spec, perm, &refnum);
+
+ if (err == noErr && (nsprMode & PR_TRUNCATE))
+ err = ::SetEOF(refnum, 0);
+ if (err == noErr && (nsprMode & PR_APPEND))
+ err = SetFPos(refnum, fsFromLEOF, 0);
+ if (err != noErr)
+ return NS_FILE_RESULT(err);
+
+ if ((mFileDesc = PR_ImportFile(refnum)) == 0)
+ return NS_FILE_RESULT(PR_GetError());
+#else
+ // Platforms other than Macintosh...
+ // Another bug in NSPR: Mac PR_Open assumes a unix style path, but Win PR_Open assumes
+ // a windows path.
+ if ((mFileDesc = PR_Open((const char*)nsFileSpec(inFile), nsprMode, accessMode)) == 0)
+ return NS_FILE_RESULT(PR_GetError());
+#endif
+ mNSPRMode = nsprMode;
+ mLength = PR_Available(mFileDesc);
+ return NS_OK;
+} // FileImpl::Open
+
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP FileImpl::Available(PRUint32 *aLength)
+//----------------------------------------------------------------------------------------
+{
+ NS_PRECONDITION(aLength != nsnull, "null ptr");
+ if (!aLength)
+ return NS_ERROR_NULL_POINTER;
+ if (mLength < 0)
+ return NS_ERROR_UNEXPECTED;
+ *aLength = mLength;
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP FileImpl::GetIsOpen(PRBool* outOpen)
+//----------------------------------------------------------------------------------------
+{
+ *outOpen = (mFileDesc != nsnull && !mFailed);
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP FileImpl::Seek(PRInt32 whence, PRInt64 offset)
+//----------------------------------------------------------------------------------------
+{
+ if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR || !mFileDesc)
+ return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR);
+ mFailed = PR_FALSE; // reset on a seek.
+ mEOF = PR_FALSE; // reset on a seek.
+
+ // To avoid corruption, we flush during a seek. see bug number 18949
+ InternalFlush(PR_FALSE);
+
+ nsInt64 position = PR_Seek64(mFileDesc, 0, PR_SEEK_CUR);
+ nsInt64 available = PR_Available64(mFileDesc);
+ nsInt64 fileSize = position + available;
+ nsInt64 newPosition = offset;
+ switch (whence)
+ {
+ case NS_SEEK_CUR: newPosition += position; break;
+ case NS_SEEK_SET: ; break;
+ case NS_SEEK_END: newPosition += fileSize; break;
+ }
+ const nsInt64 zero = 0;
+ if (newPosition < zero)
+ {
+ newPosition = 0;
+ mFailed = PR_TRUE;
+ }
+ if (newPosition >= fileSize) // nb: not "else if".
+ {
+ newPosition = fileSize;
+ mEOF = PR_TRUE;
+ }
+ if (PR_Seek64(mFileDesc, newPosition, PR_SEEK_SET) < 0)
+ mFailed = PR_TRUE;
+ return NS_OK;
+} // FileImpl::Seek
+
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP FileImpl::Read(char* aBuf, PRUint32 aCount, PRUint32 *aReadCount)
+//----------------------------------------------------------------------------------------
+{
+ NS_PRECONDITION(aBuf != nsnull, "null ptr");
+ if (!aBuf)
+ return NS_ERROR_NULL_POINTER;
+ NS_PRECONDITION(aReadCount != nsnull, "null ptr");
+ if (!aReadCount)
+ return NS_ERROR_NULL_POINTER;
+ if (!mFileDesc)
+ return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR);
+ if (mFailed)
+ return NS_ERROR_FAILURE;
+ PRInt32 bytesRead = PR_Read(mFileDesc, aBuf, aCount);
+ if (bytesRead < 0)
+ {
+ *aReadCount = 0;
+ mFailed = PR_TRUE;
+ return NS_FILE_RESULT(PR_GetError());
+ }
+ else if (bytesRead == 0)
+ {
+ mEOF = PR_TRUE;
+ }
+ *aReadCount = bytesRead;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+FileImpl::ReadSegments(nsWriteSegmentFun writer, void * closure, PRUint32 count, PRUint32 *_retval)
+{
+ NS_NOTREACHED("ReadSegments");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP FileImpl::Write(const char* aBuf, PRUint32 aCount, PRUint32 *aWriteCount)
+//----------------------------------------------------------------------------------------
+{
+ 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.
+ if (mFileDesc == PR_STDOUT || mFileDesc == PR_STDERR)
+ {
+ std::cout.write(aBuf, aCount);
+ *aWriteCount = aCount;
+ return NS_OK;
+ }
+#endif
+ if (!mFileDesc)
+ return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR);
+ if (mFailed)
+ return NS_ERROR_FAILURE;
+
+ if (!mGotBuffers)
+ {
+ nsresult rv = AllocateBuffers(kOuputBufferSegmentSize, kOuputBufferMaxSize);
+ if (NS_FAILED(rv))
+ return rv; // try to write non-buffered?
+ }
+
+ PRUint32 bufOffset = 0;
+ PRUint32 currentWrite = 0;
+ while (aCount > 0)
+ {
+ if (mWriteCursor == nsnull || mWriteCursor == mWriteLimit)
+ {
+ char* seg = mOutBuffer.AppendNewSegment();
+ if (seg == nsnull)
+ {
+ // buffer is full, try again
+ InternalFlush(PR_FALSE);
+ seg = mOutBuffer.AppendNewSegment();
+ if (seg == nsnull)
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ mWriteCursor = seg;
+ mWriteLimit = seg + mOutBuffer.GetSegmentSize();
+ }
+
+ // move
+ currentWrite = mWriteLimit - mWriteCursor;
+
+ if (aCount < currentWrite)
+ currentWrite = aCount;
+
+ memcpy(mWriteCursor, (aBuf + bufOffset), currentWrite);
+
+ mWriteCursor += currentWrite;
+
+ aCount -= currentWrite;
+ bufOffset += currentWrite;
+ *aWriteCount += currentWrite;
+ }
+
+ return NS_OK;
+}
+
+static NS_METHOD
+nsWriteSegmentToFile(nsIInputStream* in,
+ void* closure,
+ const char* fromRawSegment,
+ PRUint32 toOffset,
+ PRUint32 count,
+ PRUint32 *writeCount)
+{
+ NS_NOTREACHED("nsWriteSegmentToFile");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+FileImpl::WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *result)
+{
+ return inStr->ReadSegments(nsWriteSegmentToFile, nsnull, count, result);
+}
+
+NS_IMETHODIMP
+FileImpl::WriteSegments(nsReadSegmentFun reader, void * closure,
+ PRUint32 count, PRUint32 *result)
+{
+ NS_NOTREACHED("WriteSegments");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+FileImpl::IsNonBlocking(PRBool *aNonBlocking)
+{
+ *aNonBlocking = PR_FALSE;
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP FileImpl::Tell(PRInt64* outWhere)
+//----------------------------------------------------------------------------------------
+{
+ if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR || !mFileDesc)
+ return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR);
+ *outWhere = PR_Seek64(mFileDesc, 0, PR_SEEK_CUR);
+ return NS_OK;
+} // FileImpl::Tell
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP FileImpl::Close()
+//----------------------------------------------------------------------------------------
+{
+ if ((mNSPRMode & PR_RDONLY) == 0)
+ InternalFlush(PR_FALSE);
+
+ if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR || !mFileDesc)
+ return NS_OK;
+ if (PR_Close(mFileDesc) == PR_SUCCESS)
+ mFileDesc = 0;
+ else
+ return NS_FILE_RESULT(PR_GetError());
+ return NS_OK;
+} // FileImpl::close
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP FileImpl::Flush()
+//----------------------------------------------------------------------------------------
+{
+ // for external callers, this will do a Sync as well as flush buffers.
+ return InternalFlush(PR_TRUE);
+} // FileImpl::flush
+
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP FileImpl::GetAtEOF(PRBool* outAtEOF)
+//----------------------------------------------------------------------------------------
+{
+ *outAtEOF = mEOF;
+ return NS_OK;
+}
+
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP FileImpl::SetAtEOF(PRBool inAtEOF)
+//----------------------------------------------------------------------------------------
+{
+ mEOF = inAtEOF;
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP FileImpl::SetEOF()
+//----------------------------------------------------------------------------------------
+{
+ NS_NOTYETIMPLEMENTED("FileImpl::SetEOF");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+//----------------------------------------------------------------------------------------
+nsresult FileImpl::AllocateBuffers(PRUint32 segmentSize, PRUint32 maxBufSize)
+//----------------------------------------------------------------------------------------
+{
+ nsresult rv = mOutBuffer.Init(segmentSize, maxBufSize);
+ if (NS_SUCCEEDED(rv))
+ mGotBuffers = PR_TRUE;
+
+ return rv;
+}
+
+// external callers of Flush will have sync get called,
+// but internal callers just want to flush the buffers to disk.
+nsresult FileImpl::InternalFlush(PRBool syncFile)
+{
+#ifdef XP_MAC
+ if (mFileDesc == PR_STDOUT || mFileDesc == PR_STDERR)
+ {
+ std::cout.flush();
+ return NS_OK;
+ }
+#endif
+ 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());
+ }
+ }
+
+ if (mGotBuffers)
+ mOutBuffer.Empty();
+ mWriteCursor = nsnull;
+ mWriteLimit = nsnull;
+
+ // On unix, it seems to fail always.
+ if (syncFile && PR_Sync(mFileDesc) != PR_SUCCESS)
+ mFailed = PR_TRUE;
+
+ return NS_OK;
+}
+//----------------------------------------------------------------------------------------
+nsresult NS_NewTypicalInputFileStream(
+ nsISupports** aResult,
+ const nsFileSpec& inFile
+ /*Default nsprMode == PR_RDONLY*/
+ /*Default accessmode = 0666 (octal)*/)
+// Factory method to get an nsInputStream from a file, using most common options
+//----------------------------------------------------------------------------------------
+{
+ // This QueryInterface was needed because NS_NewIOFileStream
+ // does a cast from (void *) to (nsISupports *) thus causing a
+ // vtable problem on Windows, where we really didn't have the proper pointer
+ // to an nsIInputStream, this ensures that we do
+ nsISupports * supports;
+ nsIInputStream * inStr;
+
+ nsresult rv = NS_NewIOFileStream(&supports, inFile, PR_RDONLY, 0666);
+
+ *aResult = nsnull;
+ if (NS_SUCCEEDED(rv)) {
+ if (NS_SUCCEEDED(supports->QueryInterface(NS_GET_IID(nsIInputStream), (void**)&inStr))) {
+ *aResult = inStr;
+ }
+ NS_RELEASE(supports);
+ }
+ return rv;
+}
+
+//----------------------------------------------------------------------------------------
+nsresult NS_NewTypicalOutputFileStream(
+ nsISupports** aResult,
+ const nsFileSpec& inFile
+ /*default nsprMode= (PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE)*/
+ /*Default accessMode= 0666 (octal)*/)
+// Factory method to get an nsOutputStream to a file - most common case.
+//----------------------------------------------------------------------------------------
+{
+ // This QueryInterface was needed because NS_NewIOFileStream
+ // does a cast from (void *) to (nsISupports *) thus causing a
+ // vtable problem on Windows, where we really didn't have the proper pointer
+ // to an nsIOutputStream, this ensures that we do
+#if 1
+/* nsISupports * supports;
+ nsIOutputStream * outStr;
+
+ nsresult rv = NS_NewIOFileStream(
+ &supports,
+ inFile,
+ (PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE),
+ 0666);
+
+ *aResult = nsnull;
+ if (NS_SUCCEEDED(rv)) {
+ if (NS_SUCCEEDED(supports->QueryInterface(NS_GET_IID(nsIOutputStream), (void**)&outStr))) {
+ *aResult = outStr;
+ }
+ NS_RELEASE(supports);
+ }
+ return rv;
+ */
+
+ nsCOMPtr<nsISupports> supports;
+ nsIOutputStream * outStr;
+
+ nsresult rv = NS_NewIOFileStream(
+ getter_AddRefs(supports),
+ inFile,
+ (PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE),
+ 0666);
+
+ *aResult = nsnull;
+ if (NS_SUCCEEDED(rv)) {
+ if (NS_SUCCEEDED(supports->QueryInterface(NS_GET_IID(nsIOutputStream), (void**)&outStr))) {
+ *aResult = outStr;
+ }
+ }
+ return rv;
+#else
+ return NS_NewIOFileStream(
+ aResult,
+ inFile,
+ (PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE),
+ 0666);
+#endif
+}
+
+//----------------------------------------------------------------------------------------
+NS_COM_OBSOLETE nsresult NS_NewIOFileStream(
+ nsISupports** aResult,
+ const nsFileSpec& inFile,
+ PRInt32 nsprMode /*default = (PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE)*/,
+ PRInt32 accessMode /*Default = 0666 (octal)*/)
+ // Factory method to get an object that implements both nsIInputStream
+ // and nsIOutputStream, associated with a file.
+//----------------------------------------------------------------------------------------
+{
+ NS_PRECONDITION(aResult != nsnull, "null ptr");
+ if (!aResult)
+ return NS_ERROR_NULL_POINTER;
+
+ FileImpl* stream = new FileImpl(inFile, nsprMode, accessMode);
+ if (! stream)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ NS_ADDREF(stream);
+ PRBool isOpened = PR_FALSE;
+ stream->GetIsOpen(&isOpened);
+ if (!isOpened)
+ {
+ NS_RELEASE(stream);
+ return NS_ERROR_FAILURE;
+ }
+
+ *aResult = (nsISupports*)(void*)stream;
+ return NS_OK;
+}
+