1 /*
2  * Copyright (c) 1999
3  * Silicon Graphics Computer Systems, Inc.
4  *
5  * Copyright (c) 1999
6  * Boris Fomitchev
7  *
8  * This material is provided "as is", with absolutely no warranty expressed
9  * or implied. Any use is at your own risk.
10  *
11  * Permission to use or copy this software for any purpose is hereby granted
12  * without fee, provided the above notices are retained on all copies.
13  * Permission to modify the code and to distribute modified code is granted,
14  * provided the above notices are retained, and a notice that the code was
15  * modified is included with the above copyright notice.
16  *
17  */
18 // This header defines classes basic_filebuf, basic_ifstream,
19 // basic_ofstream, and basic_fstream.  These classes represent
20 // streambufs and streams whose sources or destinations are files.
21 
22 #ifndef _STLP_INTERNAL_FSTREAM_H
23 #define _STLP_INTERNAL_FSTREAM_H
24 
25 #if defined(__sgi) && !defined(__GNUC__) && !defined(_STANDARD_C_PLUS_PLUS)
26 #  error This header file requires the -LANG:std option
27 #endif
28 
29 #ifndef _STLP_INTERNAL_STREAMBUF
30 #  include <stl/_streambuf.h>
31 #endif
32 
33 #ifndef _STLP_INTERNAL_ISTREAM
34 #  include <stl/_istream.h>
35 #endif
36 
37 #ifndef _STLP_INTERNAL_CODECVT_H
38 #  include <stl/_codecvt.h>
39 #endif
40 
41 #if !defined (_STLP_USE_UNIX_IO) && !defined(_STLP_USE_WIN32_IO) && \
42     !defined (_STLP_USE_UNIX_EMULATION_IO) && !defined (_STLP_USE_STDIO_IO)
43 
44 #  if defined (_STLP_UNIX)  || defined (__CYGWIN__) || defined (__amigaos__) || defined (__EMX__)
45 // open/close/read/write
46 #    define _STLP_USE_UNIX_IO
47 #  elif defined (_STLP_WIN32)
48 // CreateFile/ReadFile/WriteFile
49 #    define _STLP_USE_WIN32_IO
50 #  elif defined (_STLP_WIN16) || defined (_STLP_MAC)
51 // _open/_read/_write
52 #    define _STLP_USE_UNIX_EMULATION_IO
53 #  elif defined (__SYMBIAN32__)
54 //#    define _STLP_USE_SYMBIAN_IO
55 #    define _STLP_USE_UNIX_IO
56 #  else
57 // fopen/fread/fwrite
58 #    define _STLP_USE_STDIO_IO
59 #  endif /* _STLP_UNIX */
60 #endif /* mode selection */
61 
62 #if defined (_STLP_USE_SYMBIAN_IO)
63 #  include <f32file.h>
64 #endif
65 
66 #if defined (_STLP_USE_WIN32_IO)
67 typedef void* _STLP_fd;
68 #elif defined (_STLP_USE_UNIX_EMULATION_IO) || defined (_STLP_USE_STDIO_IO) || defined (_STLP_USE_UNIX_IO)
69 typedef int _STLP_fd;
70 #elif defined (_STLP_USE_SYMBIAN_IO)
71 typedef RFile _STLP_fd;
72 #else
73 #  error "Configure i/o !"
74 #endif
75 
76 _STLP_BEGIN_NAMESPACE
77 
78 //----------------------------------------------------------------------
79 // Class _Filebuf_base, a private base class to factor out the system-
80 // dependent code from basic_filebuf<>.
81 
82 class _STLP_CLASS_DECLSPEC _Filebuf_base {
83 public:                      // Opening and closing files.
84   _Filebuf_base();
85   ~_Filebuf_base();
86 
87   bool _M_open(const char*, ios_base::openmode, long __protection);
88   bool _M_open(const char*, ios_base::openmode);
89   bool _M_open(int __id, ios_base::openmode = ios_base::__default_mode);
90 #if defined (_STLP_USE_WIN32_IO)
91   bool _M_open(_STLP_fd __id, ios_base::openmode = ios_base::__default_mode);
92 #endif /* _STLP_USE_WIN32_IO */
93   bool _M_close();
94 
95 public:                      // Low-level I/O, like Unix read/write
96   ptrdiff_t _M_read(char* __buf,  ptrdiff_t __n);
97   streamoff _M_seek(streamoff __offset, ios_base::seekdir __dir);
98   streamoff _M_file_size();
99   bool _M_write(char* __buf,  ptrdiff_t __n);
100 
101 public:                      // Memory-mapped I/O.
102   void* _M_mmap(streamoff __offset, streamoff __len);
103   void _M_unmap(void* __mmap_base, streamoff __len);
104 
105 public:
106   // Returns a value n such that, if pos is the file pointer at the
107   // beginning of the range [first, last), pos + n is the file pointer at
108   // the end.  On many operating systems n == __last - __first.
109   // In Unix, writing n characters always bumps the file position by n.
110   // In Windows text mode, however, it bumps the file position by n + m,
111   // where m is the number of newlines in the range.  That's because an
112   // internal \n corresponds to an external two-character sequence.
_M_get_offset(char * __first,char * __last)113   streamoff _M_get_offset(char* __first, char* __last) {
114 #if defined (_STLP_UNIX) || defined (_STLP_MAC) || defined (__SYMBIAN32__)
115     return __last - __first;
116 #else // defined (_STLP_WIN32) || defined (_STLP_WIN16) || defined (_STLP_DOS) || defined(N_PLAT_NLM)
117     return ( (_M_openmode & ios_base::binary) != 0 )
118       ? (__last - __first)
119       : count(__first, __last, '\n') + (__last - __first);
120 #endif
121   }
122 
123   // Returns true if we're in binary mode or if we're using an OS or file
124   // system where there is no distinction between text and binary mode.
_M_in_binary_mode()125   bool _M_in_binary_mode() const {
126 #if defined (_STLP_UNIX) || defined (_STLP_MAC)  || defined(__BEOS__) || defined (__amigaos__) || defined(__SYMBIAN32__)
127     return true;
128 #elif defined (_STLP_WIN32) || defined (_STLP_WIN16) || defined (_STLP_DOS) || defined (_STLP_VM) || defined (__EMX__) || defined(N_PLAT_NLM)
129     return (_M_openmode & ios_base::binary) != 0;
130 #else
131 #  error "Port!"
132 #endif
133   }
134 
135   static void _S_initialize();
136 
137 protected:                      // Static data members.
138   static size_t _M_page_size;
139 
140 protected:                      // Data members.
141   _STLP_fd _M_file_id;
142 #if defined (_STLP_USE_STDIO_IO)
143   // for stdio, the whole FILE* is being kept here
144   FILE* _M_file;
145 #endif
146 #if defined (_STLP_USE_WIN32_IO)
147   _STLP_fd _M_view_id;
148 #endif
149 
150   ios_base::openmode _M_openmode     ;
151   unsigned char      _M_is_open      ;
152   unsigned char      _M_should_close ;
153   unsigned char      _M_regular_file ;
154 
155 public :
__page_size()156   static size_t  _STLP_CALL __page_size() { return _M_page_size; }
__o_mode()157   int  __o_mode() const { return (int)_M_openmode; }
__is_open()158   bool __is_open()      const { return (_M_is_open !=0 ); }
__should_close()159   bool __should_close() const { return (_M_should_close != 0); }
__regular_file()160   bool __regular_file() const { return (_M_regular_file != 0); }
__get_fd()161   _STLP_fd __get_fd() const { return _M_file_id; }
162 };
163 
164 //----------------------------------------------------------------------
165 // Class basic_filebuf<>.
166 
167 // Forward declaration of two helper classes.
168 template <class _Traits> class _Noconv_input;
169 _STLP_TEMPLATE_NULL
170 class _Noconv_input<char_traits<char> >;
171 
172 template <class _Traits> class _Noconv_output;
173 _STLP_TEMPLATE_NULL
174 class _Noconv_output< char_traits<char> >;
175 
176 // There is a specialized version of underflow, for basic_filebuf<char>,
177 // in fstream.cxx.
178 
179 template <class _CharT, class _Traits>
180 class _Underflow;
181 
182 _STLP_TEMPLATE_NULL class _Underflow< char, char_traits<char> >;
183 
184 template <class _CharT, class _Traits>
185 class basic_filebuf : public basic_streambuf<_CharT, _Traits> {
186 public:                         // Types.
187   typedef _CharT                     char_type;
188   typedef typename _Traits::int_type int_type;
189   typedef typename _Traits::pos_type pos_type;
190   typedef typename _Traits::off_type off_type;
191   typedef _Traits                    traits_type;
192 
193   typedef typename _Traits::state_type _State_type;
194   typedef basic_streambuf<_CharT, _Traits> _Base;
195   typedef basic_filebuf<_CharT, _Traits> _Self;
196 
197 public:                         // Constructors, destructor.
198   basic_filebuf();
199   ~basic_filebuf();
200 
201 public:                         // Opening and closing files.
is_open()202   bool is_open() const { return _M_base.__is_open(); }
203 
open(const char * __s,ios_base::openmode __m)204   _Self* open(const char* __s, ios_base::openmode __m) {
205     return _M_base._M_open(__s, __m) ? this : 0;
206   }
207 
208 #if !defined (_STLP_NO_EXTENSIONS)
209   // These two version of open() and file descriptor getter are extensions.
open(const char * __s,ios_base::openmode __m,long __protection)210   _Self* open(const char* __s, ios_base::openmode __m,
211               long __protection) {
212     return _M_base._M_open(__s, __m, __protection) ? this : 0;
213   }
214 
fd()215   _STLP_fd fd() const { return _M_base.__get_fd(); }
216 
217   _Self* open(int __id, ios_base::openmode _Init_mode = ios_base::__default_mode) {
218     return this->_M_open(__id, _Init_mode);
219   }
220 
221 #  if defined (_STLP_USE_WIN32_IO)
222   _Self* open(_STLP_fd __id, ios_base::openmode _Init_mode = ios_base::__default_mode) {
223     return _M_base._M_open(__id, _Init_mode) ? this : 0;
224   }
225 #  endif /* _STLP_USE_WIN32_IO */
226 
227 #endif
228 
229   _Self* _M_open(int __id, ios_base::openmode _Init_mode = ios_base::__default_mode) {
230     return _M_base._M_open(__id, _Init_mode) ? this : 0;
231   }
232 
233   _Self* close();
234 
235 protected:                      // Virtual functions from basic_streambuf.
236   virtual streamsize showmanyc();
237   virtual int_type underflow();
238 
239   virtual int_type pbackfail(int_type = traits_type::eof());
240   virtual int_type overflow(int_type = traits_type::eof());
241 
242   virtual basic_streambuf<_CharT, _Traits>* setbuf(char_type*, streamsize);
243   virtual pos_type seekoff(off_type, ios_base::seekdir,
244                            ios_base::openmode = ios_base::in | ios_base::out);
245   virtual pos_type seekpos(pos_type,
246                            ios_base::openmode = ios_base::in | ios_base::out);
247 
248   virtual int sync();
249   virtual void imbue(const locale&);
250 
251 private:                        // Helper functions.
252 
253   // Precondition: we are currently in putback input mode.  Effect:
254   // switches back to ordinary input mode.
_M_exit_putback_mode()255   void _M_exit_putback_mode() {
256     this->setg(_M_saved_eback, _M_saved_gptr, _M_saved_egptr);
257     _M_in_putback_mode = false;
258   }
259   bool _M_switch_to_input_mode();
260   void _M_exit_input_mode();
261   bool _M_switch_to_output_mode();
262 
263   int_type _M_input_error();
264   int_type _M_underflow_aux();
265   //  friend class _Noconv_input<_Traits>;
266   //  friend class _Noconv_output<_Traits>;
267   friend class _Underflow<_CharT, _Traits>;
268 
269   int_type _M_output_error();
270   bool _M_unshift();
271 
272   bool _M_allocate_buffers(_CharT* __buf, streamsize __n);
273   bool _M_allocate_buffers();
274   void _M_deallocate_buffers();
275 
_M_seek_return(off_type __off,_State_type __state)276   pos_type _M_seek_return(off_type __off, _State_type __state) {
277     if (__off != -1) {
278       if (_M_in_input_mode)
279         _M_exit_input_mode();
280       _M_in_input_mode = false;
281       _M_in_output_mode = false;
282       _M_in_putback_mode = false;
283       _M_in_error_mode = false;
284       this->setg(0, 0, 0);
285       this->setp(0, 0);
286     }
287 
288     pos_type __result(__off);
289     __result.state(__state);
290     return __result;
291   }
292 
293   bool _M_seek_init(bool __do_unshift);
294 
295   void _M_setup_codecvt(const locale&, bool __on_imbue = true);
296 
297 private:                        // Data members used in all modes.
298 
299   _Filebuf_base _M_base;
300 
301 private:                        // Locale-related information.
302 
303   unsigned char _M_constant_width;
304   unsigned char _M_always_noconv;
305 
306   // private:                        // Mode flags.
307   unsigned char _M_int_buf_dynamic;  // True if internal buffer is heap allocated,
308   // false if it was supplied by the user.
309   unsigned char _M_in_input_mode;
310   unsigned char _M_in_output_mode;
311   unsigned char _M_in_error_mode;
312   unsigned char _M_in_putback_mode;
313 
314   // Internal buffer: characters seen by the filebuf's clients.
315   _CharT* _M_int_buf;
316   _CharT* _M_int_buf_EOS;
317 
318   // External buffer: characters corresponding to the external file.
319   char* _M_ext_buf;
320   char* _M_ext_buf_EOS;
321 
322   // The range [_M_ext_buf, _M_ext_buf_converted) contains the external
323   // characters corresponding to the sequence in the internal buffer.  The
324   // range [_M_ext_buf_converted, _M_ext_buf_end) contains characters that
325   // have been read into the external buffer but have not been converted
326   // to an internal sequence.
327   char* _M_ext_buf_converted;
328   char* _M_ext_buf_end;
329 
330   // State corresponding to beginning of internal buffer.
331   _State_type _M_state;
332 
333 private:                        // Data members used only in input mode.
334 
335   // Similar to _M_state except that it corresponds to
336   // the end of the internal buffer instead of the beginning.
337   _State_type _M_end_state;
338 
339   // This is a null pointer unless we are in mmap input mode.
340   void*     _M_mmap_base;
341   streamoff _M_mmap_len;
342 
343 private:                        // Data members used only in putback mode.
344   _CharT* _M_saved_eback;
345   _CharT* _M_saved_gptr;
346   _CharT* _M_saved_egptr;
347 
348   typedef codecvt<_CharT, char, _State_type> _Codecvt;
349   const _Codecvt* _M_codecvt;
350 
351   int _M_width;                 // Width of the encoding (if constant), else 1
352   int _M_max_width;             // Largest possible width of single character.
353 
354 
355   enum { _S_pback_buf_size = 8 };
356   _CharT _M_pback_buf[_S_pback_buf_size];
357 
358   // for _Noconv_output
359 public:
_M_write(char * __buf,ptrdiff_t __n)360   bool _M_write(char* __buf,  ptrdiff_t __n) {return _M_base._M_write(__buf, __n); }
361 
362 public:
363   int_type
_M_do_noconv_input()364   _M_do_noconv_input() {
365     _M_ext_buf_converted = _M_ext_buf_end;
366     /* this-> */ _Base::setg((char_type*)_M_ext_buf, (char_type*)_M_ext_buf, (char_type*)_M_ext_buf_end);
367     return traits_type::to_int_type(*_M_ext_buf);
368   }
369 };
370 
371 #if defined (_STLP_USE_TEMPLATE_EXPORT)
372 _STLP_EXPORT_TEMPLATE_CLASS basic_filebuf<char, char_traits<char> >;
373 #  if ! defined (_STLP_NO_WCHAR_T)
374 _STLP_EXPORT_TEMPLATE_CLASS basic_filebuf<wchar_t, char_traits<wchar_t> >;
375 #  endif
376 #endif /* _STLP_USE_TEMPLATE_EXPORT */
377 
378 // public:
379 // helper class.
380 template <class _CharT>
381 struct _Filebuf_Tmp_Buf {
382   _CharT* _M_ptr;
_Filebuf_Tmp_Buf_Filebuf_Tmp_Buf383   _Filebuf_Tmp_Buf(ptrdiff_t __n) : _M_ptr(0) { _M_ptr = _CHECK_PTR(new _CharT[__n]); }
~_Filebuf_Tmp_Buf_Filebuf_Tmp_Buf384   ~_Filebuf_Tmp_Buf() { delete[] _M_ptr; }
385 };
386 
387 
388 //
389 // This class had to be designed very carefully to work
390 // with Visual C++.
391 //
392 template <class _Traits>
393 class _Noconv_output {
394 public:
395   typedef typename _Traits::char_type char_type;
_M_doit(basic_filebuf<char_type,_Traits> *,char_type *,char_type *)396   static bool  _STLP_CALL _M_doit(basic_filebuf<char_type, _Traits >*,
397                                   char_type*, char_type*)
398   { return false; }
399 };
400 
401 _STLP_TEMPLATE_NULL
402 class _STLP_CLASS_DECLSPEC _Noconv_output< char_traits<char> > {
403 public:
404   static bool  _STLP_CALL
_M_doit(basic_filebuf<char,char_traits<char>> * __buf,char * __first,char * __last)405   _M_doit(basic_filebuf<char, char_traits<char> >* __buf,
406           char* __first, char* __last) {
407     ptrdiff_t __n = __last - __first;
408     return (__buf->_M_write(__first, __n));
409   }
410 };
411 
412 //----------------------------------------------------------------------
413 // basic_filebuf<> helper functions.
414 
415 
416 //----------------------------------------
417 // Helper functions for switching between modes.
418 
419 //
420 // This class had to be designed very carefully to work
421 // with Visual C++.
422 //
423 template <class _Traits>
424 class _Noconv_input {
425 public:
426   typedef typename _Traits::int_type int_type;
427   typedef typename _Traits::char_type char_type;
428 
429   static inline int_type _STLP_CALL
_M_doit(basic_filebuf<char_type,_Traits> *)430   _M_doit(basic_filebuf<char_type, _Traits>*)
431   { return _Traits::eof(); }
432 };
433 
434 _STLP_TEMPLATE_NULL
435 class _Noconv_input<char_traits<char> > {
436 public:
437   static inline int _STLP_CALL
_M_doit(basic_filebuf<char,char_traits<char>> * __buf)438   _M_doit(basic_filebuf<char, char_traits<char> >* __buf) {
439     return __buf->_M_do_noconv_input();
440   }
441 };
442 
443 // underflow() may be called for one of two reasons.  (1) We've
444 // been going through the special putback buffer, and we need to move back
445 // to the regular internal buffer.  (2) We've exhausted the internal buffer,
446 // and we need to replentish it.
447 template <class _CharT, class _Traits>
448 class _Underflow {
449 public:
450   typedef typename _Traits::int_type int_type;
451   typedef _Traits                    traits_type;
452 
453   static int_type _STLP_CALL _M_doit(basic_filebuf<_CharT, _Traits>* __this);
454 };
455 
456 
457 // Specialization of underflow: if the character type is char, maybe
458 // we can use mmap instead of read.
459 _STLP_TEMPLATE_NULL
460 class _STLP_CLASS_DECLSPEC _Underflow< char, char_traits<char> > {
461 public:
462   typedef char_traits<char>::int_type int_type;
463   typedef char_traits<char> traits_type;
464   static  int _STLP_CALL _M_doit(basic_filebuf<char, traits_type >* __this);
465 };
466 
467 // There is a specialized version of underflow, for basic_filebuf<char>,
468 // in fstream.cxx.
469 
470 template <class _CharT, class _Traits>
471 _STLP_TYPENAME_ON_RETURN_TYPE _Underflow<_CharT, _Traits>::int_type // _STLP_CALL
_M_doit(basic_filebuf<_CharT,_Traits> * __this)472  _Underflow<_CharT, _Traits>::_M_doit(basic_filebuf<_CharT, _Traits>* __this) {
473   if (!__this->_M_in_input_mode) {
474     if (!__this->_M_switch_to_input_mode())
475       return traits_type::eof();
476   }
477   else if (__this->_M_in_putback_mode) {
478     __this->_M_exit_putback_mode();
479     if (__this->gptr() != __this->egptr()) {
480       int_type __c = traits_type::to_int_type(*__this->gptr());
481       return __c;
482     }
483   }
484 
485   return __this->_M_underflow_aux();
486 }
487 
488 #if defined (_STLP_USE_TEMPLATE_EXPORT) && !defined (_STLP_NO_WCHAR_T)
489 _STLP_EXPORT_TEMPLATE_CLASS _Underflow<wchar_t, char_traits<wchar_t> >;
490 #endif
491 
492 //----------------------------------------------------------------------
493 // Class basic_ifstream<>
494 
495 template <class _CharT, class _Traits>
496 class basic_ifstream : public basic_istream<_CharT, _Traits> {
497 public:                         // Types
498   typedef _CharT                     char_type;
499   typedef typename _Traits::int_type int_type;
500   typedef typename _Traits::pos_type pos_type;
501   typedef typename _Traits::off_type off_type;
502   typedef _Traits                    traits_type;
503 
504   typedef basic_ios<_CharT, _Traits>                _Basic_ios;
505   typedef basic_istream<_CharT, _Traits>            _Base;
506   typedef basic_filebuf<_CharT, _Traits>            _Buf;
507 
508 public:                         // Constructors, destructor.
509 
basic_ifstream()510   basic_ifstream() :
511     basic_ios<_CharT, _Traits>(),  basic_istream<_CharT, _Traits>(0), _M_buf() {
512       this->init(&_M_buf);
513   }
514 
515   explicit basic_ifstream(const char* __s, ios_base::openmode __mod = ios_base::in) :
516     basic_ios<_CharT, _Traits>(),  basic_istream<_CharT, _Traits>(0),
517     _M_buf() {
518       this->init(&_M_buf);
519       if (!_M_buf.open(__s, __mod | ios_base::in))
520         this->setstate(ios_base::failbit);
521   }
522 
523 #if !defined (_STLP_NO_EXTENSIONS)
524   explicit basic_ifstream(int __id, ios_base::openmode __mod = ios_base::in) :
525     basic_ios<_CharT, _Traits>(),  basic_istream<_CharT, _Traits>(0), _M_buf() {
526     this->init(&_M_buf);
527     if (!_M_buf.open(__id, __mod | ios_base::in))
528       this->setstate(ios_base::failbit);
529   }
basic_ifstream(const char * __s,ios_base::openmode __m,long __protection)530   basic_ifstream(const char* __s, ios_base::openmode __m,
531      long __protection) :
532     basic_ios<_CharT, _Traits>(),  basic_istream<_CharT, _Traits>(0), _M_buf() {
533     this->init(&_M_buf);
534     if (!_M_buf.open(__s, __m | ios_base::in, __protection))
535       this->setstate(ios_base::failbit);
536   }
537 
538 #  if defined (_STLP_USE_WIN32_IO)
539   explicit basic_ifstream(_STLP_fd __id, ios_base::openmode __mod = ios_base::in) :
540     basic_ios<_CharT, _Traits>(),  basic_istream<_CharT, _Traits>(0), _M_buf() {
541     this->init(&_M_buf);
542     if (!_M_buf.open(__id, __mod | ios_base::in))
543       this->setstate(ios_base::failbit);
544   }
545 #  endif /* _STLP_USE_WIN32_IO */
546 #endif
547 
~basic_ifstream()548   ~basic_ifstream() {}
549 
550 public:                         // File and buffer operations.
rdbuf()551   basic_filebuf<_CharT, _Traits>* rdbuf() const
552     { return __CONST_CAST(_Buf*,&_M_buf); }
553 
is_open()554   bool is_open() {
555     return this->rdbuf()->is_open();
556   }
557 
558   void open(const char* __s, ios_base::openmode __mod = ios_base::in) {
559     if (!this->rdbuf()->open(__s, __mod | ios_base::in))
560       this->setstate(ios_base::failbit);
561   }
562 
close()563   void close() {
564     if (!this->rdbuf()->close())
565       this->setstate(ios_base::failbit);
566   }
567 
568 private:
569   basic_filebuf<_CharT, _Traits> _M_buf;
570 };
571 
572 
573 //----------------------------------------------------------------------
574 // Class basic_ofstream<>
575 
576 template <class _CharT, class _Traits>
577 class basic_ofstream : public basic_ostream<_CharT, _Traits> {
578 public:                         // Types
579   typedef _CharT                     char_type;
580   typedef typename _Traits::int_type int_type;
581   typedef typename _Traits::pos_type pos_type;
582   typedef typename _Traits::off_type off_type;
583   typedef _Traits                    traits_type;
584 
585   typedef basic_ios<_CharT, _Traits>                _Basic_ios;
586   typedef basic_ostream<_CharT, _Traits>            _Base;
587   typedef basic_filebuf<_CharT, _Traits>            _Buf;
588 
589 public:                         // Constructors, destructor.
basic_ofstream()590   basic_ofstream() :
591     basic_ios<_CharT, _Traits>(),
592     basic_ostream<_CharT, _Traits>(0), _M_buf() {
593       this->init(&_M_buf);
594   }
595   explicit basic_ofstream(const char* __s, ios_base::openmode __mod = ios_base::out)
596     : basic_ios<_CharT, _Traits>(), basic_ostream<_CharT, _Traits>(0), _M_buf() {
597     this->init(&_M_buf);
598     if (!_M_buf.open(__s, __mod | ios_base::out))
599       this->setstate(ios_base::failbit);
600   }
601 
602 #if !defined (_STLP_NO_EXTENSIONS)
603   explicit basic_ofstream(int __id, ios_base::openmode __mod = ios_base::out)
604     : basic_ios<_CharT, _Traits>(), basic_ostream<_CharT, _Traits>(0),
605     _M_buf() {
606    this->init(&_M_buf);
607    if (!_M_buf.open(__id, __mod | ios_base::out))
608      this->setstate(ios_base::failbit);
609   }
basic_ofstream(const char * __s,ios_base::openmode __m,long __protection)610   basic_ofstream(const char* __s, ios_base::openmode __m, long __protection) :
611     basic_ios<_CharT, _Traits>(),  basic_ostream<_CharT, _Traits>(0), _M_buf() {
612     this->init(&_M_buf);
613     if (!_M_buf.open(__s, __m | ios_base::out, __protection))
614       this->setstate(ios_base::failbit);
615   }
616 #  if defined (_STLP_USE_WIN32_IO)
617   explicit basic_ofstream(_STLP_fd __id, ios_base::openmode __mod = ios_base::out)
618     : basic_ios<_CharT, _Traits>(), basic_ostream<_CharT, _Traits>(0),
619     _M_buf() {
620    this->init(&_M_buf);
621    if (!_M_buf.open(__id, __mod | ios_base::out))
622      this->setstate(ios_base::failbit);
623   }
624 #  endif /* _STLP_USE_WIN32_IO */
625 #endif
626 
~basic_ofstream()627   ~basic_ofstream() {}
628 
629 public:                         // File and buffer operations.
rdbuf()630   basic_filebuf<_CharT, _Traits>* rdbuf() const
631     { return __CONST_CAST(_Buf*,&_M_buf); }
632 
is_open()633   bool is_open() {
634     return this->rdbuf()->is_open();
635   }
636 
637   void open(const char* __s, ios_base::openmode __mod= ios_base::out) {
638     if (!this->rdbuf()->open(__s, __mod | ios_base::out))
639       this->setstate(ios_base::failbit);
640   }
641 
close()642   void close() {
643     if (!this->rdbuf()->close())
644       this->setstate(ios_base::failbit);
645   }
646 
647 private:
648   basic_filebuf<_CharT, _Traits> _M_buf;
649 };
650 
651 
652 //----------------------------------------------------------------------
653 // Class basic_fstream<>
654 
655 template <class _CharT, class _Traits>
656 class basic_fstream : public basic_iostream<_CharT, _Traits> {
657 public:                         // Types
658   typedef _CharT                     char_type;
659   typedef typename _Traits::int_type int_type;
660   typedef typename _Traits::pos_type pos_type;
661   typedef typename _Traits::off_type off_type;
662   typedef _Traits                    traits_type;
663 
664   typedef basic_ios<_CharT, _Traits>                _Basic_ios;
665   typedef basic_iostream<_CharT, _Traits>           _Base;
666   typedef basic_filebuf<_CharT, _Traits>            _Buf;
667 
668 public:                         // Constructors, destructor.
669 
basic_fstream()670   basic_fstream()
671     : basic_ios<_CharT, _Traits>(), basic_iostream<_CharT, _Traits>(0), _M_buf() {
672       this->init(&_M_buf);
673   }
674 
675   explicit basic_fstream(const char* __s,
676                          ios_base::openmode __mod = ios_base::in | ios_base::out) :
677     basic_ios<_CharT, _Traits>(), basic_iostream<_CharT, _Traits>(0), _M_buf() {
678       this->init(&_M_buf);
679       if (!_M_buf.open(__s, __mod))
680         this->setstate(ios_base::failbit);
681   }
682 
683 #if !defined (_STLP_NO_EXTENSIONS)
684   explicit basic_fstream(int __id,
685                          ios_base::openmode __mod = ios_base::in | ios_base::out) :
686     basic_ios<_CharT, _Traits>(), basic_iostream<_CharT, _Traits>(0), _M_buf() {
687     this->init(&_M_buf);
688     if (!_M_buf.open(__id, __mod))
689       this->setstate(ios_base::failbit);
690   }
basic_fstream(const char * __s,ios_base::openmode __m,long __protection)691   basic_fstream(const char* __s, ios_base::openmode __m, long __protection) :
692     basic_ios<_CharT, _Traits>(),  basic_iostream<_CharT, _Traits>(0), _M_buf() {
693     this->init(&_M_buf);
694     if (!_M_buf.open(__s, __m, __protection))
695       this->setstate(ios_base::failbit);
696   }
697 #  if defined (_STLP_USE_WIN32_IO)
698   explicit basic_fstream(_STLP_fd __id,
699     ios_base::openmode __mod = ios_base::in | ios_base::out) :
700     basic_ios<_CharT, _Traits>(),  basic_iostream<_CharT, _Traits>(0), _M_buf() {
701     this->init(&_M_buf);
702     if (!_M_buf.open(__id, __mod))
703       this->setstate(ios_base::failbit);
704   }
705 #  endif /* _STLP_USE_WIN32_IO */
706 #endif
~basic_fstream()707   ~basic_fstream() {}
708 
709 public:                         // File and buffer operations.
710 
rdbuf()711   basic_filebuf<_CharT, _Traits>* rdbuf() const
712     { return __CONST_CAST(_Buf*,&_M_buf); }
713 
is_open()714   bool is_open() {
715     return this->rdbuf()->is_open();
716   }
717 
718   void open(const char* __s,
719       ios_base::openmode __mod =
720       ios_base::in | ios_base::out) {
721     if (!this->rdbuf()->open(__s, __mod))
722       this->setstate(ios_base::failbit);
723   }
724 
close()725   void close() {
726     if (!this->rdbuf()->close())
727       this->setstate(ios_base::failbit);
728   }
729 
730 private:
731   basic_filebuf<_CharT, _Traits> _M_buf;
732 
733 #if defined (_STLP_MSVC) && (_STLP_MSVC >= 1300 && _STLP_MSVC <= 1310)
734   typedef basic_fstream<_CharT, _Traits> _Self;
735   //explicitely defined as private to avoid warnings:
736   basic_fstream(_Self const&);
737   _Self& operator = (_Self const&);
738 #endif
739 };
740 
741 _STLP_END_NAMESPACE
742 
743 #if defined (_STLP_EXPOSE_STREAM_IMPLEMENTATION) && !defined (_STLP_LINK_TIME_INSTANTIATION)
744 #  include <stl/_fstream.c>
745 #endif
746 
747 _STLP_BEGIN_NAMESPACE
748 
749 #if defined (_STLP_USE_TEMPLATE_EXPORT)
750 _STLP_EXPORT_TEMPLATE_CLASS basic_ifstream<char, char_traits<char> >;
751 _STLP_EXPORT_TEMPLATE_CLASS basic_ofstream<char, char_traits<char> >;
752 _STLP_EXPORT_TEMPLATE_CLASS basic_fstream<char, char_traits<char> >;
753 #  if ! defined (_STLP_NO_WCHAR_T)
754 _STLP_EXPORT_TEMPLATE_CLASS basic_ifstream<wchar_t, char_traits<wchar_t> >;
755 _STLP_EXPORT_TEMPLATE_CLASS basic_ofstream<wchar_t, char_traits<wchar_t> >;
756 _STLP_EXPORT_TEMPLATE_CLASS basic_fstream<wchar_t, char_traits<wchar_t> >;
757 #  endif
758 #endif /* _STLP_USE_TEMPLATE_EXPORT */
759 
760 _STLP_END_NAMESPACE
761 
762 #endif /* _STLP_FSTREAM */
763 
764 
765 // Local Variables:
766 // mode:C++
767 // End:
768