Fix seek again so it resets eof. Allow ns*FileStream stack-based classes to be closed explicitly. Fix refcounting. Remove "close on destroy" kludge.

This commit is contained in:
mcmullen%netscape.com 1999-02-28 01:36:48 +00:00
parent ba3f139ef6
commit f672d26a46
20 changed files with 644 additions and 58 deletions

View File

@ -24,7 +24,8 @@
//
// Classes defined:
//
// nsFilePath, nsFileURL, nsFileSpec, nsPersistentFileDescriptor.
// nsFilePath, nsFileURL, nsFileSpec, nsPersistentFileDescriptor
// nsDirectoryIterator. Oh, and a convenience class nsAutoCString.
//
// Q. How should I represent files at run time?
// A. Use nsFileSpec. Using char* will lose information on some platforms.
@ -113,6 +114,7 @@
#include "nscore.h"
#include "nsError.h"
#include "nsString.h"
//========================================================================================
// Compiler-specific macros, as needed
@ -159,8 +161,11 @@ class nsPersistentFileDescriptor; // Used for storage across program launches.
class nsOutputStream;
class nsInputStream;
class nsIOutputStream;
class nsIInputStream;
class nsOutputFileStream;
class nsInputFileStream;
class nsString;
//========================================================================================
// Conversion of native file errors to nsresult values. These are really only for use
@ -173,6 +178,33 @@ class nsInputFileStream;
nsresult ns_file_convert_result(PRInt32 nativeErr);
#define NS_FILE_FAILURE NS_FILE_RESULT(-1)
//========================================================================================
class NS_BASE nsAutoCString
//
// This should be in nsString.h, but the owner would not reply to my proposal. After four
// weeks, I decided to put it in here.
//
// This is a quiet little class that acts as a sort of autoptr for
// a const char*. If you used to call nsString::ToNewCString(), just
// to pass the result a parameter list, it was a nuisance having to
// call delete [] on the result after the call. Now you can say
// nsString myStr;
// ...
// f(nsAutoCString(myStr));
// where f is declared as void f(const char*); This call will
// make a temporary char* pointer on the stack and delete[] it
// when the function returns.
//========================================================================================
{
public:
NS_EXPLICIT nsAutoCString(const nsString& other) : mCString(other.ToNewCString()) {}
virtual ~nsAutoCString();
operator const char*() const { return mCString; }
operator const char*() { return mCString; }
protected:
const char* mCString;
}; // class nsAutoCString
//========================================================================================
class NS_BASE nsFileSpec
// This is whatever each platform really prefers to describe files as. Declared first
@ -182,6 +214,7 @@ class NS_BASE nsFileSpec
public:
nsFileSpec();
NS_EXPLICIT nsFileSpec(const char* inString, PRBool inCreateDirs = PR_FALSE);
NS_EXPLICIT nsFileSpec(const nsString& inString, PRBool inCreateDirs = PR_FALSE);
NS_EXPLICIT nsFileSpec(const nsFilePath& inPath);
NS_EXPLICIT nsFileSpec(const nsFileURL& inURL);
NS_EXPLICIT nsFileSpec(const nsPersistentFileDescriptor& inURL);
@ -189,6 +222,10 @@ class NS_BASE nsFileSpec
virtual ~nsFileSpec();
void operator = (const char* inPath);
void operator = (const nsString& inPath)
{
*this = nsAutoCString(inPath);
}
void operator = (const nsFilePath& inPath);
void operator = (const nsFileURL& inURL);
void operator = (const nsFileSpec& inOther);
@ -245,7 +282,10 @@ class NS_BASE nsFileSpec
void SetLeafName(const char* inLeafName);
// inLeafName can be a relative path, so this allows
// one kind of concatenation of "paths".
void SetLeafName(const nsString& inLeafName)
{
SetLeafName(nsAutoCString(inLeafName));
}
void GetParent(nsFileSpec& outSpec) const;
// Return the filespec of the parent directory. Used
// in conjunction with GetLeafName(), this lets you
@ -255,6 +295,10 @@ class NS_BASE nsFileSpec
// names. Perhaps could be used for an operator --() ?
nsFileSpec operator + (const char* inRelativePath) const;
nsFileSpec operator + (const nsString& inRelativePath) const
{
return *this + nsAutoCString(inRelativePath);
}
void operator += (const char* inRelativePath);
// Concatenate the relative path to this directory.
// Used for constructing the filespec of a descendant.
@ -264,9 +308,17 @@ class NS_BASE nsFileSpec
// away its leaf information, whereas this one assumes
// this is a directory, and the relative path starts
// "below" this.
void operator += (const nsString& inRelativePath)
{
*this += nsAutoCString(inRelativePath);
}
void MakeUnique();
void MakeUnique(const char* inSuggestedLeafName);
void MakeUnique(const nsString& inSuggestedLeafName)
{
MakeUnique(nsAutoCString(inSuggestedLeafName));
}
PRBool IsDirectory() const;
// More stringent than Exists()
@ -279,12 +331,20 @@ class NS_BASE nsFileSpec
//--------------------------------------------------
void CreateDirectory(int mode = 0700 /* for unix */);
void Delete(PRBool inRecursive);
void Delete(PRBool inRecursive) const;
nsresult Rename(const char* inNewName); // not const: gets updated
nsresult Rename(const nsString& inNewName)
{
return Rename(nsAutoCString(inNewName));
}
nsresult Copy(const nsFileSpec& inNewParentDirectory) const;
nsresult Move(const nsFileSpec& inNewParentDirectory) const;
nsresult Execute(const char* args) const;
nsresult Execute(const nsString& args) const
{
return Execute(nsAutoCString(args));
}
//--------------------------------------------------
// Data
@ -314,6 +374,7 @@ class NS_BASE nsFileURL
public:
nsFileURL(const nsFileURL& inURL);
NS_EXPLICIT nsFileURL(const char* inString, PRBool inCreateDirs = PR_FALSE);
NS_EXPLICIT nsFileURL(const nsString& inString, PRBool inCreateDirs = PR_FALSE);
NS_EXPLICIT nsFileURL(const nsFilePath& inPath);
NS_EXPLICIT nsFileURL(const nsFileSpec& inPath);
virtual ~nsFileURL();
@ -324,6 +385,10 @@ class NS_BASE nsFileURL
void operator = (const nsFileURL& inURL);
void operator = (const char* inString);
void operator = (const nsString& inString)
{
*this = nsAutoCString(inString);
}
void operator = (const nsFilePath& inOther);
void operator = (const nsFileSpec& inOther);
@ -357,6 +422,7 @@ class NS_BASE nsFilePath
public:
nsFilePath(const nsFilePath& inPath);
NS_EXPLICIT nsFilePath(const char* inString, PRBool inCreateDirs = PR_FALSE);
NS_EXPLICIT nsFilePath(const nsString& inString, PRBool inCreateDirs = PR_FALSE);
NS_EXPLICIT nsFilePath(const nsFileURL& inURL);
NS_EXPLICIT nsFilePath(const nsFileSpec& inPath);
virtual ~nsFilePath();
@ -373,6 +439,10 @@ class NS_BASE nsFilePath
void operator = (const nsFilePath& inPath);
void operator = (const char* inString);
void operator = (const nsString& inString)
{
*this = nsAutoCString(inString);
}
void operator = (const nsFileURL& inURL);
void operator = (const nsFileSpec& inOther);
@ -407,6 +477,9 @@ class NS_BASE nsPersistentFileDescriptor
nsPersistentFileDescriptor(const nsFileSpec& inPath);
void operator = (const nsFileSpec& inPath);
nsresult Read(nsIInputStream* aStream);
nsresult Write(nsIOutputStream* aStream);
// writes the data to a file
friend NS_BASE nsInputStream& operator >> (nsInputStream&, nsPersistentFileDescriptor&);
// reads the data from a file
friend NS_BASE nsOutputStream& operator << (nsOutputStream&, const nsPersistentFileDescriptor&);
@ -462,7 +535,7 @@ class NS_BASE nsDirectoryIterator
operator nsFileSpec&() { return mCurrent; }
private:
nsFileSpec mCurrent;
PRBool mExists; // MUST be bool.
PRBool mExists;
#if defined(XP_UNIX)
DIR* mDir;

View File

@ -174,8 +174,12 @@ public:
{
return mInputStream;
}
char eof() const { return mEOF; }
char eof() const { return get_at_eof(); }
char get();
void close()
{
mInputStream->Close();
}
PRInt32 read(void* s, PRInt32 n)
{
if (!mInputStream)
@ -183,7 +187,7 @@ public:
PRInt32 result = 0;
mInputStream->Read((char*)s, 0, n, (PRUint32*)&result);
if (result < n)
mEOF = PR_TRUE;
set_at_eof(PR_TRUE);
return result;
}
@ -196,6 +200,19 @@ public:
{
return pf(*this);
}
protected:
// These certainly need to be overridden, they give the best shot we can at detecting
// eof in a simple nsIInputStream.
virtual void set_at_eof(PRBool atEnd)
{
mEOF = atEnd;
}
virtual PRBool get_at_eof()
{
return mEOF;
}
private:
nsInputStream& operator >> (char* buf); // TOO DANGEROUS. DON'T DEFINE.
@ -219,7 +236,7 @@ class NS_BASE nsOutputStream
public:
nsOutputStream() {}
nsOutputStream(nsIOutputStream* inStream)
: mOutputStream(do_QueryInterface(inStream))
: mOutputStream(do_QueryInterface(inStream))
{}
virtual ~nsOutputStream();
@ -228,6 +245,10 @@ public:
{
return mOutputStream;
}
void close()
{
mOutputStream->Close();
}
void put(char c);
PRInt32 write(const void* s, PRInt32 n)
{
@ -309,6 +330,7 @@ public:
void seek(PRSeekWhence whence, PRInt32 offset)
{
set_at_eof(PR_FALSE);
if (mFile)
mResult = mFile->Seek(whence, offset);
}
@ -319,7 +341,22 @@ public:
mResult = mFile->Tell(&result);
return result;
}
protected:
virtual PRBool get_at_eof()
{
PRBool result;
if (mFile)
mFile->GetAtEOF(&result);
return result;
}
virtual void set_at_eof(PRBool atEnd)
{
if (mFile)
mFile->SetAtEOF(atEnd);
}
// DATA
protected:
nsCOMPtr<nsIFile> mFile;
@ -354,6 +391,7 @@ public:
mFile = nsQueryInterface(stream);
mInputStream = nsQueryInterface(stream);
mFileInputStream = nsQueryInterface(stream);
NS_RELEASE(stream);
}
PRBool readline(char* s, PRInt32 n);
@ -377,6 +415,19 @@ public:
nsInputStream& operator >> (nsInputStream& (*pf)(nsInputStream&))
{ return nsInputStream::operator >>(pf); }
protected:
virtual PRBool get_at_eof()
{
return nsFileClient::get_at_eof();
}
virtual void set_at_eof(PRBool atEnd)
{
nsFileClient::set_at_eof(atEnd);
}
// DATA
protected:
nsCOMPtr<nsIFileInputStream> mFileInputStream;
@ -413,6 +464,7 @@ public:
mFile = nsQueryInterface(stream);
mOutputStream = nsQueryInterface(stream);
mFileOutputStream = nsQueryInterface(stream);
NS_RELEASE(stream);
}
virtual void flush();
@ -433,6 +485,18 @@ public:
nsOutputStream& operator << (nsOutputStream& (*pf)(nsOutputStream&))
{ return nsOutputStream::operator << (pf); }
protected:
virtual PRBool get_at_eof()
{
return nsFileClient::get_at_eof();
}
virtual void set_at_eof(PRBool atEnd)
{
nsFileClient::set_at_eof(atEnd);
}
// DATA
protected:
nsCOMPtr<nsIFileOutputStream> mFileOutputStream;
@ -454,6 +518,7 @@ public:
mFile = nsQueryInterface(stream);
mOutputStream = nsQueryInterface(stream);
mFileOutputStream = nsQueryInterface(stream);
NS_RELEASE(stream);
}
// Output streamers. Unfortunately, they don't inherit!
@ -509,8 +574,16 @@ public:
mOutputStream = nsQueryInterface(stream);
mFileInputStream = nsQueryInterface(stream);
mFileOutputStream = nsQueryInterface(stream);
NS_RELEASE(stream);
}
virtual void close()
{
// Doesn't matter which of the two we close:
// they're hooked up to the same file.
nsInputFileStream::close();
}
// Output streamers. Unfortunately, they don't inherit!
nsOutputStream& operator << (const char* buf)
{ return nsOutputStream::operator << (buf); }
@ -532,6 +605,7 @@ public:
{ return nsInputStream::operator >>(ch); }
nsInputStream& operator >> (nsInputStream& (*pf)(nsInputStream&))
{ return nsInputStream::operator >>(pf); }
// DATA
protected:
nsCOMPtr<nsIFileOutputStream> mFileOutputStream;

View File

@ -47,6 +47,10 @@ public:
NS_IMETHOD Seek(PRSeekWhence whence, PRInt32 offset) = 0;
NS_IMETHOD GetIsOpen(PRBool* outOpen) = 0;
NS_IMETHOD Tell(PRIntn* outWhere) = 0;
/* "PROTECTED" */
NS_IMETHOD GetAtEOF(PRBool* outAtEOF) = 0;
NS_IMETHOD SetAtEOF(PRBool inAtEOF) = 0;
}; // class nsIFile
/* a6cf90e6-15b3-11d2-932e-00805f8add32 */
@ -86,7 +90,7 @@ public:
}; // class nsIFileOutputStream
//----------------------------------------------------------------------------------------
NS_BASE nsresult NS_NewTypicalInputFileStream(
extern "C" NS_BASE nsresult NS_NewTypicalInputFileStream(
nsISupports** aStreamResult,
const nsFileSpec& inFile
/*Default nsprMode == PR_RDONLY*/

View File

@ -531,6 +531,17 @@ nsFileSpec::nsFileSpec(const char* inString, PRBool inCreateDirs)
mError = NS_OK;
} // nsFileSpec::nsFileSpec
//----------------------------------------------------------------------------------------
nsFileSpec::nsFileSpec(const nsString& inString, PRBool inCreateDirs)
//----------------------------------------------------------------------------------------
{
mError = NS_FILE_RESULT(MacFileHelpers::FSSpecFromFullUnixPath(
nsAutoCString(inString), mSpec, false, true, inCreateDirs));
// allow a partial path, create as necessary
if (mError == NS_FILE_RESULT(fnfErr))
mError = NS_OK;
} // nsFileSpec::nsFileSpec
//----------------------------------------------------------------------------------------
nsFileSpec::nsFileSpec(
short vRefNum,
@ -693,19 +704,20 @@ void nsFileSpec::CreateDirectory(int /* unix mode */)
} // nsFileSpec::CreateDirectory
//----------------------------------------------------------------------------------------
void nsFileSpec::Delete(PRBool inRecursive)
void nsFileSpec::Delete(PRBool inRecursive) const
//----------------------------------------------------------------------------------------
{
nsresult& mutableError = const_cast<nsFileSpec*>(this)->mError;
if (inRecursive)
{
// MoreFilesExtras
mError = NS_FILE_RESULT(::DeleteDirectory(
mutableError = NS_FILE_RESULT(::DeleteDirectory(
mSpec.vRefNum,
mSpec.parID,
const_cast<unsigned char*>(mSpec.name)));
}
else
mError = NS_FILE_RESULT(FSpDelete(&mSpec));
mutableError = NS_FILE_RESULT(FSpDelete(&mSpec));
} // nsFileSpec::Delete
//----------------------------------------------------------------------------------------
@ -795,6 +807,18 @@ nsFilePath::nsFilePath(const char* inString, PRBool inCreateDirs)
char * path = MacFileHelpers::PathNameFromFSSpec( mFileSpec, TRUE );
mPath = MacFileHelpers::EncodeMacPath(path, true, true);
}
//----------------------------------------------------------------------------------------
nsFilePath::nsFilePath(const nsString& inString, PRBool inCreateDirs)
//----------------------------------------------------------------------------------------
: mPath(nsnull)
, mFileSpec(nsAutoCString(inString), inCreateDirs)
{
// Make canonical and absolute.
char * path = MacFileHelpers::PathNameFromFSSpec( mFileSpec, TRUE );
mPath = MacFileHelpers::EncodeMacPath(path, true, true);
}
//----------------------------------------------------------------------------------------
nsFilePath::nsFilePath(const nsFileSpec& inSpec)
//----------------------------------------------------------------------------------------
@ -833,6 +857,23 @@ nsFileURL::nsFileURL(const char* inString, PRBool inCreateDirs)
delete [] escapedPath;
} // nsFileURL::nsFileURL
//----------------------------------------------------------------------------------------
nsFileURL::nsFileURL(const nsString& inString, PRBool inCreateDirs)
//----------------------------------------------------------------------------------------
: mURL(nsnull)
{
nsAutoCString aString(inString);
const char* aCString = (const char*)aString;
NS_ASSERTION(strstr(aCString, kFileURLPrefix) == aCString, "Not a URL!");
mFileSpec = aCString + kFileURLPrefixLength;
// Make canonical and absolute.
char* path = MacFileHelpers::PathNameFromFSSpec( mFileSpec, TRUE );
char* escapedPath = MacFileHelpers::EncodeMacPath(path, true, true);
mURL = nsFileSpecHelpers::StringDup(kFileURLPrefix, kFileURLPrefixLength + strlen(escapedPath));
strcat(mURL, escapedPath);
delete [] escapedPath;
} // nsFileURL::nsFileURL
//========================================================================================
// nsDirectoryIterator
//========================================================================================

View File

@ -287,6 +287,23 @@ nsFileURL::nsFileURL(const char* inString, PRBool inCreateDirs)
} // nsFileURL::nsFileURL
#endif
#ifndef XP_MAC
//----------------------------------------------------------------------------------------
nsFileURL::nsFileURL(const nsString& inString, PRBool inCreateDirs)
//----------------------------------------------------------------------------------------
: mURL(nsnull)
{
const nsAutoCString aString(inString);
char* aCString = (const char*) aString;
if (!inString)
return;
NS_ASSERTION(strstr(aCString, kFileURLPrefix) == inString, "Not a URL!");
// Make canonical and absolute.
nsFilePath path(aCString + kFileURLPrefixLength, inCreateDirs);
*this = path;
} // nsFileURL::nsFileURL
#endif
//----------------------------------------------------------------------------------------
nsFileURL::nsFileURL(const nsFileURL& inOther)
//----------------------------------------------------------------------------------------
@ -407,6 +424,26 @@ nsFilePath::nsFilePath(const char* inString, PRBool inCreateDirs)
}
#endif
#ifndef XP_MAC
//----------------------------------------------------------------------------------------
nsFilePath::nsFilePath(const nsString& inString, PRBool inCreateDirs)
//----------------------------------------------------------------------------------------
: mPath(inString.ToNewCString())
{
NS_ASSERTION(strstr(mPath, kFileURLPrefix) != inString, "URL passed as path");
#ifdef XP_PC
nsFileSpecHelpers::UnixToNative(mPath);
#endif
// Make canonical and absolute.
nsFileSpecHelpers::Canonify(mPath, inCreateDirs);
#ifdef XP_PC
NS_ASSERTION( mPath[1] == ':', "unexpected canonical path" );
nsFileSpecHelpers::NativeToUnix(mPath);
#endif
}
#endif
//----------------------------------------------------------------------------------------
nsFilePath::nsFilePath(const nsFileURL& inOther)
//----------------------------------------------------------------------------------------
@ -451,6 +488,7 @@ void nsFilePath::operator = (const char* inString)
mFileSpec = inString;
nsFileSpecHelpers::StringAssign(mPath, (const char*)nsFilePath(mFileSpec));
#else
nsFileSpecHelpers::StringAssign(mPath, inString);
#ifdef XP_PC
nsFileSpecHelpers::UnixToNative(mPath);
#endif
@ -640,6 +678,18 @@ nsFileSpec::nsFileSpec(const char* inString, PRBool inCreateDirs)
}
#endif //XP_UNIX,PC
#if defined(XP_UNIX) || defined(XP_PC)
//----------------------------------------------------------------------------------------
nsFileSpec::nsFileSpec(const nsString& inString, PRBool inCreateDirs)
//----------------------------------------------------------------------------------------
: mPath(inString.ToNewCString())
, mError(NS_OK)
{
// Make canonical and absolute.
nsFileSpecHelpers::Canonify(mPath, inCreateDirs);
}
#endif //XP_UNIX,PC
//----------------------------------------------------------------------------------------
nsFileSpec::~nsFileSpec()
//----------------------------------------------------------------------------------------
@ -672,6 +722,18 @@ void nsFileSpec::operator = (const char* inString)
}
#endif //XP_UNIX
#if defined(XP_UNIX) || defined(XP_PC)
//----------------------------------------------------------------------------------------
void nsFileSpec::operator = (const nsString& inString)
//----------------------------------------------------------------------------------------
{
delete [] mPath;
mPath = inString.ToNewCString();
// Make canonical and absolute.
nsFileSpecHelpers::Canonify(mPath, PR_TRUE /* XXX? */);
mError = NS_OK;
}
#endif //XP_UNIX
#if (defined(XP_UNIX) || defined(XP_PC))
//----------------------------------------------------------------------------------------
@ -774,6 +836,22 @@ void nsPersistentFileDescriptor::SetData(const void* inData, PRInt32 inSize)
#define MAX_PERSISTENT_DATA_SIZE 1000
//----------------------------------------------------------------------------------------
nsresult nsPersistentFileDescriptor::Read(nsIInputStream* aStream)
//----------------------------------------------------------------------------------------
{
nsInputStream(aStream) >> *this;
return NS_OK;
}
//----------------------------------------------------------------------------------------
nsresult nsPersistentFileDescriptor::Write(nsIOutputStream* aStream)
//----------------------------------------------------------------------------------------
{
nsOutputStream(aStream) << *this;
return NS_OK;
}
//----------------------------------------------------------------------------------------
nsInputStream& operator >> (nsInputStream& s, nsPersistentFileDescriptor& d)
// reads the data from a file
@ -792,7 +870,7 @@ nsInputStream& operator >> (nsInputStream& s, nsPersistentFileDescriptor& d)
// Now we know how many bytes to read, do it.
s.read(bigBuffer, bytesRead);
d.SetData(bigBuffer, bytesRead);
return (nsInputFileStream&)s;
return s;
}
//----------------------------------------------------------------------------------------
@ -811,3 +889,14 @@ nsOutputStream& operator << (nsOutputStream& s, const nsPersistentFileDescriptor
s << d.mDescriptorString;
return s;
}
//========================================================================================
// class nsAutoCString
//========================================================================================
//----------------------------------------------------------------------------------------
nsAutoCString::~nsAutoCString()
//----------------------------------------------------------------------------------------
{
delete [] mCString;
}

View File

@ -35,7 +35,6 @@
nsInputStream::~nsInputStream()
//----------------------------------------------------------------------------------------
{
mInputStream->Close();
}
//----------------------------------------------------------------------------------------
@ -76,7 +75,6 @@ nsInputStream& nsInputStream::operator >> (char& c)
nsOutputStream::~nsOutputStream()
//----------------------------------------------------------------------------------------
{
mOutputStream->Close();
}
//----------------------------------------------------------------------------------------

View File

@ -141,6 +141,17 @@ class FileImpl
}
NS_IMETHOD Flush();
NS_IMETHOD GetAtEOF(PRBool* outAtEOF)
{
*outAtEOF = mEOF;
return NS_OK;
}
NS_IMETHOD SetAtEOF(PRBool inAtEOF)
{
mEOF = inAtEOF;
return NS_OK;
}
protected:
PRFileDesc* mFileDesc;

View File

@ -148,7 +148,7 @@ void nsFileSpec::CreateDirectory(int mode)
} // nsFileSpec::CreateDirectory
//----------------------------------------------------------------------------------------
void nsFileSpec::Delete(PRBool inRecursive)
void nsFileSpec::Delete(PRBool inRecursive) const
// To check if this worked, call Exists() afterwards, see?
//----------------------------------------------------------------------------------------
{
@ -186,7 +186,9 @@ nsresult nsFileSpec::Rename(const char* inNewName)
return NS_OK;
} // nsFileSpec::Rename
//----------------------------------------------------------------------------------------
static int CrudeFileCopy(const char* in, const char* out)
//----------------------------------------------------------------------------------------
{
struct stat in_stat;
int stat_result = -1;

View File

@ -237,24 +237,24 @@ void nsFileSpec::CreateDirectory(int /*mode*/)
} // nsFileSpec::CreateDirectory
//----------------------------------------------------------------------------------------
void nsFileSpec::Delete(PRBool inRecursive)
void nsFileSpec::Delete(PRBool inRecursive) const
//----------------------------------------------------------------------------------------
{
if (IsDirectory())
if (IsDirectory())
{
if (inRecursive)
{
for (nsDirectoryIterator i(*this); i.Exists(); i++)
{
nsFileSpec& child = (nsFileSpec&)i;
child.Delete(inRecursive);
}
for (nsDirectoryIterator i(*this); i.Exists(); i++)
{
nsFileSpec& child = (nsFileSpec&)i;
child.Delete(inRecursive);
}
}
rmdir(mPath);
}
else
{
remove(mPath);
remove(mPath);
}
} // nsFileSpec::Delete
@ -368,7 +368,7 @@ nsDirectoryIterator::nsDirectoryIterator(
//----------------------------------------------------------------------------------------
: mCurrent(inDirectory)
, mDir(nsnull)
, mExists(false)
, mExists(PR_FALSE)
{
mDir = PR_OpenDir(inDirectory);
mCurrent += "dummy";
@ -387,13 +387,13 @@ nsDirectoryIterator::~nsDirectoryIterator()
nsDirectoryIterator& nsDirectoryIterator::operator ++ ()
//----------------------------------------------------------------------------------------
{
mExists = false;
mExists = PR_FALSE;
if (!mDir)
return *this;
PRDirEntry* entry = PR_ReadDir(mDir, PR_SKIP_BOTH); // Ignore '.' && '..'
PRDirEntry* entry = PR_ReadDir(mDir, PR_SKIP_BOTH); // Ignore '.' && '..'
if (entry)
{
mExists = true;
mExists = PR_TRUE;
mCurrent.SetLeafName(entry->name);
}
return *this;

View File

@ -20,6 +20,7 @@
#include "nsFileStream.h"
//#include "string.h"
//void* operator new(size_t n) { return malloc(n); }
struct FilesTest
{
@ -176,7 +177,7 @@ int FilesTest::IOStream(const char* relativePath)
<< nsEndl;
return -1;
}
char line[1000];
char line[5000]; // Use a buffer longer than the file!
testStream.seek(0); // check that the seek compiles
while (!testStream.eof())
{

View File

@ -287,6 +287,23 @@ nsFileURL::nsFileURL(const char* inString, PRBool inCreateDirs)
} // nsFileURL::nsFileURL
#endif
#ifndef XP_MAC
//----------------------------------------------------------------------------------------
nsFileURL::nsFileURL(const nsString& inString, PRBool inCreateDirs)
//----------------------------------------------------------------------------------------
: mURL(nsnull)
{
const nsAutoCString aString(inString);
char* aCString = (const char*) aString;
if (!inString)
return;
NS_ASSERTION(strstr(aCString, kFileURLPrefix) == inString, "Not a URL!");
// Make canonical and absolute.
nsFilePath path(aCString + kFileURLPrefixLength, inCreateDirs);
*this = path;
} // nsFileURL::nsFileURL
#endif
//----------------------------------------------------------------------------------------
nsFileURL::nsFileURL(const nsFileURL& inOther)
//----------------------------------------------------------------------------------------
@ -407,6 +424,26 @@ nsFilePath::nsFilePath(const char* inString, PRBool inCreateDirs)
}
#endif
#ifndef XP_MAC
//----------------------------------------------------------------------------------------
nsFilePath::nsFilePath(const nsString& inString, PRBool inCreateDirs)
//----------------------------------------------------------------------------------------
: mPath(inString.ToNewCString())
{
NS_ASSERTION(strstr(mPath, kFileURLPrefix) != inString, "URL passed as path");
#ifdef XP_PC
nsFileSpecHelpers::UnixToNative(mPath);
#endif
// Make canonical and absolute.
nsFileSpecHelpers::Canonify(mPath, inCreateDirs);
#ifdef XP_PC
NS_ASSERTION( mPath[1] == ':', "unexpected canonical path" );
nsFileSpecHelpers::NativeToUnix(mPath);
#endif
}
#endif
//----------------------------------------------------------------------------------------
nsFilePath::nsFilePath(const nsFileURL& inOther)
//----------------------------------------------------------------------------------------
@ -451,6 +488,7 @@ void nsFilePath::operator = (const char* inString)
mFileSpec = inString;
nsFileSpecHelpers::StringAssign(mPath, (const char*)nsFilePath(mFileSpec));
#else
nsFileSpecHelpers::StringAssign(mPath, inString);
#ifdef XP_PC
nsFileSpecHelpers::UnixToNative(mPath);
#endif
@ -640,6 +678,18 @@ nsFileSpec::nsFileSpec(const char* inString, PRBool inCreateDirs)
}
#endif //XP_UNIX,PC
#if defined(XP_UNIX) || defined(XP_PC)
//----------------------------------------------------------------------------------------
nsFileSpec::nsFileSpec(const nsString& inString, PRBool inCreateDirs)
//----------------------------------------------------------------------------------------
: mPath(inString.ToNewCString())
, mError(NS_OK)
{
// Make canonical and absolute.
nsFileSpecHelpers::Canonify(mPath, inCreateDirs);
}
#endif //XP_UNIX,PC
//----------------------------------------------------------------------------------------
nsFileSpec::~nsFileSpec()
//----------------------------------------------------------------------------------------
@ -672,6 +722,18 @@ void nsFileSpec::operator = (const char* inString)
}
#endif //XP_UNIX
#if defined(XP_UNIX) || defined(XP_PC)
//----------------------------------------------------------------------------------------
void nsFileSpec::operator = (const nsString& inString)
//----------------------------------------------------------------------------------------
{
delete [] mPath;
mPath = inString.ToNewCString();
// Make canonical and absolute.
nsFileSpecHelpers::Canonify(mPath, PR_TRUE /* XXX? */);
mError = NS_OK;
}
#endif //XP_UNIX
#if (defined(XP_UNIX) || defined(XP_PC))
//----------------------------------------------------------------------------------------
@ -774,6 +836,22 @@ void nsPersistentFileDescriptor::SetData(const void* inData, PRInt32 inSize)
#define MAX_PERSISTENT_DATA_SIZE 1000
//----------------------------------------------------------------------------------------
nsresult nsPersistentFileDescriptor::Read(nsIInputStream* aStream)
//----------------------------------------------------------------------------------------
{
nsInputStream(aStream) >> *this;
return NS_OK;
}
//----------------------------------------------------------------------------------------
nsresult nsPersistentFileDescriptor::Write(nsIOutputStream* aStream)
//----------------------------------------------------------------------------------------
{
nsOutputStream(aStream) << *this;
return NS_OK;
}
//----------------------------------------------------------------------------------------
nsInputStream& operator >> (nsInputStream& s, nsPersistentFileDescriptor& d)
// reads the data from a file
@ -792,7 +870,7 @@ nsInputStream& operator >> (nsInputStream& s, nsPersistentFileDescriptor& d)
// Now we know how many bytes to read, do it.
s.read(bigBuffer, bytesRead);
d.SetData(bigBuffer, bytesRead);
return (nsInputFileStream&)s;
return s;
}
//----------------------------------------------------------------------------------------
@ -811,3 +889,14 @@ nsOutputStream& operator << (nsOutputStream& s, const nsPersistentFileDescriptor
s << d.mDescriptorString;
return s;
}
//========================================================================================
// class nsAutoCString
//========================================================================================
//----------------------------------------------------------------------------------------
nsAutoCString::~nsAutoCString()
//----------------------------------------------------------------------------------------
{
delete [] mCString;
}

View File

@ -24,7 +24,8 @@
//
// Classes defined:
//
// nsFilePath, nsFileURL, nsFileSpec, nsPersistentFileDescriptor.
// nsFilePath, nsFileURL, nsFileSpec, nsPersistentFileDescriptor
// nsDirectoryIterator. Oh, and a convenience class nsAutoCString.
//
// Q. How should I represent files at run time?
// A. Use nsFileSpec. Using char* will lose information on some platforms.
@ -113,6 +114,7 @@
#include "nscore.h"
#include "nsError.h"
#include "nsString.h"
//========================================================================================
// Compiler-specific macros, as needed
@ -159,8 +161,11 @@ class nsPersistentFileDescriptor; // Used for storage across program launches.
class nsOutputStream;
class nsInputStream;
class nsIOutputStream;
class nsIInputStream;
class nsOutputFileStream;
class nsInputFileStream;
class nsString;
//========================================================================================
// Conversion of native file errors to nsresult values. These are really only for use
@ -173,6 +178,33 @@ class nsInputFileStream;
nsresult ns_file_convert_result(PRInt32 nativeErr);
#define NS_FILE_FAILURE NS_FILE_RESULT(-1)
//========================================================================================
class NS_BASE nsAutoCString
//
// This should be in nsString.h, but the owner would not reply to my proposal. After four
// weeks, I decided to put it in here.
//
// This is a quiet little class that acts as a sort of autoptr for
// a const char*. If you used to call nsString::ToNewCString(), just
// to pass the result a parameter list, it was a nuisance having to
// call delete [] on the result after the call. Now you can say
// nsString myStr;
// ...
// f(nsAutoCString(myStr));
// where f is declared as void f(const char*); This call will
// make a temporary char* pointer on the stack and delete[] it
// when the function returns.
//========================================================================================
{
public:
NS_EXPLICIT nsAutoCString(const nsString& other) : mCString(other.ToNewCString()) {}
virtual ~nsAutoCString();
operator const char*() const { return mCString; }
operator const char*() { return mCString; }
protected:
const char* mCString;
}; // class nsAutoCString
//========================================================================================
class NS_BASE nsFileSpec
// This is whatever each platform really prefers to describe files as. Declared first
@ -182,6 +214,7 @@ class NS_BASE nsFileSpec
public:
nsFileSpec();
NS_EXPLICIT nsFileSpec(const char* inString, PRBool inCreateDirs = PR_FALSE);
NS_EXPLICIT nsFileSpec(const nsString& inString, PRBool inCreateDirs = PR_FALSE);
NS_EXPLICIT nsFileSpec(const nsFilePath& inPath);
NS_EXPLICIT nsFileSpec(const nsFileURL& inURL);
NS_EXPLICIT nsFileSpec(const nsPersistentFileDescriptor& inURL);
@ -189,6 +222,10 @@ class NS_BASE nsFileSpec
virtual ~nsFileSpec();
void operator = (const char* inPath);
void operator = (const nsString& inPath)
{
*this = nsAutoCString(inPath);
}
void operator = (const nsFilePath& inPath);
void operator = (const nsFileURL& inURL);
void operator = (const nsFileSpec& inOther);
@ -245,7 +282,10 @@ class NS_BASE nsFileSpec
void SetLeafName(const char* inLeafName);
// inLeafName can be a relative path, so this allows
// one kind of concatenation of "paths".
void SetLeafName(const nsString& inLeafName)
{
SetLeafName(nsAutoCString(inLeafName));
}
void GetParent(nsFileSpec& outSpec) const;
// Return the filespec of the parent directory. Used
// in conjunction with GetLeafName(), this lets you
@ -255,6 +295,10 @@ class NS_BASE nsFileSpec
// names. Perhaps could be used for an operator --() ?
nsFileSpec operator + (const char* inRelativePath) const;
nsFileSpec operator + (const nsString& inRelativePath) const
{
return *this + nsAutoCString(inRelativePath);
}
void operator += (const char* inRelativePath);
// Concatenate the relative path to this directory.
// Used for constructing the filespec of a descendant.
@ -264,9 +308,17 @@ class NS_BASE nsFileSpec
// away its leaf information, whereas this one assumes
// this is a directory, and the relative path starts
// "below" this.
void operator += (const nsString& inRelativePath)
{
*this += nsAutoCString(inRelativePath);
}
void MakeUnique();
void MakeUnique(const char* inSuggestedLeafName);
void MakeUnique(const nsString& inSuggestedLeafName)
{
MakeUnique(nsAutoCString(inSuggestedLeafName));
}
PRBool IsDirectory() const;
// More stringent than Exists()
@ -279,12 +331,20 @@ class NS_BASE nsFileSpec
//--------------------------------------------------
void CreateDirectory(int mode = 0700 /* for unix */);
void Delete(PRBool inRecursive);
void Delete(PRBool inRecursive) const;
nsresult Rename(const char* inNewName); // not const: gets updated
nsresult Rename(const nsString& inNewName)
{
return Rename(nsAutoCString(inNewName));
}
nsresult Copy(const nsFileSpec& inNewParentDirectory) const;
nsresult Move(const nsFileSpec& inNewParentDirectory) const;
nsresult Execute(const char* args) const;
nsresult Execute(const nsString& args) const
{
return Execute(nsAutoCString(args));
}
//--------------------------------------------------
// Data
@ -314,6 +374,7 @@ class NS_BASE nsFileURL
public:
nsFileURL(const nsFileURL& inURL);
NS_EXPLICIT nsFileURL(const char* inString, PRBool inCreateDirs = PR_FALSE);
NS_EXPLICIT nsFileURL(const nsString& inString, PRBool inCreateDirs = PR_FALSE);
NS_EXPLICIT nsFileURL(const nsFilePath& inPath);
NS_EXPLICIT nsFileURL(const nsFileSpec& inPath);
virtual ~nsFileURL();
@ -324,6 +385,10 @@ class NS_BASE nsFileURL
void operator = (const nsFileURL& inURL);
void operator = (const char* inString);
void operator = (const nsString& inString)
{
*this = nsAutoCString(inString);
}
void operator = (const nsFilePath& inOther);
void operator = (const nsFileSpec& inOther);
@ -357,6 +422,7 @@ class NS_BASE nsFilePath
public:
nsFilePath(const nsFilePath& inPath);
NS_EXPLICIT nsFilePath(const char* inString, PRBool inCreateDirs = PR_FALSE);
NS_EXPLICIT nsFilePath(const nsString& inString, PRBool inCreateDirs = PR_FALSE);
NS_EXPLICIT nsFilePath(const nsFileURL& inURL);
NS_EXPLICIT nsFilePath(const nsFileSpec& inPath);
virtual ~nsFilePath();
@ -373,6 +439,10 @@ class NS_BASE nsFilePath
void operator = (const nsFilePath& inPath);
void operator = (const char* inString);
void operator = (const nsString& inString)
{
*this = nsAutoCString(inString);
}
void operator = (const nsFileURL& inURL);
void operator = (const nsFileSpec& inOther);
@ -407,6 +477,9 @@ class NS_BASE nsPersistentFileDescriptor
nsPersistentFileDescriptor(const nsFileSpec& inPath);
void operator = (const nsFileSpec& inPath);
nsresult Read(nsIInputStream* aStream);
nsresult Write(nsIOutputStream* aStream);
// writes the data to a file
friend NS_BASE nsInputStream& operator >> (nsInputStream&, nsPersistentFileDescriptor&);
// reads the data from a file
friend NS_BASE nsOutputStream& operator << (nsOutputStream&, const nsPersistentFileDescriptor&);
@ -462,7 +535,7 @@ class NS_BASE nsDirectoryIterator
operator nsFileSpec&() { return mCurrent; }
private:
nsFileSpec mCurrent;
PRBool mExists; // MUST be bool.
PRBool mExists;
#if defined(XP_UNIX)
DIR* mDir;

View File

@ -531,6 +531,17 @@ nsFileSpec::nsFileSpec(const char* inString, PRBool inCreateDirs)
mError = NS_OK;
} // nsFileSpec::nsFileSpec
//----------------------------------------------------------------------------------------
nsFileSpec::nsFileSpec(const nsString& inString, PRBool inCreateDirs)
//----------------------------------------------------------------------------------------
{
mError = NS_FILE_RESULT(MacFileHelpers::FSSpecFromFullUnixPath(
nsAutoCString(inString), mSpec, false, true, inCreateDirs));
// allow a partial path, create as necessary
if (mError == NS_FILE_RESULT(fnfErr))
mError = NS_OK;
} // nsFileSpec::nsFileSpec
//----------------------------------------------------------------------------------------
nsFileSpec::nsFileSpec(
short vRefNum,
@ -693,19 +704,20 @@ void nsFileSpec::CreateDirectory(int /* unix mode */)
} // nsFileSpec::CreateDirectory
//----------------------------------------------------------------------------------------
void nsFileSpec::Delete(PRBool inRecursive)
void nsFileSpec::Delete(PRBool inRecursive) const
//----------------------------------------------------------------------------------------
{
nsresult& mutableError = const_cast<nsFileSpec*>(this)->mError;
if (inRecursive)
{
// MoreFilesExtras
mError = NS_FILE_RESULT(::DeleteDirectory(
mutableError = NS_FILE_RESULT(::DeleteDirectory(
mSpec.vRefNum,
mSpec.parID,
const_cast<unsigned char*>(mSpec.name)));
}
else
mError = NS_FILE_RESULT(FSpDelete(&mSpec));
mutableError = NS_FILE_RESULT(FSpDelete(&mSpec));
} // nsFileSpec::Delete
//----------------------------------------------------------------------------------------
@ -795,6 +807,18 @@ nsFilePath::nsFilePath(const char* inString, PRBool inCreateDirs)
char * path = MacFileHelpers::PathNameFromFSSpec( mFileSpec, TRUE );
mPath = MacFileHelpers::EncodeMacPath(path, true, true);
}
//----------------------------------------------------------------------------------------
nsFilePath::nsFilePath(const nsString& inString, PRBool inCreateDirs)
//----------------------------------------------------------------------------------------
: mPath(nsnull)
, mFileSpec(nsAutoCString(inString), inCreateDirs)
{
// Make canonical and absolute.
char * path = MacFileHelpers::PathNameFromFSSpec( mFileSpec, TRUE );
mPath = MacFileHelpers::EncodeMacPath(path, true, true);
}
//----------------------------------------------------------------------------------------
nsFilePath::nsFilePath(const nsFileSpec& inSpec)
//----------------------------------------------------------------------------------------
@ -833,6 +857,23 @@ nsFileURL::nsFileURL(const char* inString, PRBool inCreateDirs)
delete [] escapedPath;
} // nsFileURL::nsFileURL
//----------------------------------------------------------------------------------------
nsFileURL::nsFileURL(const nsString& inString, PRBool inCreateDirs)
//----------------------------------------------------------------------------------------
: mURL(nsnull)
{
nsAutoCString aString(inString);
const char* aCString = (const char*)aString;
NS_ASSERTION(strstr(aCString, kFileURLPrefix) == aCString, "Not a URL!");
mFileSpec = aCString + kFileURLPrefixLength;
// Make canonical and absolute.
char* path = MacFileHelpers::PathNameFromFSSpec( mFileSpec, TRUE );
char* escapedPath = MacFileHelpers::EncodeMacPath(path, true, true);
mURL = nsFileSpecHelpers::StringDup(kFileURLPrefix, kFileURLPrefixLength + strlen(escapedPath));
strcat(mURL, escapedPath);
delete [] escapedPath;
} // nsFileURL::nsFileURL
//========================================================================================
// nsDirectoryIterator
//========================================================================================

View File

@ -148,7 +148,7 @@ void nsFileSpec::CreateDirectory(int mode)
} // nsFileSpec::CreateDirectory
//----------------------------------------------------------------------------------------
void nsFileSpec::Delete(PRBool inRecursive)
void nsFileSpec::Delete(PRBool inRecursive) const
// To check if this worked, call Exists() afterwards, see?
//----------------------------------------------------------------------------------------
{
@ -186,7 +186,9 @@ nsresult nsFileSpec::Rename(const char* inNewName)
return NS_OK;
} // nsFileSpec::Rename
//----------------------------------------------------------------------------------------
static int CrudeFileCopy(const char* in, const char* out)
//----------------------------------------------------------------------------------------
{
struct stat in_stat;
int stat_result = -1;

View File

@ -237,24 +237,24 @@ void nsFileSpec::CreateDirectory(int /*mode*/)
} // nsFileSpec::CreateDirectory
//----------------------------------------------------------------------------------------
void nsFileSpec::Delete(PRBool inRecursive)
void nsFileSpec::Delete(PRBool inRecursive) const
//----------------------------------------------------------------------------------------
{
if (IsDirectory())
if (IsDirectory())
{
if (inRecursive)
{
for (nsDirectoryIterator i(*this); i.Exists(); i++)
{
nsFileSpec& child = (nsFileSpec&)i;
child.Delete(inRecursive);
}
for (nsDirectoryIterator i(*this); i.Exists(); i++)
{
nsFileSpec& child = (nsFileSpec&)i;
child.Delete(inRecursive);
}
}
rmdir(mPath);
}
else
{
remove(mPath);
remove(mPath);
}
} // nsFileSpec::Delete
@ -368,7 +368,7 @@ nsDirectoryIterator::nsDirectoryIterator(
//----------------------------------------------------------------------------------------
: mCurrent(inDirectory)
, mDir(nsnull)
, mExists(false)
, mExists(PR_FALSE)
{
mDir = PR_OpenDir(inDirectory);
mCurrent += "dummy";
@ -387,13 +387,13 @@ nsDirectoryIterator::~nsDirectoryIterator()
nsDirectoryIterator& nsDirectoryIterator::operator ++ ()
//----------------------------------------------------------------------------------------
{
mExists = false;
mExists = PR_FALSE;
if (!mDir)
return *this;
PRDirEntry* entry = PR_ReadDir(mDir, PR_SKIP_BOTH); // Ignore '.' && '..'
PRDirEntry* entry = PR_ReadDir(mDir, PR_SKIP_BOTH); // Ignore '.' && '..'
if (entry)
{
mExists = true;
mExists = PR_TRUE;
mCurrent.SetLeafName(entry->name);
}
return *this;

View File

@ -35,7 +35,6 @@
nsInputStream::~nsInputStream()
//----------------------------------------------------------------------------------------
{
mInputStream->Close();
}
//----------------------------------------------------------------------------------------
@ -76,7 +75,6 @@ nsInputStream& nsInputStream::operator >> (char& c)
nsOutputStream::~nsOutputStream()
//----------------------------------------------------------------------------------------
{
mOutputStream->Close();
}
//----------------------------------------------------------------------------------------

View File

@ -174,8 +174,12 @@ public:
{
return mInputStream;
}
char eof() const { return mEOF; }
char eof() const { return get_at_eof(); }
char get();
void close()
{
mInputStream->Close();
}
PRInt32 read(void* s, PRInt32 n)
{
if (!mInputStream)
@ -183,7 +187,7 @@ public:
PRInt32 result = 0;
mInputStream->Read((char*)s, 0, n, (PRUint32*)&result);
if (result < n)
mEOF = PR_TRUE;
set_at_eof(PR_TRUE);
return result;
}
@ -196,6 +200,19 @@ public:
{
return pf(*this);
}
protected:
// These certainly need to be overridden, they give the best shot we can at detecting
// eof in a simple nsIInputStream.
virtual void set_at_eof(PRBool atEnd)
{
mEOF = atEnd;
}
virtual PRBool get_at_eof()
{
return mEOF;
}
private:
nsInputStream& operator >> (char* buf); // TOO DANGEROUS. DON'T DEFINE.
@ -219,7 +236,7 @@ class NS_BASE nsOutputStream
public:
nsOutputStream() {}
nsOutputStream(nsIOutputStream* inStream)
: mOutputStream(do_QueryInterface(inStream))
: mOutputStream(do_QueryInterface(inStream))
{}
virtual ~nsOutputStream();
@ -228,6 +245,10 @@ public:
{
return mOutputStream;
}
void close()
{
mOutputStream->Close();
}
void put(char c);
PRInt32 write(const void* s, PRInt32 n)
{
@ -309,6 +330,7 @@ public:
void seek(PRSeekWhence whence, PRInt32 offset)
{
set_at_eof(PR_FALSE);
if (mFile)
mResult = mFile->Seek(whence, offset);
}
@ -319,7 +341,22 @@ public:
mResult = mFile->Tell(&result);
return result;
}
protected:
virtual PRBool get_at_eof()
{
PRBool result;
if (mFile)
mFile->GetAtEOF(&result);
return result;
}
virtual void set_at_eof(PRBool atEnd)
{
if (mFile)
mFile->SetAtEOF(atEnd);
}
// DATA
protected:
nsCOMPtr<nsIFile> mFile;
@ -354,6 +391,7 @@ public:
mFile = nsQueryInterface(stream);
mInputStream = nsQueryInterface(stream);
mFileInputStream = nsQueryInterface(stream);
NS_RELEASE(stream);
}
PRBool readline(char* s, PRInt32 n);
@ -377,6 +415,19 @@ public:
nsInputStream& operator >> (nsInputStream& (*pf)(nsInputStream&))
{ return nsInputStream::operator >>(pf); }
protected:
virtual PRBool get_at_eof()
{
return nsFileClient::get_at_eof();
}
virtual void set_at_eof(PRBool atEnd)
{
nsFileClient::set_at_eof(atEnd);
}
// DATA
protected:
nsCOMPtr<nsIFileInputStream> mFileInputStream;
@ -413,6 +464,7 @@ public:
mFile = nsQueryInterface(stream);
mOutputStream = nsQueryInterface(stream);
mFileOutputStream = nsQueryInterface(stream);
NS_RELEASE(stream);
}
virtual void flush();
@ -433,6 +485,18 @@ public:
nsOutputStream& operator << (nsOutputStream& (*pf)(nsOutputStream&))
{ return nsOutputStream::operator << (pf); }
protected:
virtual PRBool get_at_eof()
{
return nsFileClient::get_at_eof();
}
virtual void set_at_eof(PRBool atEnd)
{
nsFileClient::set_at_eof(atEnd);
}
// DATA
protected:
nsCOMPtr<nsIFileOutputStream> mFileOutputStream;
@ -454,6 +518,7 @@ public:
mFile = nsQueryInterface(stream);
mOutputStream = nsQueryInterface(stream);
mFileOutputStream = nsQueryInterface(stream);
NS_RELEASE(stream);
}
// Output streamers. Unfortunately, they don't inherit!
@ -509,8 +574,16 @@ public:
mOutputStream = nsQueryInterface(stream);
mFileInputStream = nsQueryInterface(stream);
mFileOutputStream = nsQueryInterface(stream);
NS_RELEASE(stream);
}
virtual void close()
{
// Doesn't matter which of the two we close:
// they're hooked up to the same file.
nsInputFileStream::close();
}
// Output streamers. Unfortunately, they don't inherit!
nsOutputStream& operator << (const char* buf)
{ return nsOutputStream::operator << (buf); }
@ -532,6 +605,7 @@ public:
{ return nsInputStream::operator >>(ch); }
nsInputStream& operator >> (nsInputStream& (*pf)(nsInputStream&))
{ return nsInputStream::operator >>(pf); }
// DATA
protected:
nsCOMPtr<nsIFileOutputStream> mFileOutputStream;

View File

@ -141,6 +141,17 @@ class FileImpl
}
NS_IMETHOD Flush();
NS_IMETHOD GetAtEOF(PRBool* outAtEOF)
{
*outAtEOF = mEOF;
return NS_OK;
}
NS_IMETHOD SetAtEOF(PRBool inAtEOF)
{
mEOF = inAtEOF;
return NS_OK;
}
protected:
PRFileDesc* mFileDesc;

View File

@ -47,6 +47,10 @@ public:
NS_IMETHOD Seek(PRSeekWhence whence, PRInt32 offset) = 0;
NS_IMETHOD GetIsOpen(PRBool* outOpen) = 0;
NS_IMETHOD Tell(PRIntn* outWhere) = 0;
/* "PROTECTED" */
NS_IMETHOD GetAtEOF(PRBool* outAtEOF) = 0;
NS_IMETHOD SetAtEOF(PRBool inAtEOF) = 0;
}; // class nsIFile
/* a6cf90e6-15b3-11d2-932e-00805f8add32 */
@ -86,7 +90,7 @@ public:
}; // class nsIFileOutputStream
//----------------------------------------------------------------------------------------
NS_BASE nsresult NS_NewTypicalInputFileStream(
extern "C" NS_BASE nsresult NS_NewTypicalInputFileStream(
nsISupports** aStreamResult,
const nsFileSpec& inFile
/*Default nsprMode == PR_RDONLY*/

View File

@ -20,6 +20,7 @@
#include "nsFileStream.h"
//#include "string.h"
//void* operator new(size_t n) { return malloc(n); }
struct FilesTest
{
@ -176,7 +177,7 @@ int FilesTest::IOStream(const char* relativePath)
<< nsEndl;
return -1;
}
char line[1000];
char line[5000]; // Use a buffer longer than the file!
testStream.seek(0); // check that the seek compiles
while (!testStream.eof())
{