Mozilla/mozilla/xpcom/io/nsFileStream.h
mcmullen%netscape.com cf8dafefa3 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
1998-12-08 22:45:42 +00:00

782 lines
30 KiB
C++

/* -*- 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, 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 <istream>
#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
#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 charT, class traits>
class nsFileBufferT
//========================================================================================
: public basic_streambuf<charT, traits>
{
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 nsFileBufferT<charT, traits> filebuf_type;
typedef codecvt<charT, char, state_type> ofacet_type;
typedef codecvt<char, charT, state_type> ifacet_type;
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<charT, traits>* 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_;
}; // class nsFileBufferT
//========================================================================================
template<class charT, class traits>
class nsInputFileStreamT
//========================================================================================
: public basic_istream<charT, traits>
{
typedef nsFileBufferT<charT, traits> 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;
nsInputFileStreamT();
explicit nsInputFileStreamT(
const nsFilePath& inFile,
ios_base::openmode mode=ios_base::in,
PRIntn accessMode = 0x00400);
virtual ~nsInputFileStreamT();
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;
}; // class nsInputFileStreamT
//========================================================================================
template<class charT, class traits>
class nsOutputFileStreamT
//========================================================================================
: public basic_ostream<charT, traits>
{
typedef nsFileBufferT<charT, traits> 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;
nsOutputFileStreamT();
explicit nsOutputFileStreamT(
const nsFilePath& inFile,
ios_base::openmode mode = ios_base::out|ios_base::trunc,
PRIntn accessMode = 0x00200);
virtual ~nsOutputFileStreamT();
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;
}; // class nsOutputFileStreamT
//========================================================================================
// Implementation of nsFileBufferT
//========================================================================================
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline nsFileBufferT<charT, traits>::nsFileBufferT()
: basic_streambuf<charT, traits>(), mFileDesc(NULL)
//----------------------------------------------------------------------------------------
{
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline nsFileBufferT<charT, traits>::nsFileBufferT(PRFileDesc* pfarg)
: basic_streambuf<charT, traits>(), mFileDesc(pfarg)
//----------------------------------------------------------------------------------------
{
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline nsFileBufferT<charT, traits>::~nsFileBufferT()
//----------------------------------------------------------------------------------------
{
close();
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline bool
nsFileBufferT<charT, traits>::is_open() const
//----------------------------------------------------------------------------------------
{
NS_READ_LOCK(_mutex);
return bool(mFileDesc); // in case it is typedefed to int
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
nsFileBufferT<charT, traits>::filebuf_type*
nsFileBufferT<charT, traits>::open(
const nsFilePath& inFile,
ios_base::openmode mode,
PRIntn accessMode)
//----------------------------------------------------------------------------------------
{
if (mFileDesc)
return 0;
NS_WRITE_LOCK(_mutex);
mFileDesc = nsFileStreamHelpers::open(inFile, mode, accessMode);
if (!mFileDesc)
return 0;
mode_ = mode;
return this;
} // nsFileBufferT<charT, traits>::open
//----------------------------------------------------------------------------------------
template<class charT, class traits>
nsFileBufferT<charT, traits>::filebuf_type* nsFileBufferT<charT, traits>::close()
//----------------------------------------------------------------------------------------
{
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;
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline int
nsFileBufferT<charT, traits>:: sync()
//----------------------------------------------------------------------------------------
{
return (mFileDesc ? (int)PR_Sync(mFileDesc) : 0);
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline basic_streambuf<charT, traits>*
nsFileBufferT<charT, traits>::setbuf(char_type*, streamsize)
//----------------------------------------------------------------------------------------
{
return (!mFileDesc) ? 0 : this;
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
nsFileBufferT<charT, traits>::int_type nsFileBufferT<charT, traits>::overflow(int_type c)
//----------------------------------------------------------------------------------------
{
#ifdef NS_EXPLICIT_FUNC_TEMPLATE_ARG
const ofacet_type& ft=use_facet<ofacet_type>(loc);
#else
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;
}
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline nsFileBufferT<charT, traits>::int_type nsFileBufferT<charT, traits>::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;
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
streamsize nsFileBufferT<charT, traits>::xsputn(const char_type* s, streamsize n)
//----------------------------------------------------------------------------------------
{
#ifdef NS_EXPLICIT_FUNC_TEMPLATE_ARG
const ofacet_type& ft=use_facet<ofacet_type>(loc);
#else
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<ofacet_type>(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)
#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));
}
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline nsFileBufferT<charT, traits>::int_type
nsFileBufferT<charT, traits>::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;
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline nsFileBufferT<charT, traits>::int_type nsFileBufferT<charT, traits>::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;
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline streamsize nsFileBufferT<charT, traits>::xsgetn(char_type* s, streamsize n)
//----------------------------------------------------------------------------------------
{
return mFileDesc ? (streamsize)PR_Read(mFileDesc, s, sizeof(char) * size_t(n)) : 0;
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline void nsFileBufferT<charT, traits>::imbue(const locale& loc_arg)
//----------------------------------------------------------------------------------------
{
loc = loc_arg;
}
template<class charT, class traits>
inline streamsize
nsFileBufferT<charT, traits>::showmanyc()
{
return (streamsize)PR_Available(mFileDesc);
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
nsFileBufferT<charT, traits>::pos_type nsFileBufferT<charT, traits>::seekoff(
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);
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
nsFileBufferT<charT, traits>::pos_type
nsFileBufferT<charT, traits>::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;
}
//========================================================================================
// Implementation of nsInputFileStreamT
//========================================================================================
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline nsInputFileStreamT<charT, traits>::nsInputFileStreamT()
: basic_istream<charT, traits>(&mBuffer)
//----------------------------------------------------------------------------------------
{
// already inited
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline nsInputFileStreamT<charT, traits>::nsInputFileStreamT(
const nsFilePath& inFile,
ios_base::openmode mode,
PRIntn accessMode)
//----------------------------------------------------------------------------------------
: basic_istream<charT, traits>(&mBuffer)
{
// already inited
if (!mBuffer.open(inFile, openmode(mode|in), accessMode))
setstate(failbit);
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline nsInputFileStreamT<charT, traits>::~nsInputFileStreamT()
//----------------------------------------------------------------------------------------
{
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline nsInputFileStreamT<charT, traits>::filebuf_type*
nsInputFileStreamT<charT, traits>::rdbuf() const
//----------------------------------------------------------------------------------------
{
return (filebuf_type*)&mBuffer;
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline bool
nsInputFileStreamT<charT, traits>:: is_open()
//----------------------------------------------------------------------------------------
{
return mBuffer.is_open();
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline void
nsInputFileStreamT<charT, traits>::open(
const nsFilePath& inFile,
ios_base::openmode mode,
PRIntn accessMode)
//----------------------------------------------------------------------------------------
{
if (!mBuffer.open(inFile, openmode(mode|in), accessMode))
setstate(failbit);
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline void nsInputFileStreamT<charT, traits>::close()
//----------------------------------------------------------------------------------------
{
if (!mBuffer.close())
setstate(failbit);
}
//========================================================================================
// Implementation of nsOutputFileStreamT
//========================================================================================
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline nsOutputFileStreamT<charT, traits>::nsOutputFileStreamT()
: basic_ostream<charT, traits>(&mBuffer)
//----------------------------------------------------------------------------------------
{
// already inited
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
nsOutputFileStreamT<charT, traits>::nsOutputFileStreamT(
const nsFilePath& inFile,
ios_base::openmode mode,
PRIntn accessMode)
//----------------------------------------------------------------------------------------
: basic_ostream<charT, traits>(&mBuffer)
{
// already inited
if (!mBuffer.open(inFile, openmode(mode|out), accessMode))
setstate(failbit);
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline nsOutputFileStreamT<charT, traits>::~nsOutputFileStreamT()
//----------------------------------------------------------------------------------------
{
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline nsOutputFileStreamT<charT, traits>::filebuf_type*
nsOutputFileStreamT<charT, traits>::rdbuf() const
//----------------------------------------------------------------------------------------
{
return (filebuf_type*)&mBuffer;
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline bool nsOutputFileStreamT<charT, traits>:: is_open()
//----------------------------------------------------------------------------------------
{
return mBuffer.is_open();
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline void nsOutputFileStreamT<charT, traits>::open(
const nsFilePath& inFile,
ios_base::openmode mode,
PRIntn accessMode)
//----------------------------------------------------------------------------------------
{
if (!mBuffer.open(inFile, openmode(mode | out), accessMode))
setstate(failbit);
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline void nsOutputFileStreamT<charT, traits>:: close()
//----------------------------------------------------------------------------------------
{
if (!mBuffer.close())
setstate(failbit);
}
//========================================================================================
template<class charT, class traits>
class nsIOFileStreamT : public basic_iostream<charT, traits>
//========================================================================================
{
typedef nsFileBufferT<charT, traits> 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;
nsIOFileStreamT();
explicit nsIOFileStreamT(
const nsFilePath& inFile,
ios_base::openmode mode = ios_base::in|ios_base::out,
PRIntn accessMode = 0x00600);
virtual ~nsIOFileStreamT();
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;
}; // class nsIOFileStreamT
//========================================================================================
// Implementation of nsIOFileStream
//========================================================================================
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline nsIOFileStreamT<charT, traits>::nsIOFileStreamT()
//----------------------------------------------------------------------------------------
: mBuffer(), basic_iostream<charT, traits>(&mBuffer)
{
// already inited
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline nsIOFileStreamT<charT, traits>::nsIOFileStreamT(
const nsFilePath& inFile,
ios_base::openmode mode,
PRIntn accessMode)
//----------------------------------------------------------------------------------------
: mBuffer(), basic_iostream<charT, traits>(&mBuffer)
{
// already inited
if (!mBuffer.open(inFile, mode, accessMode))
setstate(failbit);
}
template<class charT, class traits>
inline nsIOFileStreamT<charT, traits>::~nsIOFileStreamT()
{
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline nsIOFileStreamT<charT, traits>::filebuf_type*
nsIOFileStreamT<charT, traits>::rdbuf() const
//----------------------------------------------------------------------------------------
{
return (filebuf_type*)&mBuffer;
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline bool
nsIOFileStreamT<charT, traits>::is_open()
//----------------------------------------------------------------------------------------
{
return mBuffer.is_open();
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline void
nsIOFileStreamT<charT, traits>::open(
const nsFilePath& inFile,
ios_base::openmode mode,
PRIntn accessMode)
//----------------------------------------------------------------------------------------
{
if (!mBuffer.open(inFile, mode, accessMode))
setstate(failbit);
}
//----------------------------------------------------------------------------------------
template<class charT, class traits>
inline void
nsIOFileStreamT<charT, traits>::close()
//----------------------------------------------------------------------------------------
{
if (!mBuffer.close())
setstate(failbit);
}
//========================================================================================
// Specializations of the stream templates
//========================================================================================
typedef nsFileBufferT<char, char_traits<char> > nsFileBuffer;
typedef nsInputFileStreamT<char, char_traits<char> > nsInputFileStream;
typedef nsOutputFileStreamT<char, char_traits<char> > nsOutputFileStream;
typedef nsIOFileStreamT<char, char_traits<char> > nsIOFileStream;
#ifdef NS_USING_WIDE_CHAR
typedef nsFileBufferT<wchar_t, char_traits<wchar_t> > nsWideFileBuffer;
typedef nsInputFileStreamT<wchar_t, char_traits<wchar_t> > nsWideInputFileStream;
typedef nsOutputFileStreamT<wchar_t, char_traits<wchar_t> > nsWideOutputFileStream;
typedef nsIOFileStreamT<wchar_t, char_traits<wchar_t> > nsWideIOFileStream;
#endif // NS_USING_WIDE_CHAR
#endif /* _FILESTREAM_H_ */