file.hpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
  2. // (C) Copyright 2003-2007 Jonathan Turkanis
  3. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
  5. // See http://www.boost.org/libs/iostreams for documentation.
  6. #ifndef BOOST_IOSTREAMS_FILE_HPP_INCLUDED
  7. #define BOOST_IOSTREAMS_FILE_HPP_INCLUDED
  8. #if defined(_MSC_VER)
  9. # pragma once
  10. #endif
  11. #include <boost/iostreams/detail/config/wide_streams.hpp>
  12. #ifndef BOOST_IOSTREAMS_NO_LOCALE
  13. # include <locale>
  14. #endif
  15. #include <string> // pathnames, char_traits.
  16. #include <boost/iostreams/categories.hpp>
  17. #include <boost/iostreams/detail/ios.hpp> // openmode, seekdir, int types.
  18. #include <boost/iostreams/detail/fstream.hpp>
  19. #include <boost/iostreams/operations.hpp> // seek.
  20. #include <boost/shared_ptr.hpp>
  21. // Must come last.
  22. #include <boost/iostreams/detail/config/disable_warnings.hpp> // MSVC.
  23. namespace boost { namespace iostreams {
  24. template<typename Ch>
  25. class basic_file {
  26. public:
  27. typedef Ch char_type;
  28. struct category
  29. : public seekable_device_tag,
  30. public closable_tag,
  31. public localizable_tag,
  32. public flushable_tag
  33. { };
  34. basic_file( const std::string& path,
  35. BOOST_IOS::openmode mode =
  36. BOOST_IOS::in | BOOST_IOS::out,
  37. BOOST_IOS::openmode base_mode =
  38. BOOST_IOS::in | BOOST_IOS::out );
  39. std::streamsize read(char_type* s, std::streamsize n);
  40. bool putback(char_type c);
  41. std::streamsize write(const char_type* s, std::streamsize n);
  42. std::streampos seek( stream_offset off, BOOST_IOS::seekdir way,
  43. BOOST_IOS::openmode which =
  44. BOOST_IOS::in | BOOST_IOS::out );
  45. void open( const std::string& path,
  46. BOOST_IOS::openmode mode =
  47. BOOST_IOS::in | BOOST_IOS::out,
  48. BOOST_IOS::openmode base_mode =
  49. BOOST_IOS::in | BOOST_IOS::out );
  50. bool is_open() const;
  51. void close();
  52. bool flush();
  53. #ifndef BOOST_IOSTREAMS_NO_LOCALE
  54. void imbue(const std::locale& loc) { pimpl_->file_.pubimbue(loc); }
  55. #endif
  56. private:
  57. struct impl {
  58. impl(const std::string& path, BOOST_IOS::openmode mode)
  59. { file_.open(path.c_str(), mode); }
  60. ~impl() { if (file_.is_open()) file_.close(); }
  61. BOOST_IOSTREAMS_BASIC_FILEBUF(Ch) file_;
  62. };
  63. shared_ptr<impl> pimpl_;
  64. };
  65. typedef basic_file<char> file;
  66. typedef basic_file<wchar_t> wfile;
  67. template<typename Ch>
  68. struct basic_file_source : private basic_file<Ch> {
  69. typedef Ch char_type;
  70. struct category
  71. : input_seekable,
  72. device_tag,
  73. closable_tag
  74. { };
  75. using basic_file<Ch>::read;
  76. using basic_file<Ch>::putback;
  77. using basic_file<Ch>::seek;
  78. using basic_file<Ch>::is_open;
  79. using basic_file<Ch>::close;
  80. basic_file_source( const std::string& path,
  81. BOOST_IOS::openmode mode =
  82. BOOST_IOS::in )
  83. : basic_file<Ch>(path, mode & ~BOOST_IOS::out, BOOST_IOS::in)
  84. { }
  85. void open( const std::string& path,
  86. BOOST_IOS::openmode mode = BOOST_IOS::in )
  87. {
  88. basic_file<Ch>::open(path, mode & ~BOOST_IOS::out, BOOST_IOS::in);
  89. }
  90. };
  91. typedef basic_file_source<char> file_source;
  92. typedef basic_file_source<wchar_t> wfile_source;
  93. template<typename Ch>
  94. struct basic_file_sink : private basic_file<Ch> {
  95. typedef Ch char_type;
  96. struct category
  97. : output_seekable,
  98. device_tag,
  99. closable_tag,
  100. flushable_tag
  101. { };
  102. using basic_file<Ch>::write;
  103. using basic_file<Ch>::seek;
  104. using basic_file<Ch>::is_open;
  105. using basic_file<Ch>::close;
  106. using basic_file<Ch>::flush;
  107. basic_file_sink( const std::string& path,
  108. BOOST_IOS::openmode mode = BOOST_IOS::out )
  109. : basic_file<Ch>(path, mode & ~BOOST_IOS::in, BOOST_IOS::out)
  110. { }
  111. void open( const std::string& path,
  112. BOOST_IOS::openmode mode = BOOST_IOS::out )
  113. {
  114. basic_file<Ch>::open(path, mode & ~BOOST_IOS::in, BOOST_IOS::out);
  115. }
  116. };
  117. typedef basic_file_sink<char> file_sink;
  118. typedef basic_file_sink<wchar_t> wfile_sink;
  119. //------------------Implementation of basic_file------------------------------//
  120. template<typename Ch>
  121. basic_file<Ch>::basic_file
  122. ( const std::string& path, BOOST_IOS::openmode mode,
  123. BOOST_IOS::openmode base_mode )
  124. {
  125. open(path, mode, base_mode);
  126. }
  127. template<typename Ch>
  128. inline std::streamsize basic_file<Ch>::read
  129. (char_type* s, std::streamsize n)
  130. {
  131. std::streamsize result = pimpl_->file_.sgetn(s, n);
  132. return result != 0 ? result : -1;
  133. }
  134. template<typename Ch>
  135. inline bool basic_file<Ch>::putback(char_type c)
  136. {
  137. return !!pimpl_->file_.sputbackc(c);
  138. }
  139. template<typename Ch>
  140. inline std::streamsize basic_file<Ch>::write
  141. (const char_type* s, std::streamsize n)
  142. { return pimpl_->file_.sputn(s, n); }
  143. template<typename Ch>
  144. std::streampos basic_file<Ch>::seek
  145. ( stream_offset off, BOOST_IOS::seekdir way,
  146. BOOST_IOS::openmode )
  147. { return iostreams::seek(pimpl_->file_, off, way); }
  148. template<typename Ch>
  149. void basic_file<Ch>::open
  150. ( const std::string& path, BOOST_IOS::openmode mode,
  151. BOOST_IOS::openmode base_mode )
  152. {
  153. pimpl_.reset(new impl(path, mode | base_mode));
  154. }
  155. template<typename Ch>
  156. bool basic_file<Ch>::is_open() const { return pimpl_->file_.is_open(); }
  157. template<typename Ch>
  158. void basic_file<Ch>::close() { pimpl_->file_.close(); }
  159. template<typename Ch>
  160. bool basic_file<Ch>::flush()
  161. { return pimpl_->file_.BOOST_IOSTREAMS_PUBSYNC() == 0; }
  162. //----------------------------------------------------------------------------//
  163. } } // End namespaces iostreams, boost.
  164. #include <boost/iostreams/detail/config/enable_warnings.hpp> // MSVC
  165. #endif // #ifndef BOOST_IOSTREAMS_FILE_HPP_INCLUDED