summaryrefslogtreecommitdiffstats
path: root/Source/kwsys/FStream.hxx.in
diff options
context:
space:
mode:
Diffstat (limited to 'Source/kwsys/FStream.hxx.in')
-rw-r--r--Source/kwsys/FStream.hxx.in278
1 files changed, 278 insertions, 0 deletions
diff --git a/Source/kwsys/FStream.hxx.in b/Source/kwsys/FStream.hxx.in
new file mode 100644
index 0000000..d79bbdf
--- /dev/null
+++ b/Source/kwsys/FStream.hxx.in
@@ -0,0 +1,278 @@
+/* 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