Ticket #2998: flushable_file.hpp

File flushable_file.hpp, 5.6 KB (added by Andrew Schweitzer <a.schweitzer.grps@…>, 13 years ago)

sample implementation of flushable file_sink, copied from boost/iostreams/device/file_sink.hpp

Line 
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//
9// Contains wrappers for standard file buffers, together
10// with convenience typedefs:
11// - flushable_basic_file_sink
12// - flushable_basic_file
13//
14
15// Copied from boost_1_38_0/boost/iostreams/device/file.hpp.
16
17#ifndef BOOST_IOSTREAMS_FLUSHABLE_FILE_HPP_INCLUDED
18#define BOOST_IOSTREAMS_FLUSHABLE_FILE_HPP_INCLUDED
19
20#if defined(_MSC_VER) && (_MSC_VER >= 1020)
21# pragma once
22#endif
23
24#include <boost/iostreams/detail/config/wide_streams.hpp>
25#ifndef BOOST_IOSTREAMS_NO_LOCALE
26# include <locale>
27#endif
28#include <string> // pathnames, char_traits.
29#include <boost/iostreams/categories.hpp>
30#include <boost/iostreams/detail/ios.hpp> // openmode, seekdir, int types.
31#include <boost/iostreams/detail/fstream.hpp>
32#include <boost/iostreams/operations.hpp> // seek.
33#include <boost/shared_ptr.hpp>
34
35// Must come last.
36#include <boost/iostreams/detail/config/disable_warnings.hpp> // MSVC.
37
38namespace boost { namespace iostreams {
39
40template<typename Ch>
41class flushable_basic_file {
42public:
43 typedef Ch char_type;
44 struct category
45 : public seekable_device_tag,
46 public closable_tag,
47 public localizable_tag,
48 public flushable_tag
49 { };
50 flushable_basic_file( const std::string& path,
51 BOOST_IOS::openmode mode =
52 BOOST_IOS::in | BOOST_IOS::out,
53 BOOST_IOS::openmode base_mode =
54 BOOST_IOS::in | BOOST_IOS::out );
55 std::streamsize read(char_type* s, std::streamsize n);
56 std::streamsize write(const char_type* s, std::streamsize n);
57 std::streampos seek( stream_offset off, BOOST_IOS::seekdir way,
58 BOOST_IOS::openmode which =
59 BOOST_IOS::in | BOOST_IOS::out );
60 void open( const std::string& path,
61 BOOST_IOS::openmode mode =
62 BOOST_IOS::in | BOOST_IOS::out,
63 BOOST_IOS::openmode base_mode =
64 BOOST_IOS::in | BOOST_IOS::out );
65 bool is_open() const;
66 void close();
67 bool flush();
68#ifndef BOOST_IOSTREAMS_NO_LOCALE
69 void imbue(const std::locale& loc) { pimpl_->file_.pubimbue(loc); }
70#endif
71private:
72 struct impl {
73 impl(const std::string& path, BOOST_IOS::openmode mode)
74 { file_.open(path.c_str(), mode); }
75 ~impl() { if (file_.is_open()) file_.close(); }
76 BOOST_IOSTREAMS_BASIC_FILEBUF(Ch) file_;
77 };
78 shared_ptr<impl> pimpl_;
79};
80
81typedef flushable_basic_file<char> flushable_file;
82typedef flushable_basic_file<wchar_t> flushable_wfile;
83
84template<typename Ch>
85struct flushable_basic_file_sink : private flushable_basic_file<Ch> {
86 typedef Ch char_type;
87 struct category
88 : output_seekable,
89 device_tag,
90 closable_tag,
91 flushable_tag
92 { };
93 using flushable_basic_file<Ch>::write;
94 using flushable_basic_file<Ch>::seek;
95 using flushable_basic_file<Ch>::is_open;
96 using flushable_basic_file<Ch>::close;
97 using flushable_basic_file<Ch>::flush;
98 flushable_basic_file_sink( const std::string& path,
99 BOOST_IOS::openmode mode = BOOST_IOS::out )
100 : flushable_basic_file<Ch>(path, mode & ~BOOST_IOS::in, BOOST_IOS::out)
101 { }
102 void open( const std::string& path,
103 BOOST_IOS::openmode mode = BOOST_IOS::out )
104 {
105 flushable_basic_file<Ch>::open(path, mode & ~BOOST_IOS::in, BOOST_IOS::out);
106 }
107};
108
109typedef flushable_basic_file_sink<char> flushable_file_sink;
110typedef flushable_basic_file_sink<wchar_t> flushable_wfile_sink;
111
112//------------------Implementation of basic_file------------------------------//
113
114template<typename Ch>
115flushable_basic_file<Ch>::flushable_basic_file
116 ( const std::string& path, BOOST_IOS::openmode mode,
117 BOOST_IOS::openmode base_mode )
118{
119 open(path, mode, base_mode);
120}
121
122template<typename Ch>
123inline std::streamsize flushable_basic_file<Ch>::read
124 (char_type* s, std::streamsize n)
125{
126 std::streamsize result = pimpl_->file_.sgetn(s, n);
127 return result != 0 ? result : -1;
128}
129
130template<typename Ch>
131inline std::streamsize flushable_basic_file<Ch>::write
132 (const char_type* s, std::streamsize n)
133{ return pimpl_->file_.sputn(s, n); }
134
135template<typename Ch>
136std::streampos flushable_basic_file<Ch>::seek
137 ( stream_offset off, BOOST_IOS::seekdir way,
138 BOOST_IOS::openmode )
139{ return iostreams::seek(pimpl_->file_, off, way); }
140
141template<typename Ch>
142void flushable_basic_file<Ch>::open
143 ( const std::string& path, BOOST_IOS::openmode mode,
144 BOOST_IOS::openmode base_mode )
145{
146 pimpl_.reset(new impl(path, mode | base_mode));
147}
148
149template<typename Ch>
150bool flushable_basic_file<Ch>::is_open() const { return pimpl_->file_.is_open(); }
151
152template<typename Ch>
153void flushable_basic_file<Ch>::close() { pimpl_->file_.close(); }
154
155template<typename Ch>
156bool flushable_basic_file<Ch>::flush() { pimpl_->file_.pubsync(); return true;}
157
158//----------------------------------------------------------------------------//
159
160} } // End namespaces iostreams, boost.
161
162#include <boost/iostreams/detail/config/enable_warnings.hpp> // MSVC
163
164#endif // #ifndef BOOST_IOSTREAMS_FILE_HPP_INCLUDED