Home | Info | Community | Development | myReactOS | Contact Us
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
1.7.6.1
|