/home/ntakagi/work/STLport-5.1.5/stlport/stl/_time_facets.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1999
00003  * Silicon Graphics Computer Systems, Inc.
00004  *
00005  * Copyright (c) 1999
00006  * Boris Fomitchev
00007  *
00008  * This material is provided "as is", with absolutely no warranty expressed
00009  * or implied. Any use is at your own risk.
00010  *
00011  * Permission to use or copy this software for any purpose is hereby granted
00012  * without fee, provided the above notices are retained on all copies.
00013  * Permission to modify the code and to distribute modified code is granted,
00014  * provided the above notices are retained, and a notice that the code was
00015  * modified is included with the above copyright notice.
00016  *
00017  */
00018 #ifndef _STLP_TIME_FACETS_C
00019 #define _STLP_TIME_FACETS_C
00020 
00021 #ifndef _STLP_INTERNAL_TIME_FACETS_H
00022 #  include <stl/_time_facets.h>
00023 #endif
00024 
00025 #ifndef _STLP_INTERNAL_NUM_PUT_H
00026 #  include <stl/_num_put.h>
00027 #endif
00028 
00029 #ifndef _STLP_INTERNAL_NUM_GET_H
00030 #  include <stl/_num_get.h>
00031 #endif
00032 
00033 _STLP_BEGIN_NAMESPACE
00034 
00035 //----------------------------------------------------------------------
00036 // Declarations of static template members.
00037 #if (_STLP_STATIC_TEMPLATE_DATA > 0)
00038 
00039 #  if !defined (__BORLANDC__)
00040 template <class _CharT, class _InputIterator>
00041 locale::id time_get<_CharT, _InputIterator>::id;
00042 
00043 template <class _CharT, class _OutputIterator>
00044 locale::id time_put<_CharT, _OutputIterator>::id;
00045 #  endif
00046 
00047 #  if (defined (__CYGWIN__) || defined (__MINGW32__)) && \
00048        defined (_STLP_USE_DYNAMIC_LIB) && !defined (__BUILDING_STLPORT)
00049 /*
00050  * Under cygwin, when STLport is used as a shared library, the id needs
00051  * to be specified as imported otherwise they will be duplicated in the
00052  * calling executable.
00053  */
00054 template <>
00055 _STLP_DECLSPEC locale::id time_get<char, istreambuf_iterator<char, char_traits<char> > >::id;
00056 /*
00057 template <>
00058 _STLP_DECLSPEC locale::id time_get<char, const char*>::id;
00059 */
00060 
00061 template <>
00062 _STLP_DECLSPEC locale::id time_put<char, ostreambuf_iterator<char, char_traits<char> > >::id;
00063 /*
00064 template <>
00065 _STLP_DECLSPEC locale::id time_put<char, char*>::id;
00066 */
00067 
00068 #    ifndef _STLP_NO_WCHAR_T
00069 template <>
00070 _STLP_DECLSPEC locale::id time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id;
00071 /*
00072 template <>
00073 _STLP_DECLSPEC locale::id time_get<wchar_t, const wchar_t*>::id;
00074 */
00075 
00076 template <>
00077 _STLP_DECLSPEC locale::id time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id;
00078 /*
00079 template <>
00080 _STLP_DECLSPEC locale::id time_put<wchar_t, wchar_t*>::id;
00081 */
00082 #    endif /* _STLP_NO_WCHAR_T */
00083 #  endif /* __CUGWIN__ && _STLP_USE_DYNAMIC_LIB */
00084 
00085 #else /* ( _STLP_STATIC_TEMPLATE_DATA > 0 ) */
00086 
00087 //typedef time_get<char, const char*> time_get_char;
00088 typedef time_get<char, istreambuf_iterator<char, char_traits<char> > > time_get_char_2;
00089 //typedef time_put<char, char*> time_put_char;
00090 typedef time_put<char, ostreambuf_iterator<char, char_traits<char> > > time_put_char_2;
00091 
00092 //__DECLARE_INSTANCE(locale::id, time_get_char::id, );
00093 __DECLARE_INSTANCE(locale::id, time_get_char_2::id, );
00094 //__DECLARE_INSTANCE(locale::id, time_put_char::id, );
00095 __DECLARE_INSTANCE(locale::id, time_put_char_2::id, );
00096 
00097 #  if !defined (_STLP_NO_WCHAR_T)
00098 
00099 //typedef time_get<wchar_t, const wchar_t*> time_get_wchar_t;
00100 typedef time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > > time_get_wchar_t_2;
00101 //typedef time_put<wchar_t, wchar_t*> time_put_wchar_t;
00102 typedef time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > > time_put_wchar_t_2;
00103 
00104 //__DECLARE_INSTANCE(locale::id, time_get_wchar_t::id, );
00105 __DECLARE_INSTANCE(locale::id, time_get_wchar_t_2::id, );
00106 //__DECLARE_INSTANCE(locale::id, time_put_wchar_t::id, );
00107 __DECLARE_INSTANCE(locale::id, time_put_wchar_t_2::id, );
00108 
00109 #  endif
00110 
00111 #endif /* ( _STLP_STATIC_TEMPLATE_DATA > 0 ) */
00112 
00113 _STLP_MOVE_TO_PRIV_NAMESPACE
00114 
00115 template <class _InIt, class _CharT>
00116 const string* _STLP_CALL
00117 __match(_InIt& __first, _InIt& __last, const string *__name, const string *__name_end,
00118         const ctype<_CharT>& __ct) {
00119   typedef ptrdiff_t difference_type;
00120   difference_type __n = __name_end - __name;
00121   difference_type __i;
00122   size_t __pos = 0;
00123   difference_type __check_count = __n;
00124   bool __do_check[_MAXNAMES];
00125   const string* __matching_name[_MAX_NAME_LENGTH];
00126 
00127   for (__i = 0; __i < _MAXNAMES; ++__i)
00128     __do_check[__i] = true;
00129 
00130   for (__i = 0; __i < _MAX_NAME_LENGTH; ++__i)
00131     __matching_name[__i] = __name_end;
00132 
00133   while (__first != __last) {
00134     for (__i = 0; __i < __n; ++__i) {
00135       if (__do_check[__i]) {
00136         if (*__first == __ct.widen(__name[__i][__pos])) {
00137           if (__pos == (__name[__i].size() - 1)) {
00138             __do_check[__i] = 0;
00139             __matching_name[__pos + 1] = __name + __i;
00140             --__check_count;
00141             if (__check_count == 0) {
00142               ++__first;
00143               return __name + __i;
00144             }
00145           }
00146         }
00147         else {
00148           __do_check[__i] = 0;
00149           --__check_count;
00150           if (__check_count == 0)
00151             return __matching_name[__pos];
00152         }
00153       }
00154     }
00155 
00156     ++__first; ++__pos;
00157   }
00158 
00159   return __matching_name[__pos];
00160 }
00161 
00162 // __get_formatted_time reads input that is assumed to be formatted
00163 // according to the rules for the C strftime function (C standard,
00164 // 7.12.3.5).  This function is used to implement the do_get_time
00165 // and do_get_date virtual functions, which depend on the locale
00166 // specifications for the time and day formats respectively.
00167 // Note the catchall default case, intended mainly for the '%Z'
00168 // format designator, which does not make sense here since the
00169 // representation of timezones is not part of the locale.
00170 //
00171 // The case branches are implemented either by doing a match using
00172 // the appopriate name table or by doing a __get_integer_nogroup.
00173 //
00174 // 'y' format is assumed to mean that the input represents years
00175 // since 1900.  That is, 2002 should be represented as 102.  There
00176 // is no century-guessing.
00177 //
00178 // The match is successful if and only if the second component of the
00179 // return value is format_end.
00180 
00181 // Note that the antepenultimate parameter is being used only to determine
00182 // the correct overloading for the calls to __get_integer_nogroup.
00183 template <class _InIt1, class _Ch>
00184 string::const_iterator _STLP_CALL
00185 __get_formatted_time _STLP_WEAK (_InIt1 __first,  _InIt1 __last,
00186                                  string::const_iterator __format, string::const_iterator __format_end,
00187                                  _Ch*, const _Time_Info& __table,
00188                                  const ios_base& __s, ios_base::iostate& __err, tm* __t) {
00189   const ctype<_Ch>& __ct = *__STATIC_CAST(const ctype<_Ch>*, __s._M_ctype_facet());
00190   while (__first != __last && __format != __format_end) {
00191     if (*__format == '%') {
00192       ++__format;
00193       char __c = *__format;
00194       if (__c == '#') { //MS extension
00195         ++__format;
00196         __c = *__format;
00197       }
00198 
00199       switch (__c) {
00200         case 'a': {
00201           const string* __pr = __match(__first, __last,
00202                                        __table._M_dayname + 0, __table._M_dayname + 7,
00203                                        __ct);
00204           if (__pr == __table._M_dayname + 7)
00205             return __format;
00206           __t->tm_wday = __STATIC_CAST(int, __pr - __table._M_dayname);
00207           break;
00208         }
00209 
00210         case 'A': {
00211           const string* __pr = __match(__first, __last,
00212                                        __table._M_dayname + 7, __table._M_dayname + 14,
00213                                        __ct);
00214           if (__pr == __table._M_dayname + 14)
00215             return __format;
00216           __t->tm_wday = __STATIC_CAST(int, __pr - __table._M_dayname - 7);
00217           break;
00218         }
00219 
00220         case 'b': {
00221           const string* __pr = __match(__first, __last,
00222                                        __table._M_monthname + 0, __table._M_monthname + 12,
00223                                        __ct);
00224           if (__pr == __table._M_monthname + 12)
00225             return __format;
00226           __t->tm_mon = __STATIC_CAST(int, __pr - __table._M_monthname);
00227           break;
00228         }
00229 
00230         case 'B': {
00231           const string* __pr = __match(__first, __last,
00232                                        __table._M_monthname + 12, __table._M_monthname + 24,
00233                                        __ct);
00234           if (__pr == __table._M_monthname + 24)
00235             return __format;
00236           __t->tm_mon = __STATIC_CAST(int, __pr - __table._M_monthname - 12);
00237           break;
00238         }
00239 
00240         case 'd': {
00241           bool __pr = __get_decimal_integer(__first, __last, __t->tm_mday, __STATIC_CAST(_Ch*, 0));
00242           if (!__pr || __t->tm_mday < 1 || __t->tm_mday > 31) {
00243             __err |= ios_base::failbit;
00244             return __format;
00245           }
00246           break;
00247         }
00248 
00249         case 'H': case 'I': {
00250           bool __pr = __get_decimal_integer(__first, __last, __t->tm_hour, __STATIC_CAST(_Ch*, 0));
00251           if (!__pr)
00252             return __format;
00253           break;
00254         }
00255 
00256         case 'j': {
00257           bool __pr = __get_decimal_integer(__first, __last, __t->tm_yday, __STATIC_CAST(_Ch*, 0));
00258           if (!__pr)
00259             return __format;
00260           break;
00261         }
00262 
00263         case 'm': {
00264           bool __pr = __get_decimal_integer(__first, __last, __t->tm_mon, __STATIC_CAST(_Ch*, 0));
00265           --__t->tm_mon;
00266           if (!__pr || __t->tm_mon < 0 || __t->tm_mon > 11) {
00267             __err |= ios_base::failbit;
00268             return __format;
00269           }
00270           break;
00271         }
00272 
00273         case 'M': {
00274           bool __pr = __get_decimal_integer(__first, __last, __t->tm_min, __STATIC_CAST(_Ch*, 0));
00275           if (!__pr)
00276             return __format;
00277           break;
00278         }
00279 
00280         case 'p': {
00281           const string* __pr = __match(__first, __last,
00282                                        __table._M_am_pm + 0, __table._M_am_pm + 2, __ct);
00283           if (__pr == __table._M_am_pm + 2)
00284             return __format;
00285           // 12:00 PM <=> 12:00, 12:00 AM <=> 00:00
00286           if (__pr == __table._M_am_pm + 1 && __t->tm_hour != 12 )
00287             __t->tm_hour += 12;
00288           if (__pr == __table._M_am_pm && __t->tm_hour == 12 )
00289             __t->tm_hour = 0;
00290           break;
00291         }
00292 
00293         case 'S': {
00294           bool __pr = __get_decimal_integer(__first, __last, __t->tm_sec, __STATIC_CAST(_Ch*, 0));
00295           if (!__pr)
00296             return __format;
00297           break;
00298         }
00299 
00300         case 'y': {
00301           bool __pr = __get_decimal_integer(__first, __last, __t->tm_year, __STATIC_CAST(_Ch*, 0));
00302           if (!__pr)
00303             return __format;
00304           break;
00305         }
00306 
00307         case 'Y': {
00308           bool __pr = __get_decimal_integer(__first, __last, __t->tm_year, __STATIC_CAST(_Ch*, 0));
00309           __t->tm_year -= 1900;
00310           if (!__pr)
00311             return __format;
00312           break;
00313         }
00314 
00315         default:
00316           break;
00317       }
00318     }
00319     else {
00320       if (*__first++ != __ct.widen(*__format)) break;
00321     }
00322 
00323     ++__format;
00324   }
00325 
00326   return __format;
00327 }
00328 
00329 template <class _InIt, class _CharT>
00330 bool _STLP_CALL
00331 __get_short_or_long_dayname(_InIt& __first, _InIt& __last, const ctype<_CharT>& __ct,
00332                             const _Time_Info& __table, tm* __t) {
00333   const string* __pr =
00334     __match(__first, __last, __table._M_dayname + 0, __table._M_dayname + 14, __ct);
00335   __t->tm_wday = __STATIC_CAST(int, (__pr - __table._M_dayname) % 7);
00336   return __pr != __table._M_dayname + 14;
00337 }
00338 
00339 template <class _InIt, class _CharT>
00340 bool _STLP_CALL
00341 __get_short_or_long_monthname(_InIt& __first, _InIt& __last, const ctype<_CharT>& __ct,
00342                               const _Time_Info& __table, tm* __t) {
00343   const string* __pr =
00344     __match(__first, __last, __table._M_monthname + 0, __table._M_monthname + 24, __ct);
00345   __t->tm_mon = __STATIC_CAST(int, (__pr - __table._M_monthname) % 12);
00346   return __pr != __table._M_monthname + 24;
00347 }
00348 
00349 #if !defined (_STLP_NO_WCHAR_T)
00350 template <class _OuIt>
00351 _OuIt _STLP_CALL
00352 __put_time(char * __first, char * __last, _OuIt __out_ite,
00353            const ios_base& __s, wchar_t) {
00354     const ctype<wchar_t>& __ct = *__STATIC_CAST(const ctype<wchar_t>*, __s._M_ctype_facet());
00355     wchar_t __wbuf[64];
00356     __ct.widen(__first, __last, __wbuf);
00357     ptrdiff_t __len = __last - __first;
00358     wchar_t * __eend = __wbuf + __len;
00359     return copy((wchar_t*)__wbuf, __eend, __out_ite);
00360 }
00361 #endif
00362 
00363 _STLP_MOVE_TO_STD_NAMESPACE
00364 
00365 template <class _Ch, class _InIt>
00366 _InIt
00367 time_get<_Ch, _InIt>::do_get_date(_InIt __s, _InIt  __end,
00368                                   ios_base& __str, ios_base::iostate&  __err,
00369                                   tm* __t) const {
00370   typedef string::const_iterator string_iterator;
00371 
00372   string_iterator __format = _M_timeinfo._M_date_format.begin();
00373   string_iterator __format_end = _M_timeinfo._M_date_format.end();
00374 
00375   string_iterator __result
00376     = _STLP_PRIV __get_formatted_time(__s, __end, __format, __format_end,
00377                                       __STATIC_CAST(_Ch*, 0), _M_timeinfo,
00378                                       __str, __err, __t);
00379   if (__result == __format_end)
00380     __err = ios_base::goodbit;
00381   else {
00382     __err = ios_base::failbit;
00383     if (__s == __end)
00384       __err |= ios_base::eofbit;
00385   }
00386   return __s;
00387 }
00388 
00389 template <class _Ch, class _InIt>
00390 _InIt
00391 time_get<_Ch, _InIt>::do_get_time(_InIt __s, _InIt  __end,
00392                                   ios_base& __str, ios_base::iostate&  __err,
00393                                   tm* __t) const {
00394   typedef string::const_iterator string_iterator;
00395   string_iterator __format = _M_timeinfo._M_time_format.begin();
00396   string_iterator __format_end = _M_timeinfo._M_time_format.end();
00397 
00398   string_iterator __result
00399     = _STLP_PRIV __get_formatted_time(__s, __end, __format, __format_end,
00400                                       __STATIC_CAST(_Ch*, 0), _M_timeinfo,
00401                                       __str, __err, __t);
00402   __err = __result == __format_end ? ios_base::goodbit
00403                                    : ios_base::failbit;
00404   if (__s == __end)
00405     __err |= ios_base::eofbit;
00406   return __s;
00407 }
00408 
00409 template <class _Ch, class _InIt>
00410 _InIt
00411 time_get<_Ch, _InIt>::do_get_year(_InIt __s, _InIt  __end,
00412                                   ios_base&, ios_base::iostate&  __err,
00413                                   tm* __t) const {
00414   if (__s == __end) {
00415     __err = ios_base::failbit | ios_base::eofbit;
00416     return __s;
00417   }
00418 
00419   bool __pr =  _STLP_PRIV __get_decimal_integer(__s, __end, __t->tm_year, __STATIC_CAST(_Ch*, 0));
00420   __t->tm_year -= 1900;
00421   __err = __pr ? ios_base::goodbit : ios_base::failbit;
00422   if (__s == __end)
00423     __err |= ios_base::eofbit;
00424 
00425   return __s;
00426 }
00427 
00428 template <class _Ch, class _InIt>
00429 _InIt
00430 time_get<_Ch, _InIt>::do_get_weekday(_InIt __s, _InIt  __end,
00431                                      ios_base &__str, ios_base::iostate &__err,
00432                                      tm *__t) const {
00433   const ctype<_Ch>& __ct = *__STATIC_CAST(const ctype<_Ch>*, __str._M_ctype_facet());
00434   bool __result =
00435     _STLP_PRIV __get_short_or_long_dayname(__s, __end, __ct, _M_timeinfo, __t);
00436   if (__result)
00437     __err = ios_base::goodbit;
00438   else {
00439     __err = ios_base::failbit;
00440     if (__s == __end)
00441       __err |= ios_base::eofbit;
00442   }
00443   return __s;
00444 }
00445 
00446 template <class _Ch, class _InIt>
00447 _InIt
00448 time_get<_Ch, _InIt>::do_get_monthname(_InIt __s, _InIt  __end,
00449                                        ios_base &__str, ios_base::iostate &__err,
00450                                        tm *__t) const {
00451   const ctype<_Ch>& __ct = *__STATIC_CAST(const ctype<_Ch>*, __str._M_ctype_facet());
00452   bool __result =
00453     _STLP_PRIV __get_short_or_long_monthname(__s, __end, __ct, _M_timeinfo, __t);
00454   if (__result)
00455     __err = ios_base::goodbit;
00456   else {
00457     __err = ios_base::failbit;
00458     if (__s == __end)
00459       __err |= ios_base::eofbit;
00460   }
00461   return __s;
00462 }
00463 
00464 template<class _Ch, class _OutputIter>
00465 _OutputIter
00466 time_put<_Ch,_OutputIter>::put(_OutputIter __s, ios_base& __f, _Ch __fill,
00467                                const tm* __tmb, const _Ch* __pat,
00468                                const _Ch* __pat_end) const {
00469   //  locale __loc = __f.getloc();
00470   //  const ctype<_Ch>& _Ct = use_facet<ctype<_Ch> >(__loc);
00471   const ctype<_Ch>& _Ct = *__STATIC_CAST(const ctype<_Ch>*, __f._M_ctype_facet());
00472   while (__pat != __pat_end) {
00473     char __c = _Ct.narrow(*__pat, 0);
00474     if (__c == '%') {
00475       char __mod = 0;
00476       ++__pat;
00477       __c = _Ct.narrow(*__pat++, 0);
00478       if (__c == '#') { // MS extension
00479         __mod = __c;
00480         __c = _Ct.narrow(*__pat++, 0);
00481       }
00482       __s = do_put(__s, __f, __fill, __tmb, __c, __mod);
00483     }
00484     else
00485       *__s++ = *__pat++;
00486   }
00487   return __s;
00488 }
00489 
00490 template<class _Ch, class _OutputIter>
00491 _OutputIter
00492 time_put<_Ch,_OutputIter>::do_put(_OutputIter __s, ios_base& __f, _Ch /* __fill */,
00493                                   const tm* __tmb, char __format,
00494                                   char __modifier ) const {
00495   char __buf[64];
00496   char * __iend = _STLP_PRIV __write_formatted_time(_STLP_ARRAY_AND_SIZE(__buf),
00497                                                     __format, __modifier, _M_timeinfo, __tmb);
00498   //  locale __loc = __f.getloc();
00499   return _STLP_PRIV __put_time(__buf, __iend, __s, __f, _Ch());
00500 }
00501 
00502 _STLP_END_NAMESPACE
00503 
00504 #endif /* _STLP_TIME_FACETS_C */
00505 
00506 // Local Variables:
00507 // mode:C++
00508 // End:



Generated on Mon Mar 10 15:32:41 2008 by  doxygen 1.5.1