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