summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2015-07-05 08:49:44 -0400
committerNat Goodspeed <nat@lindenlab.com>2015-07-05 08:49:44 -0400
commit3a5f35e2777a7ab0bc139e94342d895b8bb346ed (patch)
treebde878aa8ad3464cb4d6880f325e8b7ab94c0177 /indra
parent4aa64b99dbe6cafdccf0c25501feaef5ba3445c4 (diff)
parent0d84128983effb76c045dc38d3dd1478daecff83 (diff)
Automated merge with ssh://bitbucket.org/lindenlab/viewer-release
Diffstat (limited to 'indra')
-rwxr-xr-xindra/llcommon/llfile.cpp537
-rwxr-xr-xindra/llcommon/llfile.h213
2 files changed, 25 insertions, 725 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..3e25228aeb 100755
--- a/indra/llcommon/llfile.h
+++ b/indra/llcommon/llfile.h
@@ -45,7 +45,6 @@ typedef FILE LLFILE;
typedef struct _stat llstat;
#else
typedef struct stat llstat;
-#include <ext/stdio_filebuf.h>
#include <bits/postypes.h>
#endif
@@ -86,123 +85,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 +117,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 +127,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 +157,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;
};