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.

394 lines
12 KiB

  1. // fstream standard header
  2. #ifndef _FSTREAM_
  3. #define _FSTREAM_
  4. #include <istream>
  5. #include <new>
  6. #ifdef _MSC_VER
  7. #pragma pack(push,8)
  8. #endif /* _MSC_VER */
  9. _STD_BEGIN
  10. extern _CRTIMP2 FILE *__cdecl __Fiopen(const char *,ios_base::openmode);
  11. // TEMPLATE FUNCTION _Fgetc
  12. template<class _E> inline
  13. bool _Fgetc(_E& _C, _Filet *_Fi)
  14. {return (fread(&_C, sizeof (_E), 1, _Fi) == 1); }
  15. inline bool _Fgetc(char& _C, _Filet *_Fi)
  16. {int _Ch;
  17. if ((_Ch = fgetc(_Fi)) == EOF)
  18. return (false);
  19. else
  20. {_C = (char)_Ch;
  21. return (true); }}
  22. inline bool _Fgetc(wchar_t& _C, _Filet *_Fi)
  23. {_Wint_t _Ch;
  24. if ((_Ch = fgetwc(_Fi)) == WEOF)
  25. return (false);
  26. else
  27. {_C = _Ch;
  28. return (true); }}
  29. // TEMPLATE FUNCTION _Fputc
  30. template<class _E> inline
  31. bool _Fputc(_E _C, _Filet *_Fi)
  32. {return (fwrite(&_C, sizeof (_E), 1, _Fi) == 1); }
  33. inline bool _Fputc(char _C, _Filet *_Fi)
  34. {return (fputc(_C, _Fi) != EOF); }
  35. inline bool _Fputc(wchar_t _C, _Filet *_Fi)
  36. {return (fputwc(_C, _Fi) != WEOF); }
  37. // TEMPLATE FUNCTION _Ungetc
  38. template<class _E> inline
  39. bool _Ungetc(const _E& _C, _Filet *_Fi, size_t _N)
  40. {const unsigned char *_P = (const unsigned char *)&_C;
  41. for (_P += _N; 0 < _N && ungetc(*--_P, _Fi) != EOF; --_N)
  42. ;
  43. if (_N == 0)
  44. return (true);
  45. else
  46. {for (; _N < sizeof (_E); ++_N)
  47. fgetc(_Fi);
  48. return (false); }}
  49. template<class _E> inline
  50. bool _Ungetc(const _E& _C, _Filet *_Fi)
  51. {return (_Ungetc(_C, _Fi, sizeof (_E))); }
  52. inline bool _Ungetc(char _C, _Filet *_Fi)
  53. {return (ungetc((unsigned char)_C, _Fi) != EOF); }
  54. inline bool _Ungetc(wchar_t _C, _Filet *_Fi)
  55. {return (ungetwc(_C, _Fi) != WEOF); }
  56. // TEMPLATE CLASS basic_filebuf
  57. template<class _E, class _Tr = char_traits<_E> >
  58. class basic_filebuf : public basic_streambuf<_E, _Tr> {
  59. public:
  60. typedef basic_filebuf<_E, _Tr> _Myt;
  61. typedef basic_streambuf<_E, _Tr> _Mysb;
  62. typedef codecvt<_E, char, _Tr::state_type> _Cvt;
  63. basic_filebuf(_Filet *_F = 0)
  64. : _Loc(), _Mysb() {_Init(_F, _Newfl); }
  65. basic_filebuf(_Uninitialized)
  66. : _Loc(_Noinit), _Mysb(_Noinit) {}
  67. virtual ~basic_filebuf()
  68. {if (_Closef)
  69. close();
  70. delete _Str; }
  71. enum _Initfl {_Newfl, _Openfl, _Closefl};
  72. bool is_open() const
  73. {return (_File != 0); }
  74. _Myt *open(const char *_S, ios_base::openmode _M)
  75. {_Filet *_Fp;
  76. if (_File != 0 || (_Fp = __Fiopen(_S, _M)) == 0)
  77. return (0);
  78. _Init(_Fp, _Openfl);
  79. _Initcvt();
  80. return (this); }
  81. _Myt *open(const char *_N, ios::open_mode _M)
  82. {return (open(_N, (ios::openmode)_M)); }
  83. _Myt *close()
  84. {if (_File != 0 && fclose(_File) == 0)
  85. {_Init(0, _Closefl);
  86. return (this); }
  87. else
  88. return (0); }
  89. protected:
  90. virtual int_type overflow(int_type _C = _Tr::eof())
  91. {if (_Tr::eq_int_type(_Tr::eof(), _C))
  92. return (_Tr::not_eof(_C));
  93. else if (pptr() != 0 && pptr() < epptr())
  94. {*_Pninc() = _Tr::to_char_type(_C);
  95. return (_C); }
  96. else if (_File == 0)
  97. return (_Tr::eof());
  98. else if (_Pcvt == 0)
  99. return (_Fputc(_Tr::to_char_type(_C), _File)
  100. ? _C : _Tr::eof());
  101. else
  102. {const int _NC = 8;
  103. const _E _X = _Tr::to_char_type(_C);
  104. const _E *_S;
  105. char *_D;
  106. _Str->erase();
  107. for (size_t _I = _NC; ; _I += _NC)
  108. {_Str->append(_NC, '\0');
  109. switch (_Pcvt->out(_State,
  110. &_X, &_X + 1, _S,
  111. _Str->begin(), _Str->end(), _D))
  112. {case codecvt_base::partial:
  113. if (_S == &_X)
  114. return (_Tr::eof());
  115. case codecvt_base::ok: // can fall through
  116. {size_t _N = _D - _Str->begin();
  117. return (fwrite(_Str->begin(), 1, _N, _File)
  118. == _N ? _C : _Tr::eof()); }
  119. case codecvt_base::noconv:
  120. return (_Fputc(_X, _File) ? _C : _Tr::eof());
  121. default:
  122. return (_Tr::eof()); }}}}
  123. virtual int_type pbackfail(int_type _C = _Tr::eof())
  124. {if (gptr() != 0 && eback() < gptr()
  125. && (_Tr::eq_int_type(_Tr::eof(), _C)
  126. || _Tr::eq_int_type(_Tr::to_int_type(gptr()[-1]),
  127. _C)))
  128. {_Gndec();
  129. return (_Tr::not_eof(_C)); }
  130. else if (_File == 0 || _Tr::eq_int_type(_Tr::eof(), _C))
  131. return (_Tr::eof());
  132. else if (_Pcvt == 0)
  133. return (_Ungetc(_Tr::to_char_type(_C), _File)
  134. ? _C : _Tr::eof());
  135. else if (0 < _Str->size()
  136. && _Ungetc(*_Str->begin(), _File, _Str->size()))
  137. {_Str->erase();
  138. _State = _State0;
  139. return (_C); }
  140. else
  141. return (_Tr::eof()); }
  142. virtual int_type underflow()
  143. {if (gptr() != 0 && gptr() < egptr())
  144. return (_Tr::to_int_type(*gptr()));
  145. else
  146. return (pbackfail(uflow())); }
  147. virtual int_type uflow()
  148. {if (gptr() != 0 && gptr() < egptr())
  149. return (_Tr::to_int_type(*_Gninc()));
  150. else if (_File == 0)
  151. return (_Tr::eof());
  152. else if (_Pcvt == 0)
  153. {_E _C;
  154. return (_Fgetc(_C, _File) ? _Tr::to_int_type(_C)
  155. : _Tr::eof()); }
  156. else
  157. for (_State0 = _State, _Str->erase(); ; )
  158. {_E _X, *_D;
  159. const char *_S;
  160. int _C = fgetc(_File);
  161. if (_C == EOF)
  162. return (_Tr::eof()); // partial char?
  163. _Str->append(1, (char)_C);
  164. _State = _State0;
  165. switch (_Pcvt->in(_State,
  166. _Str->begin(), _Str->end(), _S,
  167. &_X, &_X + 1, _D))
  168. {case codecvt_base::partial:
  169. break;
  170. case codecvt_base::noconv:
  171. if (_Str->size() < sizeof (_E))
  172. break;
  173. memcpy(&_X, _Str->begin(), sizeof (_E));
  174. case codecvt_base::ok: // can fall through
  175. return (_Tr::to_int_type(_X));
  176. default:
  177. return (_Tr::eof()); }}}
  178. virtual pos_type seekoff(off_type _O, ios_base::seekdir _Way,
  179. ios_base::openmode =
  180. (ios_base::openmode)(ios_base::in | ios_base::out))
  181. {fpos_t _Fp;
  182. if (_File == 0 || fseek(_File, (long)_O, _Way) != 0
  183. || fgetpos(_File, &_Fp) != 0)
  184. return (pos_type(_BADOFF));
  185. return (pos_type(_State, _Fp)); }
  186. virtual pos_type seekpos(pos_type _P,
  187. ios_base::openmode =
  188. (ios_base::openmode)(ios_base::in | ios_base::out))
  189. {fpos_t _Fp = _P.get_fpos_t();
  190. off_type _Off = (off_type)_P - _FPOSOFF(_Fp);
  191. if (_File == 0
  192. || fsetpos(_File, &_Fp) != 0
  193. || _Off != 0 && fseek(_File, (long)_Off, SEEK_CUR) != 0
  194. || fgetpos(_File, &_Fp) != 0)
  195. return (pos_type(_BADOFF));
  196. if (_Str != 0)
  197. _State = _P.state(), _Str->erase();
  198. return (pos_type(_State, _Fp)); }
  199. virtual _Mysb *setbuf(_E *_S, streamsize _N)
  200. {return (_File == 0 || setvbuf(_File, (char *)_S,
  201. _IOFBF, _N * sizeof (_E)) != 0 ? 0 : this); }
  202. virtual int sync()
  203. {return (_File == 0 || 0 <= fflush(_File) ? 0 : -1); }
  204. void _Init(_Filet *_Fp, _Initfl _Which)
  205. {static _Tr::state_type _Stinit;
  206. _Closef = _Which == _Openfl;
  207. if (_Which == _Newfl)
  208. {_Loc.locale::~locale();
  209. new (&_Loc) locale;
  210. _Str = 0; }
  211. _Mysb::_Init();
  212. if (_Fp != 0 && !_Closef && sizeof (_E) == 1)
  213. {_Mysb::_Init((_E **)&_Fp->_base,
  214. (_E **)&_Fp->_ptr, &_Fp->_cnt,
  215. (_E **)&_Fp->_base, (_E **)&_Fp->_ptr,
  216. &_Fp->_cnt); }
  217. _File = _Fp;
  218. _State = _Stinit;
  219. _State0 = _Stinit;
  220. _Pcvt = 0; }
  221. void _Initcvt()
  222. {_Pcvt = (_Cvt *)&_USE(getloc(), _Cvt);
  223. _Loc = _ADDFAC(_Loc, _Pcvt);
  224. if (_Pcvt->always_noconv())
  225. _Pcvt = 0;
  226. if (_Str == 0)
  227. _Str = new string; }
  228. private:
  229. _Cvt *_Pcvt;
  230. _Tr::state_type _State0;
  231. _Tr::state_type _State;
  232. string *_Str;
  233. bool _Closef;
  234. locale _Loc;
  235. _Filet *_File;
  236. };
  237. #ifdef _DLL
  238. #ifdef __FORCE_INSTANCE
  239. template class _CRTIMP2 basic_filebuf<char, char_traits<char> >;
  240. template class _CRTIMP2 basic_filebuf<wchar_t, char_traits<wchar_t> >;
  241. #else // __FORCE_INSTANCE
  242. #pragma warning(disable:4231) /* the extern before template is a non-standard extension */
  243. extern template class _CRTIMP2 basic_filebuf<char, char_traits<char> >;
  244. extern template class _CRTIMP2 basic_filebuf<wchar_t, char_traits<wchar_t> >;
  245. #pragma warning(default:4231) /* restore previous warning */
  246. #endif // __FORCE_INSTANCE
  247. #endif // _DLL
  248. // TEMPLATE CLASS basic_ifstream
  249. template<class _E, class _Tr = char_traits<_E> >
  250. class basic_ifstream : public basic_istream<_E, _Tr> {
  251. public:
  252. typedef basic_ifstream<_E, _Tr> _Myt;
  253. typedef basic_filebuf<_E, _Tr> _Myfb;
  254. basic_ifstream()
  255. : basic_istream<_E, _Tr>(&_Fb) {}
  256. explicit basic_ifstream(const char *_S,
  257. ios_base::openmode _M = in)
  258. : basic_istream<_E, _Tr>(&_Fb)
  259. {if (_Fb.open(_S, _M | in) == 0)
  260. setstate(failbit); }
  261. virtual ~basic_ifstream()
  262. {}
  263. _Myfb *rdbuf() const
  264. {return ((_Myfb *)&_Fb); }
  265. bool is_open() const
  266. {return (_Fb.is_open()); }
  267. void open(const char *_S, ios_base::openmode _M = in)
  268. {if (_Fb.open(_S, _M | in) == 0)
  269. setstate(failbit); }
  270. void open(const char *_S, ios_base::open_mode _M)
  271. {open(_S, (openmode)_M); }
  272. void close()
  273. {if (_Fb.close() == 0)
  274. setstate(failbit); }
  275. private:
  276. _Myfb _Fb;
  277. };
  278. #ifdef _DLL
  279. #ifdef __FORCE_INSTANCE
  280. template class _CRTIMP2 basic_ifstream<char, char_traits<char> >;
  281. template class _CRTIMP2 basic_ifstream<wchar_t, char_traits<wchar_t> >;
  282. #else // __FORCE_INSTANCE
  283. #pragma warning(disable:4231) /* the extern before template is a non-standard extension */
  284. extern template class _CRTIMP2 basic_ifstream<char, char_traits<char> >;
  285. extern template class _CRTIMP2 basic_ifstream<wchar_t, char_traits<wchar_t> >;
  286. #pragma warning(default:4231) /* restore previous warning */
  287. #endif // __FORCE_INSTANCE
  288. #endif // _DLL
  289. // TEMPLATE CLASS basic_ofstream
  290. template<class _E, class _Tr = char_traits<_E> >
  291. class basic_ofstream : public basic_ostream<_E, _Tr> {
  292. public:
  293. typedef basic_ofstream<_E, _Tr> _Myt;
  294. typedef basic_filebuf<_E, _Tr> _Myfb;
  295. basic_ofstream()
  296. : basic_ostream<_E, _Tr>(&_Fb) {}
  297. explicit basic_ofstream(const char *_S,
  298. ios_base::openmode _M = out | trunc)
  299. : basic_ostream<_E, _Tr>(&_Fb)
  300. {if (_Fb.open(_S, _M | out) == 0)
  301. setstate(failbit); }
  302. virtual ~basic_ofstream()
  303. {}
  304. _Myfb *rdbuf() const
  305. {return ((_Myfb *)&_Fb); }
  306. bool is_open() const
  307. {return (_Fb.is_open()); }
  308. void open(const char *_S, ios_base::openmode _M = out | trunc)
  309. {if (_Fb.open(_S, _M | out) == 0)
  310. setstate(failbit); }
  311. void open(const char *_S, ios_base::open_mode _M)
  312. {open(_S, (openmode)_M); }
  313. void close()
  314. {if (_Fb.close() == 0)
  315. setstate(failbit); }
  316. private:
  317. _Myfb _Fb;
  318. };
  319. #ifdef _DLL
  320. #ifdef __FORCE_INSTANCE
  321. template class _CRTIMP2 basic_ofstream<char, char_traits<char> >;
  322. template class _CRTIMP2 basic_ofstream<wchar_t, char_traits<wchar_t> >;
  323. #else // __FORCE_INSTANCE
  324. #pragma warning(disable:4231) /* the extern before template is a non-standard extension */
  325. extern template class _CRTIMP2 basic_ofstream<char, char_traits<char> >;
  326. extern template class _CRTIMP2 basic_ofstream<wchar_t, char_traits<wchar_t> >;
  327. #pragma warning(default:4231) /* restore previous warning */
  328. #endif // __FORCE_INSTANCE
  329. #endif // _DLL
  330. // TEMPLATE CLASS basic_fstream
  331. template<class _E, class _Tr = char_traits<_E> >
  332. class basic_fstream : public basic_iostream<_E, _Tr> {
  333. public:
  334. basic_fstream()
  335. : basic_iostream<_E, _Tr>(&_Fb) {}
  336. explicit basic_fstream(const char *_S,
  337. ios_base::openmode _M = in | out)
  338. : basic_iostream<_E, _Tr>(&_Fb)
  339. {if (_Fb.open(_S, _M) == 0)
  340. setstate(failbit); }
  341. virtual ~basic_fstream()
  342. {}
  343. basic_filebuf<_E, _Tr> *rdbuf() const
  344. {return ((basic_filebuf<_E, _Tr> *)&_Fb); }
  345. bool is_open() const
  346. {return (_Fb.is_open()); }
  347. void open(const char *_S, ios_base::openmode _M = in | out)
  348. {if (_Fb.open(_S, _M) == 0)
  349. setstate(failbit); }
  350. void open(const char *_S, ios_base::open_mode _M)
  351. {open(_S, (openmode)_M); }
  352. void close()
  353. {if (_Fb.close() == 0)
  354. setstate(failbit); }
  355. private:
  356. basic_filebuf<_E, _Tr> _Fb;
  357. };
  358. #ifdef _DLL
  359. #ifdef __FORCE_INSTANCE
  360. template class _CRTIMP2 basic_fstream<char, char_traits<char> >;
  361. template class _CRTIMP2 basic_fstream<wchar_t, char_traits<wchar_t> >;
  362. #else // __FORCE_INSTANCE
  363. #pragma warning(disable:4231) /* the extern before template is a non-standard extension */
  364. extern template class _CRTIMP2 basic_fstream<char, char_traits<char> >;
  365. extern template class _CRTIMP2 basic_fstream<wchar_t, char_traits<wchar_t> >;
  366. #pragma warning(default:4231) /* restore previous warning */
  367. #endif // __FORCE_INSTANCE
  368. #endif // _DLL
  369. _STD_END
  370. #ifdef _MSC_VER
  371. #pragma pack(pop)
  372. #endif /* _MSC_VER */
  373. #endif /* _FSTREAM_ */
  374. /*
  375. * Copyright (c) 1994 by P.J. Plauger. ALL RIGHTS RESERVED.
  376. * Consult your license regarding permissions and restrictions.
  377. */