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

  1. // xloctime internal header (from <locale>)
  2.  
  3. #if     _MSC_VER > 1000
  4. #pragma once
  5. #endif
  6.  
  7. #ifndef _XLOCTIME_
  8. #define _XLOCTIME_
  9. #include <ctime>
  10. #include <xiosbase>
  11.  
  12. #ifdef  _MSC_VER
  13. #pragma pack(push,8)
  14. #endif  /* _MSC_VER */
  15. _STD_BEGIN
  16.         // STRUCT time_base
  17. struct _CRTIMP time_base : public locale::facet {
  18.     enum _Dateorder {no_order, dmy, mdy, ymd, ydm};
  19.     _BITMASK(_Dateorder, dateorder);
  20.     time_base(size_t _R = 0)
  21.         : locale::facet(_R) {}
  22.     };
  23. _BITMASK_OPS(time_base::_Dateorder);
  24.         // TEMPLATE CLASS time_get
  25. template<class _E,
  26.     class _II = istreambuf_iterator<_E, char_traits<_E> > >
  27.     class time_get : public time_base {
  28. public:
  29.     typedef _E char_type;
  30.     typedef _II iter_type;
  31.     static locale::id id;
  32.     dateorder date_order() const
  33.         {return (do_date_order()); }
  34.     _II get_time(_II _F, _II _L, ios_base& _X,
  35.         ios_base::iostate& _St, tm *_Tp) const
  36.         {return (do_get_time(_F, _L, _X, _St, _Tp)); }
  37.     _II get_date(_II _F, _II _L, ios_base& _X,
  38.         ios_base::iostate& _St, tm *_Tp) const
  39.         {return (do_get_date(_F, _L, _X, _St, _Tp)); }
  40.     _II get_weekday(_II _F, _II _L, ios_base& _X,
  41.         ios_base::iostate& _St, tm *_Tp) const
  42.         {return (do_get_weekday(_F, _L, _X, _St, _Tp)); }
  43.     _II get_monthname(_II _F, _II _L, ios_base& _X,
  44.         ios_base::iostate& _St, tm *_Tp) const
  45.         {return (do_get_monthname(_F, _L, _X, _St, _Tp)); }
  46.     _II get_year(_II _F, _II _L, ios_base& _X,
  47.         ios_base::iostate& _St, tm *_Tp) const
  48.         {return (do_get_year(_F, _L, _X, _St, _Tp)); }
  49.     explicit time_get(size_t _R = 0)
  50.         : time_base(_R) {_Init(_Locinfo()); }
  51.     time_get(const _Locinfo& _Lobj, size_t _R = 0)
  52.         : time_base(_R) {_Init(_Lobj); }
  53.     static size_t __cdecl _Getcat()
  54.         {return (_LC_TIME); }
  55. _PROTECTED:
  56.     virtual ~time_get()
  57.         {delete[] _Days;
  58.         delete[] _Months; }
  59. protected:
  60.     void _Init(const _Locinfo& _Lobj)
  61.         {_Days = _MAKLOCSTR(_E, _Lobj._Getdays());
  62.         _Months = _MAKLOCSTR(_E, _Lobj._Getmonths()); }
  63.     virtual dateorder do_date_order() const
  64.         {return (mdy); }
  65.     virtual _II do_get_time(_II _F, _II _L, ios_base& _X,
  66.         ios_base::iostate& _St, tm *_Tp) const
  67.         {const _E _Colon = _WIDEN(_E, ':');
  68.         _St |= _Getint(_F, _L, 0, 23, _Tp->tm_hour);
  69.         if (_St != ios_base::goodbit || *_F != _Colon)
  70.             _St |= ios_base::failbit;
  71.         else
  72.             _St |= _Getint(++_F, _L, 0, 59, _Tp->tm_min);
  73.         if (_St != ios_base::goodbit || *_F != _Colon)
  74.             _St |= ios_base::failbit;
  75.         else
  76.             _St |= _Getint(++_F, _L, 0, 59, _Tp->tm_sec);
  77.         return (_F); }
  78.     virtual _II do_get_date(_II _F, _II _L, ios_base& _X,
  79.         ios_base::iostate& _St, tm *_Tp) const    // Dec 2, 1979
  80.         {_F = get_monthname(_F, _L, _X, _St, _Tp);
  81.         if (_St != ios_base::goodbit || *_F != _WIDEN(_E, ' '))
  82.             _St |= ios_base::failbit;
  83.         else
  84.             _St |= _Getint(++_F, _L, 1, 31, _Tp->tm_mday);
  85.         if (_St != ios_base::goodbit || *_F != _WIDEN(_E, ','))
  86.             _St |= ios_base::failbit;
  87.         else if (++_F == _L || *_F != _WIDEN(_E, ' '))
  88.             _St |= ios_base::failbit;
  89.         else
  90.             _F = get_year(++_F, _L, _X, _St, _Tp);
  91.         if (_F == _L)
  92.             _St |= ios_base::eofbit;
  93.         return (_F); }
  94.     virtual _II do_get_weekday(_II _F, _II _L, ios_base& _X,
  95.         ios_base::iostate& _St, tm *_Tp) const
  96.         {int _N = _Getloctxt(_F, _L, (size_t)0, _Days);
  97.         if (_N < 0)
  98.             _St |= ios_base::failbit;
  99.         else
  100.             _Tp->tm_wday = _N >> 1;
  101.         return (_F); }
  102.     virtual _II do_get_monthname(_II _F, _II _L, ios_base& _X,
  103.         ios_base::iostate& _St, tm *_Tp) const
  104.         {int _N = _Getloctxt(_F, _L, (size_t)0, _Months);
  105.         if (_N < 0)
  106.             _St |= ios_base::failbit;
  107.         else
  108.             _Tp->tm_mon = _N >> 1;
  109.         return (_F); }
  110.     virtual _II do_get_year(_II _F, _II _L, ios_base& _X,
  111.         ios_base::iostate& _St, tm *_Tp) const
  112.         {int _Ans;
  113.         _St |= _Getint(_F, _L, 0, 2035, _Ans);
  114.         if (_St & ios_base::failbit)
  115.             ;
  116.         else if (1900 <= _Ans)
  117.             _Ans -= 1900;
  118.         else if (2035 - 1900 < _Ans)
  119.             _St |= ios_base::failbit;
  120.         if (!(_St & ios_base::failbit))
  121.             _Tp->tm_year = _Ans;
  122.         return (_F); }
  123. private:
  124.     static ios_base::iostate __cdecl _Getint(_II& _F, _II& _L,
  125.         int _Lo, int _Hi, int& _V)
  126.         {char _Ac[_MAX_INT_DIG], *_Ep;
  127.         char *_P = _Ac;
  128.         if (_F == _L)
  129.             ;
  130.         else if (*_F == _WIDEN(_E, '+'))
  131.             *_P++ = '+', ++_F;
  132.         else if (*_F == _WIDEN(_E, '-'))
  133.             *_P++ = '-', ++_F;
  134.         bool _Sd = false;
  135.         while (_F != _L && *_F == _WIDEN(_E, '0'))
  136.             _Sd = true, ++_F;
  137.         if (_Sd)
  138.             *_P++ = '0';
  139.         for (char *const _Pe = &_Ac[_MAX_INT_DIG - 1]; _F != _L
  140.             && '0' <= (*_P = (char)_NARROW(_E, *_F)) && *_P <= '9';
  141.             _Sd = true, ++_F)
  142.             if (_P < _Pe)
  143.                 ++_P;
  144.         if (!_Sd)
  145.             _P = _Ac;
  146.         *_P = '\0';
  147.         errno = 0;
  148.         const long _Ans = strtol(_Ac, &_Ep, 10);
  149.         ios_base::iostate _St = ios_base::goodbit;
  150.         if (_F == _L)
  151.             _St |= ios_base::eofbit;
  152.         if (_Ep == _Ac || errno != 0 || _Ans < _Lo || _Hi < _Ans)
  153.             _St |= ios_base::failbit;
  154.         else
  155.             _V = _Ans;
  156.         return (_St); }
  157.     _E *_Days, *_Months;
  158.     };
  159. template<class _E, class _II>
  160.     locale::id time_get<_E, _II>::id;
  161.         // TEMPLATE CLASS time_get_byname
  162. template<class _E,
  163.     class _II = istreambuf_iterator<_E, char_traits<_E> > >
  164.     class time_get_byname : public time_get<_E, _II> {
  165. public:
  166.     explicit time_get_byname(const char *_S, size_t _R = 0)
  167.         : time_get<_E, _II>(_Locinfo(_S), _R) {}
  168. _PROTECTED:
  169.     virtual ~time_get_byname()
  170.         {}
  171.     };
  172.         // TEMPLATE CLASS time_put
  173. template<class _E,
  174.     class _OI = ostreambuf_iterator<_E, char_traits<_E> > >
  175.     class time_put : public time_base {
  176. public:
  177.     typedef _E char_type;
  178.     typedef _OI iter_type;
  179.     _OI put(_OI _F, ios_base& _X, const tm *_Tp,
  180.         const _E *_Ff, const _E *_Lf) const
  181.         {const _E _Pct = _WIDEN(_E, '%');
  182.         for (; _Ff != _Lf; ++_Ff)
  183.             if (*_Ff != _Pct)
  184.                 *_F++ = *_Ff;
  185.             else if (++_Ff == _Lf)
  186.                 {*_F++ = _Pct;
  187.                 break; }
  188.             else
  189.                 {char _C = (char)_NARROW(_E, *_Ff);
  190.                 char _Q = '\0';
  191.                 if (_C != 'E' && _C != 'O' && _C != 'Q'
  192.                     && _C != '#')
  193.                     ;
  194.                 else if (++_Ff == _Lf)
  195.                     {*_F++ = _Pct, *_F++ = _C;
  196.                     break; }
  197.                 else
  198.                     _Q = _C, _C = (char)_NARROW(_E, *_Ff);
  199.                 _F = do_put(_F, _X, _Tp, _C, _Q); }
  200.         return (_F); }
  201.     _OI put(_OI _F, ios_base& _X, const tm *_Tp,
  202.         char _C, char _M = 0) const
  203.         {return (do_put(_F, _X, _Tp, _C, _M)); }
  204.     static locale::id id;
  205.     explicit time_put(size_t _R = 0)
  206.         : time_base(_R) {_Init(_Locinfo()); }
  207.     time_put(const _Locinfo& _Lobj, size_t _R = 0)
  208.         : time_base(_R) {_Init(_Lobj); }
  209.     static size_t __cdecl _Getcat()
  210.         {return (_LC_TIME); }
  211. _PROTECTED:
  212.     virtual ~time_put()
  213.         {}
  214. protected:
  215.     void _Init(const _Locinfo& _Lobj)
  216.         {_Tnames = _Lobj._Gettnames(); }
  217.     virtual _OI do_put(_OI _F, ios_base& _X, const tm *_Tp,
  218.         char _C, char _M = 0) const
  219.         {char _Fmt[5] = {"!%x\0"};
  220.         size_t _I, _N;
  221.         string _Str;
  222.         if (_M == (_E)0)
  223.             _Fmt[2] = _C;
  224.         else
  225.             _Fmt[2] = _M, _Fmt[3] = _C;
  226.         for (_N = 16; ; _N *= 2)
  227.             {_Str.append(_N, '\0');
  228.             if (0 < (_I = _Strftime(_Str.begin(), _Str.size(),
  229.                 _Fmt, _Tp, _Tnames._Getptr())))
  230.                 break; }
  231.         for (char *_S = _Str.begin(); 0 < --_I; ++_F)
  232.             *_F = _WIDEN(_E, *++_S);
  233.         return (_F); }
  234. private:
  235.     _Locinfo::_Timevec _Tnames;
  236.     };
  237. template<class _E, class _OI>
  238.     locale::id time_put<_E, _OI>::id;
  239.         // TEMPLATE CLASS time_put_byname
  240. template<class _E,
  241.     class _OI = ostreambuf_iterator<_E, char_traits<_E> > >
  242.     class time_put_byname : public time_put<_E, _OI> {
  243. public:
  244.     explicit time_put_byname(const char *_S, size_t _R = 0)
  245.         : time_put<_E, _OI>(_Locinfo(_S), _R) {}
  246. _PROTECTED:
  247.     virtual ~time_put_byname()
  248.         {}
  249.     };
  250. #ifdef    _DLL
  251.  
  252. #pragma warning(disable:4231) /* the extern before template is a non-standard extension */
  253.  
  254. extern template class _CRTIMP time_get<char, 
  255.                       istreambuf_iterator<char, char_traits<char> > >;
  256. extern template class _CRTIMP time_get<wchar_t, 
  257.                       istreambuf_iterator<wchar_t, char_traits<wchar_t> > >;
  258. extern template class _CRTIMP time_put<char,
  259.                       ostreambuf_iterator<char, char_traits<char> > >;
  260. extern template class _CRTIMP time_put<wchar_t,
  261.                       ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >;
  262.  
  263. #pragma warning(default:4231) /* restore previous warning */
  264.  
  265. #endif        // _DLL
  266.  
  267. _STD_END
  268. #ifdef  _MSC_VER
  269. #pragma pack(pop)
  270. #endif  /* _MSC_VER */
  271.  
  272. #endif /* _XLOCTIME_ */
  273.  
  274. /*
  275.  * Copyright (c) 1995 by P.J. Plauger.  ALL RIGHTS RESERVED. 
  276.  * Consult your license regarding permissions and restrictions.
  277.  */
  278.