diff options
Diffstat (limited to 'Source/kwsys/FStream.hxx.in')
-rw-r--r-- | Source/kwsys/FStream.hxx.in | 276 |
1 files changed, 276 insertions, 0 deletions
diff --git a/Source/kwsys/FStream.hxx.in b/Source/kwsys/FStream.hxx.in new file mode 100644 index 0000000..a4c65fe --- /dev/null +++ b/Source/kwsys/FStream.hxx.in @@ -0,0 +1,276 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ +#ifndef @KWSYS_NAMESPACE@_FStream_hxx +#define @KWSYS_NAMESPACE@_FStream_hxx + +#include <@KWSYS_NAMESPACE@/Configure.hxx> + +#include <@KWSYS_NAMESPACE@/Encoding.hxx> + +#include <fstream> +#if defined(_WIN32) +#if !defined(_MSC_VER) && @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H +#include <ext/stdio_filebuf.h> +#endif +#endif + +namespace @KWSYS_NAMESPACE@ { +#if defined(_WIN32) && \ + (defined(_MSC_VER) || @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H) +#if defined(_NOEXCEPT) +#define @KWSYS_NAMESPACE@_FStream_NOEXCEPT _NOEXCEPT +#else +#define @KWSYS_NAMESPACE@_FStream_NOEXCEPT +#endif + +#if defined(_MSC_VER) + +template <typename CharType, typename Traits> +class basic_filebuf : public std::basic_filebuf<CharType, Traits> +{ +#if _MSC_VER >= 1400 +public: + typedef std::basic_filebuf<CharType, Traits> my_base_type; + basic_filebuf* open(char const* s, std::ios_base::openmode mode) + { + const std::wstring wstr = Encoding::ToWindowsExtendedPath(s); + return static_cast<basic_filebuf*>(my_base_type::open(wstr.c_str(), mode)); + } +#endif +}; + +#else + +inline std::wstring getcmode(const std::ios_base::openmode mode) +{ + std::wstring cmode; + bool plus = false; + if (mode & std::ios_base::app) { + cmode += L"a"; + plus = mode & std::ios_base::in ? true : false; + } else if (mode & std::ios_base::trunc || + (mode & std::ios_base::out && (mode & std::ios_base::in) == 0)) { + cmode += L"w"; + plus = mode & std::ios_base::in ? true : false; + } else { + cmode += L"r"; + plus = mode & std::ios_base::out ? true : false; + } + if (plus) { + cmode += L"+"; + } + if (mode & std::ios_base::binary) { + cmode += L"b"; + } else { + cmode += L"t"; + } + return cmode; +}; + +#endif + +template <typename CharType, typename Traits = std::char_traits<CharType> > +class basic_efilebuf +{ +public: +#if defined(_MSC_VER) + typedef basic_filebuf<CharType, Traits> internal_buffer_type; +#else + typedef __gnu_cxx::stdio_filebuf<CharType, Traits> internal_buffer_type; +#endif + + basic_efilebuf() + : file_(0) + { + buf_ = 0; + } + + bool _open(char const* file_name, std::ios_base::openmode mode) + { + if (is_open() || file_) { + return false; + } +#if defined(_MSC_VER) + const bool success = buf_->open(file_name, mode) != 0; +#else + const std::wstring wstr = Encoding::ToWindowsExtendedPath(file_name); + bool success = false; + std::wstring cmode = getcmode(mode); + file_ = _wfopen(wstr.c_str(), cmode.c_str()); + if (file_) { + if (buf_) { + delete buf_; + } + buf_ = new internal_buffer_type(file_, mode); + success = true; + } +#endif + return success; + } + + bool is_open() + { + if (!buf_) { + return false; + } + return buf_->is_open(); + } + + bool is_open() const + { + if (!buf_) { + return false; + } + return buf_->is_open(); + } + + bool _close() + { + bool success = false; + if (buf_) { + success = buf_->close() != 0; +#if !defined(_MSC_VER) + if (file_) { + success = fclose(file_) == 0 ? success : false; + file_ = 0; + } +#endif + } + return success; + } + + static void _set_state(bool success, std::basic_ios<CharType, Traits>* ios, + basic_efilebuf* efilebuf) + { +#if !defined(_MSC_VER) + ios->rdbuf(efilebuf->buf_); +#else + static_cast<void>(efilebuf); +#endif + if (!success) { + ios->setstate(std::ios_base::failbit); + } else { + ios->clear(); + } + } + + ~basic_efilebuf() + { + if (buf_) { + delete buf_; + } + } + +protected: + internal_buffer_type* buf_; + FILE* file_; +}; + +template <typename CharType, typename Traits = std::char_traits<CharType> > +class basic_ifstream : public std::basic_istream<CharType, Traits>, + public basic_efilebuf<CharType, Traits> +{ +public: + typedef typename basic_efilebuf<CharType, Traits>::internal_buffer_type + internal_buffer_type; + typedef std::basic_istream<CharType, Traits> internal_stream_type; + + basic_ifstream() + : internal_stream_type(new internal_buffer_type()) + { + this->buf_ = + static_cast<internal_buffer_type*>(internal_stream_type::rdbuf()); + } + explicit basic_ifstream(char const* file_name, + std::ios_base::openmode mode = std::ios_base::in) + : internal_stream_type(new internal_buffer_type()) + { + this->buf_ = + static_cast<internal_buffer_type*>(internal_stream_type::rdbuf()); + open(file_name, mode); + } + + void open(char const* file_name, + std::ios_base::openmode mode = std::ios_base::in) + { + mode = mode | std::ios_base::in; + this->_set_state(this->_open(file_name, mode), this, this); + } + + void close() { this->_set_state(this->_close(), this, this); } + + using basic_efilebuf<CharType, Traits>::is_open; + + internal_buffer_type* rdbuf() const { return this->buf_; } + + ~basic_ifstream() @KWSYS_NAMESPACE@_FStream_NOEXCEPT { close(); } +}; + +template <typename CharType, typename Traits = std::char_traits<CharType> > +class basic_ofstream : public std::basic_ostream<CharType, Traits>, + public basic_efilebuf<CharType, Traits> +{ + using basic_efilebuf<CharType, Traits>::is_open; + +public: + typedef typename basic_efilebuf<CharType, Traits>::internal_buffer_type + internal_buffer_type; + typedef std::basic_ostream<CharType, Traits> internal_stream_type; + + basic_ofstream() + : internal_stream_type(new internal_buffer_type()) + { + this->buf_ = + static_cast<internal_buffer_type*>(internal_stream_type::rdbuf()); + } + explicit basic_ofstream(char const* file_name, + std::ios_base::openmode mode = std::ios_base::out) + : internal_stream_type(new internal_buffer_type()) + { + this->buf_ = + static_cast<internal_buffer_type*>(internal_stream_type::rdbuf()); + open(file_name, mode); + } + void open(char const* file_name, + std::ios_base::openmode mode = std::ios_base::out) + { + mode = mode | std::ios_base::out; + this->_set_state(this->_open(file_name, mode), this, this); + } + + void close() { this->_set_state(this->_close(), this, this); } + + internal_buffer_type* rdbuf() const { return this->buf_; } + + ~basic_ofstream() @KWSYS_NAMESPACE@_FStream_NOEXCEPT { close(); } +}; + +typedef basic_ifstream<char> ifstream; +typedef basic_ofstream<char> ofstream; + +#undef @KWSYS_NAMESPACE@_FStream_NOEXCEPT +#else +using std::ofstream; +using std::ifstream; +#endif + +namespace FStream { +enum BOM +{ + BOM_None, + BOM_UTF8, + BOM_UTF16BE, + BOM_UTF16LE, + BOM_UTF32BE, + BOM_UTF32LE +}; + +// Read a BOM, if one exists. +// If a BOM exists, the stream is advanced to after the BOM. +// This function requires a seekable stream (but not a relative +// seekable stream). +@KWSYS_NAMESPACE@_EXPORT BOM ReadBOM(std::istream& in); +} +} + +#endif |