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