ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

_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 
00038 template <class _CharT, class _InputIterator>
00039 locale::id time_get<_CharT, _InputIterator>::id;
00040 
00041 template <class _CharT, class _OutputIterator>
00042 locale::id time_put<_CharT, _OutputIterator>::id;
00043 
00044 _STLP_MOVE_TO_PRIV_NAMESPACE
00045 
00046 /* Matching input against a list of names
00047 
00048  * Alphabetic input of the names of months and the names
00049  * of weekdays requires matching input against a list of names.
00050  * We use a simple generic algorithm to accomplish this.  This
00051  * algorithm is not very efficient, especially for longer lists
00052  * of names, but it probably does not matter for the initial
00053  * implementation and it may never matter, since we do not expect
00054  * this kind of input to be used very often.  The algorithm
00055  * could be improved fairly simply by creating a new list of
00056  * names still in the running at each iteration.  A more sophisticated
00057  * approach would be to build a tree to do the matching.
00058  *
00059  * We compare each character of the input to the corresponding
00060  * character of each name on the list that has not been eliminated,
00061  * either because every character in the name has already been
00062  * matched, or because some character has not been matched.  We
00063  * continue only as long as there are some names that have not been
00064  * eliminated.
00065 
00066  * We do not really need a random access iterator (a forward iterator
00067  * would do), but the extra generality makes the notation clumsier,
00068  * and we don't really need it.
00069 
00070  * We can recognize a failed match by the fact that the return value
00071  * will be __name_end.
00072  */
00073 
00074 #define _MAXNAMES        24
00075 
00076 template <class _InIt, class _NameIt>
00077 size_t _STLP_CALL
00078 __match(_InIt& __first, _InIt& __last, _NameIt __name, _NameIt __name_end) {
00079   typedef ptrdiff_t difference_type;
00080   difference_type __n = __name_end - __name;
00081   difference_type __i, __start = 0;
00082   size_t __pos = 0;
00083   difference_type __check_count = __n;
00084   bool __do_not_check[_MAXNAMES];
00085   size_t __matching_name_index = __n;
00086 
00087   memset(__do_not_check, 0, sizeof(__do_not_check));
00088 
00089   while (__first != __last) {
00090     difference_type __new_n = __n;
00091     for (__i = __start; __i < __n; ++__i) {
00092       if (!__do_not_check[__i]) {
00093         if (*__first == __name[__i][__pos]) {
00094           if (__pos == (__name[__i].size() - 1)) {
00095             __matching_name_index = __i;
00096             __do_not_check[__i] = true;
00097             if (__i == __start) ++__start;
00098             --__check_count;
00099             if (__check_count == 0) {
00100               ++__first;
00101               return __matching_name_index;
00102             }
00103           }
00104           __new_n = __i + 1;
00105         }
00106         else {
00107           __do_not_check[__i] = true;
00108           if (__i == __start) ++__start;
00109           --__check_count;
00110           if (__check_count == 0)
00111             return __matching_name_index;
00112         }
00113       }
00114       else {
00115         if (__i == __start) ++ __start;
00116       }
00117     }
00118 
00119     __n = __new_n;
00120     ++__first; ++__pos;
00121   }
00122 
00123   return __matching_name_index;
00124 }
00125 
00126 // __get_formatted_time reads input that is assumed to be formatted
00127 // according to the rules for the C strftime function (C standard,
00128 // 7.12.3.5).  This function is used to implement the do_get_time
00129 // and do_get_date virtual functions, which depend on the locale
00130 // specifications for the time and day formats respectively.
00131 // Note the catchall default case, intended mainly for the '%Z'
00132 // format designator, which does not make sense here since the
00133 // representation of timezones is not part of the locale.
00134 //
00135 // The case branches are implemented either by doing a match using
00136 // the appopriate name table or by doing a __get_integer_nogroup.
00137 //
00138 // 'y' format is assumed to mean that the input represents years
00139 // since 1900.  That is, 2002 should be represented as 102.  There
00140 // is no century-guessing.
00141 //
00142 // The match is successful if and only if the second component of the
00143 // return value is format_end.
00144 
00145 // Note that the antepenultimate parameter is being used only to determine
00146 // the correct overloading for the calls to __get_integer_nogroup.
00147 template <class _InIt1, class _Ch, class _TimeInfo>
00148 string::const_iterator _STLP_CALL
00149 __get_formatted_time _STLP_WEAK (_InIt1 __first,  _InIt1 __last,
00150                                  string::const_iterator __format, string::const_iterator __format_end,
00151                                  _Ch*, const _TimeInfo& __table,
00152                                  const ios_base& __s, ios_base::iostate& __err, tm* __t) {
00153   const ctype<_Ch>& __ct = use_facet<ctype<_Ch> >(__s.getloc());
00154   typedef basic_string<_Ch, char_traits<_Ch>, allocator<_Ch> > string_type;
00155   size_t offset;
00156 
00157   while (__first != __last && __format != __format_end) {
00158     offset = 0;
00159     if (*__format == '%') {
00160       ++__format;
00161       char __c = *__format;
00162       if (__c == '#') { //MS extension
00163         ++__format;
00164         __c = *__format;
00165       }
00166 
00167       switch (__c) {
00168         case 'A':
00169           offset = 7;
00170         case 'a': {
00171           size_t __index = __match(__first, __last,
00172                                    __table._M_dayname + offset, __table._M_dayname + offset + 7);
00173           if (__index == 7)
00174             return __format;
00175           __t->tm_wday = __STATIC_CAST(int, __index);
00176           break;
00177         }
00178 
00179         case 'B':
00180           offset = 12;
00181         case 'b': {
00182           size_t __index = __match(__first, __last,
00183                                    __table._M_monthname + offset, __table._M_monthname + offset + 12);
00184           if (__index == 12)
00185             return __format;
00186           __t->tm_mon = __STATIC_CAST(int, __index);
00187           break;
00188         }
00189 
00190         case 'd': {
00191           bool __pr = __get_decimal_integer(__first, __last, __t->tm_mday, __STATIC_CAST(_Ch*, 0));
00192           if (!__pr || __t->tm_mday < 1 || __t->tm_mday > 31) {
00193             __err |= ios_base::failbit;
00194             return __format;
00195           }
00196           break;
00197         }
00198 
00199         case 'H': case 'I': {
00200           bool __pr = __get_decimal_integer(__first, __last, __t->tm_hour, __STATIC_CAST(_Ch*, 0));
00201           if (!__pr)
00202             return __format;
00203           break;
00204         }
00205 
00206         case 'j': {
00207           bool __pr = __get_decimal_integer(__first, __last, __t->tm_yday, __STATIC_CAST(_Ch*, 0));
00208           if (!__pr)
00209             return __format;
00210           break;
00211         }
00212 
00213         case 'm': {
00214           bool __pr = __get_decimal_integer(__first, __last, __t->tm_mon, __STATIC_CAST(_Ch*, 0));
00215           --__t->tm_mon;
00216           if (!__pr || __t->tm_mon < 0 || __t->tm_mon > 11) {
00217             __err |= ios_base::failbit;
00218             return __format;
00219           }
00220           break;
00221         }
00222 
00223         case 'M': {
00224           bool __pr = __get_decimal_integer(__first, __last, __t->tm_min, __STATIC_CAST(_Ch*, 0));
00225           if (!__pr)
00226             return __format;
00227           break;
00228         }
00229 
00230         case 'p': {
00231           size_t __index = __match(__first, __last,
00232                                    __table._M_am_pm + 0, __table._M_am_pm + 2);
00233           if (__index == 2)
00234             return __format;
00235           // 12:00 PM <=> 12:00, 12:00 AM <=> 00:00
00236           if (__index == 1 && __t->tm_hour != 12 )
00237             __t->tm_hour += 12;
00238           if (__index == 0 && __t->tm_hour == 12 )
00239             __t->tm_hour = 0;
00240           break;
00241         }
00242 
00243         case 'S': {
00244           bool __pr = __get_decimal_integer(__first, __last, __t->tm_sec, __STATIC_CAST(_Ch*, 0));
00245           if (!__pr)
00246             return __format;
00247           break;
00248         }
00249 
00250         case 'y': {
00251           bool __pr = __get_decimal_integer(__first, __last, __t->tm_year, __STATIC_CAST(_Ch*, 0));
00252           if (!__pr)
00253             return __format;
00254           break;
00255         }
00256 
00257         case 'Y': {
00258           bool __pr = __get_decimal_integer(__first, __last, __t->tm_year, __STATIC_CAST(_Ch*, 0));
00259           __t->tm_year -= 1900;
00260           if (!__pr)
00261             return __format;
00262           break;
00263         }
00264 
00265         default:
00266           break;
00267       }
00268     }
00269     else {
00270       if (*__first++ != __ct.widen(*__format)) break;
00271     }
00272 
00273     ++__format;
00274   }
00275 
00276   return __format;
00277 }
00278 
00279 template <class _InIt, class _TimeInfo>
00280 bool _STLP_CALL
00281 __get_short_or_long_dayname(_InIt& __first, _InIt& __last, const _TimeInfo& __table, tm* __t) {
00282   size_t __index = __match(__first, __last, __table._M_dayname + 0, __table._M_dayname + 14);
00283   if (__index != 14) {
00284     __t->tm_wday = __STATIC_CAST(int, __index % 7);
00285     return true;
00286   }
00287   return false;
00288 }
00289 
00290 template <class _InIt, class _TimeInfo>
00291 bool _STLP_CALL
00292 __get_short_or_long_monthname(_InIt& __first, _InIt& __last, const _TimeInfo& __table, tm* __t) {
00293   size_t __index = __match(__first, __last, __table._M_monthname + 0, __table._M_monthname + 24);
00294   if (__index != 24) {
00295     __t->tm_mon = __STATIC_CAST(int, __index % 12);
00296     return true;
00297   }
00298   return false;
00299 }
00300 
00301 _STLP_MOVE_TO_STD_NAMESPACE
00302 
00303 template <class _Ch, class _InIt>
00304 _InIt
00305 time_get<_Ch, _InIt>::do_get_date(_InIt __s, _InIt  __end,
00306                                   ios_base& __str, ios_base::iostate&  __err,
00307                                   tm* __t) const {
00308   typedef string::const_iterator string_iterator;
00309 
00310   string_iterator __format = this->_M_timeinfo._M_date_format.begin();
00311   string_iterator __format_end = this->_M_timeinfo._M_date_format.end();
00312 
00313   string_iterator __result
00314     = _STLP_PRIV __get_formatted_time(__s, __end, __format, __format_end,
00315                                       __STATIC_CAST(_Ch*, 0), this->_M_timeinfo,
00316                                       __str, __err, __t);
00317   if (__result == __format_end)
00318     __err = ios_base::goodbit;
00319   else {
00320     __err = ios_base::failbit;
00321     if (__s == __end)
00322       __err |= ios_base::eofbit;
00323   }
00324   return __s;
00325 }
00326 
00327 template <class _Ch, class _InIt>
00328 _InIt
00329 time_get<_Ch, _InIt>::do_get_time(_InIt __s, _InIt  __end,
00330                                   ios_base& __str, ios_base::iostate&  __err,
00331                                   tm* __t) const {
00332   typedef string::const_iterator string_iterator;
00333   string_iterator __format = this->_M_timeinfo._M_time_format.begin();
00334   string_iterator __format_end = this->_M_timeinfo._M_time_format.end();
00335 
00336   string_iterator __result
00337     = _STLP_PRIV __get_formatted_time(__s, __end, __format, __format_end,
00338                                       __STATIC_CAST(_Ch*, 0), this->_M_timeinfo,
00339                                       __str, __err, __t);
00340   __err = __result == __format_end ? ios_base::goodbit
00341                                    : ios_base::failbit;
00342   if (__s == __end)
00343     __err |= ios_base::eofbit;
00344   return __s;
00345 }
00346 
00347 template <class _Ch, class _InIt>
00348 _InIt
00349 time_get<_Ch, _InIt>::do_get_year(_InIt __s, _InIt  __end,
00350                                   ios_base&, ios_base::iostate&  __err,
00351                                   tm* __t) const {
00352   if (__s == __end) {
00353     __err = ios_base::failbit | ios_base::eofbit;
00354     return __s;
00355   }
00356 
00357   bool __pr =  _STLP_PRIV __get_decimal_integer(__s, __end, __t->tm_year, __STATIC_CAST(_Ch*, 0));
00358   __t->tm_year -= 1900;
00359   __err = __pr ? ios_base::goodbit : ios_base::failbit;
00360   if (__s == __end)
00361     __err |= ios_base::eofbit;
00362 
00363   return __s;
00364 }
00365 
00366 template <class _Ch, class _InIt>
00367 _InIt
00368 time_get<_Ch, _InIt>::do_get_weekday(_InIt __s, _InIt  __end,
00369                                      ios_base &__str, ios_base::iostate &__err,
00370                                      tm *__t) const {
00371   bool __result =
00372     _STLP_PRIV __get_short_or_long_dayname(__s, __end, this->_M_timeinfo, __t);
00373   if (__result)
00374     __err = ios_base::goodbit;
00375   else {
00376     __err = ios_base::failbit;
00377     if (__s == __end)
00378       __err |= ios_base::eofbit;
00379   }
00380   return __s;
00381 }
00382 
00383 template <class _Ch, class _InIt>
00384 _InIt
00385 time_get<_Ch, _InIt>::do_get_monthname(_InIt __s, _InIt  __end,
00386                                        ios_base &__str, ios_base::iostate &__err,
00387                                        tm *__t) const {
00388   bool __result =
00389     _STLP_PRIV __get_short_or_long_monthname(__s, __end, this->_M_timeinfo, __t);
00390   if (__result)
00391     __err = ios_base::goodbit;
00392   else {
00393     __err = ios_base::failbit;
00394     if (__s == __end)
00395       __err |= ios_base::eofbit;
00396   }
00397   return __s;
00398 }
00399 
00400 template<class _Ch, class _OutputIter>
00401 _OutputIter
00402 time_put<_Ch,_OutputIter>::put(_OutputIter __s, ios_base& __f, _Ch __fill,
00403                                const tm* __tmb, const _Ch* __pat,
00404                                const _Ch* __pat_end) const {
00405   const ctype<_Ch>& _Ct = use_facet<ctype<_Ch> >(__f.getloc());
00406   while (__pat != __pat_end) {
00407     char __c = _Ct.narrow(*__pat, 0);
00408     if (__c == '%') {
00409       char __mod = 0;
00410       ++__pat;
00411       __c = _Ct.narrow(*__pat++, 0);
00412       if (__c == '#') { // MS extension
00413         __mod = __c;
00414         __c = _Ct.narrow(*__pat++, 0);
00415       }
00416       __s = do_put(__s, __f, __fill, __tmb, __c, __mod);
00417     }
00418     else
00419       *__s++ = *__pat++;
00420   }
00421   return __s;
00422 }
00423 
00424 template<class _Ch, class _OutputIter>
00425 _OutputIter
00426 time_put<_Ch,_OutputIter>::do_put(_OutputIter __s, ios_base& __f, _Ch /* __fill */,
00427                                   const tm* __tmb, char __format,
00428                                   char __modifier ) const {
00429   const ctype<_Ch>& __ct = use_facet<ctype<_Ch> >(__f.getloc());
00430   _STLP_BASIC_IOSTRING(_Ch) __buf;
00431   _STLP_PRIV __write_formatted_time(__buf, __ct, __format, __modifier, this->_M_timeinfo, __tmb);
00432   return copy(__buf.begin(), __buf.end(), __s);
00433 }
00434 
00435 _STLP_END_NAMESPACE
00436 
00437 #endif /* _STLP_TIME_FACETS_C */
00438 
00439 // Local Variables:
00440 // mode:C++
00441 // End:

Generated on Sun May 27 2012 04:29:39 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.