From cf8dafefa38ffeda995794c1afb7bda803acd228 Mon Sep 17 00:00:00 2001 From: "mcmullen%netscape.com" Date: Tue, 8 Dec 1998 22:45:42 +0000 Subject: [PATCH] Polished the interfaces, added long comments in the headers. The next step is checking by Bill Law and Steve Lamm for Win and Unix. Then it's open season. git-svn-id: svn://10.0.0.236/trunk@16002 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/base/macbuild/TestFiles.mcp | Bin 81980 -> 81980 bytes mozilla/base/public/nsFileSpec.h | 336 ++++++----- mozilla/base/public/nsFileStream.h | 654 +++++++++++---------- mozilla/base/src/mac/nsFileSpecMac.cpp | 14 +- mozilla/base/src/nsFileSpec.cpp | 18 +- mozilla/base/src/unix/nsFileSpecUnix.cpp | 2 +- mozilla/base/src/windows/nsFileSpecWin.cpp | 6 +- mozilla/base/tests/FilesTest.cpp | 28 +- mozilla/xpcom/io/nsFileSpec.cpp | 18 +- mozilla/xpcom/io/nsFileSpec.h | 336 ++++++----- mozilla/xpcom/io/nsFileSpecMac.cpp | 14 +- mozilla/xpcom/io/nsFileSpecUnix.cpp | 2 +- mozilla/xpcom/io/nsFileSpecWin.cpp | 6 +- mozilla/xpcom/io/nsFileStream.h | 654 +++++++++++---------- mozilla/xpcom/tests/FilesTest.cpp | 28 +- 15 files changed, 1172 insertions(+), 944 deletions(-) diff --git a/mozilla/base/macbuild/TestFiles.mcp b/mozilla/base/macbuild/TestFiles.mcp index 55c19824b483d429856aa92a6f0656abd887a4c6..d80accd17c33e1d6c8efca769c8f4a3792288938 100644 GIT binary patch delta 198 zcmdnfz`Cb_bwiF6`=r;^|Nn1K-rO=tgK-k?`^g3KSSI($h_O#Px8wi+U!OM@7XD-e z32t5?*Uh*&UcsM{k#X~S#d(a)iptv+l^NTl8I7l}uw#s8^qtOO&!{gM!oa{_S5TCi z#xUWRF#`irAdn9Pij$@X*fWYtE&#HVz|s@#%z@IuAV~%WC8p^OAZalmn+qa+_76}x d6fDc2q%eI0P?}L^`U!hRHzuVI(*+zDbpXWQJHY?| delta 207 zcmdnfz`Cb_bwiF6`@~aM85kVSZEl&Q!8nQc{p5mqER*|W#MmeHPXGV^xAf-1!k>&F z!Obh=x)~>jPtndzQT?%p0RQ|hdrad zWCH^OgIz&UY8u0YU&ag!Oo2c?5Gd}O9$?QXE_nvXP6A6$v@-`v2ZLo9l=P-IfTW#( kTrP<8**`$(P^h%e^bJ61#)#=B>>1sdlx3z1I56q}0HF##9RL6T diff --git a/mozilla/base/public/nsFileSpec.h b/mozilla/base/public/nsFileSpec.h index 2c12feda22d..53bee8a9b10 100644 --- a/mozilla/base/public/nsFileSpec.h +++ b/mozilla/base/public/nsFileSpec.h @@ -16,29 +16,93 @@ * Reserved. */ -// First checked in on 98/11/20 by John R. McMullen. Checked in again 98/12/04. +// First checked in on 98/11/20 by John R. McMullen in the wrong directory. +// Checked in again 98/12/04. +// Polished version 98/12/08. + +//======================================================================================== +// +// Classes defined: +// +// nsFilePath, nsFileURL, nsNativeFileSpec. +// +// This suite provides the following services: +// +// 1. Encapsulates all platform-specific file details, so that files can be +// described correctly without any platform #ifdefs +// +// 2. Type safety. This will fix the problems that used to occur because people +// confused file paths. They used to use const char*, which could mean three +// or four different things. Bugs were introduced as people coded, right up +// to the moment Communicator 4.5 shipped. +// +// 3. Used in conjunction with nsFileStream.h (q.v.), this supports all the power +// and readability of the ansi stream syntax. ALL METHODS OF istream, ostream, +// AND iostream ARE AVAILABLE! +// +// Basic example: +// +// nsFilePath myPath("/Development/iotest.txt"); +// +// nsOutputFileStream testStream(myPath); +// testStream << "Hello World" << endl; +// +// 4. Handy methods for manipulating file specifiers safely, e.g. MakeUnique(), +// SetLeafName(), Exists(). +// +// 5. Easy cross-conversion. +// +// Examples: +// +// Initialize a URL from a string without suffix +// +// nsFileURL fileURL("file:///Development/MPW/MPW%20Shell"); +// +// Initialize a Unix path from a URL +// +// nsFilePath filePath(fileURL); +// +// Initialize a native file spec from a URL +// +// nsNativeFileSpec fileSpec(fileURL); +// +// Make the spec unique (this one has no suffix). +// +// fileSpec.MakeUnique(); +// +// Assign the spec to a URL +// +// fileURL = fileSpec; +// +// Assign a unix path using a string with a suffix. +// +// filePath = "/Development/MPW/SysErrs.err"; +// +// Assign to a file spec using a unix path. +// +// fileSpec = filePath; +// +// Make this unique (this one has a suffix). +// +// fileSpec.MakeUnique(); +// +// 6. Fixes a bug that have been there for a long time, and +// is inevitable if you use NSPR alone, where files are described as paths. +// +// The problem affects platforms (Macintosh) in which a path does not fully +// specify a file, because two volumes can have the same name. This +// is solved by holding a "private" native file spec inside the +// nsFilePath and nsFileURL classes, which is used when appropriate. +// +// Not yet done: +// +// Equality operators... much more. +// +//======================================================================================== #ifndef _FILESPEC_H_ #define _FILESPEC_H_ -//======================================================================================== -// This is intended to be part of the API for all C++ in the mozilla code base from now on. -// It provides -// * Type-safe ways of describing files (no more char* parameters) -// * Conversions between these -// * Methods for testing existence and for forcing uniqueness. -// -// A file specification can come from two outside sources: -// 1. A file:// URL, or -// 2. A native spec (such as an OS-based save/open dialog and the like). -// Therefore, these are the only ingredients one can use to make a file specification. -// -// Once one of our spec types has been made, conversions are provided between them -// -// In addition, string accessors are provided, because people like to manipulate -// nsFileURL and nsUnixFilePath strings directly. -//======================================================================================== - #include #include "nsDebug.h" #ifdef XP_MAC @@ -49,7 +113,7 @@ // Here are the allowable ways to describe a file. //======================================================================================== -class nsUnixFilePath; // This can be passed to NSPR file I/O routines. +class nsFilePath; // This can be passed to NSPR file I/O routines. class nsFileURL; class nsNativeFileSpec; @@ -58,202 +122,202 @@ class nsNativeFileSpec; //======================================================================================== class nsNativeFileSpec -// This is whatever each platform really prefers to describe files as. +// This is whatever each platform really prefers to describe files as. Declared first +// because the other two types have an embeded nsNativeFileSpec object. //======================================================================================== { - public: - nsNativeFileSpec(); - nsNativeFileSpec(const std::string& inString); - nsNativeFileSpec(const nsUnixFilePath& inPath); - nsNativeFileSpec(const nsFileURL& inURL); - nsNativeFileSpec(const nsNativeFileSpec& inPath); + public: + nsNativeFileSpec(); + explicit nsNativeFileSpec(const std::string& inString); + nsNativeFileSpec(const nsFilePath& inPath); + nsNativeFileSpec(const nsFileURL& inURL); + nsNativeFileSpec(const nsNativeFileSpec& inPath); - void operator = (const std::string& inPath); - void operator = (const nsUnixFilePath& inPath); - void operator = (const nsFileURL& inURL); - void operator = (const nsNativeFileSpec& inOther); + void operator = (const std::string& inPath); + void operator = (const nsFilePath& inPath); + void operator = (const nsFileURL& inURL); + void operator = (const nsNativeFileSpec& inOther); #ifdef XP_MAC - // For Macintosh people, this is meant to be useful in its own right as a C++ version - // of the FSSPec class. - nsNativeFileSpec( - short vRefNum, - long parID, - ConstStr255Param name); - nsNativeFileSpec(const FSSpec& inSpec) - : mSpec(inSpec), mError(noErr) {} + // For Macintosh people, this is meant to be useful in its own right as a C++ version + // of the FSSPec class. + nsNativeFileSpec( + short vRefNum, + long parID, + ConstStr255Param name); + nsNativeFileSpec(const FSSpec& inSpec) + : mSpec(inSpec), mError(noErr) {} - operator FSSpec* () { return &mSpec; } - operator const FSSpec* const () { return &mSpec; } - operator FSSpec& () { return mSpec; } - operator const FSSpec& () const { return mSpec; } - bool Valid() const { return mError == noErr; } - OSErr Error() const { return mError; } - void MakeUnique(ConstStr255Param inSuggestedLeafName); - StringPtr GetLeafPName() { return mSpec.name; } - ConstStr255Param GetLeafPName() const { return mSpec.name; } + operator FSSpec* () { return &mSpec; } + operator const FSSpec* const () { return &mSpec; } + operator FSSpec& () { return mSpec; } + operator const FSSpec& () const { return mSpec; } + bool Valid() const { return mError == noErr; } + OSErr Error() const { return mError; } + void MakeUnique(ConstStr255Param inSuggestedLeafName); + StringPtr GetLeafPName() { return mSpec.name; } + ConstStr255Param GetLeafPName() const { return mSpec.name; } #else - bool Valid() const { return TRUE; } // Fixme. + bool Valid() const { return TRUE; } // Fixme. #endif #if DEBUG - friend ostream& operator << (ostream& s, const nsNativeFileSpec& spec); + friend ostream& operator << (ostream& s, const nsNativeFileSpec& spec); #endif - string GetLeafName() const; - void SetLeafName(const std::string& inLeafName); - bool Exists() const; - void MakeUnique(); - void MakeUnique(const std::string& inSuggestedLeafName); - - private: - friend class nsUnixFilePath; + string GetLeafName() const; + void SetLeafName(const std::string& inLeafName); + bool Exists() const; + void MakeUnique(); + void MakeUnique(const std::string& inSuggestedLeafName); + + private: + friend class nsFilePath; #ifdef XP_MAC - FSSpec mSpec; - OSErr mError; + FSSpec mSpec; + OSErr mError; #elif defined(XP_UNIX) || defined(XP_WIN) - std::string mPath; + std::string mPath; #endif }; // class nsNativeFileSpec //======================================================================================== class nsFileURL -// This is an escaped string that looks like "file:///foo/bar/mumble%20fish". Since URLs -// are the standard way of doing things in mozilla, this allows a string constructor, -// which just stashes the string with no conversion. +// This is an escaped string that looks like "file:///foo/bar/mumble%20fish". Since URLs +// are the standard way of doing things in mozilla, this allows a string constructor, +// which just stashes the string with no conversion. //======================================================================================== { - public: - nsFileURL(const nsFileURL& inURL); - nsFileURL(const std::string& inString); - nsFileURL(const nsUnixFilePath& inPath); - nsFileURL(const nsNativeFileSpec& inPath); - - operator std::string& () { return mURL; } - // This is the only automatic conversion to string - // that is provided, because a naked string should - // only mean a file URL. + public: + nsFileURL(const nsFileURL& inURL); + explicit nsFileURL(const std::string& inString); + nsFileURL(const nsFilePath& inPath); + nsFileURL(const nsNativeFileSpec& inPath); -// std::string GetString() const { return mPath; } - // may be needed for implementation reasons, - // but should not provide a conversion constructor. +// std::string GetString() const { return mPath; } + // may be needed for implementation reasons, + // but should not provide a conversion constructor. - void operator = (const nsFileURL& inURL); - void operator = (const std::string& inString); - void operator = (const nsUnixFilePath& inOther); - void operator = (const nsNativeFileSpec& inOther); + void operator = (const nsFileURL& inURL); + void operator = (const std::string& inString); + void operator = (const nsFilePath& inOther); + void operator = (const nsNativeFileSpec& inOther); #ifdef XP_MAC - // Accessor to allow quick assignment to a mNativeFileSpec - const nsNativeFileSpec& GetNativeSpec() const { return mNativeFileSpec; } + // Accessor to allow quick assignment to a mNativeFileSpec + const nsNativeFileSpec& GetNativeSpec() const { return mNativeFileSpec; } #endif - private: - - std::string mURL; + private: + // Should not be defined (only nsFilePath is to be treated as strings. + operator std::string& (); + private: + + std::string mURL; #ifdef XP_MAC - // Since the path on the macintosh does not uniquely specify a file (volumes - // can have the same name), stash the secret nsNativeFileSpec, too. - nsNativeFileSpec mNativeFileSpec; + // Since the path on the macintosh does not uniquely specify a file (volumes + // can have the same name), stash the secret nsNativeFileSpec, too. + nsNativeFileSpec mNativeFileSpec; #endif }; // class nsFileURL //======================================================================================== -class nsUnixFilePath -// This is a string that looks like "/foo/bar/mumble%20fish". Same as nsFileURL, but -// without the "file:// prefix". +class nsFilePath +// This is a string that looks like "/foo/bar/mumble%20fish". Same as nsFileURL, but +// without the "file:// prefix". //======================================================================================== { - public: - nsUnixFilePath(const nsUnixFilePath& inPath); - nsUnixFilePath(const std::string& inString); - nsUnixFilePath(const nsFileURL& inURL); - nsUnixFilePath(const nsNativeFileSpec& inPath); + public: + nsFilePath(const nsFilePath& inPath); + explicit nsFilePath(const std::string& inString); + nsFilePath(const nsFileURL& inURL); + nsFilePath(const nsNativeFileSpec& inPath); - - operator const char* () const { return mPath.c_str(); } - // This is the only automatic conversion to const char* - // that is provided, and it allows the - // path to be "passed" to NSPR file routines. + + operator const char* () const { return mPath.c_str(); } + // This is the only automatic conversion to const char* + // that is provided, and it allows the + // path to be "passed" to NSPR file routines. + operator std::string& () { return mPath; } + // This is the only automatic conversion to string + // that is provided, because a naked string should + // only mean a standard file path. - void operator = (const nsUnixFilePath& inPath); - void operator = (const std::string& inString); - void operator = (const nsFileURL& inURL); - void operator = (const nsNativeFileSpec& inOther); + void operator = (const nsFilePath& inPath); + void operator = (const std::string& inString); + void operator = (const nsFileURL& inURL); + void operator = (const nsNativeFileSpec& inOther); #ifdef XP_MAC - public: - // Accessor to allow quick assignment to a mNativeFileSpec - const nsNativeFileSpec& GetNativeSpec() const { return mNativeFileSpec; } + public: + // Accessor to allow quick assignment to a mNativeFileSpec + const nsNativeFileSpec& GetNativeSpec() const { return mNativeFileSpec; } #endif - private: - // Should not be defined (only file URLs are to be treated as strings. - operator std::string& (); - private: + private: - std::string mPath; + std::string mPath; #ifdef XP_MAC - // Since the path on the macintosh does not uniquely specify a file (volumes - // can have the same name), stash the secret nsNativeFileSpec, too. - nsNativeFileSpec mNativeFileSpec; + // Since the path on the macintosh does not uniquely specify a file (volumes + // can have the same name), stash the secret nsNativeFileSpec, too. + nsNativeFileSpec mNativeFileSpec; #endif -}; // class nsUnixFilePath +}; // class nsFilePath #ifdef XP_UNIX //======================================================================================== -// UNIX nsUnixFilePath implementation +// UNIX nsFilePath implementation //======================================================================================== //---------------------------------------------------------------------------------------- -inline nsUnixFilePath::nsUnixFilePath(const nsNativeFileSpec& inOther) +inline nsFilePath::nsFilePath(const nsNativeFileSpec& inOther) //---------------------------------------------------------------------------------------- -: mPath((std::string&)inOther) +: mPath((std::string&)inOther) { } //---------------------------------------------------------------------------------------- -inline void nsUnixFilePath::operator = (const nsNativeFileSpec& inOther) +inline void nsFilePath::operator = (const nsNativeFileSpec& inOther) //---------------------------------------------------------------------------------------- { - mPath = (std::string&)inOther; + mPath = (std::string&)inOther; } #endif // XP_UNIX //======================================================================================== -// COMMON nsNativeFileSpec implementation +// COMMON nsNativeFileSpec implementation //======================================================================================== //---------------------------------------------------------------------------------------- inline nsNativeFileSpec::nsNativeFileSpec(const nsFileURL& inURL) //---------------------------------------------------------------------------------------- { - *this = nsUnixFilePath(inURL); // convert to unix path first + *this = nsFilePath(inURL); // convert to unix path first } //---------------------------------------------------------------------------------------- inline void nsNativeFileSpec::operator = (const nsFileURL& inURL) //---------------------------------------------------------------------------------------- { - *this = nsUnixFilePath(inURL); // convert to unix path first + *this = nsFilePath(inURL); // convert to unix path first } //======================================================================================== -// UNIX & WIN nsNativeFileSpec implementation +// UNIX & WIN nsNativeFileSpec implementation //======================================================================================== #ifdef XP_UNIX //---------------------------------------------------------------------------------------- -inline nsNativeFileSpec::nsNativeFileSpec(const nsUnixFilePath& inPath) +inline nsNativeFileSpec::nsNativeFileSpec(const nsFilePath& inPath) //---------------------------------------------------------------------------------------- -: mPath((std::string&)inPath) +: mPath((std::string&)inPath) { } #endif // XP_UNIX #ifdef XP_UNIX //---------------------------------------------------------------------------------------- -inline void nsNativeFileSpec::operator = (const nsUnixFilePath& inPath) +inline void nsNativeFileSpec::operator = (const nsFilePath& inPath) //---------------------------------------------------------------------------------------- { - mPath = (std::string&)inPath; + mPath = (std::string&)inPath; } #endif //XP_UNIX @@ -261,7 +325,7 @@ inline void nsNativeFileSpec::operator = (const nsUnixFilePath& inPath) //---------------------------------------------------------------------------------------- inline nsNativeFileSpec::nsNativeFileSpec(const nsNativeFileSpec& inSpec) //---------------------------------------------------------------------------------------- -: mPath((std::string&)inSpec) +: mPath((std::string&)inSpec) { } #endif //XP_UNIX @@ -270,7 +334,7 @@ inline nsNativeFileSpec::nsNativeFileSpec(const nsNativeFileSpec& inSpec) //---------------------------------------------------------------------------------------- inline nsNativeFileSpec::nsNativeFileSpec(const std::string& inString) //---------------------------------------------------------------------------------------- -: mPath(inString) +: mPath(inString) { } #endif //XP_UNIX @@ -280,7 +344,7 @@ inline nsNativeFileSpec::nsNativeFileSpec(const std::string& inString) inline void nsNativeFileSpec::operator = (const nsNativeFileSpec& inSpec) //---------------------------------------------------------------------------------------- { - mPath = (std::string&)inSpec; + mPath = (std::string&)inSpec; } #endif //XP_UNIX @@ -290,7 +354,7 @@ inline void nsNativeFileSpec::operator = (const nsNativeFileSpec& inSpec) inline nsNativeFileSpec::operator = (const std::string& inString) //---------------------------------------------------------------------------------------- { - mPath = inString; + mPath = inString; } #endif //XP_UNIX @@ -299,7 +363,7 @@ inline nsNativeFileSpec::operator = (const std::string& inString) inline ostream& operator << (ostream& s, const nsNativeFileSpec& spec) //---------------------------------------------------------------------------------------- { - return (s << (std::string&)spec.mPath); + return (s << (std::string&)spec.mPath); } #endif // DEBUG && XP_UNIX diff --git a/mozilla/base/public/nsFileStream.h b/mozilla/base/public/nsFileStream.h index df0851d6eb4..4a265fbd401 100644 --- a/mozilla/base/public/nsFileStream.h +++ b/mozilla/base/public/nsFileStream.h @@ -16,109 +16,193 @@ * Reserved. */ -// First checked in on 98/11/20 by John R. McMullen. Checked in again 98/12/04. +// First checked in on 98/11/20 by John R. McMullen in the wrong directory. +// Checked in again 98/12/04. +// Polished version 98/12/08. -#ifndef _STREAM_H_ -#define _STREAM_H_ +//======================================================================================== +// +// Classes defined: +// +// single-byte char: +// +// nsInputFileStream, nsOutputFileStream, nsIOFileStream +// +// wide char: +// +// nsWideInputFileStream, nsWideOutputFileStream, nsWideIOFileStream +// +// This suite provide the following services: +// +// 1. Encapsulates all platform-specific file details, so that file i/o +// can be done correctly without any platform #ifdefs +// +// 2. Uses NSPR file services (NOT ansi file I/O), in order to get best +// native performance. This performance difference is especially large on +// macintosh. +// +// 3. Allows all the power of the ansi stream syntax: these streams +// ARE derived classes of ostream, istream, and iostream. ALL METHODS OF +// istream, ostream, AND iostream ARE AVAILABLE! +// +// Basic example: +// +// nsFilePath myPath("/Development/iotest.txt"); +// +// nsOutputFileStream testStream(myPath); +// testStream << "Hello World" << endl; +// +// 4. Requires streams to be constructed using typesafe nsFilePath specifier +// (not the notorious and bug prone const char*), namely nsFilePath. See +// nsFileSpec.h for more details. +// +// 5. Fixes a two bugs that have been there for a long time, and +// are inevitable if you use NSPR alone: +// +// The problem on platforms (Macintosh) in which a path does not fully +// specify a file. +// +// Not yet provided: +// +// Endian-awareness for reading and writing crossplatform binary files. At this +// time there seems to be no demand for this. +// +//======================================================================================== + +#ifndef _FILESTREAM_H_ +#define _FILESTREAM_H_ #include +#ifdef XP_MAC +#include "pprio.h" // To get PR_ImportFile +#else #include "prio.h" +#endif #include "nsFileSpec.h" +//======================================================================================== +// Compiler-specific macros, as needed +//======================================================================================== #ifdef __MWERKS__ + #ifdef MSIPL_WCHART #define NS_USING_WIDE_CHAR #endif #ifdef MSIPL_EXPLICIT_FUNC_TEMPLATE_ARG #define NS_EXPLICIT_FUNC_TEMPLATE_ARG #endif -#endif +#define NS_READ_LOCK(mut) READ_LOCK(mut) +#define NS_WRITE_LOCK(mut) WRITE_LOCK(mut) + +#else + +// Fix me for thread-safety. +#define NS_READ_LOCK(mut) +#define NS_WRITE_LOCK(mut) + +#endif //==================== End Compiler-specific macros =============================== + +//======================================================================================== +namespace nsFileStreamHelpers +// Prototypes for common (non-template) implementations in the .cpp file which do not +// need the template args (charT, traits). +//======================================================================================== +{ + PRFileDesc* open( + const nsFilePath& inFile, + ios_base::openmode mode, + PRIntn accessMode); +} // nsFileStreamHelpers + +//======================================================================================== +// Template declarations +//======================================================================================== //======================================================================================== template class nsFileBufferT //======================================================================================== -: public basic_streambuf +: public basic_streambuf { - typedef codecvt_base::result result; + typedef codecvt_base::result result; public: - typedef charT char_type; - typedef typename traits::pos_type pos_type; - typedef typename traits::off_type off_type; - typedef typename traits::int_type int_type; - typedef traits traits_type; - typedef typename traits::state_type state_type; + typedef charT char_type; + typedef typename traits::pos_type pos_type; + typedef typename traits::off_type off_type; + typedef typename traits::int_type int_type; + typedef traits traits_type; + typedef typename traits::state_type state_type; - typedef nsFileBufferT filebuf_type; - typedef codecvt ofacet_type; - typedef codecvt ifacet_type; + typedef nsFileBufferT filebuf_type; + typedef codecvt ofacet_type; + typedef codecvt ifacet_type; - nsFileBufferT(); - nsFileBufferT(PRFileDesc* pfile_arg); - virtual ~nsFileBufferT(); - bool is_open() const; - filebuf_type* open( - const nsUnixFilePath& inFile, - ios_base::openmode mode, - PRIntn accessMode); - filebuf_type* close(); + nsFileBufferT(); + nsFileBufferT(PRFileDesc* pfile_arg); + virtual ~nsFileBufferT(); + bool is_open() const; + filebuf_type* open( + const nsFilePath& inFile, + ios_base::openmode mode, + PRIntn accessMode); + filebuf_type* close(); protected: - virtual int_type overflow(int_type c=traits::eof()); - virtual int_type pbackfail(int_type c=traits::eof()); - virtual int_type underflow(); - virtual pos_type seekoff( - off_type off, ios_base::seekdir way, - ios_base::openmode which=ios_base::in|ios_base::out); - virtual pos_type seekpos(pos_type sp, - ios_base::openmode which=ios_base::in|ios_base::out); - virtual basic_streambuf* setbuf(char_type* s, streamsize n); - virtual int sync(); - virtual int_type uflow(); - virtual void imbue(const locale& loc); - virtual streamsize showmanyc(); - virtual streamsize xsgetn(char_type* s, streamsize n); - virtual streamsize xsputn(const char_type* s, streamsize n); + virtual int_type overflow(int_type c=traits::eof()); + virtual int_type pbackfail(int_type c=traits::eof()); + virtual int_type underflow(); + virtual pos_type seekoff( + off_type off, ios_base::seekdir way, + ios_base::openmode which=ios_base::in|ios_base::out); + virtual pos_type seekpos(pos_type sp, + ios_base::openmode which=ios_base::in|ios_base::out); + virtual basic_streambuf* setbuf(char_type* s, streamsize n); + virtual int sync(); + virtual int_type uflow(); + virtual void imbue(const locale& loc); + virtual streamsize showmanyc(); + virtual streamsize xsgetn(char_type* s, streamsize n); + virtual streamsize xsputn(const char_type* s, streamsize n); private: - PRFileDesc* mFileDesc; - ios_base::openmode mode_; + PRFileDesc* mFileDesc; + ios_base::openmode mode_; }; // class nsFileBufferT //======================================================================================== template class nsInputFileStreamT //======================================================================================== -: public basic_istream +: public basic_istream { - typedef nsFileBufferT filebuf_type; + typedef nsFileBufferT filebuf_type; public: - typedef charT char_type; - typedef typename traits::pos_type pos_type; - typedef typename traits::off_type off_type; - typedef typename traits::int_type int_type; - typedef traits traits_type; + typedef charT char_type; + typedef typename traits::pos_type pos_type; + typedef typename traits::off_type off_type; + typedef typename traits::int_type int_type; + typedef traits traits_type; - nsInputFileStreamT(); - explicit nsInputFileStreamT( - const nsUnixFilePath& inFile, - ios_base::openmode mode=ios_base::in, - PRIntn accessMode = 0x00400); + nsInputFileStreamT(); + explicit nsInputFileStreamT( + const nsFilePath& inFile, + ios_base::openmode mode=ios_base::in, + PRIntn accessMode = 0x00400); - virtual ~nsInputFileStreamT(); + virtual ~nsInputFileStreamT(); - filebuf_type* rdbuf() const; - inline bool is_open(); - inline void open( - const nsUnixFilePath& inFile, - ios_base::openmode mode=ios_base::in, - PRIntn accessMode = 0x00400); - inline void close(); + filebuf_type* rdbuf() const; + inline bool is_open(); + inline void open( + const nsFilePath& inFile, + ios_base::openmode mode=ios_base::in, + PRIntn accessMode = 0x00400); + inline void close(); private: - filebuf_type mBuffer; + filebuf_type mBuffer; }; // class nsInputFileStreamT //======================================================================================== @@ -127,43 +211,43 @@ class nsOutputFileStreamT //======================================================================================== : public basic_ostream { - typedef nsFileBufferT filebuf_type; + typedef nsFileBufferT filebuf_type; public: - typedef charT char_type; - typedef typename traits::pos_type pos_type; - typedef typename traits::off_type off_type; - typedef typename traits::int_type int_type; - typedef traits traits_type; + typedef charT char_type; + typedef typename traits::pos_type pos_type; + typedef typename traits::off_type off_type; + typedef typename traits::int_type int_type; + typedef traits traits_type; - nsOutputFileStreamT(); - explicit nsOutputFileStreamT( - const nsUnixFilePath& inFile, - ios_base::openmode mode = ios_base::out|ios_base::trunc, - PRIntn accessMode = 0x00200); + nsOutputFileStreamT(); + explicit nsOutputFileStreamT( + const nsFilePath& inFile, + ios_base::openmode mode = ios_base::out|ios_base::trunc, + PRIntn accessMode = 0x00200); - virtual ~nsOutputFileStreamT(); + virtual ~nsOutputFileStreamT(); - filebuf_type* rdbuf() const; - inline bool is_open(); - inline void open( - const nsUnixFilePath& inFile, - ios_base::openmode mode = ios_base::out|ios_base::trunc, - PRIntn accessMode = 0x00200); - inline void close(); + filebuf_type* rdbuf() const; + inline bool is_open(); + inline void open( + const nsFilePath& inFile, + ios_base::openmode mode = ios_base::out|ios_base::trunc, + PRIntn accessMode = 0x00200); + inline void close(); private: - filebuf_type mBuffer; + filebuf_type mBuffer; }; // class nsOutputFileStreamT //======================================================================================== -// Implementation of nsFileBufferT +// Implementation of nsFileBufferT //======================================================================================== //---------------------------------------------------------------------------------------- -template +template inline nsFileBufferT::nsFileBufferT() - : basic_streambuf(), mFileDesc(NULL) + : basic_streambuf(), mFileDesc(NULL) //---------------------------------------------------------------------------------------- { } @@ -171,7 +255,7 @@ inline nsFileBufferT::nsFileBufferT() //---------------------------------------------------------------------------------------- template inline nsFileBufferT::nsFileBufferT(PRFileDesc* pfarg) - : basic_streambuf(), mFileDesc(pfarg) + : basic_streambuf(), mFileDesc(pfarg) //---------------------------------------------------------------------------------------- { } @@ -181,7 +265,7 @@ template inline nsFileBufferT::~nsFileBufferT() //---------------------------------------------------------------------------------------- { - close(); + close(); } //---------------------------------------------------------------------------------------- @@ -190,78 +274,38 @@ inline bool nsFileBufferT::is_open() const //---------------------------------------------------------------------------------------- { - READ_LOCK(_mutex); - return bool(mFileDesc); // in case it is typedefed to int + NS_READ_LOCK(_mutex); + return bool(mFileDesc); // in case it is typedefed to int } //---------------------------------------------------------------------------------------- template nsFileBufferT::filebuf_type* nsFileBufferT::open( - const nsUnixFilePath& inFile, - ios_base::openmode mode, - PRIntn accessMode - ) + const nsFilePath& inFile, + ios_base::openmode mode, + PRIntn accessMode) //---------------------------------------------------------------------------------------- { - if (mFileDesc) - return 0; - const ios_base::openmode valid_modes[]= - { - ios_base::out, - ios_base::out | ios_base::app, - ios_base::out | ios_base::trunc, - ios_base::in, - ios_base::in | ios_base::out, - ios_base::in | ios_base::out | ios_base::trunc, -// ios_base::out | ios_base::binary, -// ios_base::out | ios_base::app | ios_base::binary, -// ios_base::out | ios_base::trunc | ios_base::binary, -// ios_base::in | ios_base::binary, -// ios_base::in | ios_base::out | ios_base::binary, -// ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary, - 0 - }; - 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 }; - int ind=0; - while (valid_modes[ind] && valid_modes[ind] != (mode&~ios_base::ate)) - ++ind; - if (!nspr_modes[ind]) - return 0; - - WRITE_LOCK(_mutex); - mode_ = mode; - if ((mFileDesc = PR_Open(inFile, nspr_modes[ind], accessMode)) != 0) - if (mode&ios_base::ate && PR_Seek(mFileDesc, 0, PR_SEEK_END) >= 0) - close(); - else - return this; - return 0; -} // nsFileBufferT::open + if (mFileDesc) + return 0; + NS_WRITE_LOCK(_mutex); + mFileDesc = nsFileStreamHelpers::open(inFile, mode, accessMode); + if (!mFileDesc) + return 0; + mode_ = mode; + return this; +} // nsFileBufferT::open //---------------------------------------------------------------------------------------- template nsFileBufferT::filebuf_type* nsFileBufferT::close() //---------------------------------------------------------------------------------------- { - if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR) - return this; - WRITE_LOCK(_mutex); - return (mFileDesc && PR_Close(mFileDesc) == PR_SUCCESS) ? mFileDesc = 0, this : 0; + if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR) + return this; + NS_WRITE_LOCK(_mutex); + return (mFileDesc && PR_Close(mFileDesc) == PR_SUCCESS) ? mFileDesc = 0, this : 0; } //---------------------------------------------------------------------------------------- @@ -270,7 +314,7 @@ inline int nsFileBufferT:: sync() //---------------------------------------------------------------------------------------- { - return (mFileDesc ? (int)PR_Sync(mFileDesc) : 0); + return (mFileDesc ? (int)PR_Sync(mFileDesc) : 0); } //---------------------------------------------------------------------------------------- @@ -279,7 +323,7 @@ inline basic_streambuf* nsFileBufferT::setbuf(char_type*, streamsize) //---------------------------------------------------------------------------------------- { - return (!mFileDesc) ? 0 : this; + return (!mFileDesc) ? 0 : this; } //---------------------------------------------------------------------------------------- @@ -287,39 +331,39 @@ template nsFileBufferT::int_type nsFileBufferT::overflow(int_type c) //---------------------------------------------------------------------------------------- { -#ifdef NS_EXPLICIT_FUNC_TEMPLATE_ARG - const ofacet_type& ft=use_facet(loc); +#ifdef NS_EXPLICIT_FUNC_TEMPLATE_ARG + const ofacet_type& ft=use_facet(loc); #else - const ofacet_type& ft=use_facet(loc, (ofacet_type*)0); + const ofacet_type& ft=use_facet(loc, (ofacet_type*)0); #endif - char_type ch = traits_type::to_char_type(c); - if (!mFileDesc) - return traits_type::eof(); - if (traits_type::eq_int_type(c, traits::eof())) - return traits_type::not_eof(c); - if (ft.always_noconv()) - { - PRInt32 bytesWrit1 = PR_Write(mFileDesc, &ch, sizeof(ch)); - return bytesWrit1 < sizeof(ch) ? traits::eof() : c; - } - { // <- sic! - state_type fst; - const char_type* end; - char buf[4]; - char* ebuf; - result conv; - if ((conv=ft.out(fst, &ch, &ch+1, end, buf, buf+3, ebuf))== - codecvt_base::noconv) - { - PRInt32 bytesWrit2 = PR_Write(mFileDesc, &ch, sizeof(ch)); - return bytesWrit2 < sizeof(ch) ? traits::eof() : c; - } - if ((conv==codecvt_base::partial)||(conv==codecvt_base::error)) - return traits::eof(); - *ebuf=0; - PRInt32 bytesWrit3 = strlen(buf); - return PR_Write(mFileDesc, buf, bytesWrit3) < bytesWrit3 ? traits_type::eof() : c; - } + char_type ch = traits_type::to_char_type(c); + if (!mFileDesc) + return traits_type::eof(); + if (traits_type::eq_int_type(c, traits::eof())) + return traits_type::not_eof(c); + if (ft.always_noconv()) + { + PRInt32 bytesWrit1 = PR_Write(mFileDesc, &ch, sizeof(ch)); + return bytesWrit1 < sizeof(ch) ? traits::eof() : c; + } + { // <- sic! + state_type fst; + const char_type* end; + char buf[4]; + char* ebuf; + result conv; + if ((conv=ft.out(fst, &ch, &ch+1, end, buf, buf+3, ebuf))== + codecvt_base::noconv) + { + PRInt32 bytesWrit2 = PR_Write(mFileDesc, &ch, sizeof(ch)); + return bytesWrit2 < sizeof(ch) ? traits::eof() : c; + } + if ((conv==codecvt_base::partial)||(conv==codecvt_base::error)) + return traits::eof(); + *ebuf=0; + PRInt32 bytesWrit3 = strlen(buf); + return PR_Write(mFileDesc, buf, bytesWrit3) < bytesWrit3 ? traits_type::eof() : c; + } } //---------------------------------------------------------------------------------------- @@ -327,14 +371,14 @@ template inline nsFileBufferT::int_type nsFileBufferT::underflow() //---------------------------------------------------------------------------------------- { - if (!mFileDesc) - return traits_type::eof(); - char_type s; - PRInt32 request = 1; - if (1 != PR_Read(mFileDesc, &s, request)) - return traits_type::eof(); - PR_Seek(mFileDesc, -1, PR_SEEK_CUR); - return (int_type)s; + if (!mFileDesc) + return traits_type::eof(); + char_type s; + PRInt32 request = 1; + if (1 != PR_Read(mFileDesc, &s, request)) + return traits_type::eof(); + PR_Seek(mFileDesc, -1, PR_SEEK_CUR); + return (int_type)s; } //---------------------------------------------------------------------------------------- @@ -343,51 +387,51 @@ streamsize nsFileBufferT::xsputn(const char_type* s, streamsize n //---------------------------------------------------------------------------------------- { #ifdef NS_EXPLICIT_FUNC_TEMPLATE_ARG - const ofacet_type& ft=use_facet(loc); + const ofacet_type& ft=use_facet(loc); #else - const ofacet_type& ft=use_facet(loc, (ofacet_type*)0); + const ofacet_type& ft=use_facet(loc, (ofacet_type*)0); #endif - if (!mFileDesc || !n) - return 0; - if (ft.always_noconv()) - { - PRInt32 bytesWrit1 = PR_Write(mFileDesc, s, sizeof(char) * size_t(n)); - return bytesWrit1 < 0 ? 0 : (streamsize)bytesWrit1; - } - { // <- sic! - state_type fst; - const char_type* end; - char buf[8]; - char* ebuf; - result conv; -#ifdef NS_EXPLICIT_FUNC_TEMPLATE_ARG - if ((conv=use_facet(loc). - out(fst, s, s+n, end, buf, buf+7, ebuf))==codecvt_base::noconv) + if (!mFileDesc || !n) + return 0; + if (ft.always_noconv()) + { + PRInt32 bytesWrit1 = PR_Write(mFileDesc, s, sizeof(char) * size_t(n)); + return bytesWrit1 < 0 ? 0 : (streamsize)bytesWrit1; + } + { // <- sic! + state_type fst; + const char_type* end; + char buf[8]; + char* ebuf; + result conv; +#ifdef NS_EXPLICIT_FUNC_TEMPLATE_ARG + if ((conv=use_facet(loc). + out(fst, s, s+n, end, buf, buf+7, ebuf))==codecvt_base::noconv) #else - if ((conv=use_facet(loc, (ofacet_type*)0). - out(fst, s, s+n, end, buf, buf+7, ebuf))==codecvt_base::noconv) + if ((conv=use_facet(loc, (ofacet_type*)0). + out(fst, s, s+n, end, buf, buf+7, ebuf))==codecvt_base::noconv) #endif - return (streamsize)PR_Write(mFileDesc, s, sizeof(char) * size_t(n)); - if ((conv==codecvt_base::partial) ||(conv==codecvt_base::error)) - return 0; - *ebuf=0; - PRInt32 bytesWrit2 = strlen(buf); - bytesWrit2 = PR_Write(mFileDesc, buf, bytesWrit2); - return bytesWrit2 < 0 ? 0 : streamsize(bytesWrit2 / sizeof(char_type)); - } + return (streamsize)PR_Write(mFileDesc, s, sizeof(char) * size_t(n)); + if ((conv==codecvt_base::partial) ||(conv==codecvt_base::error)) + return 0; + *ebuf=0; + PRInt32 bytesWrit2 = strlen(buf); + bytesWrit2 = PR_Write(mFileDesc, buf, bytesWrit2); + return bytesWrit2 < 0 ? 0 : streamsize(bytesWrit2 / sizeof(char_type)); + } } //---------------------------------------------------------------------------------------- template inline nsFileBufferT::int_type - nsFileBufferT::pbackfail(int_type c) + nsFileBufferT::pbackfail(int_type c) //---------------------------------------------------------------------------------------- { - if (!mFileDesc) - return traits_type::eof(); - if (PR_Seek(mFileDesc, -1, PR_SEEK_CUR) < 0) - return traits_type::eof(); - return (traits::eq_int_type(c, traits_type::eof())) ? traits::not_eof(c) : c; + if (!mFileDesc) + return traits_type::eof(); + if (PR_Seek(mFileDesc, -1, PR_SEEK_CUR) < 0) + return traits_type::eof(); + return (traits::eq_int_type(c, traits_type::eof())) ? traits::not_eof(c) : c; } //---------------------------------------------------------------------------------------- @@ -395,12 +439,12 @@ template inline nsFileBufferT::int_type nsFileBufferT::uflow() //---------------------------------------------------------------------------------------- { - if (!mFileDesc) - return traits_type::eof(); - char_type s; - if (1 != PR_Read(mFileDesc, &s, 1)) // attempt to read 1 byte, confirm 1 byte - return traits_type::eof(); - return (int_type)s; + if (!mFileDesc) + return traits_type::eof(); + char_type s; + if (1 != PR_Read(mFileDesc, &s, 1)) // attempt to read 1 byte, confirm 1 byte + return traits_type::eof(); + return (int_type)s; } //---------------------------------------------------------------------------------------- @@ -408,7 +452,7 @@ template inline streamsize nsFileBufferT::xsgetn(char_type* s, streamsize n) //---------------------------------------------------------------------------------------- { - return mFileDesc ? (streamsize)PR_Read(mFileDesc, s, sizeof(char) * size_t(n)) : 0; + return mFileDesc ? (streamsize)PR_Read(mFileDesc, s, sizeof(char) * size_t(n)) : 0; } //---------------------------------------------------------------------------------------- @@ -416,38 +460,38 @@ template inline void nsFileBufferT::imbue(const locale& loc_arg) //---------------------------------------------------------------------------------------- { - loc = loc_arg; + loc = loc_arg; } template inline streamsize nsFileBufferT::showmanyc() { - return (streamsize)PR_Available(mFileDesc); + return (streamsize)PR_Available(mFileDesc); } //---------------------------------------------------------------------------------------- template nsFileBufferT::pos_type nsFileBufferT::seekoff( - off_type off, - ios_base::seekdir way, - ios_base::openmode /* which */) + off_type off, + ios_base::seekdir way, + ios_base::openmode /* which */) //---------------------------------------------------------------------------------------- { - if (!mFileDesc || ((way&ios_base::beg) && off<0) || ((way&ios_base::end) && off > 0)) - return pos_type(-1); - PRSeekWhence poseek = PR_SEEK_CUR; - switch (way) - { - case ios_base::beg : poseek= PR_SEEK_SET; - break; - case ios_base::end : poseek= PR_SEEK_END; - break; - } - PRInt32 position = PR_Seek(mFileDesc, off, poseek); - if (position < 0) - return pos_type(-1); - return pos_type(position); + if (!mFileDesc || ((way&ios_base::beg) && off<0) || ((way&ios_base::end) && off > 0)) + return pos_type(-1); + PRSeekWhence poseek = PR_SEEK_CUR; + switch (way) + { + case ios_base::beg : poseek= PR_SEEK_SET; + break; + case ios_base::end : poseek= PR_SEEK_END; + break; + } + PRInt32 position = PR_Seek(mFileDesc, off, poseek); + if (position < 0) + return pos_type(-1); + return pos_type(position); } //---------------------------------------------------------------------------------------- @@ -456,39 +500,39 @@ nsFileBufferT::pos_type nsFileBufferT::seekpos(pos_type sp, ios_base::openmode) //---------------------------------------------------------------------------------------- { - if (!mFileDesc || sp==pos_type(-1)) - return -1; - PRInt32 position = PR_Seek(mFileDesc, sp.offset(), PR_SEEK_SET); - if (position < 0) - return pos_type(-1); - return position; + if (!mFileDesc || sp==pos_type(-1)) + return -1; + PRInt32 position = PR_Seek(mFileDesc, sp.offset(), PR_SEEK_SET); + if (position < 0) + return pos_type(-1); + return position; } //======================================================================================== -// Implementation of nsInputFileStreamT +// Implementation of nsInputFileStreamT //======================================================================================== //---------------------------------------------------------------------------------------- template inline nsInputFileStreamT::nsInputFileStreamT() - : basic_istream(&mBuffer) + : basic_istream(&mBuffer) //---------------------------------------------------------------------------------------- { - // already inited + // already inited } //---------------------------------------------------------------------------------------- template inline nsInputFileStreamT::nsInputFileStreamT( - const nsUnixFilePath& inFile, + const nsFilePath& inFile, ios_base::openmode mode, PRIntn accessMode) //---------------------------------------------------------------------------------------- - : basic_istream(&mBuffer) + : basic_istream(&mBuffer) { - // already inited + // already inited if (!mBuffer.open(inFile, openmode(mode|in), accessMode)) - setstate(failbit); + setstate(failbit); } //---------------------------------------------------------------------------------------- @@ -520,13 +564,13 @@ nsInputFileStreamT:: is_open() template inline void nsInputFileStreamT::open( - const nsUnixFilePath& inFile, - ios_base::openmode mode, - PRIntn accessMode) + const nsFilePath& inFile, + ios_base::openmode mode, + PRIntn accessMode) //---------------------------------------------------------------------------------------- { if (!mBuffer.open(inFile, openmode(mode|in), accessMode)) - setstate(failbit); + setstate(failbit); } //---------------------------------------------------------------------------------------- @@ -535,34 +579,34 @@ inline void nsInputFileStreamT::close() //---------------------------------------------------------------------------------------- { if (!mBuffer.close()) - setstate(failbit); + setstate(failbit); } //======================================================================================== -// Implementation of nsOutputFileStreamT +// Implementation of nsOutputFileStreamT //======================================================================================== //---------------------------------------------------------------------------------------- template inline nsOutputFileStreamT::nsOutputFileStreamT() - : basic_ostream(&mBuffer) + : basic_ostream(&mBuffer) //---------------------------------------------------------------------------------------- { - // already inited + // already inited } //---------------------------------------------------------------------------------------- template nsOutputFileStreamT::nsOutputFileStreamT( - const nsUnixFilePath& inFile, + const nsFilePath& inFile, ios_base::openmode mode, PRIntn accessMode) //---------------------------------------------------------------------------------------- : basic_ostream(&mBuffer) { - // already inited + // already inited if (!mBuffer.open(inFile, openmode(mode|out), accessMode)) - setstate(failbit); + setstate(failbit); } //---------------------------------------------------------------------------------------- @@ -592,13 +636,13 @@ inline bool nsOutputFileStreamT:: is_open() //---------------------------------------------------------------------------------------- template inline void nsOutputFileStreamT::open( - const nsUnixFilePath& inFile, - ios_base::openmode mode, - PRIntn accessMode) + const nsFilePath& inFile, + ios_base::openmode mode, + PRIntn accessMode) //---------------------------------------------------------------------------------------- { if (!mBuffer.open(inFile, openmode(mode | out), accessMode)) - setstate(failbit); + setstate(failbit); } //---------------------------------------------------------------------------------------- @@ -607,7 +651,7 @@ inline void nsOutputFileStreamT:: close() //---------------------------------------------------------------------------------------- { if (!mBuffer.close()) - setstate(failbit); + setstate(failbit); } //======================================================================================== @@ -618,57 +662,57 @@ class nsIOFileStreamT : public basic_iostream typedef nsFileBufferT filebuf_type; public: - typedef charT char_type; + typedef charT char_type; typedef typename traits::pos_type pos_type; typedef typename traits::off_type off_type; typedef typename traits::int_type int_type; - typedef traits traits_type; + typedef traits traits_type; - nsIOFileStreamT(); - explicit nsIOFileStreamT( - const nsUnixFilePath& inFile, - ios_base::openmode mode = ios_base::in|ios_base::out, - PRIntn accessMode = 0x00600); + nsIOFileStreamT(); + explicit nsIOFileStreamT( + const nsFilePath& inFile, + ios_base::openmode mode = ios_base::in|ios_base::out, + PRIntn accessMode = 0x00600); - virtual ~nsIOFileStreamT(); + virtual ~nsIOFileStreamT(); - filebuf_type* rdbuf() const; - inline bool is_open(); - inline void open( - const nsUnixFilePath& inFile, - ios_base::openmode mode = ios_base::in|ios_base::out, - PRIntn accessMode = 0x00600); - inline void close(); + filebuf_type* rdbuf() const; + inline bool is_open(); + inline void open( + const nsFilePath& inFile, + ios_base::openmode mode = ios_base::in|ios_base::out, + PRIntn accessMode = 0x00600); + inline void close(); private: - filebuf_type mBuffer; + filebuf_type mBuffer; }; // class nsIOFileStreamT //======================================================================================== -// Implementation of nsIOFileStream +// Implementation of nsIOFileStream //======================================================================================== //---------------------------------------------------------------------------------------- template inline nsIOFileStreamT::nsIOFileStreamT() //---------------------------------------------------------------------------------------- - : mBuffer(), basic_iostream(&mBuffer) + : mBuffer(), basic_iostream(&mBuffer) { - // already inited + // already inited } //---------------------------------------------------------------------------------------- template inline nsIOFileStreamT::nsIOFileStreamT( - const nsUnixFilePath& inFile, + const nsFilePath& inFile, ios_base::openmode mode, PRIntn accessMode) //---------------------------------------------------------------------------------------- - : mBuffer(), basic_iostream(&mBuffer) + : mBuffer(), basic_iostream(&mBuffer) { - // already inited + // already inited if (!mBuffer.open(inFile, mode, accessMode)) - setstate(failbit); + setstate(failbit); } template @@ -698,13 +742,13 @@ nsIOFileStreamT::is_open() template inline void nsIOFileStreamT::open( - const nsUnixFilePath& inFile, - ios_base::openmode mode, - PRIntn accessMode) + const nsFilePath& inFile, + ios_base::openmode mode, + PRIntn accessMode) //---------------------------------------------------------------------------------------- { if (!mBuffer.open(inFile, mode, accessMode)) - setstate(failbit); + setstate(failbit); } //---------------------------------------------------------------------------------------- @@ -714,11 +758,11 @@ nsIOFileStreamT::close() //---------------------------------------------------------------------------------------- { if (!mBuffer.close()) - setstate(failbit); + setstate(failbit); } //======================================================================================== -// Specializations of the stream templates +// Specializations of the stream templates //======================================================================================== typedef nsFileBufferT > nsFileBuffer; @@ -733,5 +777,5 @@ typedef nsOutputFileStreamT > nsWideOutputFileStre typedef nsIOFileStreamT > nsWideIOFileStream; #endif // NS_USING_WIDE_CHAR -#endif /* _STREAM_H_ */ +#endif /* _FILESTREAM_H_ */ diff --git a/mozilla/base/src/mac/nsFileSpecMac.cpp b/mozilla/base/src/mac/nsFileSpecMac.cpp index b2a5930b0ee..3e0dbffae3f 100644 --- a/mozilla/base/src/mac/nsFileSpecMac.cpp +++ b/mozilla/base/src/mac/nsFileSpecMac.cpp @@ -459,6 +459,8 @@ nsNativeFileSpec::nsNativeFileSpec(const std::string& inString) //---------------------------------------------------------------------------------------- { mError = MacFileHelpers::FSSpecFromFullUnixPath(inString.c_str(), mSpec, true); + if (mError == fnfErr) + mError = noErr; } // nsNativeFileSpec::nsNativeFileSpec //---------------------------------------------------------------------------------------- @@ -474,7 +476,7 @@ nsNativeFileSpec::nsNativeFileSpec( } //---------------------------------------------------------------------------------------- -nsNativeFileSpec::nsNativeFileSpec(const nsUnixFilePath& inPath) +nsNativeFileSpec::nsNativeFileSpec(const nsFilePath& inPath) //---------------------------------------------------------------------------------------- { *this = inPath.GetNativeSpec(); @@ -508,7 +510,7 @@ void nsNativeFileSpec::operator = (const nsNativeFileSpec& inSpec) } // nsNativeFileSpec::operator = //---------------------------------------------------------------------------------------- -void nsNativeFileSpec::operator = (const nsUnixFilePath& inPath) +void nsNativeFileSpec::operator = (const nsFilePath& inPath) //---------------------------------------------------------------------------------------- { mSpec = inPath.GetNativeSpec(); @@ -541,11 +543,11 @@ std::string nsNativeFileSpec::GetLeafName() const } // nsNativeFileSpec::GetLeafName //======================================================================================== -// Macintosh nsUnixFilePath implementation +// Macintosh nsFilePath implementation //======================================================================================== //---------------------------------------------------------------------------------------- -nsUnixFilePath::nsUnixFilePath(const nsNativeFileSpec& inSpec) +nsFilePath::nsFilePath(const nsNativeFileSpec& inSpec) //---------------------------------------------------------------------------------------- #ifdef XP_MAC : mNativeFileSpec(inSpec) @@ -558,7 +560,7 @@ nsUnixFilePath::nsUnixFilePath(const nsNativeFileSpec& inSpec) } //---------------------------------------------------------------------------------------- -void nsUnixFilePath::operator = (const nsNativeFileSpec& inSpec) +void nsFilePath::operator = (const nsNativeFileSpec& inSpec) //---------------------------------------------------------------------------------------- { char * path = MacFileHelpers::PathNameFromFSSpec( inSpec.mSpec, TRUE ); @@ -568,4 +570,4 @@ void nsUnixFilePath::operator = (const nsNativeFileSpec& inSpec) #ifdef XP_MAC mNativeFileSpec = inSpec; #endif -} // nsUnixFilePath::operator = +} // nsFilePath::operator = diff --git a/mozilla/base/src/nsFileSpec.cpp b/mozilla/base/src/nsFileSpec.cpp index f13554bd62e..dfb71190bcb 100644 --- a/mozilla/base/src/nsFileSpec.cpp +++ b/mozilla/base/src/nsFileSpec.cpp @@ -125,7 +125,7 @@ void nsFileURL::operator = (const nsFileURL& inOther) } //---------------------------------------------------------------------------------------- -nsFileURL::nsFileURL(const nsUnixFilePath& inOther) +nsFileURL::nsFileURL(const nsFilePath& inOther) //---------------------------------------------------------------------------------------- { mURL = kFileURLPrefix + ((string&)inOther); @@ -134,7 +134,7 @@ nsFileURL::nsFileURL(const nsUnixFilePath& inOther) #endif } //---------------------------------------------------------------------------------------- -void nsFileURL::operator = (const nsUnixFilePath& inOther) +void nsFileURL::operator = (const nsFilePath& inOther) //---------------------------------------------------------------------------------------- { mURL = kFileURLPrefix + ((string&)inOther); @@ -147,7 +147,7 @@ void nsFileURL::operator = (const nsUnixFilePath& inOther) nsFileURL::nsFileURL(const nsNativeFileSpec& inOther) //---------------------------------------------------------------------------------------- { - mURL = kFileURLPrefix + (std::string&)nsUnixFilePath(inOther); + mURL = kFileURLPrefix + (std::string&)nsFilePath(inOther); #ifdef XP_MAC mNativeFileSpec = inOther; #endif @@ -156,18 +156,18 @@ nsFileURL::nsFileURL(const nsNativeFileSpec& inOther) void nsFileURL::operator = (const nsNativeFileSpec& inOther) //---------------------------------------------------------------------------------------- { - mURL = kFileURLPrefix + (std::string&)nsUnixFilePath(inOther); + mURL = kFileURLPrefix + (std::string&)nsFilePath(inOther); #ifdef XP_MAC mNativeFileSpec = inOther; #endif } //======================================================================================== -// nsUnixFilePath implementation +// nsFilePath implementation //======================================================================================== //---------------------------------------------------------------------------------------- -nsUnixFilePath::nsUnixFilePath(const std::string& inString) +nsFilePath::nsFilePath(const std::string& inString) //---------------------------------------------------------------------------------------- : mPath(inString) #ifdef XP_MAC @@ -178,7 +178,7 @@ nsUnixFilePath::nsUnixFilePath(const std::string& inString) } //---------------------------------------------------------------------------------------- -nsUnixFilePath::nsUnixFilePath(const nsFileURL& inOther) +nsFilePath::nsFilePath(const nsFileURL& inOther) //---------------------------------------------------------------------------------------- : mPath(((string&)inOther).substr( kFileURLPrefixLength, ((string&)inOther).length() - kFileURLPrefixLength)) @@ -189,7 +189,7 @@ nsUnixFilePath::nsUnixFilePath(const nsFileURL& inOther) } //---------------------------------------------------------------------------------------- -void nsUnixFilePath::operator = (const std::string& inString) +void nsFilePath::operator = (const std::string& inString) //---------------------------------------------------------------------------------------- { mPath = inString; @@ -200,7 +200,7 @@ void nsUnixFilePath::operator = (const std::string& inString) } //---------------------------------------------------------------------------------------- -void nsUnixFilePath::operator = (const nsFileURL& inOther) +void nsFilePath::operator = (const nsFileURL& inOther) //---------------------------------------------------------------------------------------- { mPath = ((string&)inOther).substr( diff --git a/mozilla/base/src/unix/nsFileSpecUnix.cpp b/mozilla/base/src/unix/nsFileSpecUnix.cpp index 8680b1fec90..adaa4acac92 100644 --- a/mozilla/base/src/unix/nsFileSpecUnix.cpp +++ b/mozilla/base/src/unix/nsFileSpecUnix.cpp @@ -16,7 +16,7 @@ * Reserved. */ -// This file is included by nsFile.cpp, and includes the Unix-specific +// This file is included by nsFileSpec.cpp, and includes the Unix-specific // implementations. //---------------------------------------------------------------------------------------- diff --git a/mozilla/base/src/windows/nsFileSpecWin.cpp b/mozilla/base/src/windows/nsFileSpecWin.cpp index 4192593dbbb..fcc07645843 100644 --- a/mozilla/base/src/windows/nsFileSpecWin.cpp +++ b/mozilla/base/src/windows/nsFileSpecWin.cpp @@ -16,18 +16,18 @@ * Reserved. */ -// This file is included by nsFile.cp, and includes the Windows-specific +// This file is included by nsFileSpec.cp, and includes the Windows-specific // implementations. //---------------------------------------------------------------------------------------- -nsNativeFileSpec::nsNativeFileSpec(const nsUnixFilePath& inPath) +nsNativeFileSpec::nsNativeFileSpec(const nsFilePath& inPath) //---------------------------------------------------------------------------------------- { *this = inPath; } //---------------------------------------------------------------------------------------- -void nsNativeFileSpec::operator = (const nsUnixFilePath& inPath) +void nsNativeFileSpec::operator = (const nsFilePath& inPath) //---------------------------------------------------------------------------------------- { // Convert '/' to '\' diff --git a/mozilla/base/tests/FilesTest.cpp b/mozilla/base/tests/FilesTest.cpp index 4563b2cd924..17cf4af4a31 100644 --- a/mozilla/base/tests/FilesTest.cpp +++ b/mozilla/base/tests/FilesTest.cpp @@ -17,7 +17,7 @@ void FileTest::WriteStuff(ostream& s) s << "File URL initialized to: \"" << (string&)fileURL << "\""<< endl; // Initialize a Unix path from a URL - nsUnixFilePath filePath(fileURL); + nsFilePath filePath(fileURL); s << "As a unix path: \"" << (string&)filePath << "\""<< endl; // Initialize a native file spec from a URL @@ -62,21 +62,25 @@ void main() // Test of nsOutputFileStream - nsUnixFilePath myTextFilePath("/Development/iotest.txt"); + nsFilePath myTextFilePath("/Development/iotest.txt"); + + { + cout << "WRITING IDENTICAL OUTPUT TO " << myTextFilePath << endl << endl; + nsOutputFileStream testStream(myTextFilePath); + FileTest::WriteStuff(testStream); + } // <-- Scope closes the stream (and the file). - cout << "WRITING IDENTICAL OUTPUT TO " << myTextFilePath << endl << endl; - nsOutputFileStream testStream(myTextFilePath); - FileTest::WriteStuff(testStream); - // Test of nsInputFileStream - cout << "READING BACK DATA FROM " << myTextFilePath << endl << endl; - nsInputFileStream testStream2(myTextFilePath); - char line[1000]; - while (!testStream2.eof()) { - testStream2.getline(line, sizeof(line), '\n'); - cout << line << endl; + cout << "READING BACK DATA FROM " << myTextFilePath << endl << endl; + nsInputFileStream testStream2(myTextFilePath); + char line[1000]; + while (!testStream2.eof()) + { + testStream2.getline(line, sizeof(line), '\n'); + cout << line << endl; + } } } // main diff --git a/mozilla/xpcom/io/nsFileSpec.cpp b/mozilla/xpcom/io/nsFileSpec.cpp index f13554bd62e..dfb71190bcb 100644 --- a/mozilla/xpcom/io/nsFileSpec.cpp +++ b/mozilla/xpcom/io/nsFileSpec.cpp @@ -125,7 +125,7 @@ void nsFileURL::operator = (const nsFileURL& inOther) } //---------------------------------------------------------------------------------------- -nsFileURL::nsFileURL(const nsUnixFilePath& inOther) +nsFileURL::nsFileURL(const nsFilePath& inOther) //---------------------------------------------------------------------------------------- { mURL = kFileURLPrefix + ((string&)inOther); @@ -134,7 +134,7 @@ nsFileURL::nsFileURL(const nsUnixFilePath& inOther) #endif } //---------------------------------------------------------------------------------------- -void nsFileURL::operator = (const nsUnixFilePath& inOther) +void nsFileURL::operator = (const nsFilePath& inOther) //---------------------------------------------------------------------------------------- { mURL = kFileURLPrefix + ((string&)inOther); @@ -147,7 +147,7 @@ void nsFileURL::operator = (const nsUnixFilePath& inOther) nsFileURL::nsFileURL(const nsNativeFileSpec& inOther) //---------------------------------------------------------------------------------------- { - mURL = kFileURLPrefix + (std::string&)nsUnixFilePath(inOther); + mURL = kFileURLPrefix + (std::string&)nsFilePath(inOther); #ifdef XP_MAC mNativeFileSpec = inOther; #endif @@ -156,18 +156,18 @@ nsFileURL::nsFileURL(const nsNativeFileSpec& inOther) void nsFileURL::operator = (const nsNativeFileSpec& inOther) //---------------------------------------------------------------------------------------- { - mURL = kFileURLPrefix + (std::string&)nsUnixFilePath(inOther); + mURL = kFileURLPrefix + (std::string&)nsFilePath(inOther); #ifdef XP_MAC mNativeFileSpec = inOther; #endif } //======================================================================================== -// nsUnixFilePath implementation +// nsFilePath implementation //======================================================================================== //---------------------------------------------------------------------------------------- -nsUnixFilePath::nsUnixFilePath(const std::string& inString) +nsFilePath::nsFilePath(const std::string& inString) //---------------------------------------------------------------------------------------- : mPath(inString) #ifdef XP_MAC @@ -178,7 +178,7 @@ nsUnixFilePath::nsUnixFilePath(const std::string& inString) } //---------------------------------------------------------------------------------------- -nsUnixFilePath::nsUnixFilePath(const nsFileURL& inOther) +nsFilePath::nsFilePath(const nsFileURL& inOther) //---------------------------------------------------------------------------------------- : mPath(((string&)inOther).substr( kFileURLPrefixLength, ((string&)inOther).length() - kFileURLPrefixLength)) @@ -189,7 +189,7 @@ nsUnixFilePath::nsUnixFilePath(const nsFileURL& inOther) } //---------------------------------------------------------------------------------------- -void nsUnixFilePath::operator = (const std::string& inString) +void nsFilePath::operator = (const std::string& inString) //---------------------------------------------------------------------------------------- { mPath = inString; @@ -200,7 +200,7 @@ void nsUnixFilePath::operator = (const std::string& inString) } //---------------------------------------------------------------------------------------- -void nsUnixFilePath::operator = (const nsFileURL& inOther) +void nsFilePath::operator = (const nsFileURL& inOther) //---------------------------------------------------------------------------------------- { mPath = ((string&)inOther).substr( diff --git a/mozilla/xpcom/io/nsFileSpec.h b/mozilla/xpcom/io/nsFileSpec.h index 2c12feda22d..53bee8a9b10 100644 --- a/mozilla/xpcom/io/nsFileSpec.h +++ b/mozilla/xpcom/io/nsFileSpec.h @@ -16,29 +16,93 @@ * Reserved. */ -// First checked in on 98/11/20 by John R. McMullen. Checked in again 98/12/04. +// First checked in on 98/11/20 by John R. McMullen in the wrong directory. +// Checked in again 98/12/04. +// Polished version 98/12/08. + +//======================================================================================== +// +// Classes defined: +// +// nsFilePath, nsFileURL, nsNativeFileSpec. +// +// This suite provides the following services: +// +// 1. Encapsulates all platform-specific file details, so that files can be +// described correctly without any platform #ifdefs +// +// 2. Type safety. This will fix the problems that used to occur because people +// confused file paths. They used to use const char*, which could mean three +// or four different things. Bugs were introduced as people coded, right up +// to the moment Communicator 4.5 shipped. +// +// 3. Used in conjunction with nsFileStream.h (q.v.), this supports all the power +// and readability of the ansi stream syntax. ALL METHODS OF istream, ostream, +// AND iostream ARE AVAILABLE! +// +// Basic example: +// +// nsFilePath myPath("/Development/iotest.txt"); +// +// nsOutputFileStream testStream(myPath); +// testStream << "Hello World" << endl; +// +// 4. Handy methods for manipulating file specifiers safely, e.g. MakeUnique(), +// SetLeafName(), Exists(). +// +// 5. Easy cross-conversion. +// +// Examples: +// +// Initialize a URL from a string without suffix +// +// nsFileURL fileURL("file:///Development/MPW/MPW%20Shell"); +// +// Initialize a Unix path from a URL +// +// nsFilePath filePath(fileURL); +// +// Initialize a native file spec from a URL +// +// nsNativeFileSpec fileSpec(fileURL); +// +// Make the spec unique (this one has no suffix). +// +// fileSpec.MakeUnique(); +// +// Assign the spec to a URL +// +// fileURL = fileSpec; +// +// Assign a unix path using a string with a suffix. +// +// filePath = "/Development/MPW/SysErrs.err"; +// +// Assign to a file spec using a unix path. +// +// fileSpec = filePath; +// +// Make this unique (this one has a suffix). +// +// fileSpec.MakeUnique(); +// +// 6. Fixes a bug that have been there for a long time, and +// is inevitable if you use NSPR alone, where files are described as paths. +// +// The problem affects platforms (Macintosh) in which a path does not fully +// specify a file, because two volumes can have the same name. This +// is solved by holding a "private" native file spec inside the +// nsFilePath and nsFileURL classes, which is used when appropriate. +// +// Not yet done: +// +// Equality operators... much more. +// +//======================================================================================== #ifndef _FILESPEC_H_ #define _FILESPEC_H_ -//======================================================================================== -// This is intended to be part of the API for all C++ in the mozilla code base from now on. -// It provides -// * Type-safe ways of describing files (no more char* parameters) -// * Conversions between these -// * Methods for testing existence and for forcing uniqueness. -// -// A file specification can come from two outside sources: -// 1. A file:// URL, or -// 2. A native spec (such as an OS-based save/open dialog and the like). -// Therefore, these are the only ingredients one can use to make a file specification. -// -// Once one of our spec types has been made, conversions are provided between them -// -// In addition, string accessors are provided, because people like to manipulate -// nsFileURL and nsUnixFilePath strings directly. -//======================================================================================== - #include #include "nsDebug.h" #ifdef XP_MAC @@ -49,7 +113,7 @@ // Here are the allowable ways to describe a file. //======================================================================================== -class nsUnixFilePath; // This can be passed to NSPR file I/O routines. +class nsFilePath; // This can be passed to NSPR file I/O routines. class nsFileURL; class nsNativeFileSpec; @@ -58,202 +122,202 @@ class nsNativeFileSpec; //======================================================================================== class nsNativeFileSpec -// This is whatever each platform really prefers to describe files as. +// This is whatever each platform really prefers to describe files as. Declared first +// because the other two types have an embeded nsNativeFileSpec object. //======================================================================================== { - public: - nsNativeFileSpec(); - nsNativeFileSpec(const std::string& inString); - nsNativeFileSpec(const nsUnixFilePath& inPath); - nsNativeFileSpec(const nsFileURL& inURL); - nsNativeFileSpec(const nsNativeFileSpec& inPath); + public: + nsNativeFileSpec(); + explicit nsNativeFileSpec(const std::string& inString); + nsNativeFileSpec(const nsFilePath& inPath); + nsNativeFileSpec(const nsFileURL& inURL); + nsNativeFileSpec(const nsNativeFileSpec& inPath); - void operator = (const std::string& inPath); - void operator = (const nsUnixFilePath& inPath); - void operator = (const nsFileURL& inURL); - void operator = (const nsNativeFileSpec& inOther); + void operator = (const std::string& inPath); + void operator = (const nsFilePath& inPath); + void operator = (const nsFileURL& inURL); + void operator = (const nsNativeFileSpec& inOther); #ifdef XP_MAC - // For Macintosh people, this is meant to be useful in its own right as a C++ version - // of the FSSPec class. - nsNativeFileSpec( - short vRefNum, - long parID, - ConstStr255Param name); - nsNativeFileSpec(const FSSpec& inSpec) - : mSpec(inSpec), mError(noErr) {} + // For Macintosh people, this is meant to be useful in its own right as a C++ version + // of the FSSPec class. + nsNativeFileSpec( + short vRefNum, + long parID, + ConstStr255Param name); + nsNativeFileSpec(const FSSpec& inSpec) + : mSpec(inSpec), mError(noErr) {} - operator FSSpec* () { return &mSpec; } - operator const FSSpec* const () { return &mSpec; } - operator FSSpec& () { return mSpec; } - operator const FSSpec& () const { return mSpec; } - bool Valid() const { return mError == noErr; } - OSErr Error() const { return mError; } - void MakeUnique(ConstStr255Param inSuggestedLeafName); - StringPtr GetLeafPName() { return mSpec.name; } - ConstStr255Param GetLeafPName() const { return mSpec.name; } + operator FSSpec* () { return &mSpec; } + operator const FSSpec* const () { return &mSpec; } + operator FSSpec& () { return mSpec; } + operator const FSSpec& () const { return mSpec; } + bool Valid() const { return mError == noErr; } + OSErr Error() const { return mError; } + void MakeUnique(ConstStr255Param inSuggestedLeafName); + StringPtr GetLeafPName() { return mSpec.name; } + ConstStr255Param GetLeafPName() const { return mSpec.name; } #else - bool Valid() const { return TRUE; } // Fixme. + bool Valid() const { return TRUE; } // Fixme. #endif #if DEBUG - friend ostream& operator << (ostream& s, const nsNativeFileSpec& spec); + friend ostream& operator << (ostream& s, const nsNativeFileSpec& spec); #endif - string GetLeafName() const; - void SetLeafName(const std::string& inLeafName); - bool Exists() const; - void MakeUnique(); - void MakeUnique(const std::string& inSuggestedLeafName); - - private: - friend class nsUnixFilePath; + string GetLeafName() const; + void SetLeafName(const std::string& inLeafName); + bool Exists() const; + void MakeUnique(); + void MakeUnique(const std::string& inSuggestedLeafName); + + private: + friend class nsFilePath; #ifdef XP_MAC - FSSpec mSpec; - OSErr mError; + FSSpec mSpec; + OSErr mError; #elif defined(XP_UNIX) || defined(XP_WIN) - std::string mPath; + std::string mPath; #endif }; // class nsNativeFileSpec //======================================================================================== class nsFileURL -// This is an escaped string that looks like "file:///foo/bar/mumble%20fish". Since URLs -// are the standard way of doing things in mozilla, this allows a string constructor, -// which just stashes the string with no conversion. +// This is an escaped string that looks like "file:///foo/bar/mumble%20fish". Since URLs +// are the standard way of doing things in mozilla, this allows a string constructor, +// which just stashes the string with no conversion. //======================================================================================== { - public: - nsFileURL(const nsFileURL& inURL); - nsFileURL(const std::string& inString); - nsFileURL(const nsUnixFilePath& inPath); - nsFileURL(const nsNativeFileSpec& inPath); - - operator std::string& () { return mURL; } - // This is the only automatic conversion to string - // that is provided, because a naked string should - // only mean a file URL. + public: + nsFileURL(const nsFileURL& inURL); + explicit nsFileURL(const std::string& inString); + nsFileURL(const nsFilePath& inPath); + nsFileURL(const nsNativeFileSpec& inPath); -// std::string GetString() const { return mPath; } - // may be needed for implementation reasons, - // but should not provide a conversion constructor. +// std::string GetString() const { return mPath; } + // may be needed for implementation reasons, + // but should not provide a conversion constructor. - void operator = (const nsFileURL& inURL); - void operator = (const std::string& inString); - void operator = (const nsUnixFilePath& inOther); - void operator = (const nsNativeFileSpec& inOther); + void operator = (const nsFileURL& inURL); + void operator = (const std::string& inString); + void operator = (const nsFilePath& inOther); + void operator = (const nsNativeFileSpec& inOther); #ifdef XP_MAC - // Accessor to allow quick assignment to a mNativeFileSpec - const nsNativeFileSpec& GetNativeSpec() const { return mNativeFileSpec; } + // Accessor to allow quick assignment to a mNativeFileSpec + const nsNativeFileSpec& GetNativeSpec() const { return mNativeFileSpec; } #endif - private: - - std::string mURL; + private: + // Should not be defined (only nsFilePath is to be treated as strings. + operator std::string& (); + private: + + std::string mURL; #ifdef XP_MAC - // Since the path on the macintosh does not uniquely specify a file (volumes - // can have the same name), stash the secret nsNativeFileSpec, too. - nsNativeFileSpec mNativeFileSpec; + // Since the path on the macintosh does not uniquely specify a file (volumes + // can have the same name), stash the secret nsNativeFileSpec, too. + nsNativeFileSpec mNativeFileSpec; #endif }; // class nsFileURL //======================================================================================== -class nsUnixFilePath -// This is a string that looks like "/foo/bar/mumble%20fish". Same as nsFileURL, but -// without the "file:// prefix". +class nsFilePath +// This is a string that looks like "/foo/bar/mumble%20fish". Same as nsFileURL, but +// without the "file:// prefix". //======================================================================================== { - public: - nsUnixFilePath(const nsUnixFilePath& inPath); - nsUnixFilePath(const std::string& inString); - nsUnixFilePath(const nsFileURL& inURL); - nsUnixFilePath(const nsNativeFileSpec& inPath); + public: + nsFilePath(const nsFilePath& inPath); + explicit nsFilePath(const std::string& inString); + nsFilePath(const nsFileURL& inURL); + nsFilePath(const nsNativeFileSpec& inPath); - - operator const char* () const { return mPath.c_str(); } - // This is the only automatic conversion to const char* - // that is provided, and it allows the - // path to be "passed" to NSPR file routines. + + operator const char* () const { return mPath.c_str(); } + // This is the only automatic conversion to const char* + // that is provided, and it allows the + // path to be "passed" to NSPR file routines. + operator std::string& () { return mPath; } + // This is the only automatic conversion to string + // that is provided, because a naked string should + // only mean a standard file path. - void operator = (const nsUnixFilePath& inPath); - void operator = (const std::string& inString); - void operator = (const nsFileURL& inURL); - void operator = (const nsNativeFileSpec& inOther); + void operator = (const nsFilePath& inPath); + void operator = (const std::string& inString); + void operator = (const nsFileURL& inURL); + void operator = (const nsNativeFileSpec& inOther); #ifdef XP_MAC - public: - // Accessor to allow quick assignment to a mNativeFileSpec - const nsNativeFileSpec& GetNativeSpec() const { return mNativeFileSpec; } + public: + // Accessor to allow quick assignment to a mNativeFileSpec + const nsNativeFileSpec& GetNativeSpec() const { return mNativeFileSpec; } #endif - private: - // Should not be defined (only file URLs are to be treated as strings. - operator std::string& (); - private: + private: - std::string mPath; + std::string mPath; #ifdef XP_MAC - // Since the path on the macintosh does not uniquely specify a file (volumes - // can have the same name), stash the secret nsNativeFileSpec, too. - nsNativeFileSpec mNativeFileSpec; + // Since the path on the macintosh does not uniquely specify a file (volumes + // can have the same name), stash the secret nsNativeFileSpec, too. + nsNativeFileSpec mNativeFileSpec; #endif -}; // class nsUnixFilePath +}; // class nsFilePath #ifdef XP_UNIX //======================================================================================== -// UNIX nsUnixFilePath implementation +// UNIX nsFilePath implementation //======================================================================================== //---------------------------------------------------------------------------------------- -inline nsUnixFilePath::nsUnixFilePath(const nsNativeFileSpec& inOther) +inline nsFilePath::nsFilePath(const nsNativeFileSpec& inOther) //---------------------------------------------------------------------------------------- -: mPath((std::string&)inOther) +: mPath((std::string&)inOther) { } //---------------------------------------------------------------------------------------- -inline void nsUnixFilePath::operator = (const nsNativeFileSpec& inOther) +inline void nsFilePath::operator = (const nsNativeFileSpec& inOther) //---------------------------------------------------------------------------------------- { - mPath = (std::string&)inOther; + mPath = (std::string&)inOther; } #endif // XP_UNIX //======================================================================================== -// COMMON nsNativeFileSpec implementation +// COMMON nsNativeFileSpec implementation //======================================================================================== //---------------------------------------------------------------------------------------- inline nsNativeFileSpec::nsNativeFileSpec(const nsFileURL& inURL) //---------------------------------------------------------------------------------------- { - *this = nsUnixFilePath(inURL); // convert to unix path first + *this = nsFilePath(inURL); // convert to unix path first } //---------------------------------------------------------------------------------------- inline void nsNativeFileSpec::operator = (const nsFileURL& inURL) //---------------------------------------------------------------------------------------- { - *this = nsUnixFilePath(inURL); // convert to unix path first + *this = nsFilePath(inURL); // convert to unix path first } //======================================================================================== -// UNIX & WIN nsNativeFileSpec implementation +// UNIX & WIN nsNativeFileSpec implementation //======================================================================================== #ifdef XP_UNIX //---------------------------------------------------------------------------------------- -inline nsNativeFileSpec::nsNativeFileSpec(const nsUnixFilePath& inPath) +inline nsNativeFileSpec::nsNativeFileSpec(const nsFilePath& inPath) //---------------------------------------------------------------------------------------- -: mPath((std::string&)inPath) +: mPath((std::string&)inPath) { } #endif // XP_UNIX #ifdef XP_UNIX //---------------------------------------------------------------------------------------- -inline void nsNativeFileSpec::operator = (const nsUnixFilePath& inPath) +inline void nsNativeFileSpec::operator = (const nsFilePath& inPath) //---------------------------------------------------------------------------------------- { - mPath = (std::string&)inPath; + mPath = (std::string&)inPath; } #endif //XP_UNIX @@ -261,7 +325,7 @@ inline void nsNativeFileSpec::operator = (const nsUnixFilePath& inPath) //---------------------------------------------------------------------------------------- inline nsNativeFileSpec::nsNativeFileSpec(const nsNativeFileSpec& inSpec) //---------------------------------------------------------------------------------------- -: mPath((std::string&)inSpec) +: mPath((std::string&)inSpec) { } #endif //XP_UNIX @@ -270,7 +334,7 @@ inline nsNativeFileSpec::nsNativeFileSpec(const nsNativeFileSpec& inSpec) //---------------------------------------------------------------------------------------- inline nsNativeFileSpec::nsNativeFileSpec(const std::string& inString) //---------------------------------------------------------------------------------------- -: mPath(inString) +: mPath(inString) { } #endif //XP_UNIX @@ -280,7 +344,7 @@ inline nsNativeFileSpec::nsNativeFileSpec(const std::string& inString) inline void nsNativeFileSpec::operator = (const nsNativeFileSpec& inSpec) //---------------------------------------------------------------------------------------- { - mPath = (std::string&)inSpec; + mPath = (std::string&)inSpec; } #endif //XP_UNIX @@ -290,7 +354,7 @@ inline void nsNativeFileSpec::operator = (const nsNativeFileSpec& inSpec) inline nsNativeFileSpec::operator = (const std::string& inString) //---------------------------------------------------------------------------------------- { - mPath = inString; + mPath = inString; } #endif //XP_UNIX @@ -299,7 +363,7 @@ inline nsNativeFileSpec::operator = (const std::string& inString) inline ostream& operator << (ostream& s, const nsNativeFileSpec& spec) //---------------------------------------------------------------------------------------- { - return (s << (std::string&)spec.mPath); + return (s << (std::string&)spec.mPath); } #endif // DEBUG && XP_UNIX diff --git a/mozilla/xpcom/io/nsFileSpecMac.cpp b/mozilla/xpcom/io/nsFileSpecMac.cpp index b2a5930b0ee..3e0dbffae3f 100644 --- a/mozilla/xpcom/io/nsFileSpecMac.cpp +++ b/mozilla/xpcom/io/nsFileSpecMac.cpp @@ -459,6 +459,8 @@ nsNativeFileSpec::nsNativeFileSpec(const std::string& inString) //---------------------------------------------------------------------------------------- { mError = MacFileHelpers::FSSpecFromFullUnixPath(inString.c_str(), mSpec, true); + if (mError == fnfErr) + mError = noErr; } // nsNativeFileSpec::nsNativeFileSpec //---------------------------------------------------------------------------------------- @@ -474,7 +476,7 @@ nsNativeFileSpec::nsNativeFileSpec( } //---------------------------------------------------------------------------------------- -nsNativeFileSpec::nsNativeFileSpec(const nsUnixFilePath& inPath) +nsNativeFileSpec::nsNativeFileSpec(const nsFilePath& inPath) //---------------------------------------------------------------------------------------- { *this = inPath.GetNativeSpec(); @@ -508,7 +510,7 @@ void nsNativeFileSpec::operator = (const nsNativeFileSpec& inSpec) } // nsNativeFileSpec::operator = //---------------------------------------------------------------------------------------- -void nsNativeFileSpec::operator = (const nsUnixFilePath& inPath) +void nsNativeFileSpec::operator = (const nsFilePath& inPath) //---------------------------------------------------------------------------------------- { mSpec = inPath.GetNativeSpec(); @@ -541,11 +543,11 @@ std::string nsNativeFileSpec::GetLeafName() const } // nsNativeFileSpec::GetLeafName //======================================================================================== -// Macintosh nsUnixFilePath implementation +// Macintosh nsFilePath implementation //======================================================================================== //---------------------------------------------------------------------------------------- -nsUnixFilePath::nsUnixFilePath(const nsNativeFileSpec& inSpec) +nsFilePath::nsFilePath(const nsNativeFileSpec& inSpec) //---------------------------------------------------------------------------------------- #ifdef XP_MAC : mNativeFileSpec(inSpec) @@ -558,7 +560,7 @@ nsUnixFilePath::nsUnixFilePath(const nsNativeFileSpec& inSpec) } //---------------------------------------------------------------------------------------- -void nsUnixFilePath::operator = (const nsNativeFileSpec& inSpec) +void nsFilePath::operator = (const nsNativeFileSpec& inSpec) //---------------------------------------------------------------------------------------- { char * path = MacFileHelpers::PathNameFromFSSpec( inSpec.mSpec, TRUE ); @@ -568,4 +570,4 @@ void nsUnixFilePath::operator = (const nsNativeFileSpec& inSpec) #ifdef XP_MAC mNativeFileSpec = inSpec; #endif -} // nsUnixFilePath::operator = +} // nsFilePath::operator = diff --git a/mozilla/xpcom/io/nsFileSpecUnix.cpp b/mozilla/xpcom/io/nsFileSpecUnix.cpp index 8680b1fec90..adaa4acac92 100644 --- a/mozilla/xpcom/io/nsFileSpecUnix.cpp +++ b/mozilla/xpcom/io/nsFileSpecUnix.cpp @@ -16,7 +16,7 @@ * Reserved. */ -// This file is included by nsFile.cpp, and includes the Unix-specific +// This file is included by nsFileSpec.cpp, and includes the Unix-specific // implementations. //---------------------------------------------------------------------------------------- diff --git a/mozilla/xpcom/io/nsFileSpecWin.cpp b/mozilla/xpcom/io/nsFileSpecWin.cpp index 4192593dbbb..fcc07645843 100644 --- a/mozilla/xpcom/io/nsFileSpecWin.cpp +++ b/mozilla/xpcom/io/nsFileSpecWin.cpp @@ -16,18 +16,18 @@ * Reserved. */ -// This file is included by nsFile.cp, and includes the Windows-specific +// This file is included by nsFileSpec.cp, and includes the Windows-specific // implementations. //---------------------------------------------------------------------------------------- -nsNativeFileSpec::nsNativeFileSpec(const nsUnixFilePath& inPath) +nsNativeFileSpec::nsNativeFileSpec(const nsFilePath& inPath) //---------------------------------------------------------------------------------------- { *this = inPath; } //---------------------------------------------------------------------------------------- -void nsNativeFileSpec::operator = (const nsUnixFilePath& inPath) +void nsNativeFileSpec::operator = (const nsFilePath& inPath) //---------------------------------------------------------------------------------------- { // Convert '/' to '\' diff --git a/mozilla/xpcom/io/nsFileStream.h b/mozilla/xpcom/io/nsFileStream.h index df0851d6eb4..4a265fbd401 100644 --- a/mozilla/xpcom/io/nsFileStream.h +++ b/mozilla/xpcom/io/nsFileStream.h @@ -16,109 +16,193 @@ * Reserved. */ -// First checked in on 98/11/20 by John R. McMullen. Checked in again 98/12/04. +// First checked in on 98/11/20 by John R. McMullen in the wrong directory. +// Checked in again 98/12/04. +// Polished version 98/12/08. -#ifndef _STREAM_H_ -#define _STREAM_H_ +//======================================================================================== +// +// Classes defined: +// +// single-byte char: +// +// nsInputFileStream, nsOutputFileStream, nsIOFileStream +// +// wide char: +// +// nsWideInputFileStream, nsWideOutputFileStream, nsWideIOFileStream +// +// This suite provide the following services: +// +// 1. Encapsulates all platform-specific file details, so that file i/o +// can be done correctly without any platform #ifdefs +// +// 2. Uses NSPR file services (NOT ansi file I/O), in order to get best +// native performance. This performance difference is especially large on +// macintosh. +// +// 3. Allows all the power of the ansi stream syntax: these streams +// ARE derived classes of ostream, istream, and iostream. ALL METHODS OF +// istream, ostream, AND iostream ARE AVAILABLE! +// +// Basic example: +// +// nsFilePath myPath("/Development/iotest.txt"); +// +// nsOutputFileStream testStream(myPath); +// testStream << "Hello World" << endl; +// +// 4. Requires streams to be constructed using typesafe nsFilePath specifier +// (not the notorious and bug prone const char*), namely nsFilePath. See +// nsFileSpec.h for more details. +// +// 5. Fixes a two bugs that have been there for a long time, and +// are inevitable if you use NSPR alone: +// +// The problem on platforms (Macintosh) in which a path does not fully +// specify a file. +// +// Not yet provided: +// +// Endian-awareness for reading and writing crossplatform binary files. At this +// time there seems to be no demand for this. +// +//======================================================================================== + +#ifndef _FILESTREAM_H_ +#define _FILESTREAM_H_ #include +#ifdef XP_MAC +#include "pprio.h" // To get PR_ImportFile +#else #include "prio.h" +#endif #include "nsFileSpec.h" +//======================================================================================== +// Compiler-specific macros, as needed +//======================================================================================== #ifdef __MWERKS__ + #ifdef MSIPL_WCHART #define NS_USING_WIDE_CHAR #endif #ifdef MSIPL_EXPLICIT_FUNC_TEMPLATE_ARG #define NS_EXPLICIT_FUNC_TEMPLATE_ARG #endif -#endif +#define NS_READ_LOCK(mut) READ_LOCK(mut) +#define NS_WRITE_LOCK(mut) WRITE_LOCK(mut) + +#else + +// Fix me for thread-safety. +#define NS_READ_LOCK(mut) +#define NS_WRITE_LOCK(mut) + +#endif //==================== End Compiler-specific macros =============================== + +//======================================================================================== +namespace nsFileStreamHelpers +// Prototypes for common (non-template) implementations in the .cpp file which do not +// need the template args (charT, traits). +//======================================================================================== +{ + PRFileDesc* open( + const nsFilePath& inFile, + ios_base::openmode mode, + PRIntn accessMode); +} // nsFileStreamHelpers + +//======================================================================================== +// Template declarations +//======================================================================================== //======================================================================================== template class nsFileBufferT //======================================================================================== -: public basic_streambuf +: public basic_streambuf { - typedef codecvt_base::result result; + typedef codecvt_base::result result; public: - typedef charT char_type; - typedef typename traits::pos_type pos_type; - typedef typename traits::off_type off_type; - typedef typename traits::int_type int_type; - typedef traits traits_type; - typedef typename traits::state_type state_type; + typedef charT char_type; + typedef typename traits::pos_type pos_type; + typedef typename traits::off_type off_type; + typedef typename traits::int_type int_type; + typedef traits traits_type; + typedef typename traits::state_type state_type; - typedef nsFileBufferT filebuf_type; - typedef codecvt ofacet_type; - typedef codecvt ifacet_type; + typedef nsFileBufferT filebuf_type; + typedef codecvt ofacet_type; + typedef codecvt ifacet_type; - nsFileBufferT(); - nsFileBufferT(PRFileDesc* pfile_arg); - virtual ~nsFileBufferT(); - bool is_open() const; - filebuf_type* open( - const nsUnixFilePath& inFile, - ios_base::openmode mode, - PRIntn accessMode); - filebuf_type* close(); + nsFileBufferT(); + nsFileBufferT(PRFileDesc* pfile_arg); + virtual ~nsFileBufferT(); + bool is_open() const; + filebuf_type* open( + const nsFilePath& inFile, + ios_base::openmode mode, + PRIntn accessMode); + filebuf_type* close(); protected: - virtual int_type overflow(int_type c=traits::eof()); - virtual int_type pbackfail(int_type c=traits::eof()); - virtual int_type underflow(); - virtual pos_type seekoff( - off_type off, ios_base::seekdir way, - ios_base::openmode which=ios_base::in|ios_base::out); - virtual pos_type seekpos(pos_type sp, - ios_base::openmode which=ios_base::in|ios_base::out); - virtual basic_streambuf* setbuf(char_type* s, streamsize n); - virtual int sync(); - virtual int_type uflow(); - virtual void imbue(const locale& loc); - virtual streamsize showmanyc(); - virtual streamsize xsgetn(char_type* s, streamsize n); - virtual streamsize xsputn(const char_type* s, streamsize n); + virtual int_type overflow(int_type c=traits::eof()); + virtual int_type pbackfail(int_type c=traits::eof()); + virtual int_type underflow(); + virtual pos_type seekoff( + off_type off, ios_base::seekdir way, + ios_base::openmode which=ios_base::in|ios_base::out); + virtual pos_type seekpos(pos_type sp, + ios_base::openmode which=ios_base::in|ios_base::out); + virtual basic_streambuf* setbuf(char_type* s, streamsize n); + virtual int sync(); + virtual int_type uflow(); + virtual void imbue(const locale& loc); + virtual streamsize showmanyc(); + virtual streamsize xsgetn(char_type* s, streamsize n); + virtual streamsize xsputn(const char_type* s, streamsize n); private: - PRFileDesc* mFileDesc; - ios_base::openmode mode_; + PRFileDesc* mFileDesc; + ios_base::openmode mode_; }; // class nsFileBufferT //======================================================================================== template class nsInputFileStreamT //======================================================================================== -: public basic_istream +: public basic_istream { - typedef nsFileBufferT filebuf_type; + typedef nsFileBufferT filebuf_type; public: - typedef charT char_type; - typedef typename traits::pos_type pos_type; - typedef typename traits::off_type off_type; - typedef typename traits::int_type int_type; - typedef traits traits_type; + typedef charT char_type; + typedef typename traits::pos_type pos_type; + typedef typename traits::off_type off_type; + typedef typename traits::int_type int_type; + typedef traits traits_type; - nsInputFileStreamT(); - explicit nsInputFileStreamT( - const nsUnixFilePath& inFile, - ios_base::openmode mode=ios_base::in, - PRIntn accessMode = 0x00400); + nsInputFileStreamT(); + explicit nsInputFileStreamT( + const nsFilePath& inFile, + ios_base::openmode mode=ios_base::in, + PRIntn accessMode = 0x00400); - virtual ~nsInputFileStreamT(); + virtual ~nsInputFileStreamT(); - filebuf_type* rdbuf() const; - inline bool is_open(); - inline void open( - const nsUnixFilePath& inFile, - ios_base::openmode mode=ios_base::in, - PRIntn accessMode = 0x00400); - inline void close(); + filebuf_type* rdbuf() const; + inline bool is_open(); + inline void open( + const nsFilePath& inFile, + ios_base::openmode mode=ios_base::in, + PRIntn accessMode = 0x00400); + inline void close(); private: - filebuf_type mBuffer; + filebuf_type mBuffer; }; // class nsInputFileStreamT //======================================================================================== @@ -127,43 +211,43 @@ class nsOutputFileStreamT //======================================================================================== : public basic_ostream { - typedef nsFileBufferT filebuf_type; + typedef nsFileBufferT filebuf_type; public: - typedef charT char_type; - typedef typename traits::pos_type pos_type; - typedef typename traits::off_type off_type; - typedef typename traits::int_type int_type; - typedef traits traits_type; + typedef charT char_type; + typedef typename traits::pos_type pos_type; + typedef typename traits::off_type off_type; + typedef typename traits::int_type int_type; + typedef traits traits_type; - nsOutputFileStreamT(); - explicit nsOutputFileStreamT( - const nsUnixFilePath& inFile, - ios_base::openmode mode = ios_base::out|ios_base::trunc, - PRIntn accessMode = 0x00200); + nsOutputFileStreamT(); + explicit nsOutputFileStreamT( + const nsFilePath& inFile, + ios_base::openmode mode = ios_base::out|ios_base::trunc, + PRIntn accessMode = 0x00200); - virtual ~nsOutputFileStreamT(); + virtual ~nsOutputFileStreamT(); - filebuf_type* rdbuf() const; - inline bool is_open(); - inline void open( - const nsUnixFilePath& inFile, - ios_base::openmode mode = ios_base::out|ios_base::trunc, - PRIntn accessMode = 0x00200); - inline void close(); + filebuf_type* rdbuf() const; + inline bool is_open(); + inline void open( + const nsFilePath& inFile, + ios_base::openmode mode = ios_base::out|ios_base::trunc, + PRIntn accessMode = 0x00200); + inline void close(); private: - filebuf_type mBuffer; + filebuf_type mBuffer; }; // class nsOutputFileStreamT //======================================================================================== -// Implementation of nsFileBufferT +// Implementation of nsFileBufferT //======================================================================================== //---------------------------------------------------------------------------------------- -template +template inline nsFileBufferT::nsFileBufferT() - : basic_streambuf(), mFileDesc(NULL) + : basic_streambuf(), mFileDesc(NULL) //---------------------------------------------------------------------------------------- { } @@ -171,7 +255,7 @@ inline nsFileBufferT::nsFileBufferT() //---------------------------------------------------------------------------------------- template inline nsFileBufferT::nsFileBufferT(PRFileDesc* pfarg) - : basic_streambuf(), mFileDesc(pfarg) + : basic_streambuf(), mFileDesc(pfarg) //---------------------------------------------------------------------------------------- { } @@ -181,7 +265,7 @@ template inline nsFileBufferT::~nsFileBufferT() //---------------------------------------------------------------------------------------- { - close(); + close(); } //---------------------------------------------------------------------------------------- @@ -190,78 +274,38 @@ inline bool nsFileBufferT::is_open() const //---------------------------------------------------------------------------------------- { - READ_LOCK(_mutex); - return bool(mFileDesc); // in case it is typedefed to int + NS_READ_LOCK(_mutex); + return bool(mFileDesc); // in case it is typedefed to int } //---------------------------------------------------------------------------------------- template nsFileBufferT::filebuf_type* nsFileBufferT::open( - const nsUnixFilePath& inFile, - ios_base::openmode mode, - PRIntn accessMode - ) + const nsFilePath& inFile, + ios_base::openmode mode, + PRIntn accessMode) //---------------------------------------------------------------------------------------- { - if (mFileDesc) - return 0; - const ios_base::openmode valid_modes[]= - { - ios_base::out, - ios_base::out | ios_base::app, - ios_base::out | ios_base::trunc, - ios_base::in, - ios_base::in | ios_base::out, - ios_base::in | ios_base::out | ios_base::trunc, -// ios_base::out | ios_base::binary, -// ios_base::out | ios_base::app | ios_base::binary, -// ios_base::out | ios_base::trunc | ios_base::binary, -// ios_base::in | ios_base::binary, -// ios_base::in | ios_base::out | ios_base::binary, -// ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary, - 0 - }; - 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 }; - int ind=0; - while (valid_modes[ind] && valid_modes[ind] != (mode&~ios_base::ate)) - ++ind; - if (!nspr_modes[ind]) - return 0; - - WRITE_LOCK(_mutex); - mode_ = mode; - if ((mFileDesc = PR_Open(inFile, nspr_modes[ind], accessMode)) != 0) - if (mode&ios_base::ate && PR_Seek(mFileDesc, 0, PR_SEEK_END) >= 0) - close(); - else - return this; - return 0; -} // nsFileBufferT::open + if (mFileDesc) + return 0; + NS_WRITE_LOCK(_mutex); + mFileDesc = nsFileStreamHelpers::open(inFile, mode, accessMode); + if (!mFileDesc) + return 0; + mode_ = mode; + return this; +} // nsFileBufferT::open //---------------------------------------------------------------------------------------- template nsFileBufferT::filebuf_type* nsFileBufferT::close() //---------------------------------------------------------------------------------------- { - if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR) - return this; - WRITE_LOCK(_mutex); - return (mFileDesc && PR_Close(mFileDesc) == PR_SUCCESS) ? mFileDesc = 0, this : 0; + if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR) + return this; + NS_WRITE_LOCK(_mutex); + return (mFileDesc && PR_Close(mFileDesc) == PR_SUCCESS) ? mFileDesc = 0, this : 0; } //---------------------------------------------------------------------------------------- @@ -270,7 +314,7 @@ inline int nsFileBufferT:: sync() //---------------------------------------------------------------------------------------- { - return (mFileDesc ? (int)PR_Sync(mFileDesc) : 0); + return (mFileDesc ? (int)PR_Sync(mFileDesc) : 0); } //---------------------------------------------------------------------------------------- @@ -279,7 +323,7 @@ inline basic_streambuf* nsFileBufferT::setbuf(char_type*, streamsize) //---------------------------------------------------------------------------------------- { - return (!mFileDesc) ? 0 : this; + return (!mFileDesc) ? 0 : this; } //---------------------------------------------------------------------------------------- @@ -287,39 +331,39 @@ template nsFileBufferT::int_type nsFileBufferT::overflow(int_type c) //---------------------------------------------------------------------------------------- { -#ifdef NS_EXPLICIT_FUNC_TEMPLATE_ARG - const ofacet_type& ft=use_facet(loc); +#ifdef NS_EXPLICIT_FUNC_TEMPLATE_ARG + const ofacet_type& ft=use_facet(loc); #else - const ofacet_type& ft=use_facet(loc, (ofacet_type*)0); + const ofacet_type& ft=use_facet(loc, (ofacet_type*)0); #endif - char_type ch = traits_type::to_char_type(c); - if (!mFileDesc) - return traits_type::eof(); - if (traits_type::eq_int_type(c, traits::eof())) - return traits_type::not_eof(c); - if (ft.always_noconv()) - { - PRInt32 bytesWrit1 = PR_Write(mFileDesc, &ch, sizeof(ch)); - return bytesWrit1 < sizeof(ch) ? traits::eof() : c; - } - { // <- sic! - state_type fst; - const char_type* end; - char buf[4]; - char* ebuf; - result conv; - if ((conv=ft.out(fst, &ch, &ch+1, end, buf, buf+3, ebuf))== - codecvt_base::noconv) - { - PRInt32 bytesWrit2 = PR_Write(mFileDesc, &ch, sizeof(ch)); - return bytesWrit2 < sizeof(ch) ? traits::eof() : c; - } - if ((conv==codecvt_base::partial)||(conv==codecvt_base::error)) - return traits::eof(); - *ebuf=0; - PRInt32 bytesWrit3 = strlen(buf); - return PR_Write(mFileDesc, buf, bytesWrit3) < bytesWrit3 ? traits_type::eof() : c; - } + char_type ch = traits_type::to_char_type(c); + if (!mFileDesc) + return traits_type::eof(); + if (traits_type::eq_int_type(c, traits::eof())) + return traits_type::not_eof(c); + if (ft.always_noconv()) + { + PRInt32 bytesWrit1 = PR_Write(mFileDesc, &ch, sizeof(ch)); + return bytesWrit1 < sizeof(ch) ? traits::eof() : c; + } + { // <- sic! + state_type fst; + const char_type* end; + char buf[4]; + char* ebuf; + result conv; + if ((conv=ft.out(fst, &ch, &ch+1, end, buf, buf+3, ebuf))== + codecvt_base::noconv) + { + PRInt32 bytesWrit2 = PR_Write(mFileDesc, &ch, sizeof(ch)); + return bytesWrit2 < sizeof(ch) ? traits::eof() : c; + } + if ((conv==codecvt_base::partial)||(conv==codecvt_base::error)) + return traits::eof(); + *ebuf=0; + PRInt32 bytesWrit3 = strlen(buf); + return PR_Write(mFileDesc, buf, bytesWrit3) < bytesWrit3 ? traits_type::eof() : c; + } } //---------------------------------------------------------------------------------------- @@ -327,14 +371,14 @@ template inline nsFileBufferT::int_type nsFileBufferT::underflow() //---------------------------------------------------------------------------------------- { - if (!mFileDesc) - return traits_type::eof(); - char_type s; - PRInt32 request = 1; - if (1 != PR_Read(mFileDesc, &s, request)) - return traits_type::eof(); - PR_Seek(mFileDesc, -1, PR_SEEK_CUR); - return (int_type)s; + if (!mFileDesc) + return traits_type::eof(); + char_type s; + PRInt32 request = 1; + if (1 != PR_Read(mFileDesc, &s, request)) + return traits_type::eof(); + PR_Seek(mFileDesc, -1, PR_SEEK_CUR); + return (int_type)s; } //---------------------------------------------------------------------------------------- @@ -343,51 +387,51 @@ streamsize nsFileBufferT::xsputn(const char_type* s, streamsize n //---------------------------------------------------------------------------------------- { #ifdef NS_EXPLICIT_FUNC_TEMPLATE_ARG - const ofacet_type& ft=use_facet(loc); + const ofacet_type& ft=use_facet(loc); #else - const ofacet_type& ft=use_facet(loc, (ofacet_type*)0); + const ofacet_type& ft=use_facet(loc, (ofacet_type*)0); #endif - if (!mFileDesc || !n) - return 0; - if (ft.always_noconv()) - { - PRInt32 bytesWrit1 = PR_Write(mFileDesc, s, sizeof(char) * size_t(n)); - return bytesWrit1 < 0 ? 0 : (streamsize)bytesWrit1; - } - { // <- sic! - state_type fst; - const char_type* end; - char buf[8]; - char* ebuf; - result conv; -#ifdef NS_EXPLICIT_FUNC_TEMPLATE_ARG - if ((conv=use_facet(loc). - out(fst, s, s+n, end, buf, buf+7, ebuf))==codecvt_base::noconv) + if (!mFileDesc || !n) + return 0; + if (ft.always_noconv()) + { + PRInt32 bytesWrit1 = PR_Write(mFileDesc, s, sizeof(char) * size_t(n)); + return bytesWrit1 < 0 ? 0 : (streamsize)bytesWrit1; + } + { // <- sic! + state_type fst; + const char_type* end; + char buf[8]; + char* ebuf; + result conv; +#ifdef NS_EXPLICIT_FUNC_TEMPLATE_ARG + if ((conv=use_facet(loc). + out(fst, s, s+n, end, buf, buf+7, ebuf))==codecvt_base::noconv) #else - if ((conv=use_facet(loc, (ofacet_type*)0). - out(fst, s, s+n, end, buf, buf+7, ebuf))==codecvt_base::noconv) + if ((conv=use_facet(loc, (ofacet_type*)0). + out(fst, s, s+n, end, buf, buf+7, ebuf))==codecvt_base::noconv) #endif - return (streamsize)PR_Write(mFileDesc, s, sizeof(char) * size_t(n)); - if ((conv==codecvt_base::partial) ||(conv==codecvt_base::error)) - return 0; - *ebuf=0; - PRInt32 bytesWrit2 = strlen(buf); - bytesWrit2 = PR_Write(mFileDesc, buf, bytesWrit2); - return bytesWrit2 < 0 ? 0 : streamsize(bytesWrit2 / sizeof(char_type)); - } + return (streamsize)PR_Write(mFileDesc, s, sizeof(char) * size_t(n)); + if ((conv==codecvt_base::partial) ||(conv==codecvt_base::error)) + return 0; + *ebuf=0; + PRInt32 bytesWrit2 = strlen(buf); + bytesWrit2 = PR_Write(mFileDesc, buf, bytesWrit2); + return bytesWrit2 < 0 ? 0 : streamsize(bytesWrit2 / sizeof(char_type)); + } } //---------------------------------------------------------------------------------------- template inline nsFileBufferT::int_type - nsFileBufferT::pbackfail(int_type c) + nsFileBufferT::pbackfail(int_type c) //---------------------------------------------------------------------------------------- { - if (!mFileDesc) - return traits_type::eof(); - if (PR_Seek(mFileDesc, -1, PR_SEEK_CUR) < 0) - return traits_type::eof(); - return (traits::eq_int_type(c, traits_type::eof())) ? traits::not_eof(c) : c; + if (!mFileDesc) + return traits_type::eof(); + if (PR_Seek(mFileDesc, -1, PR_SEEK_CUR) < 0) + return traits_type::eof(); + return (traits::eq_int_type(c, traits_type::eof())) ? traits::not_eof(c) : c; } //---------------------------------------------------------------------------------------- @@ -395,12 +439,12 @@ template inline nsFileBufferT::int_type nsFileBufferT::uflow() //---------------------------------------------------------------------------------------- { - if (!mFileDesc) - return traits_type::eof(); - char_type s; - if (1 != PR_Read(mFileDesc, &s, 1)) // attempt to read 1 byte, confirm 1 byte - return traits_type::eof(); - return (int_type)s; + if (!mFileDesc) + return traits_type::eof(); + char_type s; + if (1 != PR_Read(mFileDesc, &s, 1)) // attempt to read 1 byte, confirm 1 byte + return traits_type::eof(); + return (int_type)s; } //---------------------------------------------------------------------------------------- @@ -408,7 +452,7 @@ template inline streamsize nsFileBufferT::xsgetn(char_type* s, streamsize n) //---------------------------------------------------------------------------------------- { - return mFileDesc ? (streamsize)PR_Read(mFileDesc, s, sizeof(char) * size_t(n)) : 0; + return mFileDesc ? (streamsize)PR_Read(mFileDesc, s, sizeof(char) * size_t(n)) : 0; } //---------------------------------------------------------------------------------------- @@ -416,38 +460,38 @@ template inline void nsFileBufferT::imbue(const locale& loc_arg) //---------------------------------------------------------------------------------------- { - loc = loc_arg; + loc = loc_arg; } template inline streamsize nsFileBufferT::showmanyc() { - return (streamsize)PR_Available(mFileDesc); + return (streamsize)PR_Available(mFileDesc); } //---------------------------------------------------------------------------------------- template nsFileBufferT::pos_type nsFileBufferT::seekoff( - off_type off, - ios_base::seekdir way, - ios_base::openmode /* which */) + off_type off, + ios_base::seekdir way, + ios_base::openmode /* which */) //---------------------------------------------------------------------------------------- { - if (!mFileDesc || ((way&ios_base::beg) && off<0) || ((way&ios_base::end) && off > 0)) - return pos_type(-1); - PRSeekWhence poseek = PR_SEEK_CUR; - switch (way) - { - case ios_base::beg : poseek= PR_SEEK_SET; - break; - case ios_base::end : poseek= PR_SEEK_END; - break; - } - PRInt32 position = PR_Seek(mFileDesc, off, poseek); - if (position < 0) - return pos_type(-1); - return pos_type(position); + if (!mFileDesc || ((way&ios_base::beg) && off<0) || ((way&ios_base::end) && off > 0)) + return pos_type(-1); + PRSeekWhence poseek = PR_SEEK_CUR; + switch (way) + { + case ios_base::beg : poseek= PR_SEEK_SET; + break; + case ios_base::end : poseek= PR_SEEK_END; + break; + } + PRInt32 position = PR_Seek(mFileDesc, off, poseek); + if (position < 0) + return pos_type(-1); + return pos_type(position); } //---------------------------------------------------------------------------------------- @@ -456,39 +500,39 @@ nsFileBufferT::pos_type nsFileBufferT::seekpos(pos_type sp, ios_base::openmode) //---------------------------------------------------------------------------------------- { - if (!mFileDesc || sp==pos_type(-1)) - return -1; - PRInt32 position = PR_Seek(mFileDesc, sp.offset(), PR_SEEK_SET); - if (position < 0) - return pos_type(-1); - return position; + if (!mFileDesc || sp==pos_type(-1)) + return -1; + PRInt32 position = PR_Seek(mFileDesc, sp.offset(), PR_SEEK_SET); + if (position < 0) + return pos_type(-1); + return position; } //======================================================================================== -// Implementation of nsInputFileStreamT +// Implementation of nsInputFileStreamT //======================================================================================== //---------------------------------------------------------------------------------------- template inline nsInputFileStreamT::nsInputFileStreamT() - : basic_istream(&mBuffer) + : basic_istream(&mBuffer) //---------------------------------------------------------------------------------------- { - // already inited + // already inited } //---------------------------------------------------------------------------------------- template inline nsInputFileStreamT::nsInputFileStreamT( - const nsUnixFilePath& inFile, + const nsFilePath& inFile, ios_base::openmode mode, PRIntn accessMode) //---------------------------------------------------------------------------------------- - : basic_istream(&mBuffer) + : basic_istream(&mBuffer) { - // already inited + // already inited if (!mBuffer.open(inFile, openmode(mode|in), accessMode)) - setstate(failbit); + setstate(failbit); } //---------------------------------------------------------------------------------------- @@ -520,13 +564,13 @@ nsInputFileStreamT:: is_open() template inline void nsInputFileStreamT::open( - const nsUnixFilePath& inFile, - ios_base::openmode mode, - PRIntn accessMode) + const nsFilePath& inFile, + ios_base::openmode mode, + PRIntn accessMode) //---------------------------------------------------------------------------------------- { if (!mBuffer.open(inFile, openmode(mode|in), accessMode)) - setstate(failbit); + setstate(failbit); } //---------------------------------------------------------------------------------------- @@ -535,34 +579,34 @@ inline void nsInputFileStreamT::close() //---------------------------------------------------------------------------------------- { if (!mBuffer.close()) - setstate(failbit); + setstate(failbit); } //======================================================================================== -// Implementation of nsOutputFileStreamT +// Implementation of nsOutputFileStreamT //======================================================================================== //---------------------------------------------------------------------------------------- template inline nsOutputFileStreamT::nsOutputFileStreamT() - : basic_ostream(&mBuffer) + : basic_ostream(&mBuffer) //---------------------------------------------------------------------------------------- { - // already inited + // already inited } //---------------------------------------------------------------------------------------- template nsOutputFileStreamT::nsOutputFileStreamT( - const nsUnixFilePath& inFile, + const nsFilePath& inFile, ios_base::openmode mode, PRIntn accessMode) //---------------------------------------------------------------------------------------- : basic_ostream(&mBuffer) { - // already inited + // already inited if (!mBuffer.open(inFile, openmode(mode|out), accessMode)) - setstate(failbit); + setstate(failbit); } //---------------------------------------------------------------------------------------- @@ -592,13 +636,13 @@ inline bool nsOutputFileStreamT:: is_open() //---------------------------------------------------------------------------------------- template inline void nsOutputFileStreamT::open( - const nsUnixFilePath& inFile, - ios_base::openmode mode, - PRIntn accessMode) + const nsFilePath& inFile, + ios_base::openmode mode, + PRIntn accessMode) //---------------------------------------------------------------------------------------- { if (!mBuffer.open(inFile, openmode(mode | out), accessMode)) - setstate(failbit); + setstate(failbit); } //---------------------------------------------------------------------------------------- @@ -607,7 +651,7 @@ inline void nsOutputFileStreamT:: close() //---------------------------------------------------------------------------------------- { if (!mBuffer.close()) - setstate(failbit); + setstate(failbit); } //======================================================================================== @@ -618,57 +662,57 @@ class nsIOFileStreamT : public basic_iostream typedef nsFileBufferT filebuf_type; public: - typedef charT char_type; + typedef charT char_type; typedef typename traits::pos_type pos_type; typedef typename traits::off_type off_type; typedef typename traits::int_type int_type; - typedef traits traits_type; + typedef traits traits_type; - nsIOFileStreamT(); - explicit nsIOFileStreamT( - const nsUnixFilePath& inFile, - ios_base::openmode mode = ios_base::in|ios_base::out, - PRIntn accessMode = 0x00600); + nsIOFileStreamT(); + explicit nsIOFileStreamT( + const nsFilePath& inFile, + ios_base::openmode mode = ios_base::in|ios_base::out, + PRIntn accessMode = 0x00600); - virtual ~nsIOFileStreamT(); + virtual ~nsIOFileStreamT(); - filebuf_type* rdbuf() const; - inline bool is_open(); - inline void open( - const nsUnixFilePath& inFile, - ios_base::openmode mode = ios_base::in|ios_base::out, - PRIntn accessMode = 0x00600); - inline void close(); + filebuf_type* rdbuf() const; + inline bool is_open(); + inline void open( + const nsFilePath& inFile, + ios_base::openmode mode = ios_base::in|ios_base::out, + PRIntn accessMode = 0x00600); + inline void close(); private: - filebuf_type mBuffer; + filebuf_type mBuffer; }; // class nsIOFileStreamT //======================================================================================== -// Implementation of nsIOFileStream +// Implementation of nsIOFileStream //======================================================================================== //---------------------------------------------------------------------------------------- template inline nsIOFileStreamT::nsIOFileStreamT() //---------------------------------------------------------------------------------------- - : mBuffer(), basic_iostream(&mBuffer) + : mBuffer(), basic_iostream(&mBuffer) { - // already inited + // already inited } //---------------------------------------------------------------------------------------- template inline nsIOFileStreamT::nsIOFileStreamT( - const nsUnixFilePath& inFile, + const nsFilePath& inFile, ios_base::openmode mode, PRIntn accessMode) //---------------------------------------------------------------------------------------- - : mBuffer(), basic_iostream(&mBuffer) + : mBuffer(), basic_iostream(&mBuffer) { - // already inited + // already inited if (!mBuffer.open(inFile, mode, accessMode)) - setstate(failbit); + setstate(failbit); } template @@ -698,13 +742,13 @@ nsIOFileStreamT::is_open() template inline void nsIOFileStreamT::open( - const nsUnixFilePath& inFile, - ios_base::openmode mode, - PRIntn accessMode) + const nsFilePath& inFile, + ios_base::openmode mode, + PRIntn accessMode) //---------------------------------------------------------------------------------------- { if (!mBuffer.open(inFile, mode, accessMode)) - setstate(failbit); + setstate(failbit); } //---------------------------------------------------------------------------------------- @@ -714,11 +758,11 @@ nsIOFileStreamT::close() //---------------------------------------------------------------------------------------- { if (!mBuffer.close()) - setstate(failbit); + setstate(failbit); } //======================================================================================== -// Specializations of the stream templates +// Specializations of the stream templates //======================================================================================== typedef nsFileBufferT > nsFileBuffer; @@ -733,5 +777,5 @@ typedef nsOutputFileStreamT > nsWideOutputFileStre typedef nsIOFileStreamT > nsWideIOFileStream; #endif // NS_USING_WIDE_CHAR -#endif /* _STREAM_H_ */ +#endif /* _FILESTREAM_H_ */ diff --git a/mozilla/xpcom/tests/FilesTest.cpp b/mozilla/xpcom/tests/FilesTest.cpp index 4563b2cd924..17cf4af4a31 100644 --- a/mozilla/xpcom/tests/FilesTest.cpp +++ b/mozilla/xpcom/tests/FilesTest.cpp @@ -17,7 +17,7 @@ void FileTest::WriteStuff(ostream& s) s << "File URL initialized to: \"" << (string&)fileURL << "\""<< endl; // Initialize a Unix path from a URL - nsUnixFilePath filePath(fileURL); + nsFilePath filePath(fileURL); s << "As a unix path: \"" << (string&)filePath << "\""<< endl; // Initialize a native file spec from a URL @@ -62,21 +62,25 @@ void main() // Test of nsOutputFileStream - nsUnixFilePath myTextFilePath("/Development/iotest.txt"); + nsFilePath myTextFilePath("/Development/iotest.txt"); + + { + cout << "WRITING IDENTICAL OUTPUT TO " << myTextFilePath << endl << endl; + nsOutputFileStream testStream(myTextFilePath); + FileTest::WriteStuff(testStream); + } // <-- Scope closes the stream (and the file). - cout << "WRITING IDENTICAL OUTPUT TO " << myTextFilePath << endl << endl; - nsOutputFileStream testStream(myTextFilePath); - FileTest::WriteStuff(testStream); - // Test of nsInputFileStream - cout << "READING BACK DATA FROM " << myTextFilePath << endl << endl; - nsInputFileStream testStream2(myTextFilePath); - char line[1000]; - while (!testStream2.eof()) { - testStream2.getline(line, sizeof(line), '\n'); - cout << line << endl; + cout << "READING BACK DATA FROM " << myTextFilePath << endl << endl; + nsInputFileStream testStream2(myTextFilePath); + char line[1000]; + while (!testStream2.eof()) + { + testStream2.getline(line, sizeof(line), '\n'); + cout << line << endl; + } } } // main