home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / include / fstream < prev    next >
Text File  |  1998-06-16  |  12KB  |  380 lines

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