CppCMS
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> >
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:
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:
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:
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 
415 
416 #endif
417 } // nowide
418 } // booster
419 
420 
421 
422 #endif
Definition: fstream.h:283
this is an implementation of generic streambuffer
Definition: streambuf.h:70
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_API std::string convert(wchar_t const *s)
Definition: fstream.h:343
pos_type
Definition: streambuf.h:24
basic_filebuf< char > filebuf
Definition: fstream.h:402
basic_ofstream< char > ofstream
Definition: fstream.h:410
Definition: fstream.h:108
Definition: fstream.h:223
basic_ifstream< char > ifstream
Definition: fstream.h:406
Booster library namespace. The library that implements Boost Like API in ABI backward compatible way...
Definition: application.h:23
basic_fstream< char > fstream
Definition: fstream.h:414
This exception is thrown if invalid UTF-8 or UTF-16 is given as input.
Definition: convert.h:14