/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public License * Version 1.0(the "NPL"); you may not use this file except in * compliance with the NPL. You may obtain a copy of the NPL at * http://www.mozilla.org/NPL/ * * Software distributed under the NPL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL * for the specific language governing rights and limitations under the * NPL. * * The Initial Developer of this code under the NPL is Netscape * Communications Corporation. Portions created by Netscape are * Copyright(C) 1998 Netscape Communications Corporation. All Rights * Reserved. */ // 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: // // single-byte char: // // nsInputFileStream, nsOutputFileStream // // 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. // // Basic example: // // nsFilePath myPath("/Development/iotest.txt"); // // nsOutputFileStream testStream(myPath); // testStream << "Hello World" << nsEndl; // // 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 bug that have been there for a long time, and // is inevitable if you use NSPR alone: // // The problem on platforms (Macintosh) in which a path does not fully // specify a file, because two volumes can have the same name. // // 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 "nscore.h" #ifdef XP_MAC #include "pprio.h" // To get PR_ImportFile #else #include "prio.h" #endif #include "nsFileSpec.h" //======================================================================================== // Compiler-specific macros, as needed //======================================================================================== #if !defined(NS_USING_NAMESPACE) && (defined(__MWERKS__) || defined(XP_PC)) #define NS_USING_NAMESPACE #endif #if !defined(NS_USING_STL) && (defined(__MWERKS__) || defined(XP_PC)) #define NS_USING_STL #endif #ifdef NS_USING_NAMESPACE #define NS_NAMESPACE_PROTOTYPE #define NS_NAMESPACE namespace #define NS_NAMESPACE_END #else #define NS_NAMESPACE_PROTOTYPE static #define NS_NAMESPACE struct #define NS_NAMESPACE_END ; #endif // NS_USING_NAMESPACE #ifndef XP_MAC // PR_STDOUT and PR_STDIN are fatal on Macintosh. So for console i/o, we must use the std // stream stuff instead. However, we have to require that cout and cin are passed in // to the constructor because in the current build, there is a copy in the base.shlb, // and another in the caller's file. Passing it in as a parameter ensures that the // caller and this library are using the same global object. Groan. // // Unix currently does not support iostreams at all. Their compilers do not support // ANSI C++, or even ARM C++. // // Windows supports them, but only if you turn on the -GX compile flag, to support // exceptions. // Catch 22. #define NS_USE_PR_STDIO #endif #ifdef NS_USE_PR_STDIO class istream; class ostream; #define CONSOLE_IN 0 #define CONSOLE_OUT 0 #else #include using std::istream; using std::ostream; #define CONSOLE_IN &std::cin #define CONSOLE_OUT &std::cout #endif //=========================== End Compiler-specific macros =============================== //======================================================================================== class NS_BASE nsBasicFileStream //======================================================================================== { public: nsBasicFileStream(); nsBasicFileStream(PRFileDesc* desc, int nsprMode); nsBasicFileStream( const nsFilePath& inFile, int nsprMode, PRIntn accessMode); virtual ~nsBasicFileStream(); inline PRBool is_open() const { return mFileDesc != 0; } void open( const nsFilePath& inFile, int nsprMode, PRIntn accessMode); void close(); PRIntn tell() const; void seek(PRInt32 offset) { seek(PR_SEEK_SET, offset); } void seek(PRSeekWhence whence, PRInt32 offset); PRBool eof() const { return mEOF; } PRBool failed() const { return mFailed; } // call PR_GetError() for details protected: PRFileDesc* GetFileDescriptor() const { return mFileDesc; } protected: friend class nsBasicInStream; friend class nsBasicOutStream; PRFileDesc* mFileDesc; int mNSPRMode; PRBool mFailed; PRBool mEOF; }; // class nsBasicFileStream //======================================================================================== class NS_BASE nsBasicInStream //======================================================================================== { protected: nsBasicInStream(nsBasicFileStream& inStream, istream* stream); public: nsBasicInStream& operator >> (nsBasicInStream& (*pf)(nsBasicInStream&)) { return pf(*this); } void get(char& c); PRInt32 read(void* s, PRInt32 n); PRBool readline(char* s, PRInt32 n); // Result always null-terminated // false result indicates line was truncated // to fit buffer, or an error occurred. // Input streamers. Add more as needed nsBasicInStream& operator >> (char& ch); istream* GetStandardStream() const { return mStdStream; } protected: nsBasicFileStream& mBase; istream* mStdStream; }; // class nsBasicInStream //======================================================================================== class NS_BASE nsBasicOutStream //======================================================================================== { protected: nsBasicOutStream(nsBasicFileStream& inStream, ostream* stream); public: nsBasicOutStream& operator << (nsBasicOutStream& (*pf)(nsBasicOutStream&)) { return pf(*this); } void put(char c); PRInt32 write(const void* s, PRInt32 n); void flush(); // Output streamers. Add more as needed nsBasicOutStream& operator << (const char* buf); nsBasicOutStream& operator << (char ch); nsBasicOutStream& operator << (short val); nsBasicOutStream& operator << (unsigned short val); nsBasicOutStream& operator << (long val); nsBasicOutStream& operator << (unsigned long val); ostream* GetStandardStream() const { return mStdStream; } protected: nsBasicFileStream& mBase; ostream* mStdStream; }; // class nsBasicOutStream //======================================================================================== class NS_BASE nsInputFileStream //======================================================================================== : public nsBasicFileStream , public nsBasicInStream { public: enum { kDefaultMode = PR_RDONLY }; nsInputFileStream(istream* stream = CONSOLE_IN); nsInputFileStream( const nsFilePath& inFile, int nsprMode = kDefaultMode, PRIntn accessMode = 00700) // <- OCTAL : nsBasicFileStream(inFile, nsprMode, accessMode) , nsBasicInStream(*this, 0) {} void open( const nsFilePath& inFile, int nsprMode = kDefaultMode, PRIntn accessMode = 00700) // <- OCTAL { nsBasicFileStream::open(inFile, nsprMode, accessMode); } private: nsInputFileStream& operator >> (char* buf); // TOO DANGEROUS. DON'T DEFINE. }; // class nsInputFileStream //======================================================================================== class NS_BASE nsOutputFileStream //======================================================================================== : public nsBasicFileStream , public nsBasicOutStream { public: enum { kDefaultMode = (PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE) }; nsOutputFileStream(ostream* stream = CONSOLE_OUT); nsOutputFileStream( const nsFilePath& inFile, int nsprMode = kDefaultMode, PRIntn accessMode = 00700) // <- OCTAL : nsBasicFileStream(inFile, nsprMode, accessMode) , nsBasicOutStream(*this, 0) {} inline void open( const nsFilePath& inFile, int nsprMode = kDefaultMode, PRIntn accessMode = 00700) // <- OCTAL { nsBasicFileStream::open(inFile, nsprMode, accessMode); } }; // class nsOutputFileStream //======================================================================================== class NS_BASE nsIOFileStream //======================================================================================== : public nsBasicFileStream , public nsBasicOutStream , public nsBasicInStream { public: enum { kDefaultMode = (PR_RDWR | PR_CREATE_FILE) }; nsIOFileStream( const nsFilePath& inFile, int nsprMode = kDefaultMode, PRIntn accessMode = 00700) // <- OCTAL : nsBasicFileStream(inFile, nsprMode, accessMode) , nsBasicInStream(*this, 0) , nsBasicOutStream(*this, 0) {} inline void open( const nsFilePath& inFile, int nsprMode = kDefaultMode, PRIntn accessMode = 00700) // <- OCTAL { nsBasicFileStream::open(inFile, nsprMode, accessMode); } }; // class nsIOFileStream //======================================================================================== // Manipulators //======================================================================================== NS_BASE nsBasicOutStream& nsEndl(nsBasicOutStream& os); #endif /* _FILESTREAM_H_ */