Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

730 lines
20 KiB

  1. // fstream standard header
  2. #pragma once
  3. #ifndef _FSTREAM_
  4. #define _FSTREAM_
  5. #include <istream>
  6. #pragma pack(push,8)
  7. #pragma warning(push,3)
  8. #pragma warning(disable: 4127)
  9. _STD_BEGIN
  10. extern _CRTIMP2 _Filet *__cdecl _Fiopen(const char *, ios_base::openmode);
  11. // TEMPLATE FUNCTION _Fgetc
  12. template<class _Elem> inline
  13. bool _Fgetc(_Elem& _Ch, _Filet *_File)
  14. { // get an element from a C stream
  15. return (fread(&_Ch, sizeof (_Elem), 1, _File) == 1);
  16. }
  17. template<> inline bool _Fgetc(char& _Byte, _Filet *_File)
  18. { // get a char element from a C stream
  19. int _Meta;
  20. if ((_Meta = fgetc(_File)) == EOF)
  21. return (false);
  22. else
  23. { // got one, convert to char
  24. _Byte = (char)_Meta;
  25. return (true);
  26. }
  27. }
  28. template<> inline bool _Fgetc(wchar_t& _Wchar, _Filet *_File)
  29. { // get a wchar_t element from a C stream
  30. wint_t _Meta;
  31. if ((_Meta = fgetwc(_File)) == WEOF)
  32. return (false);
  33. else
  34. { // got one, convert to wchar_t
  35. _Wchar = (wchar_t)_Meta;
  36. return (true);
  37. }
  38. }
  39. #ifdef _CRTBLD_NATIVE_WCHAR_T
  40. template<> inline bool _Fgetc(unsigned short& _Wchar, _Filet *_File)
  41. { // get a unsigned short element from a C stream
  42. wint_t _Meta;
  43. if ((_Meta = fgetwc(_File)) == WEOF)
  44. return (false);
  45. else
  46. { // got one, convert to unsigned short
  47. _Wchar = (unsigned short)_Meta;
  48. return (true);
  49. }
  50. }
  51. #endif
  52. // TEMPLATE FUNCTION _Fputc
  53. template<class _Elem> inline
  54. bool _Fputc(_Elem _Ch, _Filet *_File)
  55. { // put an element to a C stream
  56. return (fwrite(&_Ch, sizeof (_Elem), 1, _File) == 1);
  57. }
  58. template<> inline bool _Fputc(char _Byte, _Filet *_File)
  59. { // put a char element to a C stream
  60. return (fputc(_Byte, _File) != EOF);
  61. }
  62. template<> inline bool _Fputc(wchar_t _Wchar, _Filet *_File)
  63. { // put a wchar_t element to a C stream
  64. return (fputwc(_Wchar, _File) != WEOF);
  65. }
  66. #ifdef _CRTBLD_NATIVE_WCHAR_T
  67. template<> inline bool _Fputc(unsigned short _Wchar, _Filet *_File)
  68. { // put a unsigned short element to a C stream
  69. return (fputwc(_Wchar, _File) != WEOF);
  70. }
  71. #endif
  72. // TEMPLATE FUNCTION _Ungetc
  73. template<class _Elem> inline
  74. bool _Ungetc(const _Elem& _Ch, _Filet *_File)
  75. { // put back an arbitrary element to a C stream (always fail)
  76. return (false);
  77. }
  78. template<> inline bool _Ungetc(const char& _Byte, _Filet *_File)
  79. { // put back a char element to a C stream
  80. return (ungetc((unsigned char)_Byte, _File) != EOF);
  81. }
  82. template<> inline bool _Ungetc(const signed char& _Byte, _Filet *_File)
  83. { // put back a signed char element to a C stream
  84. return (ungetc((unsigned char)_Byte, _File) != EOF);
  85. }
  86. template<> inline bool _Ungetc(const unsigned char& _Byte, _Filet *_File)
  87. { // put back an unsigned char element to a C stream
  88. return (ungetc(_Byte, _File) != EOF);
  89. }
  90. template<> inline bool _Ungetc(const wchar_t& _Wchar, _Filet *_File)
  91. { // put back a wchar_t element to a C stream
  92. return (ungetwc(_Wchar, _File) != WEOF);
  93. }
  94. #ifdef _CRTBLD_NATIVE_WCHAR_T
  95. template<> inline bool _Ungetc(const unsigned short& _Wchar, _Filet *_File)
  96. { // put back a unsigned short element to a C stream
  97. return (ungetwc(_Wchar, _File) != WEOF);
  98. }
  99. #endif
  100. // TEMPLATE CLASS basic_filebuf
  101. template<class _Elem,
  102. class _Traits>
  103. class basic_filebuf
  104. : public basic_streambuf<_Elem, _Traits>
  105. { // stream buffer associated with a C stream
  106. public:
  107. typedef basic_filebuf<_Elem, _Traits> _Myt;
  108. typedef basic_streambuf<_Elem, _Traits> _Mysb;
  109. typedef codecvt<_Elem, char, typename _Traits::state_type> _Cvt;
  110. virtual ~basic_filebuf()
  111. { // destroy the object
  112. if (_Closef)
  113. close();
  114. _DELETE_CRT(_Mystr);
  115. }
  116. basic_filebuf(_Filet *_File = 0)
  117. : _Mysb(), _Mystr(0), _Loc()
  118. { // construct from pointer to C stream
  119. _Init(_File, _Newfl);
  120. }
  121. typedef typename _Traits::int_type int_type;
  122. typedef typename _Traits::pos_type pos_type;
  123. typedef typename _Traits::off_type off_type;
  124. basic_filebuf(_Uninitialized)
  125. : _Mysb(_Noinit), _Loc(_Noinit)
  126. { // construct uninitialized
  127. }
  128. enum _Initfl
  129. { // reasons for a call to _Init
  130. _Newfl, _Openfl, _Closefl};
  131. bool is_open() const
  132. { // test if C stream has been opened
  133. return (_Myfile != 0);
  134. }
  135. _Myt *open(const char *_Filename, ios_base::openmode _Mode)
  136. { // open a C stream with specified mode
  137. _Filet *_File;
  138. if (_Myfile != 0 || (_File = _Fiopen(_Filename, _Mode)) == 0)
  139. return (0); // open failed
  140. _Init(_File, _Openfl);
  141. _Initcvt((_Cvt *)&_USE(_Mysb::getloc(), _Cvt));
  142. return (this); // open succeeded
  143. }
  144. _Myt *open(const char *_Filename, ios_base::open_mode _Mode)
  145. { // open a C stream with specified mode (old style)
  146. return (open(_Filename, (ios_base::openmode)_Mode));
  147. }
  148. _Myt *close()
  149. { // close the C stream
  150. if (_Myfile != 0 && _Endwrite() && fclose(_Myfile) == 0)
  151. { // close succeeded, tidy up
  152. _Init(0, _Closefl);
  153. return (this);
  154. }
  155. else
  156. return (0);
  157. }
  158. protected:
  159. virtual int_type overflow(int_type _Meta = _Traits::eof())
  160. { // put an element to stream
  161. if (_Traits::eq_int_type(_Traits::eof(), _Meta))
  162. return (_Traits::not_eof(_Meta)); // EOF, return success code
  163. else if (_Mysb::pptr() != 0
  164. && _Mysb::pptr() < _Mysb::epptr())
  165. { // room in buffer, store it
  166. *_Mysb::_Pninc() = _Traits::to_char_type(_Meta);
  167. return (_Meta);
  168. }
  169. else if (_Myfile == 0)
  170. return (_Traits::eof()); // no open C stream, fail
  171. else if (_Pcvt == 0)
  172. return (_Fputc(_Traits::to_char_type(_Meta), _Myfile)
  173. ? _Meta : _Traits::eof()); // no codecvt facet, put as is
  174. else
  175. { // put using codecvt facet
  176. const int _STRING_INC = 8;
  177. const _Elem _Ch = _Traits::to_char_type(_Meta);
  178. const _Elem *_Source;
  179. char *_Dest;
  180. _Mystr->erase();
  181. string _Str(_STRING_INC, '\0');
  182. for (; ; )
  183. switch (_Pcvt->out(_State,
  184. &_Ch, &_Ch + 1, _Source,
  185. &*_Str.begin(), &*_Str.end(), _Dest))
  186. { // test result of converting one element
  187. case codecvt_base::partial:
  188. case codecvt_base::ok:
  189. { // converted something, try to put it out
  190. size_t _Count = _Dest - &*_Str.begin();
  191. if (0 < _Count && _Count !=
  192. fwrite(&*_Str.begin(), 1, _Count, _Myfile))
  193. return (_Traits::eof()); // write failed
  194. _Wrotesome = true; // write succeeded
  195. if (_Source != &_Ch)
  196. return (_Meta); // converted whole element
  197. if (_Count == 0)
  198. _Str.append(_STRING_INC, '\0'); // try some more
  199. break;
  200. }
  201. case codecvt_base::noconv:
  202. return (_Fputc(_Ch, _Myfile) ? _Meta
  203. : _Traits::eof()); // no conversion, put as is
  204. default:
  205. return (_Traits::eof()); // conversion failed
  206. }
  207. }
  208. }
  209. virtual int_type pbackfail(int_type _Meta = _Traits::eof())
  210. { // put an element back to stream
  211. if (_Mysb::gptr() != 0
  212. && _Mysb::eback() < _Mysb::gptr()
  213. && (_Traits::eq_int_type(_Traits::eof(), _Meta)
  214. || _Traits::eq_int_type(_Traits::to_int_type(_Mysb::gptr()[-1]),
  215. _Meta)))
  216. { // just back up position
  217. _Mysb::_Gndec();
  218. return (_Traits::not_eof(_Meta));
  219. }
  220. else if (_Myfile == 0 || _Traits::eq_int_type(_Traits::eof(), _Meta))
  221. return (_Traits::eof()); // no open C stream or EOF, fail
  222. else if (_Pcvt == 0 && _Ungetc(_Traits::to_char_type(_Meta), _Myfile))
  223. return (_Meta); // no facet and unget succeeded, return
  224. else
  225. { // putback to _Mychar
  226. _Mychar = _Traits::to_char_type(_Meta);
  227. _Mysb::setg(&_Mychar, &_Mychar, &_Mychar + 1);
  228. return (_Meta);
  229. }
  230. }
  231. virtual int_type underflow()
  232. { // get an element from stream, but don't point past it
  233. int_type _Meta;
  234. if (_Mysb::gptr() != 0
  235. && _Mysb::gptr() < _Mysb::egptr())
  236. return (_Traits::to_int_type(*_Mysb::gptr())); // return buffered
  237. else if (_Traits::eq_int_type(_Traits::eof(), _Meta = uflow()))
  238. return (_Meta); // uflow failed, return EOF
  239. else
  240. { // get a char, don't point past it
  241. pbackfail(_Meta);
  242. return (_Meta);
  243. }
  244. }
  245. virtual int_type uflow()
  246. { // get an element from stream, point past it
  247. if (_Mysb::gptr() != 0
  248. && _Mysb::gptr() < _Mysb::egptr())
  249. return (_Traits::to_int_type(
  250. *_Mysb::_Gninc())); // return buffered
  251. else if (_Myfile == 0)
  252. return (_Traits::eof()); // no open C stream, fail
  253. else if (_Pcvt == 0)
  254. { // no codecvt facet, just get it
  255. _Elem _Ch = 0;
  256. return (_Fgetc(_Ch, _Myfile) ? _Traits::to_int_type(_Ch)
  257. : _Traits::eof());
  258. }
  259. else
  260. for (_State0 = _State, _Mystr->erase(); ; )
  261. { // get using codecvt facet
  262. _Elem _Ch, *_Dest;
  263. const char *_Source;
  264. int _Meta = fgetc(_Myfile);
  265. if (_Meta == EOF)
  266. return (_Traits::eof()); // partial char?
  267. _Mystr->append(1, (char)_Meta); // append byte and convert
  268. _State = _State0;
  269. switch (_Pcvt->in(_State,
  270. &*_Mystr->begin(), &*_Mystr->end(), _Source,
  271. &_Ch, &_Ch + 1, _Dest))
  272. { // test result of converting one element
  273. case codecvt_base::partial:
  274. break; // partial, not done yet
  275. case codecvt_base::noconv:
  276. if (_Mystr->size() < sizeof (_Elem))
  277. break; // no conversion, but need more chars
  278. memcpy(&_Ch, &*_Mystr->begin(),
  279. sizeof (_Elem)); // copy raw bytes to element
  280. case codecvt_base::ok: // can fall through
  281. return (_Traits::to_int_type(_Ch)); // return result
  282. default:
  283. return (_Traits::eof()); // conversion failed
  284. }
  285. }
  286. }
  287. virtual pos_type seekoff(off_type _Off, ios_base::seekdir _Way,
  288. ios_base::openmode =
  289. (ios_base::openmode)(ios_base::in | ios_base::out))
  290. { // change position by _Off
  291. fpos_t _Fileposition;
  292. if (_Mysb::gptr() != &_Mychar
  293. || _Mysb::egptr() <= _Mysb::gptr()
  294. || _Way != ios_base::cur)
  295. ; // don't have to worry about putback character
  296. else if (_Pcvt == 0)
  297. _Off -= (off_type)sizeof (_Elem); // back up over _Elem bytes
  298. else
  299. { // back up over converted bytes
  300. _Off -= (off_type)_Mystr->size();
  301. _Mystr->erase();
  302. _State = _State0;
  303. }
  304. if (_Myfile == 0 || !_Endwrite()
  305. || (_Off != 0 || _Way != ios_base::cur)
  306. && fseek(_Myfile, (long)_Off, _Way) != 0
  307. || fgetpos(_Myfile, &_Fileposition) != 0)
  308. return (pos_type(_BADOFF)); // report failure
  309. if (_Mysb::gptr() == &_Mychar)
  310. _Mysb::setg(&_Mychar, &_Mychar, &_Mychar); // discard putback
  311. return (pos_type(_State, _Fileposition)); // return new position
  312. }
  313. virtual pos_type seekpos(pos_type _Pos,
  314. ios_base::openmode =
  315. (ios_base::openmode)(ios_base::in | ios_base::out))
  316. { // change position to _Pos
  317. fpos_t _Fileposition = _Pos.seekpos();
  318. off_type _Off = (off_type)_Pos - _FPOSOFF(_Fileposition);
  319. if (_Myfile == 0 || !_Endwrite()
  320. || fsetpos(_Myfile, &_Fileposition) != 0
  321. || _Off != 0 && fseek(_Myfile, (long)_Off, SEEK_CUR) != 0
  322. || fgetpos(_Myfile, &_Fileposition) != 0)
  323. return (pos_type(_BADOFF)); // report failure
  324. if (_Mystr != 0)
  325. _State = _Pos.state(), _Mystr->erase(); // restore state
  326. if (_Mysb::gptr() == &_Mychar)
  327. _Mysb::setg(&_Mychar, &_Mychar, &_Mychar); // discard putback
  328. return (pos_type(_State, _Fileposition)); // return new position
  329. }
  330. virtual _Mysb *setbuf(_Elem *_Buffer, streamsize _Count)
  331. { // offer _Buffer to C stream
  332. return (_Myfile == 0 || setvbuf(_Myfile, (char *)_Buffer,
  333. _Buffer == 0 && _Count == 0 ? _IONBF : _IOFBF,
  334. _Count * sizeof (_Elem)) != 0 ? 0 : this);
  335. }
  336. virtual int sync()
  337. { // synchronize C stream with external file
  338. return (_Myfile == 0
  339. || _Traits::eq_int_type(_Traits::eof(), overflow())
  340. || 0 <= fflush(_Myfile) ? 0 : -1);
  341. }
  342. virtual void imbue(const locale& _Loc)
  343. { // set locale to argument (capture nontrivial codecvt facet)
  344. _Initcvt((_Cvt *)&_USE(_Loc, _Cvt));
  345. }
  346. void _Init(_Filet *_File, _Initfl _Which)
  347. { // initialize to C stream _File after {new, open, close}
  348. static typename _Traits::state_type _Stinit; // initial state
  349. _Closef = _Which == _Openfl;
  350. _Wrotesome = false;
  351. _Mysb::_Init(); // initialize stream buffer base object
  352. #ifndef _IORCNT
  353. #define _IORCNT _IOCNT /* read and write counts are the same */
  354. #define _IOWCNT _IOCNT
  355. #endif
  356. if (_File != 0 && sizeof (_Elem) == 1)
  357. { // point inside C stream with [first, first + count) buffer
  358. _Elem **_Pb = (_Elem **)&_File->_IOBASE;
  359. _Elem **_Pn = (_Elem **)&_File->_IOPTR;
  360. int *_Nr = (int *)&_File->_IORCNT;
  361. int *_Nw = (int *)&_File->_IOWCNT;
  362. _Mysb::_Init(_Pb, _Pn, _Nr, _Pb, _Pn, _Nw);
  363. }
  364. _Myfile = _File;
  365. _State = _Stinit;
  366. _State0 = _Stinit;
  367. _Pcvt = 0; // pointer to codecvt facet
  368. }
  369. bool _Endwrite()
  370. { // put shift to initial conversion state, as needed
  371. if (_Pcvt == 0 || !_Wrotesome)
  372. return (true);
  373. else
  374. { // may have to put
  375. const int _STRING_INC = 8;
  376. char *_Dest;
  377. overflow();
  378. string _Str(_STRING_INC, '\0');
  379. for (; ; )
  380. switch (_Pcvt->unshift(_State,
  381. &*_Str.begin(), &*_Str.end(), _Dest))
  382. { // test result of homing conversion
  383. case codecvt_base::ok:
  384. _Wrotesome = false; // homed successfully
  385. case codecvt_base::partial: // can fall through
  386. { // put any generated bytes
  387. size_t _Count = _Dest - &*_Str.begin();
  388. if (0 < _Count && _Count !=
  389. fwrite(&*_Str.begin(), _Count, 1, _Myfile))
  390. return (false); // write failed
  391. if (!_Wrotesome)
  392. return (true);
  393. _Str.append(_STRING_INC, '\0'); // try some more
  394. break;
  395. }
  396. case codecvt_base::noconv:
  397. return (true); // nothing to do
  398. default:
  399. return (false); // conversion failed
  400. }
  401. }
  402. }
  403. void _Initcvt(_Cvt *_Newpcvt)
  404. { // initialize codecvt pointer
  405. if (_Newpcvt->always_noconv())
  406. _Pcvt = 0; // nothing to do
  407. else
  408. { // set up for nontrivial codecvt facet
  409. _Pcvt = _Newpcvt;
  410. _Loc = _ADDFAC(_Loc, _Pcvt); // to keep facet alive
  411. _Mysb::_Init(); // reset any buffering
  412. if (_Mystr == 0)
  413. _Mystr = _NEW_CRT _STRING_CRT; // buy conversion buffer
  414. }
  415. }
  416. private:
  417. _Cvt *_Pcvt; // pointer to codecvt facet (may be null)
  418. typename _Traits::state_type _State0; // rollback for bad conversion
  419. _Elem _Mychar; // putback character, when _Ungetc fails
  420. _STRING_CRT *_Mystr; // string to hold partial conversion byte sequences
  421. bool _Wrotesome; // true if homing sequence may be needed
  422. typename _Traits::state_type _State; // current conversion state
  423. bool _Closef; // true if C stream must be closed
  424. locale _Loc; // locale object to hold codecvt facet
  425. _Filet *_Myfile; // pointer to C stream
  426. };
  427. #ifdef _DLL_CPPLIB
  428. #ifdef __FORCE_INSTANCE
  429. template class _CRTIMP2 basic_filebuf<char,
  430. char_traits<char> >;
  431. template class _CRTIMP2 basic_filebuf<wchar_t,
  432. char_traits<wchar_t> >;
  433. #ifdef _CRTBLD_NATIVE_WCHAR_T
  434. template class _CRTIMP2 basic_filebuf<unsigned short,
  435. char_traits<unsigned short> >;
  436. #endif
  437. #endif // __FORCE_INSTANCE
  438. #endif // _DLL_CPPLIB
  439. // TEMPLATE CLASS basic_ifstream
  440. template<class _Elem,
  441. class _Traits>
  442. class basic_ifstream
  443. : public basic_istream<_Elem, _Traits>
  444. { // input stream associated with a C stream
  445. public:
  446. typedef basic_ifstream<_Elem, _Traits> _Myt;
  447. typedef basic_filebuf<_Elem, _Traits> _Myfb;
  448. typedef basic_ios<_Elem, _Traits> _Myios;
  449. basic_ifstream()
  450. : basic_istream<_Elem, _Traits>(&_Filebuffer)
  451. { // construct unopened
  452. }
  453. explicit basic_ifstream(const char *_Filename,
  454. ios_base::openmode _Mode = ios_base::in)
  455. : basic_istream<_Elem, _Traits>(&_Filebuffer)
  456. { // construct with named file and specified mode
  457. if (_Filebuffer.open(_Filename, _Mode | ios_base::in) == 0)
  458. _Myios::setstate(ios_base::failbit);
  459. }
  460. virtual ~basic_ifstream()
  461. { // destroy the object
  462. }
  463. _Myfb *rdbuf() const
  464. { // return pointer to file buffer
  465. return ((_Myfb *)&_Filebuffer);
  466. }
  467. bool is_open() const
  468. { // test if C stream has been opened
  469. return (_Filebuffer.is_open());
  470. }
  471. void open(const char *_Filename,
  472. ios_base::openmode _Mode = ios_base::in)
  473. { // open a C stream with specified mode
  474. if (_Filebuffer.open(_Filename, _Mode | ios_base::in) == 0)
  475. _Myios::setstate(ios_base::failbit);
  476. }
  477. void open(const char *_Filename, ios_base::open_mode _Mode)
  478. { // open named file with specified mode (old style)
  479. open(_Filename, (ios_base::openmode)_Mode);
  480. }
  481. void close()
  482. { // close the C stream
  483. if (_Filebuffer.close() == 0)
  484. _Myios::setstate(ios_base::failbit);
  485. }
  486. private:
  487. _Myfb _Filebuffer; // the file buffer
  488. };
  489. #ifdef _DLL_CPPLIB
  490. #ifdef __FORCE_INSTANCE
  491. template class _CRTIMP2 basic_ifstream<char,
  492. char_traits<char> >;
  493. template class _CRTIMP2 basic_ifstream<wchar_t,
  494. char_traits<wchar_t> >;
  495. #ifdef _CRTBLD_NATIVE_WCHAR_T
  496. template class _CRTIMP2 basic_ifstream<unsigned short,
  497. char_traits<unsigned short> >;
  498. #endif
  499. #endif // __FORCE_INSTANCE
  500. #endif // _DLL_CPPLIB
  501. // TEMPLATE CLASS basic_ofstream
  502. template<class _Elem,
  503. class _Traits>
  504. class basic_ofstream
  505. : public basic_ostream<_Elem, _Traits>
  506. { // output stream associated with a C stream
  507. public:
  508. typedef basic_ofstream<_Elem, _Traits> _Myt;
  509. typedef basic_filebuf<_Elem, _Traits> _Myfb;
  510. typedef basic_ios<_Elem, _Traits> _Myios;
  511. basic_ofstream()
  512. : basic_ostream<_Elem, _Traits>(&_Filebuffer)
  513. { // construct unopened
  514. }
  515. explicit basic_ofstream(const char *_Filename,
  516. ios_base::openmode _Mode = ios_base::out)
  517. : basic_ostream<_Elem, _Traits>(&_Filebuffer)
  518. { // construct with named file and specified mode
  519. if (_Filebuffer.open(_Filename, _Mode | ios_base::out) == 0)
  520. _Myios::setstate(ios_base::failbit);
  521. }
  522. virtual ~basic_ofstream()
  523. { // destroy the object
  524. }
  525. _Myfb *rdbuf() const
  526. { // return pointer to file buffer
  527. return ((_Myfb *)&_Filebuffer);
  528. }
  529. bool is_open() const
  530. { // test if C stream has been opened
  531. return (_Filebuffer.is_open());
  532. }
  533. void open(const char *_Filename,
  534. ios_base::openmode _Mode = ios_base::out)
  535. { // open a C stream with specified mode
  536. if (_Filebuffer.open(_Filename, _Mode | ios_base::out) == 0)
  537. _Myios::setstate(ios_base::failbit);
  538. }
  539. void open(const char *_Filename, ios_base::open_mode _Mode)
  540. { // open a C stream with specified mode (old style)
  541. open(_Filename, (ios_base::openmode)_Mode);
  542. }
  543. void close()
  544. { // close the C stream
  545. if (_Filebuffer.close() == 0)
  546. _Myios::setstate(ios_base::failbit);
  547. }
  548. private:
  549. _Myfb _Filebuffer; // the file buffer
  550. };
  551. #ifdef _DLL_CPPLIB
  552. #ifdef __FORCE_INSTANCE
  553. template class _CRTIMP2 basic_ofstream<char,
  554. char_traits<char> >;
  555. template class _CRTIMP2 basic_ofstream<wchar_t,
  556. char_traits<wchar_t> >;
  557. #ifdef _CRTBLD_NATIVE_WCHAR_T
  558. template class _CRTIMP2 basic_ofstream<unsigned short,
  559. char_traits<unsigned short> >;
  560. #endif
  561. #endif // __FORCE_INSTANCE
  562. #endif // _DLL_CPPLIB
  563. // TEMPLATE CLASS basic_fstream
  564. template<class _Elem,
  565. class _Traits>
  566. class basic_fstream
  567. : public basic_iostream<_Elem, _Traits>
  568. { // input/output stream associated with a C stream
  569. public:
  570. typedef basic_ios<_Elem, _Traits> _Myios;
  571. typedef _Elem char_type;
  572. typedef _Traits traits_type;
  573. typedef typename _Traits::int_type int_type;
  574. typedef typename _Traits::pos_type pos_type;
  575. typedef typename _Traits::off_type off_type;
  576. basic_fstream()
  577. : basic_iostream<_Elem, _Traits>(&_Filebuffer)
  578. { // construct unopened
  579. }
  580. explicit basic_fstream(const char *_Filename,
  581. ios_base::openmode _Mode = ios_base::in | ios_base::out)
  582. : basic_iostream<_Elem, _Traits>(&_Filebuffer)
  583. { // construct with named file and specified mode
  584. if (_Filebuffer.open(_Filename, _Mode) == 0)
  585. _Myios::setstate(ios_base::failbit);
  586. }
  587. virtual ~basic_fstream()
  588. { // destroy the object
  589. }
  590. basic_filebuf<_Elem, _Traits> *rdbuf() const
  591. { // return pointer to file buffer
  592. return ((basic_filebuf<_Elem, _Traits> *)&_Filebuffer);
  593. }
  594. bool is_open() const
  595. { // test if C stream has been opened
  596. return (_Filebuffer.is_open());
  597. }
  598. void open(const char *_Filename,
  599. ios_base::openmode _Mode = ios_base::in | ios_base::out)
  600. { // open a C stream with specified mode
  601. if (_Filebuffer.open(_Filename, _Mode) == 0)
  602. _Myios::setstate(ios_base::failbit);
  603. }
  604. void open(const char *_Filename, ios_base::open_mode _Mode)
  605. { // open a C stream with specified mode (old style)
  606. open(_Filename, (ios_base::openmode)_Mode);
  607. }
  608. void close()
  609. { // close the C stream
  610. if (_Filebuffer.close() == 0)
  611. _Myios::setstate(ios_base::failbit);
  612. }
  613. private:
  614. basic_filebuf<_Elem, _Traits> _Filebuffer; // the file buffer
  615. };
  616. #ifdef _DLL_CPPLIB
  617. #ifdef __FORCE_INSTANCE
  618. template class _CRTIMP2 basic_fstream<char,
  619. char_traits<char> >;
  620. template class _CRTIMP2 basic_fstream<wchar_t,
  621. char_traits<wchar_t> >;
  622. #ifdef _CRTBLD_NATIVE_WCHAR_T
  623. template class _CRTIMP2 basic_fstream<unsigned short,
  624. char_traits<unsigned short> >;
  625. #endif
  626. #endif // __FORCE_INSTANCE
  627. #endif // _DLL_CPPLIB
  628. _STD_END
  629. #pragma warning(default: 4127)
  630. #pragma warning(pop)
  631. #pragma pack(pop)
  632. #endif /* _FSTREAM_ */
  633. /*
  634. * Copyright (c) 1992-2001 by P.J. Plauger. ALL RIGHTS RESERVED.
  635. * Consult your license regarding permissions and restrictions.
  636. V3.10:0009 */