blob: b8c85f2e13de2059567382ac3aea31aa7cb098f6 [file] [log] [blame]
Jeff Thompson86b6d642013-10-17 15:01:56 -07001// (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 NDNBOOST_IOSTREAMS_FILE_HPP_INCLUDED
9#define NDNBOOST_IOSTREAMS_FILE_HPP_INCLUDED
10
11#if defined(_MSC_VER) && (_MSC_VER >= 1020)
12# pragma once
13#endif
14
15#include <ndnboost/iostreams/detail/config/wide_streams.hpp>
16#ifndef NDNBOOST_IOSTREAMS_NO_LOCALE
17# include <locale>
18#endif
19#include <string> // pathnames, char_traits.
20#include <ndnboost/iostreams/categories.hpp>
21#include <ndnboost/iostreams/detail/ios.hpp> // openmode, seekdir, int types.
22#include <ndnboost/iostreams/detail/fstream.hpp>
23#include <ndnboost/iostreams/operations.hpp> // seek.
24#include <ndnboost/shared_ptr.hpp>
25
26// Must come last.
27#include <ndnboost/iostreams/detail/config/disable_warnings.hpp> // MSVC.
28
29namespace ndnboost { namespace iostreams {
30
31template<typename Ch>
32class basic_file {
33public:
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 NDNBOOST_IOS::openmode mode =
43 NDNBOOST_IOS::in | NDNBOOST_IOS::out,
44 NDNBOOST_IOS::openmode base_mode =
45 NDNBOOST_IOS::in | NDNBOOST_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, NDNBOOST_IOS::seekdir way,
50 NDNBOOST_IOS::openmode which =
51 NDNBOOST_IOS::in | NDNBOOST_IOS::out );
52 void open( const std::string& path,
53 NDNBOOST_IOS::openmode mode =
54 NDNBOOST_IOS::in | NDNBOOST_IOS::out,
55 NDNBOOST_IOS::openmode base_mode =
56 NDNBOOST_IOS::in | NDNBOOST_IOS::out );
57 bool is_open() const;
58 void close();
59 bool flush();
60#ifndef NDNBOOST_IOSTREAMS_NO_LOCALE
61 void imbue(const std::locale& loc) { pimpl_->file_.pubimbue(loc); }
62#endif
63private:
64 struct impl {
65 impl(const std::string& path, NDNBOOST_IOS::openmode mode)
66 { file_.open(path.c_str(), mode); }
67 ~impl() { if (file_.is_open()) file_.close(); }
68 NDNBOOST_IOSTREAMS_BASIC_FILEBUF(Ch) file_;
69 };
70 shared_ptr<impl> pimpl_;
71};
72
73typedef basic_file<char> file;
74typedef basic_file<wchar_t> wfile;
75
76template<typename Ch>
77struct 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;
89 basic_file_source( const std::string& path,
90 NDNBOOST_IOS::openmode mode =
91 NDNBOOST_IOS::in )
92 : basic_file<Ch>(path, mode & ~NDNBOOST_IOS::out, NDNBOOST_IOS::in)
93 { }
94 void open( const std::string& path,
95 NDNBOOST_IOS::openmode mode = NDNBOOST_IOS::in )
96 {
97 basic_file<Ch>::open(path, mode & ~NDNBOOST_IOS::out, NDNBOOST_IOS::in);
98 }
99};
100
101typedef basic_file_source<char> file_source;
102typedef basic_file_source<wchar_t> wfile_source;
103
104template<typename Ch>
105struct 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;
118 basic_file_sink( const std::string& path,
119 NDNBOOST_IOS::openmode mode = NDNBOOST_IOS::out )
120 : basic_file<Ch>(path, mode & ~NDNBOOST_IOS::in, NDNBOOST_IOS::out)
121 { }
122 void open( const std::string& path,
123 NDNBOOST_IOS::openmode mode = NDNBOOST_IOS::out )
124 {
125 basic_file<Ch>::open(path, mode & ~NDNBOOST_IOS::in, NDNBOOST_IOS::out);
126 }
127};
128
129typedef basic_file_sink<char> file_sink;
130typedef basic_file_sink<wchar_t> wfile_sink;
131
132//------------------Implementation of basic_file------------------------------//
133
134template<typename Ch>
135basic_file<Ch>::basic_file
136 ( const std::string& path, NDNBOOST_IOS::openmode mode,
137 NDNBOOST_IOS::openmode base_mode )
138{
139 open(path, mode, base_mode);
140}
141
142template<typename Ch>
143inline 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
150template<typename Ch>
151inline bool basic_file<Ch>::putback(char_type c)
152{
153 return !!pimpl_->file_.sputbackc(c);
154}
155
156template<typename Ch>
157inline std::streamsize basic_file<Ch>::write
158 (const char_type* s, std::streamsize n)
159{ return pimpl_->file_.sputn(s, n); }
160
161template<typename Ch>
162std::streampos basic_file<Ch>::seek
163 ( stream_offset off, NDNBOOST_IOS::seekdir way,
164 NDNBOOST_IOS::openmode )
165{ return iostreams::seek(pimpl_->file_, off, way); }
166
167template<typename Ch>
168void basic_file<Ch>::open
169 ( const std::string& path, NDNBOOST_IOS::openmode mode,
170 NDNBOOST_IOS::openmode base_mode )
171{
172 pimpl_.reset(new impl(path, mode | base_mode));
173}
174
175template<typename Ch>
176bool basic_file<Ch>::is_open() const { return pimpl_->file_.is_open(); }
177
178template<typename Ch>
179void basic_file<Ch>::close() { pimpl_->file_.close(); }
180
181template<typename Ch>
182bool basic_file<Ch>::flush()
183{ return pimpl_->file_.NDNBOOST_IOSTREAMS_PUBSYNC() == 0; }
184
185//----------------------------------------------------------------------------//
186
187} } // End namespaces iostreams, boost.
188
189#include <ndnboost/iostreams/detail/config/enable_warnings.hpp> // MSVC
190
191#endif // #ifndef NDNBOOST_IOSTREAMS_FILE_HPP_INCLUDED