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