diff options
| author | Nat Goodspeed <nat@lindenlab.com> | 2015-04-15 13:26:32 -0400 | 
|---|---|---|
| committer | Nat Goodspeed <nat@lindenlab.com> | 2015-04-15 13:26:32 -0400 | 
| commit | e9be710daf3d1135f732632d09007920e1d0ff81 (patch) | |
| tree | 1e695f44ef020bf59c745a2317484ce13fee9c29 | |
| parent | 9dbea04a5023d33ebac66463dd51b7050b7f41ab (diff) | |
Strip down the Windows ll[io]fstream implementations to constructors
and open() methods. The only remaining value added by ll[io]fstream over
std::[io]stream is proper handling of non-ASCII pathnames, which can be done
by deriving from std::[io]stream, converting pathname strings and passing them
to the corresponding base-class methods.
This is only necessary on Windows. On Posix, ll[io]fstream are already
typedefs for std::[io]fstream.
This change removes a significant volume of cruft from llfile.{h,cpp}.
| -rwxr-xr-x | indra/llcommon/llfile.cpp | 537 | ||||
| -rwxr-xr-x | indra/llcommon/llfile.h | 212 | 
2 files changed, 25 insertions, 724 deletions
| diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index 295c97eac8..873a7bce25 100755 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -421,551 +421,42 @@ LLFILE *	LLFile::_Fiopen(const std::string& filename,  #endif /* LL_WINDOWS */ -/************** llstdio file buffer ********************************/ - - -#if !LL_WINDOWS -llstdio_filebuf::int_type llstdio_filebuf::overflow(llstdio_filebuf::int_type __c) -{ -	int_type __ret = traits_type::eof(); -	const bool __testeof = traits_type::eq_int_type(__c, __ret); -	const bool __testout = _M_mode & ios_base::out; -	if (__testout && !_M_reading) -	{ -		if (this->pbase() < this->pptr()) -		{ -			// If appropriate, append the overflow char. -			if (!__testeof) -			{ -				*this->pptr() = traits_type::to_char_type(__c); -				this->pbump(1); -			} - -			// Convert pending sequence to external representation, -			// and output. -			if (_convert_to_external(this->pbase(), -					 this->pptr() - this->pbase())) -			{ -				_M_set_buffer(0); -				__ret = traits_type::not_eof(__c); -			} -		} -		else if (_M_buf_size > 1) -		{ -			// Overflow in 'uncommitted' mode: set _M_writing, set -			// the buffer to the initial 'write' mode, and put __c -			// into the buffer. -			_M_set_buffer(0); -			_M_writing = true; -			if (!__testeof) -			{ -				*this->pptr() = traits_type::to_char_type(__c); -				this->pbump(1); -			} -			__ret = traits_type::not_eof(__c); -		} -		else -		{ -			// Unbuffered. -			char_type __conv = traits_type::to_char_type(__c); -			if (__testeof || _convert_to_external(&__conv, 1)) -			{ -				_M_writing = true; -				__ret = traits_type::not_eof(__c); -			} -		} -	} -	return __ret; -} - -bool llstdio_filebuf::_convert_to_external(char_type* __ibuf, -						std::streamsize __ilen) -{ -	// Sizes of external and pending output. -	streamsize __elen; -	streamsize __plen; -	if (__check_facet(_M_codecvt).always_noconv()) -	{ -		//__elen = _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen); -		__elen = fwrite(reinterpret_cast<void*>(__ibuf), 1, -						__ilen, _M_file.file()); -		__plen = __ilen; -	} -	else -	{ -		// Worst-case number of external bytes needed. -		// XXX Not done encoding() == -1. -		streamsize __blen = __ilen * _M_codecvt->max_length(); -		char* __buf = static_cast<char*>(__builtin_alloca(__blen)); - -		char* __bend; -		const char_type* __iend; -		codecvt_base::result __r; -		__r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen, -				__iend, __buf, __buf + __blen, __bend); - -		if (__r == codecvt_base::ok || __r == codecvt_base::partial) -			__blen = __bend - __buf; -		else if (__r == codecvt_base::noconv) -		{ -			// Same as the always_noconv case above. -			__buf = reinterpret_cast<char*>(__ibuf); -			__blen = __ilen; -		} -		else -			__throw_ios_failure(__N("llstdio_filebuf::_convert_to_external " -									"conversion error")); -   -		//__elen = _M_file.xsputn(__buf, __blen); -		__elen = fwrite(__buf, 1, __blen, _M_file.file()); -		__plen = __blen; - -		// Try once more for partial conversions. -		if (__r == codecvt_base::partial && __elen == __plen) -		{ -			const char_type* __iresume = __iend; -			streamsize __rlen = this->pptr() - __iend; -			__r = _M_codecvt->out(_M_state_cur, __iresume, -					__iresume + __rlen, __iend, __buf, -					__buf + __blen, __bend); -			if (__r != codecvt_base::error) -			{ -				__rlen = __bend - __buf; -				//__elen = _M_file.xsputn(__buf, __rlen); -				__elen = fwrite(__buf, 1, __rlen, _M_file.file()); -				__plen = __rlen; -			} -			else -			{ -				__throw_ios_failure(__N("llstdio_filebuf::_convert_to_external " -										"conversion error")); -			} -		} -	} -	return __elen == __plen; -} - -llstdio_filebuf::int_type llstdio_filebuf::underflow() -{ -	int_type __ret = traits_type::eof(); -	const bool __testin = _M_mode & ios_base::in; -	if (__testin) -	{ -		if (_M_writing) -		{ -			if (overflow() == traits_type::eof()) -			return __ret; -			//_M_set_buffer(-1); -			//_M_writing = false; -		} -		// Check for pback madness, and if so switch back to the -		// normal buffers and jet outta here before expensive -		// fileops happen... -		_M_destroy_pback(); - -		if (this->gptr() < this->egptr()) -			return traits_type::to_int_type(*this->gptr()); - -		// Get and convert input sequence. -		const size_t __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1; - -		// Will be set to true if ::fread() returns 0 indicating EOF. -		bool __got_eof = false; -		// Number of internal characters produced. -		streamsize __ilen = 0; -		codecvt_base::result __r = codecvt_base::ok; -		if (__check_facet(_M_codecvt).always_noconv()) -		{ -			//__ilen = _M_file.xsgetn(reinterpret_cast<char*>(this->eback()), -			//			__buflen); -			__ilen = fread(reinterpret_cast<void*>(this->eback()), 1, -						__buflen, _M_file.file()); -			if (__ilen == 0) -				__got_eof = true; -		} -		else -	    { -			// Worst-case number of external bytes. -			// XXX Not done encoding() == -1. -			const int __enc = _M_codecvt->encoding(); -			streamsize __blen; // Minimum buffer size. -			streamsize __rlen; // Number of chars to read. -			if (__enc > 0) -				__blen = __rlen = __buflen * __enc; -			else -			{ -				__blen = __buflen + _M_codecvt->max_length() - 1; -				__rlen = __buflen; -			} -			const streamsize __remainder = _M_ext_end - _M_ext_next; -			__rlen = __rlen > __remainder ? __rlen - __remainder : 0; - -			// An imbue in 'read' mode implies first converting the external -			// chars already present. -			if (_M_reading && this->egptr() == this->eback() && __remainder) -				__rlen = 0; - -			// Allocate buffer if necessary and move unconverted -			// bytes to front. -			if (_M_ext_buf_size < __blen) -			{ -				char* __buf = new char[__blen]; -				if (__remainder) -					__builtin_memcpy(__buf, _M_ext_next, __remainder); - -				delete [] _M_ext_buf; -				_M_ext_buf = __buf; -				_M_ext_buf_size = __blen; -			} -			else if (__remainder) -				__builtin_memmove(_M_ext_buf, _M_ext_next, __remainder); - -			_M_ext_next = _M_ext_buf; -			_M_ext_end = _M_ext_buf + __remainder; -			_M_state_last = _M_state_cur; - -			do -			{ -				if (__rlen > 0) -				{ -					// Sanity check! -					// This may fail if the return value of -					// codecvt::max_length() is bogus. -					if (_M_ext_end - _M_ext_buf + __rlen > _M_ext_buf_size) -					{ -						__throw_ios_failure(__N("llstdio_filebuf::underflow " -							"codecvt::max_length() " -							"is not valid")); -					} -					//streamsize __elen = _M_file.xsgetn(_M_ext_end, __rlen); -					streamsize __elen = fread(_M_ext_end, 1, -						__rlen, _M_file.file()); -					if (__elen == 0) -						__got_eof = true; -					else if (__elen == -1) -					break; -					//_M_ext_end += __elen; -				} - -				char_type* __iend = this->eback(); -				if (_M_ext_next < _M_ext_end) -				{ -					__r = _M_codecvt->in(_M_state_cur, _M_ext_next, -							_M_ext_end, _M_ext_next, -							this->eback(), -							this->eback() + __buflen, __iend); -				} -				if (__r == codecvt_base::noconv) -				{ -					size_t __avail = _M_ext_end - _M_ext_buf; -					__ilen = std::min(__avail, __buflen); -					traits_type::copy(this->eback(), -						reinterpret_cast<char_type*> -						(_M_ext_buf), __ilen); -					_M_ext_next = _M_ext_buf + __ilen; -				} -				else -					__ilen = __iend - this->eback(); - -				// _M_codecvt->in may return error while __ilen > 0: this is -				// ok, and actually occurs in case of mixed encodings (e.g., -				// XML files). -				if (__r == codecvt_base::error) -					break; - -				__rlen = 1; -			} while (__ilen == 0 && !__got_eof); -		} - -		if (__ilen > 0) -		{ -			_M_set_buffer(__ilen); -			_M_reading = true; -			__ret = traits_type::to_int_type(*this->gptr()); -		} -		else if (__got_eof) -		{ -			// If the actual end of file is reached, set 'uncommitted' -			// mode, thus allowing an immediate write without an -			// intervening seek. -			_M_set_buffer(-1); -			_M_reading = false; -			// However, reaching it while looping on partial means that -			// the file has got an incomplete character. -			if (__r == codecvt_base::partial) -				__throw_ios_failure(__N("llstdio_filebuf::underflow " -					"incomplete character in file")); -		} -		else if (__r == codecvt_base::error) -			__throw_ios_failure(__N("llstdio_filebuf::underflow " -					"invalid byte sequence in file")); -		else -			__throw_ios_failure(__N("llstdio_filebuf::underflow " -					"error reading the file")); -	} -	return __ret; -} - -std::streamsize llstdio_filebuf::xsgetn(char_type* __s, std::streamsize __n) -{ -	// Clear out pback buffer before going on to the real deal... -	streamsize __ret = 0; -	if (_M_pback_init) -	{ -		if (__n > 0 && this->gptr() == this->eback()) -		{ -			*__s++ = *this->gptr(); -			this->gbump(1); -			__ret = 1; -			--__n; -		} -		_M_destroy_pback(); -	} -        -	// Optimization in the always_noconv() case, to be generalized in the -	// future: when __n > __buflen we read directly instead of using the -	// buffer repeatedly. -	const bool __testin = _M_mode & ios_base::in; -	const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1; - -	if (__n > __buflen && __check_facet(_M_codecvt).always_noconv() -		&& __testin && !_M_writing) -	{ -		// First, copy the chars already present in the buffer. -		const streamsize __avail = this->egptr() - this->gptr(); -		if (__avail != 0) -		{ -			if (__avail == 1) -				*__s = *this->gptr(); -			else -				traits_type::copy(__s, this->gptr(), __avail); -			__s += __avail; -			this->gbump(__avail); -			__ret += __avail; -			__n -= __avail; -		} - -		// Need to loop in case of short reads (relatively common -		// with pipes). -		streamsize __len; -		for (;;) -		{ -			//__len = _M_file.xsgetn(reinterpret_cast<char*>(__s), __n); -			__len = fread(reinterpret_cast<void*>(__s), 1,  -						__n, _M_file.file()); -			if (__len == -1) -				__throw_ios_failure(__N("llstdio_filebuf::xsgetn " -										"error reading the file")); -			if (__len == 0) -				break; - -			__n -= __len; -			__ret += __len; -			if (__n == 0) -				break; - -			__s += __len; -		} - -		if (__n == 0) -		{ -			_M_set_buffer(0); -			_M_reading = true; -		} -		else if (__len == 0) -		{ -			// If end of file is reached, set 'uncommitted' -			// mode, thus allowing an immediate write without -			// an intervening seek. -			_M_set_buffer(-1); -			_M_reading = false; -		} -	} -	else -		__ret += __streambuf_type::xsgetn(__s, __n); - -	return __ret; -} - -std::streamsize llstdio_filebuf::xsputn(const char_type* __s, std::streamsize __n) -{ -	// Optimization in the always_noconv() case, to be generalized in the -	// future: when __n is sufficiently large we write directly instead of -	// using the buffer. -	streamsize __ret = 0; -	const bool __testout = _M_mode & ios_base::out; -	if (__check_facet(_M_codecvt).always_noconv() -		&& __testout && !_M_reading) -	{ -		// Measurement would reveal the best choice. -		const streamsize __chunk = 1ul << 10; -		streamsize __bufavail = this->epptr() - this->pptr(); - -		// Don't mistake 'uncommitted' mode buffered with unbuffered. -		if (!_M_writing && _M_buf_size > 1) -			__bufavail = _M_buf_size - 1; - -		const streamsize __limit = std::min(__chunk, __bufavail); -		if (__n >= __limit) -		{ -			const streamsize __buffill = this->pptr() - this->pbase(); -			const char* __buf = reinterpret_cast<const char*>(this->pbase()); -			//__ret = _M_file.xsputn_2(__buf, __buffill, -			//			reinterpret_cast<const char*>(__s), __n); -			if (__buffill) -			{ -				__ret = fwrite(__buf, 1, __buffill, _M_file.file()); -			} -			if (__ret == __buffill) -			{ -				__ret += fwrite(reinterpret_cast<const char*>(__s), 1, -								__n, _M_file.file()); -			} -			if (__ret == __buffill + __n) -			{ -				_M_set_buffer(0); -				_M_writing = true; -			} -			if (__ret > __buffill) -				__ret -= __buffill; -			else -				__ret = 0; -		} -		else -			__ret = __streambuf_type::xsputn(__s, __n); -	} -	else -		__ret = __streambuf_type::xsputn(__s, __n); -    return __ret; -} - -int llstdio_filebuf::sync() -{ -	return (_M_file.sync() == 0 ? 0 : -1); -} -#endif  #if LL_WINDOWS  /************** input file stream ********************************/ -llifstream::llifstream() : -    _M_filebuf(), -	std::istream(&_M_filebuf) -{ -} +llifstream::llifstream() {}  // explicit -llifstream::llifstream(const std::string& _Filename,  -                       ios_base::openmode _Mode) : -    _M_filebuf(), -	std::istream(&_M_filebuf) +llifstream::llifstream(const std::string& _Filename, ios_base::openmode _Mode): +    std::ifstream(utf8str_to_utf16str( _Filename ).c_str(), +                  _Mode | ios_base::in)  { -	llutf16string wideName = utf8str_to_utf16str( _Filename ); -	if (_M_filebuf.open(wideName.c_str(), _Mode | ios_base::in) == 0) -	{ -		_Myios::setstate(ios_base::failbit); -	}  } -// explicit -llifstream::llifstream(const char* _Filename,  -                       ios_base::openmode _Mode) : -    _M_filebuf(), -	std::istream(&_M_filebuf) +void llifstream::open(const std::string& _Filename, ios_base::openmode _Mode)  { -	llutf16string wideName = utf8str_to_utf16str( _Filename ); -	if (_M_filebuf.open(wideName.c_str(), _Mode | ios_base::in) == 0) -	{ -		_Myios::setstate(ios_base::failbit); -	} -} - -bool llifstream::is_open() const -{	// test if C stream has been opened -	return _M_filebuf.is_open(); -} - -void llifstream::open(const char* _Filename, ios_base::openmode _Mode) -{	// open a C stream with specified mode -	llutf16string wideName = utf8str_to_utf16str( _Filename ); -	if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::in) == 0) -	{ -		_Myios::setstate(ios_base::failbit); -	} -	else -	{ -		_Myios::clear(); -	} -} - -void llifstream::close() -{	// close the C stream -	if (_M_filebuf.close() == 0) -	{ -		_Myios::setstate(ios_base::failbit); -	} +    std::ifstream::open(utf8str_to_utf16str(_Filename).c_str(), +                        _Mode | ios_base::in);  }  /************** output file stream ********************************/ -llofstream::llofstream() : -    _M_filebuf(), -	std::ostream(&_M_filebuf) -{ -} +llofstream::llofstream() {}  // explicit -llofstream::llofstream(const std::string& _Filename, -                       ios_base::openmode _Mode) : -    _M_filebuf(), -	std::ostream(&_M_filebuf) +llofstream::llofstream(const std::string& _Filename, ios_base::openmode _Mode): +    std::ofstream(utf8str_to_utf16str( _Filename ).c_str(), +                  _Mode | ios_base::out)  { -	llutf16string wideName = utf8str_to_utf16str( _Filename ); -	if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0) -	{ -		_Myios::setstate(ios_base::failbit); -	}  } -// explicit -llofstream::llofstream(const char* _Filename, -                       ios_base::openmode _Mode) : -    _M_filebuf(), -	std::ostream(&_M_filebuf) +void llofstream::open(const std::string& _Filename, ios_base::openmode _Mode)  { -	llutf16string wideName = utf8str_to_utf16str( _Filename ); -	if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0) -	{ -		_Myios::setstate(ios_base::failbit); -	} -} - -bool llofstream::is_open() const -{	// test if C stream has been opened -	return _M_filebuf.is_open(); -} - -void llofstream::open(const char* _Filename, ios_base::openmode _Mode) -{	// open a C stream with specified mode -	llutf16string wideName = utf8str_to_utf16str( _Filename ); -	if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0) -	{ -		_Myios::setstate(ios_base::failbit); -	} -	else -	{ -		_Myios::clear(); -	} -} - -void llofstream::close() -{	// close the C stream -	if (_M_filebuf.close() == 0) -	{ -		_Myios::setstate(ios_base::failbit); -	} +    std::ofstream::open(utf8str_to_utf16str( _Filename ).c_str(), +                        _Mode | ios_base::out);  }  /************** helper functions ********************************/ diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h index 347c9867aa..423f1f4965 100755 --- a/indra/llcommon/llfile.h +++ b/indra/llcommon/llfile.h @@ -86,123 +86,16 @@ public:  	static  const char * tmpdir();  }; -/** - *  @brief Provides a layer of compatibility for C/POSIX. - * - *  This is taken from both the GNU __gnu_cxx::stdio_filebuf extension and  - *  VC's basic_filebuf implementation. - *  This file buffer provides extensions for working with standard C FILE*'s  - *  and POSIX file descriptors for platforms that support this. -*/ -namespace -{ -#if LL_WINDOWS -typedef std::filebuf						_Myfb; -#else -typedef  __gnu_cxx::stdio_filebuf< char >	_Myfb; -typedef std::__c_file						_Filet; -#endif /* LL_WINDOWS */ -} - -class LL_COMMON_API llstdio_filebuf : public _Myfb -{ -public: -	/** -	 * deferred initialization / destruction -	*/ -	llstdio_filebuf() : _Myfb() {} -	virtual ~llstdio_filebuf() {}  - -	/** -	 *  @param  f  An open @c FILE*. -	 *  @param  mode  Same meaning as in a standard filebuf. -	 *  @param  size  Optimal or preferred size of internal buffer, in chars. -	 *                Defaults to system's @c BUFSIZ. -	 * -	 *  This constructor associates a file stream buffer with an open -	 *  C @c FILE*.  The @c FILE* will not be automatically closed when the -	 *  stdio_filebuf is closed/destroyed. -	*/ -	llstdio_filebuf(_Filet* __f, std::ios_base::openmode __mode, -		    //size_t __size = static_cast<size_t>(BUFSIZ)) : -		    size_t __size = static_cast<size_t>(1)) : -#if LL_WINDOWS -		_Myfb(__f) {} -#else -		_Myfb(__f, __mode, __size) {} -#endif - -	/** -	 *  @brief  Opens an external file. -	 *  @param  s  The name of the file. -	 *  @param  mode  The open mode flags. -	 *  @return  @c this on success, NULL on failure -	 * -	 *  If a file is already open, this function immediately fails. -	 *  Otherwise it tries to open the file named @a s using the flags -	 *  given in @a mode. -	*/ -	//llstdio_filebuf* open(const char *_Filename, -	//		std::ios_base::openmode _Mode); - -	/** -	 *  @param  fd  An open file descriptor. -	 *  @param  mode  Same meaning as in a standard filebuf. -	 *  @param  size  Optimal or preferred size of internal buffer, in chars. -	 * -	 *  This constructor associates a file stream buffer with an open -	 *  POSIX file descriptor. The file descriptor will be automatically -	 *  closed when the stdio_filebuf is closed/destroyed. -	*/ -#if !LL_WINDOWS -	llstdio_filebuf(int __fd, std::ios_base::openmode __mode, -		//size_t __size = static_cast<size_t>(BUFSIZ)) : -		size_t __size = static_cast<size_t>(1)) : -		_Myfb(__fd, __mode, __size) {} -#endif - -// *TODO: Seek the underlying c stream for better cross-platform compatibility? -#if !LL_WINDOWS -protected: -	/** underflow() and uflow() functions are called to get the next -	 *  character from the real input source when the buffer is empty. -	 *  Buffered input uses underflow() -	*/ -	/*virtual*/ int_type underflow(); - -	/*  Convert internal byte sequence to external, char-based -	 * sequence via codecvt. -	*/ -	bool _convert_to_external(char_type*, std::streamsize); - -	/** The overflow() function is called to transfer characters to the -	 *  real output destination when the buffer is full. A call to -	 *  overflow(c) outputs the contents of the buffer plus the -	 *  character c. -	 *  Consume some sequence of the characters in the pending sequence. -	*/ -	/*virtual*/ int_type overflow(int_type __c = traits_type::eof()); - -	/** sync() flushes the underlying @c FILE* stream. -	*/ -	/*virtual*/ int sync(); - -	std::streamsize xsgetn(char_type*, std::streamsize); -	std::streamsize xsputn(const char_type*, std::streamsize); -#endif -}; -  #if LL_WINDOWS  /**   *  @brief  Controlling input for files.   *   *  This class supports reading from named files, using the inherited - *  functions from std::basic_istream.  To control the associated - *  sequence, an instance of std::basic_filebuf (or a platform-specific derivative) - *  which allows construction using a pre-exisintg file stream buffer.  - *  We refer to this std::basic_filebuf (or derivative) as @c sb. + *  functions from std::ifstream. The only added value is that our constructor + *  Does The Right Thing when passed a non-ASCII pathname. Sadly, that isn't + *  true of Microsoft's std::ifstream.   */ -class LL_COMMON_API llifstream	:	public	std::istream +class LL_COMMON_API llifstream	:	public	std::ifstream  {  	// input stream associated with a C stream    public: @@ -225,32 +118,6 @@ class LL_COMMON_API llifstream	:	public	std::istream       */  	explicit llifstream(const std::string& _Filename,                          ios_base::openmode _Mode = ios_base::in); -	explicit llifstream(const char* _Filename, -                        ios_base::openmode _Mode = ios_base::in); - -	/** -	 *  @brief  The destructor does nothing. -	 * -	 *  The file is closed by the filebuf object, not the formatting -	 *  stream. -     */ -	virtual ~llifstream() {} - -	// Members: -	/** -	 *  @brief  Accessing the underlying buffer. -	 *  @return  The current basic_filebuf buffer. -	 * -	 *  This hides both signatures of std::basic_ios::rdbuf(). -	*/ -	llstdio_filebuf* rdbuf() const -	{ return const_cast<llstdio_filebuf*>(&_M_filebuf); } - -	/** -	 *  @brief  Wrapper to test for an open file. -	 *  @return  @c rdbuf()->is_open() -     */ -	bool is_open() const;  	/**  	 *  @brief  Opens an external file. @@ -261,34 +128,19 @@ class LL_COMMON_API llifstream	:	public	std::istream  	 *  fails, @c failbit is set in the stream's error state.       */  	void open(const std::string& _Filename, -              ios_base::openmode _Mode = ios_base::in) -	{ open(_Filename.c_str(), _Mode); } -	void open(const char* _Filename,                ios_base::openmode _Mode = ios_base::in); - -	/** -	 *  @brief  Close the file. -	 * -	 *  Calls @c llstdio_filebuf::close().  If that function -	 *  fails, @c failbit is set in the stream's error state. -     */ -	void close(); - -  private: -	llstdio_filebuf _M_filebuf;  };  /**   *  @brief  Controlling output for files.   * - *  This class supports writing to named files, using the inherited - *  functions from std::basic_ostream.  To control the associated - *  sequence, an instance of std::basic_filebuf (or a platform-specific derivative) - *  which allows construction using a pre-exisintg file stream buffer.  - *  We refer to this std::basic_filebuf (or derivative) as @c sb. + *  This class supports writing to named files, using the inherited functions + *  from std::ofstream. The only added value is that our constructor Does The + *  Right Thing when passed a non-ASCII pathname. Sadly, that isn't true of + *  Microsoft's std::ofstream.  */ -class LL_COMMON_API llofstream	:	public	std::ostream +class LL_COMMON_API llofstream	:	public	std::ofstream  {    public:  	// Constructors: @@ -306,62 +158,20 @@ class LL_COMMON_API llofstream	:	public	std::ostream  	 *  @param  Filename  String specifying the filename.  	 *  @param  Mode  Open file in specified mode (see std::ios_base).  	 * -	 *  @c ios_base::out|ios_base::trunc is automatically included in -	 *  @a mode. +	 *  @c ios_base::out is automatically included in @a mode.       */  	explicit llofstream(const std::string& _Filename,                          ios_base::openmode _Mode = ios_base::out|ios_base::trunc); -	explicit llofstream(const char* _Filename, -                        ios_base::openmode _Mode = ios_base::out|ios_base::trunc); - -	/** -	 *  @brief  The destructor does nothing. -	 * -	 *  The file is closed by the filebuf object, not the formatting -	 *  stream. -	*/ -	virtual ~llofstream() {} - -	// Members: -	/** -	 *  @brief  Accessing the underlying buffer. -	 *  @return  The current basic_filebuf buffer. -	 * -	 *  This hides both signatures of std::basic_ios::rdbuf(). -	*/ -	llstdio_filebuf* rdbuf() const -	{ return const_cast<llstdio_filebuf*>(&_M_filebuf); } - -	/** -	 *  @brief  Wrapper to test for an open file. -	 *  @return  @c rdbuf()->is_open() -	*/ -	bool is_open() const;  	/**  	 *  @brief  Opens an external file.  	 *  @param  Filename  The name of the file.  	 *  @param  Node  The open mode flags.  	 * -	 *  Calls @c llstdio_filebuf::open(s,mode|out).  If that function -	 *  fails, @c failbit is set in the stream's error state. +	 *  @c ios_base::out is automatically included in @a mode.       */  	void open(const std::string& _Filename, -              ios_base::openmode _Mode = ios_base::out|ios_base::trunc) -	{ open(_Filename.c_str(), _Mode); } -	void open(const char* _Filename,                ios_base::openmode _Mode = ios_base::out|ios_base::trunc); - -	/** -	 *  @brief  Close the file. -	 * -	 *  Calls @c llstdio_filebuf::close().  If that function -	 *  fails, @c failbit is set in the stream's error state. -     */ -	void close(); - -  private: -	llstdio_filebuf _M_filebuf;  }; | 
