FStream.hxx.in 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. /*============================================================================
  2. KWSys - Kitware System Library
  3. Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
  4. Distributed under the OSI-approved BSD License (the "License");
  5. see accompanying file Copyright.txt for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even the
  7. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the License for more information.
  9. ============================================================================*/
  10. #ifndef @KWSYS_NAMESPACE@_FStream_hxx
  11. #define @KWSYS_NAMESPACE@_FStream_hxx
  12. #include <@KWSYS_NAMESPACE@/Configure.hxx>
  13. #include <@KWSYS_NAMESPACE@/Encoding.hxx>
  14. #include <fstream>
  15. #if defined(_WIN32)
  16. # if !defined(_MSC_VER) && @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H
  17. # include <ext/stdio_filebuf.h>
  18. # endif
  19. #endif
  20. namespace @KWSYS_NAMESPACE@
  21. {
  22. #if defined(_WIN32) && (defined(_MSC_VER) || @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H)
  23. # if defined(_NOEXCEPT)
  24. # define @KWSYS_NAMESPACE@_FStream_NOEXCEPT _NOEXCEPT
  25. # else
  26. # define @KWSYS_NAMESPACE@_FStream_NOEXCEPT
  27. # endif
  28. #if defined(_MSC_VER)
  29. template<typename CharType,typename Traits>
  30. class basic_filebuf : public std::basic_filebuf<CharType,Traits>
  31. {
  32. # if _MSC_VER >= 1400
  33. public:
  34. typedef std::basic_filebuf<CharType,Traits> my_base_type;
  35. basic_filebuf *open(char const *s,std::ios_base::openmode mode)
  36. {
  37. const std::wstring wstr = Encoding::ToWide(s);
  38. return static_cast<basic_filebuf*>(
  39. my_base_type::open(wstr.c_str(), mode)
  40. );
  41. }
  42. # endif
  43. };
  44. #else
  45. inline std::wstring getcmode(const std::ios_base::openmode mode) {
  46. std::wstring cmode;
  47. bool plus = false;
  48. if (mode & std::ios_base::app) {
  49. cmode += L"a";
  50. plus = mode & std::ios_base::in ? true : false;
  51. } else if (mode & std::ios_base::trunc ||
  52. (mode & std::ios_base::out && (mode & std::ios_base::in) == 0)) {
  53. cmode += L"w";
  54. plus = mode & std::ios_base::in ? true : false;
  55. } else {
  56. cmode += L"r";
  57. plus = mode & std::ios_base::out ? true : false;
  58. }
  59. if (plus) {
  60. cmode += L"+";
  61. }
  62. if (mode & std::ios_base::binary) {
  63. cmode += L"b";
  64. } else {
  65. cmode += L"t";
  66. }
  67. return cmode;
  68. };
  69. #endif
  70. template<typename CharType,typename Traits = std::char_traits<CharType> >
  71. class basic_efilebuf
  72. {
  73. public:
  74. #if defined(_MSC_VER)
  75. typedef basic_filebuf<CharType,Traits> internal_buffer_type;
  76. #else
  77. typedef __gnu_cxx::stdio_filebuf<CharType,Traits> internal_buffer_type;
  78. #endif
  79. basic_efilebuf() : file_(0)
  80. {
  81. buf_ = 0;
  82. }
  83. bool _open(char const *file_name,std::ios_base::openmode mode)
  84. {
  85. if (is_open() || file_) {
  86. return false;
  87. }
  88. #if defined(_MSC_VER)
  89. const bool success = buf_->open(file_name,mode) != 0;
  90. #else
  91. const std::wstring wstr = Encoding::ToWide(file_name);
  92. bool success = false;
  93. std::wstring cmode = getcmode(mode);
  94. file_ = _wfopen(wstr.c_str(), cmode.c_str());
  95. if (file_) {
  96. if (buf_) {
  97. delete buf_;
  98. }
  99. buf_ = new internal_buffer_type(file_, mode);
  100. success = true;
  101. }
  102. #endif
  103. return success;
  104. }
  105. bool is_open()
  106. {
  107. if (!buf_) {
  108. return false;
  109. }
  110. return buf_->is_open();
  111. }
  112. bool is_open() const
  113. {
  114. if (!buf_) {
  115. return false;
  116. }
  117. return buf_->is_open();
  118. }
  119. bool _close()
  120. {
  121. bool success = false;
  122. if (buf_) {
  123. success = buf_->close() != 0;
  124. #if !defined(_MSC_VER)
  125. if (file_) {
  126. success = fclose(file_) == 0 ? success : false;
  127. file_ = 0;
  128. }
  129. #endif
  130. }
  131. return success;
  132. }
  133. static void _set_state(bool success, std::basic_ios<CharType,Traits> *ios, basic_efilebuf* efilebuf)
  134. {
  135. #if !defined(_MSC_VER)
  136. ios->rdbuf(efilebuf->buf_);
  137. #endif
  138. if (!success) {
  139. ios->setstate(std::ios_base::failbit);
  140. } else {
  141. ios->clear();
  142. }
  143. }
  144. ~basic_efilebuf()
  145. {
  146. if (buf_) {
  147. delete buf_;
  148. }
  149. }
  150. protected:
  151. internal_buffer_type* buf_;
  152. FILE *file_;
  153. };
  154. template<typename CharType,typename Traits = std::char_traits<CharType> >
  155. class basic_ifstream : public std::basic_istream<CharType,Traits>,
  156. public basic_efilebuf<CharType,Traits>
  157. {
  158. using basic_efilebuf<CharType,Traits>::is_open;
  159. public:
  160. typedef typename basic_efilebuf<CharType, Traits>::internal_buffer_type internal_buffer_type;
  161. typedef std::basic_istream<CharType,Traits> internal_stream_type;
  162. basic_ifstream() : internal_stream_type(new internal_buffer_type())
  163. {
  164. this->buf_ = static_cast<internal_buffer_type *>(internal_stream_type::rdbuf());
  165. }
  166. explicit basic_ifstream(char const *file_name,
  167. std::ios_base::openmode mode = std::ios_base::in)
  168. : internal_stream_type(new internal_buffer_type())
  169. {
  170. this->buf_ = static_cast<internal_buffer_type *>(internal_stream_type::rdbuf());
  171. open(file_name,mode);
  172. }
  173. void open(char const *file_name,std::ios_base::openmode mode = std::ios_base::in)
  174. {
  175. mode = mode | std::ios_base::in;
  176. this->_set_state(this->_open(file_name, mode), this, this);
  177. }
  178. void close()
  179. {
  180. this->_set_state(this->_close(), this, this);
  181. }
  182. internal_buffer_type *rdbuf() const
  183. {
  184. return this->buf_;
  185. }
  186. ~basic_ifstream() @KWSYS_NAMESPACE@_FStream_NOEXCEPT
  187. {
  188. close();
  189. }
  190. };
  191. template<typename CharType,typename Traits = std::char_traits<CharType> >
  192. class basic_ofstream : public std::basic_ostream<CharType,Traits>,
  193. public basic_efilebuf<CharType,Traits>
  194. {
  195. using basic_efilebuf<CharType,Traits>::is_open;
  196. public:
  197. typedef typename basic_efilebuf<CharType, Traits>::internal_buffer_type internal_buffer_type;
  198. typedef std::basic_ostream<CharType,Traits> internal_stream_type;
  199. basic_ofstream() : internal_stream_type(new internal_buffer_type())
  200. {
  201. this->buf_ = static_cast<internal_buffer_type *>(internal_stream_type::rdbuf());
  202. }
  203. explicit basic_ofstream(char const *file_name,std::ios_base::openmode mode = std::ios_base::out) :
  204. internal_stream_type(new internal_buffer_type())
  205. {
  206. this->buf_ = static_cast<internal_buffer_type *>(internal_stream_type::rdbuf());
  207. open(file_name,mode);
  208. }
  209. void open(char const *file_name,std::ios_base::openmode mode = std::ios_base::out)
  210. {
  211. mode = mode | std::ios_base::out;
  212. this->_set_state(this->_open(file_name, mode), this, this);
  213. }
  214. void close()
  215. {
  216. this->_set_state(this->_close(), this, this);
  217. }
  218. internal_buffer_type *rdbuf() const
  219. {
  220. return this->buf_;
  221. }
  222. ~basic_ofstream() @KWSYS_NAMESPACE@_FStream_NOEXCEPT
  223. {
  224. close();
  225. }
  226. };
  227. typedef basic_ifstream<char> ifstream;
  228. typedef basic_ofstream<char> ofstream;
  229. # undef @KWSYS_NAMESPACE@_FStream_NOEXCEPT
  230. #else
  231. using std::ofstream;
  232. using std::ifstream;
  233. #endif
  234. namespace FStream
  235. {
  236. enum BOM
  237. {
  238. BOM_None,
  239. BOM_UTF8,
  240. BOM_UTF16BE,
  241. BOM_UTF16LE,
  242. BOM_UTF32BE,
  243. BOM_UTF32LE
  244. };
  245. // Read a BOM, if one exists.
  246. // If a BOM exists, the stream is advanced to after the BOM.
  247. // This function requires a seekable stream (but not a relative
  248. // seekable stream).
  249. BOM ReadBOM(std::istream& in);
  250. }
  251. }
  252. #endif