CppCMS

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

fstream.h
1 #ifndef BOOSTER_NOWIDE_FSTREAM_H
2 #define BOOSTER_NOWIDE_FSTREAM_H
3
4 #include <booster/config.h>
5 #include <booster/nowide/convert.h>
6 #include <fstream>
7 #include <booster/auto_ptr_inc.h>
8
9 #if defined BOOSTER_WIN_NATIVE || defined BOOSTER_WORKAROUND_BROKEN_GCC_ON_DARWIN
10 #include <booster/streambuf.h>
11 #include <booster/nowide/cstdio.h>
12 #endif
13
14 namespace booster {
20 namespace nowide {
21 #if !defined BOOSTER_WIN_NATIVE && !defined(BOOSTER_WORKAROUND_BROKEN_GCC_ON_DARWIN)
22
23 using std::basic_ifstream;
24 using std::basic_ofstream;
25 using std::basic_fstream;
26 using std::basic_filebuf;
27 using std::filebuf;
28 using std::ifstream;
29 using std::ofstream;
30 using std::fstream;
31
32 #endif
33 #if defined(BOOSTER_WIN_NATIVE) || defined(BOOSTER_DOXYGEN_DOCS) || defined(BOOSTER_WORKAROUND_BROKEN_GCC_ON_DARWIN)
34
35 #if defined BOOSTER_MSVC
36
37 template<typename CharType,typename Traits = std::char_traits<CharType> >
38 class basic_filebuf : public std::basic_filebuf<CharType,Traits> {
39 public:
40 typedef std::basic_filebuf<CharType,Traits> my_base_type;
41 basic_filebuf *open(char const *s,std::ios_base::openmode mode)
42 {
43 try {
44 if(my_base_type::open(convert(s).c_str(),mode)) {
45 return this;
46 }
47 return 0;
48 }
49 catch(bad_utf const &e) {
50 return 0;
51 }
52 }
53 };
54
55 #else // not msvc
56
58
59 namespace details {
60 class stdio_iodev : public booster::io_device {
61 stdio_iodev(stdio_iodev const &);
62 void operator=(stdio_iodev const &);
63 public:
64 stdio_iodev(FILE *f) :
65 file_(f)
66 {
67
68 }
69 size_t read(char *p,size_t n)
70 {
71 return fread(p,1,n,file_);
72 }
73 size_t write(char const *p,size_t n)
74 {
75 size_t res = fwrite(p,1,n,file_);
76 fflush(file_);
77 return res;
78 }
79 long long seek(long long pos,io_device::pos_type t=set)
80 {
81 switch(t) {
82 case cur:
83 fseek(file_,pos,SEEK_CUR);
84 break;
85 case set:
86 fseek(file_,pos,SEEK_SET);
87 break;
88 case end:
89 fseek(file_,pos,SEEK_END);
90 break;
91 default:
92 return -1;
93 }
94 return ftell(file_);
95 }
96 ~stdio_iodev()
97 {
98 fclose(file_);
99 }
100 private:
101 FILE *file_;
102 };
103 } // details
104
106
107 template<typename CharType,typename Traits = std::char_traits<CharType> >
108 class basic_filebuf;
109
113
114 template<>
115 class basic_filebuf<char> : public booster::streambuf {
116 public:
117
118 basic_filebuf() : opened_(false)
119 {
120 }
121 ~basic_filebuf()
122 {
123 }
124 basic_filebuf *open(char const *s,std::ios_base::openmode mode)
125 {
126 reset_device();
127 bool seek_end = mode & std::ios_base::ate;
128 if(seek_end)
129 mode ^= std::ios_base::ate;
130 wchar_t const *smode = get_mode(mode);
131 if(!smode)
132 return 0;
133 std::wstring name;
134 try {
135 name = convert(s);
136 }
137 catch(bad_utf const &) {
138 return 0;
139 }
140 FILE *f = _wfopen(name.c_str(),smode);
141 if(!f)
142 return 0;
143 if(seek_end) {
144 if(fseek(f,0,SEEK_END)!=0) {
145 fclose(f);
146 return 0;
147 }
148 }
149 std::auto_ptr<io_device> dev(new details::stdio_iodev(f));
150 device(dev);
151 opened_ = true;
152 return this;
153 }
154 basic_filebuf *close()
155 {
156
157 bool res = sync();
158 reset_device();
159 opened_ = false;
160 return res ? this : 0;
161 }
162 bool is_open() const
163 {
164 return opened_;
165 }
166 private:
167 static wchar_t const *get_mode(std::ios_base::openmode mode)
168 {
169 //
170 // done according to n2914 table 106 27.9.1.4
171 //
172
173 // note can't use switch case as overload operator can't be used
174 // in constant expression
175 if(mode == (std::ios_base::out))
176 return L"w";
177 if(mode == (std::ios_base::out | std::ios_base::app))
178 return L"a";
179 if(mode == (std::ios_base::app))
180 return L"a";
181 if(mode == (std::ios_base::out | std::ios_base::trunc))
182 return L"w";
183 if(mode == (std::ios_base::in))
184 return L"r";
185 if(mode == (std::ios_base::in | std::ios_base::out))
186 return L"r+";
187 if(mode == (std::ios_base::in | std::ios_base::out | std::ios_base::trunc))
188 return L"w+";
189 if(mode == (std::ios_base::in | std::ios_base::out | std::ios_base::app))
190 return L"a+";
191 if(mode == (std::ios_base::in | std::ios_base::app))
192 return L"a+";
193 if(mode == (std::ios_base::binary | std::ios_base::out))
194 return L"wb";
195 if(mode == (std::ios_base::binary | std::ios_base::out | std::ios_base::app))
196 return L"ab";
197 if(mode == (std::ios_base::binary | std::ios_base::app))
198 return L"ab";
199 if(mode == (std::ios_base::binary | std::ios_base::out | std::ios_base::trunc))
200 return L"wb";
201 if(mode == (std::ios_base::binary | std::ios_base::in))
202 return L"rb";
203 if(mode == (std::ios_base::binary | std::ios_base::in | std::ios_base::out))
204 return L"r+b";
205 if(mode == (std::ios_base::binary | std::ios_base::in | std::ios_base::out | std::ios_base::trunc))
206 return L"w+b";
207 if(mode == (std::ios_base::binary | std::ios_base::in | std::ios_base::out | std::ios_base::app))
208 return L"a+b";
209 if(mode == (std::ios_base::binary | std::ios_base::in | std::ios_base::app))
210 return L"a+b";
211 return 0;
212 }
213
214 bool opened_;
215 };
216
217 #endif
218
222 template<typename CharType,typename Traits = std::char_traits<CharType> >
223 class basic_ifstream : public std::basic_istream<CharType,Traits>
224 {
225 public:
226 typedef basic_filebuf<CharType,Traits> internal_buffer_type;
227 typedef std::basic_istream<CharType,Traits> internal_stream_type;
228
229 basic_ifstream() :
230 internal_stream_type(new internal_buffer_type())
231 {
232 buf_.reset(static_cast<internal_buffer_type *>(internal_stream_type::rdbuf()));
233 }
234 explicit basic_ifstream(char const *file_name,std::ios_base::openmode mode = std::ios_base::in) :
235 internal_stream_type(new internal_buffer_type())
236 {
237 buf_.reset(static_cast<internal_buffer_type *>(internal_stream_type::rdbuf()));
238 open(file_name,mode);
239 }
240 void open(char const *file_name,std::ios_base::openmode mode = std::ios_base::in)
241 {
242 if(!buf_->open(file_name,mode | std::ios_base::in)) {
243 this->setstate(std::ios_base::failbit);
244 }
245 else {
246 this->clear();
247 }
248 }
249 bool is_open()
250 {
251 return buf_->is_open();
252 }
253 bool is_open() const
254 {
255 return buf_->is_open();
256 }
257 void close()
258 {
259 if(!buf_->close())
260 this->setstate(std::ios_base::failbit);
261 else
262 this->clear();
263 }
264
265 internal_buffer_type *rdbuf() const
266 {
267 return buf_.get();
268 }
269 ~basic_ifstream()
270 {
271 buf_->close();
272 }
273
274 private:
275 std::auto_ptr<internal_buffer_type> buf_;
276 };
277
281
282 template<typename CharType,typename Traits = std::char_traits<CharType> >
283 class basic_ofstream : public std::basic_ostream<CharType,Traits>
284 {
285 public:
286 typedef basic_filebuf<CharType,Traits> internal_buffer_type;
287 typedef std::basic_ostream<CharType,Traits> internal_stream_type;
288
289 basic_ofstream() :
290 internal_stream_type(new internal_buffer_type())
291 {
292 buf_.reset(static_cast<internal_buffer_type *>(internal_stream_type::rdbuf()));
293 }
294 explicit basic_ofstream(char const *file_name,std::ios_base::openmode mode = std::ios_base::out) :
295 internal_stream_type(new internal_buffer_type())
296 {
297 buf_.reset(static_cast<internal_buffer_type *>(internal_stream_type::rdbuf()));
298 open(file_name,mode);
299 }
300 void open(char const *file_name,std::ios_base::openmode mode = std::ios_base::out)
301 {
302 if(!buf_->open(file_name,mode | std::ios_base::out)) {
303 this->setstate(std::ios_base::failbit);
304 }
305 else {
306 this->clear();
307 }
308 }
309 bool is_open()
310 {
311 return buf_->is_open();
312 }
313 bool is_open() const
314 {
315 return buf_->is_open();
316 }
317 void close()
318 {
319 if(!buf_->close())
320 this->setstate(std::ios_base::failbit);
321 else
322 this->clear();
323 }
324
325 internal_buffer_type *rdbuf() const
326 {
327 return buf_.get();
328 }
329 ~basic_ofstream()
330 {
331 buf_->close();
332 }
333
334 private:
335 std::auto_ptr<internal_buffer_type> buf_;
336 };
337
341
342 template<typename CharType,typename Traits = std::char_traits<CharType> >
343 class basic_fstream : public std::basic_iostream<CharType,Traits>
344 {
345 public:
346 typedef basic_filebuf<CharType,Traits> internal_buffer_type;
347 typedef std::basic_iostream<CharType,Traits> internal_stream_type;
348
349 basic_fstream() :
350 internal_stream_type(new internal_buffer_type())
351 {
352 buf_.reset(static_cast<internal_buffer_type *>(internal_stream_type::rdbuf()));
353 }
354 explicit basic_fstream(char const *file_name,std::ios_base::openmode mode = std::ios_base::out | std::ios_base::in) :
355 internal_stream_type(new internal_buffer_type())
356 {
357 buf_.reset(static_cast<internal_buffer_type *>(internal_stream_type::rdbuf()));
358 open(file_name,mode);
359 }
360 void open(char const *file_name,std::ios_base::openmode mode = std::ios_base::out | std::ios_base::out)
361 {
362 if(!buf_->open(file_name,mode)) {
363 this->setstate(std::ios_base::failbit);
364 }
365 else {
366 this->clear();
367 }
368 }
369 bool is_open()
370 {
371 return buf_->is_open();
372 }
373 bool is_open() const
374 {
375 return buf_->is_open();
376 }
377 void close()
378 {
379 if(!buf_->close())
380 this->setstate(std::ios_base::failbit);
381 else
382 this->clear();
383 }
384
385 internal_buffer_type *rdbuf() const
386 {
387 return buf_.get();
388 }
389 ~basic_fstream()
390 {
391 buf_->close();
392 }
393
394 private:
395 std::auto_ptr<internal_buffer_type> buf_;
396 };
397
398
402 typedef basic_filebuf<char> filebuf;
406 typedef basic_ifstream<char> ifstream;
410 typedef basic_ofstream<char> ofstream;
414 typedef basic_fstream<char> fstream;
415
416 #endif
417 } // nowide
418 } // booster
419
420
421
422 #endif
booster::nowide::basic_ofstream
Definition: fstream.h:283
booster::streambuf
this is an implementation of generic streambuffer
Definition: streambuf.h:70
booster::io_device
This class is a base class of generic I/O device that can be used in very simple manner with booster:...
Definition: streambuf.h:19
booster::nowide::convert
BOOSTER_API std::string convert(wchar_t const *s)
booster::nowide::basic_fstream
Definition: fstream.h:343
booster::io_device::pos_type
pos_type
Definition: streambuf.h:24
booster::nowide::filebuf
basic_filebuf< char > filebuf
Definition: fstream.h:402
booster::nowide::ofstream
basic_ofstream< char > ofstream
Definition: fstream.h:410
booster::nowide::basic_filebuf
Definition: fstream.h:108
booster::nowide::basic_filebuf< char >
Definition: fstream.h:115
booster::nowide::basic_ifstream
Definition: fstream.h:223
booster::nowide::ifstream
basic_ifstream< char > ifstream
Definition: fstream.h:406
booster
Booster library namespace. The library that implements Boost Like API in ABI backward compatible way...
Definition: application.h:23
booster::nowide::fstream
basic_fstream< char > fstream
Definition: fstream.h:414
booster::nowide::bad_utf
This exception is thrown if invalid UTF-8 or UTF-16 is given as input.
Definition: convert.h:14