| /* 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 |