home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / stlpt453.zip / STLport-4.5.3 / stlport / stl / _time_facets.c < prev    next >
C/C++ Source or Header  |  2002-02-02  |  15KB  |  498 lines

  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. #ifndef _STLP_TIME_FACETS_C
  19. #define _STLP_TIME_FACETS_C
  20.  
  21. #ifndef _STLP_INTERNAL_TIME_FACETS_H
  22. # include <stl/_time_facets.h>
  23. #endif
  24.  
  25. #if defined (_STLP_EXPOSE_STREAM_IMPLEMENTATION)
  26.  
  27. #ifndef _STLP_INTERNAL_NUM_PUT_H
  28. # include <stl/_num_put.h>
  29. #endif
  30.  
  31. #ifndef _STLP_INTERNAL_NUM_GET_H
  32. # include <stl/_num_get.h>
  33. #endif
  34.  
  35. _STLP_BEGIN_NAMESPACE
  36.  
  37. //----------------------------------------------------------------------
  38. // Declarations of static template members.
  39. # if ( _STLP_STATIC_TEMPLATE_DATA > 0 )
  40.  
  41. template <class _CharT, class _InputIterator>
  42. locale::id time_get<_CharT, _InputIterator>::id;
  43.  
  44. template <class _CharT, class _OutputIterator>
  45. locale::id time_put<_CharT, _OutputIterator>::id;
  46.  
  47. # else /* ( _STLP_STATIC_TEMPLATE_DATA > 0 ) */
  48.  
  49. typedef time_get<char, const char*> time_get_char;
  50. typedef time_get<char, char*> time_get_char_2;
  51. typedef time_get<char, istreambuf_iterator<char, char_traits<char> > > time_get_char_3;
  52. typedef time_put<char, const char*> time_put_char;
  53. typedef time_put<char, char*> time_put_char_2;
  54. typedef time_put<char, ostreambuf_iterator<char, char_traits<char> > > time_put_char_3;
  55.  
  56. __DECLARE_INSTANCE(locale::id, time_get_char::id, );
  57. __DECLARE_INSTANCE(locale::id, time_get_char_2::id, );
  58. __DECLARE_INSTANCE(locale::id, time_get_char_3::id, );
  59. __DECLARE_INSTANCE(locale::id, time_put_char::id, );
  60. __DECLARE_INSTANCE(locale::id, time_put_char_2::id, );
  61. __DECLARE_INSTANCE(locale::id, time_put_char_3::id, );
  62.  
  63. # ifndef _STLP_NO_WCHAR_T
  64.  
  65. typedef time_get<wchar_t, const wchar_t*> time_get_wchar_t;
  66. typedef time_get<wchar_t, wchar_t*> time_get_wchar_t_2;
  67. typedef time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > > time_get_wchar_t_3;
  68. typedef time_put<wchar_t, const wchar_t*> time_put_wchar_t;
  69. typedef time_put<wchar_t, wchar_t*> time_put_wchar_t_2;
  70. typedef time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > > time_put_wchar_t_3;
  71.  
  72. __DECLARE_INSTANCE(locale::id, time_get_wchar_t::id, );
  73. __DECLARE_INSTANCE(locale::id, time_get_wchar_t_2::id, );
  74. __DECLARE_INSTANCE(locale::id, time_get_wchar_t_3::id, );
  75. __DECLARE_INSTANCE(locale::id, time_put_wchar_t::id, );
  76. __DECLARE_INSTANCE(locale::id, time_put_wchar_t_2::id, );
  77. __DECLARE_INSTANCE(locale::id, time_put_wchar_t_3::id, );
  78.  
  79. # endif
  80.  
  81. # endif /* ( _STLP_STATIC_TEMPLATE_DATA > 0 ) */
  82.  
  83. template <class _InIt, class _RAIt, class _DiffType>
  84. _RAIt _STLP_CALL
  85. __match(_InIt& __first, _InIt& __last, _RAIt __name, _RAIt __name_end, _DiffType*) {
  86.   typedef _DiffType difference_type;
  87.   difference_type __n = __name_end - __name;
  88.   size_t __max_pos = 0;
  89.   difference_type __i;
  90.   difference_type __pos = 0;
  91.   difference_type __check_count = __n;
  92.   bool __do_check[_MAXNAMES];
  93.   _RAIt __matching_name[_MAX_NAME_LENGTH];
  94.  
  95.   for (__i = 0; __i < __n; ++__i)
  96.     __max_pos = (max)(__max_pos,  __name[__i].size());
  97.  
  98.   for (__i = 0; __i < _MAXNAMES; ++__i)
  99.     __do_check[__i] = true;
  100.  
  101.  
  102.  
  103.   for (__i = 0; __i < _MAX_NAME_LENGTH; ++__i)
  104.     __matching_name[__i] = __name_end;
  105.  
  106.   while (__first != __last) {
  107.     for (__i = 0; __i < __n; ++__i)
  108.       if (__do_check[__i])
  109.         if (*__first == __name[__i][__pos]) {
  110.           if (__pos == _DiffType(__name[__i].size()) - 1) {
  111.             __do_check[__i] = 0;
  112.             __matching_name[__pos+1] = __name + __i;
  113.             --__check_count;
  114.             if (__check_count == 0) {
  115.               ++__first; 
  116.           return __name + __i;
  117.         }
  118.           }
  119.         }
  120.         else {
  121.           __do_check[__i] = 0;
  122.           --__check_count;
  123.           if (__check_count == 0) 
  124.             return __matching_name[__pos];
  125.         }
  126.  
  127.     ++__first; ++__pos;
  128.   }
  129.  
  130.   return __matching_name[__pos];
  131. }
  132.  
  133. template <class _InIt, class _RAIt>
  134. _RAIt _STLP_CALL
  135. __match(_InIt& __first, _InIt& __last, _RAIt __name, _RAIt __name_end) {
  136.   return __match((_InIt&)__first, (_InIt&)__last, __name, __name_end, _STLP_DISTANCE_TYPE(__name, _InIt));
  137. }
  138.  
  139. // __get_formatted_time reads input that is assumed to be formatted
  140. // according to the rules for the C strftime function (C standard,
  141. // 7.12.3.5).  This function is used to implement the do_get_time
  142. // and do_get_date virtual functions, which depend on the locale
  143. // specifications for the time and day formats respectively.
  144. // Note the catchall default case, intended mainly for the '%Z'
  145. // format designator, which does not make sense here since the
  146. // representation of timezones is not part of the locale.
  147. //
  148. // The case branches are implemented either by doing a match using
  149. // the appopriate name table or by doing a __get_integer_nogroup.
  150. //
  151. // 'y' format is assumed to mean that the input represents years
  152. // since 1900.  That is, 2002 should be represented as 102.  There
  153. // is no century-guessing.
  154. //
  155. // The match is successful if and only if the second component of the
  156. // return value is format_end.
  157.  
  158. // Note that the antepenultimate parameter is being used only to determine
  159. // the correct overloading for the calls to __get_integer_nogroup.
  160.  
  161. template <class _InIt1, class _InIt2 /* , class _Ch */ >
  162. _InIt2 _STLP_CALL
  163. __get_formatted_time _STLP_WEAK (_InIt1 __first,  _InIt1 __last,
  164.                      _InIt2 __format, _InIt2 __format_end,
  165.                  /* _Ch, */ const _Time_Info& __table,
  166.              ios_base::iostate& __err,
  167.                      tm*         __t) {
  168.   while(__first != __last && __format != __format_end) {
  169.     if (*__format == '%') {
  170.       ++__format;
  171.       char __c = *__format;
  172.       switch (__c) {
  173.         case 'a': {
  174.           const string* __pr =
  175.             __match(__first, __last,
  176.             (string*)__table._M_dayname + 0 , (string*)__table._M_dayname + 7);
  177.             if (__pr == (string*)__table._M_dayname + 7)
  178.               return __format;
  179.             __t->tm_wday = (int)(__pr - (string*)__table._M_dayname);
  180.             break;
  181.         }
  182.  
  183.         case 'A': {
  184.           const string* __pr =
  185.             __match(__first, __last,
  186.             (string*)__table._M_dayname + 7, (string*)__table._M_dayname + 14);
  187.             if (__pr == (string*)__table._M_dayname + 14)
  188.               return __format;
  189.             __t->tm_wday = (int)(__pr - (string*)__table._M_dayname - 7);
  190.             break;
  191.         }
  192.  
  193.         case 'b': {
  194.           const string* __pr =
  195.             __match(__first, __last,
  196.             (string*)__table._M_monthname + 0, (string*)__table._M_monthname + 12);
  197.             if (__pr == (string*)__table._M_monthname + 12)
  198.               return __format;
  199.             __t->tm_mon = (int)(__pr - (string*)__table._M_monthname);
  200.             break;
  201.         }
  202.  
  203.         case 'B': {
  204.           const string* __pr =
  205.             __match(__first, __last,
  206.             (string*)__table._M_monthname + 12, (string*)__table._M_monthname + 24);
  207.             if (__pr == (string*)__table._M_monthname + 24)
  208.               return __format;
  209.             __t->tm_mon = (int)(__pr - (string*)__table._M_monthname - 12);
  210.             break;
  211.         }
  212.  
  213.         case 'd': {
  214.           bool __pr =
  215.             __get_decimal_integer(__first, __last, __t->tm_mday);
  216.           if (!__pr || __t->tm_mday < 1 || __t->tm_mday > 31) {
  217.         __err |= ios_base::failbit;
  218.             return __format;
  219.       }
  220.           break;
  221.         }
  222.         
  223.         case 'H': case 'I': {
  224.           bool __pr =
  225.             __get_decimal_integer(__first, __last, __t->tm_hour);
  226.             if (!__pr)
  227.               return __format;
  228.             break;
  229.         }
  230.  
  231.         case 'j': {
  232.           bool __pr =
  233.             __get_decimal_integer(__first, __last, __t->tm_yday);
  234.           if (!__pr)
  235.             return __format;
  236.           break;
  237.         }
  238.  
  239.         case 'm': {
  240.           bool __pr =
  241.             __get_decimal_integer(__first, __last, __t->tm_mon);
  242.         --__t->tm_mon;
  243.           if (!__pr || __t->tm_mon < 0 || __t->tm_mon > 11) {
  244.         __err |= ios_base::failbit;
  245.             return __format;
  246.       }
  247.           break;
  248.         }
  249.  
  250.         case 'M': {
  251.           bool __pr =
  252.             __get_decimal_integer(__first, __last, __t->tm_min);
  253.           if (!__pr)
  254.             return __format;
  255.           break;
  256.         }
  257.  
  258.         case 'p': {
  259.           const string* __pr =
  260.             __match(__first, __last, (string*)__table._M_am_pm + 0, (string*)__table._M_am_pm + 2);
  261.           if (__pr == (string*)__table._M_am_pm + 2)
  262.             return __format;
  263.           if (__pr == (string*)__table._M_am_pm + 1)
  264.             __t->tm_hour += 12;
  265.           break;
  266.         }
  267.  
  268.         case 'S': {
  269.           bool __pr =
  270.             __get_decimal_integer(__first, __last, __t->tm_sec);
  271.           if (!__pr)
  272.             return __format;
  273.           break;
  274.         }
  275.  
  276.     case 'y': {
  277.       bool __pr =
  278.         __get_decimal_integer(__first, __last, __t->tm_year);
  279.       if (!__pr)
  280.         return __format;
  281.       break;
  282.         }
  283.  
  284.         case 'Y': {
  285.       bool __pr =
  286.             __get_decimal_integer(__first, __last, __t->tm_year);
  287.           __t->tm_year -= 1900;
  288.           if (!__pr)
  289.             return __format;
  290.           break;
  291.         }
  292.  
  293.         default:
  294.           break;
  295.       }
  296.  
  297.     }
  298.     else {
  299.       if (*__first++ != *__format) break;
  300.     }
  301.     
  302.     ++__format;
  303.   }
  304.  
  305.   return __format;
  306. }
  307.  
  308. template <class _InIt>
  309. bool _STLP_CALL
  310. __get_short_or_long_dayname(_InIt& __first, _InIt& __last,
  311.                             const _Time_Info& __table, tm* __t) {
  312.   const string* __pr =
  313.     __match(__first, __last, __table._M_dayname + 0, __table._M_dayname + 14);
  314.   __t->tm_wday = (int)(__pr - __table._M_dayname) % 7;
  315.   return __pr != __table._M_dayname + 14;
  316. }
  317.  
  318. template <class _InIt>
  319. bool _STLP_CALL
  320. __get_short_or_long_monthname(_InIt& __first, _InIt& __last,
  321.                               const _Time_Info& __table, tm* __t) {
  322.   const string* __pr =
  323.     __match(__first, __last, (string*)__table._M_monthname + 0, (string*)__table._M_monthname + 24);
  324.   __t->tm_mon = (int)(__pr - __table._M_monthname) % 12;
  325.   return __pr != __table._M_monthname + 24;
  326. }
  327.  
  328. # ifndef _STLP_NO_WCHAR_T
  329. template <class _OuIt>
  330. _OuIt _STLP_CALL
  331. __put_time(char * __first, char * __last, _OuIt __out,
  332.            const ios_base& __s, wchar_t) {
  333.     const ctype<wchar_t>& __ct = *(ctype<wchar_t>*)__s._M_ctype_facet();
  334.     wchar_t __wbuf[64];
  335.     __ct.widen(__first, __last, __wbuf);
  336.     ptrdiff_t __len = __last - __first;
  337.     wchar_t * __eend = __wbuf + __len;
  338.     return copy((wchar_t*)__wbuf, __eend, __out);
  339. }
  340. # endif
  341.  
  342. template <class _Ch, class _InIt>
  343. _InIt
  344. time_get<_Ch, _InIt>::do_get_date(_InIt __s, _InIt  __end,
  345.                   ios_base& /* __str */, ios_base::iostate&  __err,
  346.                   tm* __t) const 
  347. {
  348.   typedef string::const_iterator string_iterator;
  349.  
  350.   string_iterator __format
  351.     = _M_timeinfo._M_date_format.begin();
  352.   string_iterator __format_end
  353.     = _M_timeinfo._M_date_format.end();
  354.   
  355.   string_iterator __result
  356.     = __get_formatted_time(__s, __end, __format, __format_end,
  357.                            /* _Ch() ,*/  _M_timeinfo, __err, __t);
  358.   if (__result == __format_end)
  359.     __err = ios_base::goodbit;
  360.   else {
  361.     __err = ios_base::failbit;
  362.     if (__s == __end)
  363.       __err |= ios_base::eofbit;
  364.   }
  365.   return __s;
  366. }
  367.  
  368. template <class _Ch, class _InIt>
  369. _InIt
  370. time_get<_Ch, _InIt>::do_get_time(_InIt __s, _InIt  __end,
  371.                   ios_base& /* __str */, ios_base::iostate&  __err,
  372.                   tm* __t) const 
  373. {
  374.   typedef string::const_iterator string_iterator;
  375.   string_iterator __format
  376.     = _M_timeinfo._M_time_format.begin();
  377.   string_iterator __format_end
  378.     = _M_timeinfo._M_time_format.end();
  379.   
  380.   string_iterator __result
  381.     = __get_formatted_time(__s, __end, __format, __format_end,
  382.                /* _Ch() , */ _M_timeinfo, __err, __t);
  383.   __err = __result == __format_end ? ios_base::goodbit 
  384.     : ios_base::failbit;
  385.   if (__s == __end)
  386.     __err |= ios_base::eofbit;
  387.   return __s;
  388. }
  389.  
  390. template <class _Ch, class _InIt>
  391. _InIt
  392. time_get<_Ch, _InIt>::do_get_year(_InIt __s, _InIt  __end,
  393.                   ios_base&, 
  394.                   ios_base::iostate&  __err,
  395.                   tm* __t) const
  396. {
  397.   
  398.   if (__s == __end) {
  399.     __err = ios_base::failbit | ios_base::eofbit;
  400.     return __s;
  401.   }
  402.   
  403.   bool __pr =  __get_decimal_integer(__s, __end, __t->tm_year);
  404.   __t->tm_year -= 1900;
  405.   __err = __pr ? ios_base::goodbit : ios_base::failbit;
  406.   if (__s == __end)
  407.     __err |= ios_base::eofbit;
  408.   
  409.   return __s;
  410. }
  411.  
  412. template <class _Ch, class _InIt>
  413. _InIt
  414. time_get<_Ch, _InIt>::do_get_weekday(_InIt __s, _InIt  __end,
  415.                      ios_base& /* __str */, 
  416.                      ios_base::iostate&  __err,
  417.                      tm* __t) const 
  418. {
  419.     bool __result =
  420.       __get_short_or_long_dayname(__s, __end, _M_timeinfo, __t);
  421.     if (__result)
  422.       __err = ios_base::goodbit;
  423.     else {
  424.       __err = ios_base::failbit;
  425.       if (__s == __end)
  426.         __err |= ios_base::eofbit;
  427.     }
  428.     return __s;
  429. }
  430.  
  431. template <class _Ch, class _InIt>
  432. _InIt
  433. time_get<_Ch, _InIt>::do_get_monthname(_InIt __s, _InIt  __end,
  434.                        ios_base& /* __str */, 
  435.                        ios_base::iostate&  __err,
  436.                        tm* __t) const 
  437. {
  438.   bool __result =
  439.     __get_short_or_long_monthname(__s, __end, _M_timeinfo, __t);
  440.   if (__result)
  441.     __err = ios_base::goodbit;
  442.   else {
  443.     __err = ios_base::failbit;
  444.     if (__s == __end)
  445.       __err |= ios_base::eofbit;
  446.   }
  447.   return __s;
  448. }
  449.  
  450. template<class _Ch, class _OutputIter>
  451. _OutputIter
  452. time_put<_Ch,_OutputIter>::put(_OutputIter __s, ios_base& __f, _Ch __fill,
  453.                    const tm* __tmb,
  454.                    const _Ch* __pat, const _Ch* __pat_end) const 
  455. {
  456.   //  locale __loc = __f.getloc();
  457.   //  const ctype<_Ch>& _Ct = use_facet<ctype<_Ch> >(__loc); 
  458.   const ctype<_Ch>& _Ct = *(ctype<_Ch>*)__f._M_ctype_facet(); 
  459.   while (__pat != __pat_end) {
  460.     char __c = _Ct.narrow(*__pat, 0);
  461.     if (__c == '%') {
  462.       char __mod = 0;
  463.       ++__pat;
  464.       __c = _Ct.narrow(*__pat++, 0);
  465.       if(__c == '#') { // MS extension
  466.         __mod = __c;
  467.         __c = _Ct.narrow(*__pat++, 0);
  468.       }
  469.       __s = do_put(__s, __f, __fill, __tmb, __c, __mod);
  470.     }
  471.     else
  472.       *__s++ = *__pat++;
  473.   }
  474.   return __s;
  475. }
  476.  
  477. template<class _Ch, class _OutputIter>
  478. _OutputIter
  479. time_put<_Ch,_OutputIter>::do_put(_OutputIter __s, ios_base& __f, _Ch     /* __fill */ ,
  480.                   const tm* __tmb,
  481.                   char __format, char __modifier ) const 
  482. {
  483.   char __buf[64];
  484.   char * __iend = __write_formatted_time(__buf, __format, __modifier,
  485.                      _M_timeinfo, __tmb);
  486.   //  locale __loc = __f.getloc();
  487.   return __put_time(__buf, __iend, __s, __f, _Ch());
  488. }
  489.  
  490. _STLP_END_NAMESPACE
  491.  
  492. # endif /* defined (_STLP_EXPOSE_STREAM_IMPLEMENTATION) */
  493. #endif /* _STLP_TIME_FACETS_C */
  494.  
  495. // Local Variables:
  496. // mode:C++
  497. // End:
  498.