home *** CD-ROM | disk | FTP | other *** search
- #ifndef __TIME_CC
- #define __TIME_CC
- #pragma option push -b -a8 -pc -Vx- -Ve- -w-inl -w-aus -w-sig
- /***************************************************************************
- *
- * time.cc - Definitions for the Standard Library time facets
- *
- *
- ***************************************************************************
- *
- * Copyright (c) 1994-1999 Rogue Wave Software, Inc. All Rights Reserved.
- *
- * This computer software is owned by Rogue Wave Software, Inc. and is
- * protected by U.S. copyright laws and other laws and by international
- * treaties. This computer software is furnished by Rogue Wave Software,
- * Inc. pursuant to a written license agreement and may be used, copied,
- * transmitted, and stored only in accordance with the terms of such
- * license and with the inclusion of the above copyright notice. This
- * computer software or any other copies thereof may not be provided or
- * otherwise made available to any other person.
- *
- * U.S. Government Restricted Rights. This computer software is provided
- * with Restricted Rights. Use, duplication, or disclosure by the
- * Government is subject to restrictions as set forth in subparagraph (c)
- * (1) (ii) of The Rights in Technical Data and Computer Software clause
- * at DFARS 252.227-7013 or subparagraphs (c) (1) and (2) of the
- * Commercial Computer Software รป Restricted Rights at 48 CFR 52.227-19,
- * as applicable. Manufacturer is Rogue Wave Software, Inc., 5500
- * Flatiron Parkway, Boulder, Colorado 80301 USA.
- *
- **************************************************************************/
-
- #include <time.h>
-
- #ifndef _RWSTD_NO_NAMESPACE
- namespace __rwstd {
- #endif
-
- // --------------------------------------
- // Template time_reader member templates.
- // --------------------------------------
-
- template <class charT,class InputIterator>
- time_reader<charT,InputIterator>::time_reader
- (InputIterator& in,InputIterator& end,_RW_STD::ios_base& io,
- const __RWSTD::timepunct<charT>& tpunct)
- : digit_reader<charT,InputIterator>(in,end,io), __timp(tpunct)
- {
- // Don't recognize signs on any numeric input.
- this->is_signed=false;
- }
-
- template <class charT,class InputIterator>
- bool time_reader<charT,InputIterator>::
- get_time_pattern (const string_type &patt,tm *time)
- {
- enum {
- edit_year = 0x01,
- edit_month = 0x02,
- edit_century = 0x04,
- edit_hour = 0x08
- };
-
- int post_edits=0;
- const charT *p=patt.c_str(),*patt_end=p+patt.length();
- for ( ; p<patt_end; p++) {
- switch (this->ctyp.narrow(*p,' ')) {
- case '%':
- {
- int *iresult;
- int ampm_dummy; // scratch space for ampm value
- const keyword_map<charT> *keywords=NULL;
-
- switch (this->ctyp.narrow(*++p,' ')) {
- case 'a':
- case 'A':
- // Day of week (abbreviated or not).
- keywords=&get_day_map(__timp);
- iresult=&time->tm_wday;
- break;
- case 'b':
- case 'B':
- // Month name (abbreviated or not).
- keywords=&get_month_map(__timp);
- iresult=&time->tm_mon;
- break;
- case 'm':
- // Numeric month, comes in 1 higher than the number we want.
- post_edits|=edit_month;
- iresult=&time->tm_mon;
- break;
- case 'c':
- // Full date, time and year in default format.
- return get_time_pattern(get_patt_string(__timp,2),time);
- case 'd':
- // Day of month.
- iresult=&time->tm_mday;
- break;
- case 'I': // 12-hour clock
- case 'H': // 24-hour clock
- // Hours (12/24 distinction is made in the 'p' section)
- iresult=&time->tm_hour;
- break;
- case 'p':
- // am/pm indicator
- keywords=&get_ampm_map(__timp);
- // Assumes charT[0] are equal means entire string will be
- if (*(this->in) == get_ampm_string(__timp,true)[0])
- post_edits|=edit_hour;
- iresult=&m_dummy;
- break;
- case 'M':
- // Minutes.
- iresult=&time->tm_min;
- break;
- case 'S':
- // Seconds.
- iresult=&time->tm_sec;
- break;
- case 'Y':
- // Year with Century.
- post_edits|=edit_year;
- iresult=&time->tm_year;
- break;
- case 'y':
- // 2-digit Year without Century.
- post_edits|=(edit_year|edit_century);
- iresult=&time->tm_year;
- break;
- default:
- // All other format characters are not supported on input.
- return false;
- }
-
- if (keywords) {
- if ((*iresult=get_keyword(*keywords))<0)
- return false;
- } else
- *iresult=to_ulong(this->get_int_digits());
- }
- break;
-
- default:
- if (!this->at_end() && *this->in==*p)
- this->in++;
- else
- return false;
- }
-
- if (this->error)
- return false;
- }
-
- if (post_edits&edit_year)
- if (post_edits&edit_century && time->tm_year<100)
- ; // 2-digit year is already relative to 1900
- else
- time->tm_year-=1900;
-
- if (post_edits&edit_month)
- time->tm_mon--;
-
- if (post_edits&edit_hour)
- if (time->tm_hour < 12)
- time->tm_hour+=12;
-
- return true;
- }
- #ifndef _RWSTD_NO_NAMESPACE
- } namespace std {
- #endif
- // -----------------------------------------------------
- // Facet time_get<charT,InputIterator> member templates.
- // -----------------------------------------------------
-
- template <class charT, class InputIterator>
- locale::id time_get<charT,InputIterator>::id;
-
- template <class charT, class InputIterator>
- time_get<charT,InputIterator>::~time_get() { }
-
- template <class charT, class InputIterator>
- time_base::dateorder time_get<charT,InputIterator>::do_date_order () const
- {
- // We would prefer to return a value that matches the date format defined
- // in the timepunct facet in the caller's locale, but we can't get there
- // from here ...
-
- #ifndef _RWSTD_NO_NAMESPACE
- const _TYPENAME __RWSTD::timepunct<charT>::string_type& s =
- __RWSTD::keyword_cracker<charT>::get_patt_string(*__timp,0);
- #else
- const _TYPENAME timepunct<charT>::string_type& s =
- keyword_cracker<charT>::get_patt_string(*__timp,0);
- #endif
-
- bool haveYear = false;
-
- for (size_t i = 0; i < s.length(); i++) {
- if (s[i] == charT('y') || s[i] == charT('Y')) haveYear = true;
- if (s[i] == charT('d') || s[i] == charT('a') || s[i] == charT('A'))
- if (haveYear) return ydm;
- else return dmy;
- if (s[i] == charT('m') || s[i] == charT('b') || s[i] == charT('B'))
- if (haveYear) return ymd;
- else return mdy;
- }
-
- return no_order;
- }
-
- template <class charT, class InputIterator>
- _TYPENAME time_get<charT,InputIterator>::iter_type
- time_get<charT,InputIterator>::do_get_time (InputIterator in,
- InputIterator end, ios_base& io, ios_base::iostate& err, tm* time) const
- {
- __RWSTD::time_reader<charT,InputIterator> reader(in,end,io,*__timp);
- err=ios_base::goodbit;
-
- // Parse according to pattern 1 (strftime '%X' -- default time pattern)
- if (!reader.get_time_pattern(reader.get_patt_string(reader.__timp,1),time))
- err=ios_base::failbit;
-
- if (reader.reached_end)
- err|=ios_base::eofbit;
-
- return in;
- }
-
- template <class charT, class InputIterator >
- _TYPENAME time_get<charT,InputIterator>::iter_type
- time_get<charT,InputIterator>::do_get_date (InputIterator in,
- InputIterator end, ios_base& io, ios_base::iostate& err, tm* time) const
- {
- __RWSTD::time_reader<charT,InputIterator> reader(in,end,io,*__timp);
- err=ios_base::goodbit;
-
- // Parse according to pattern 0 (strftime '%x' -- default date pattern)
- if (!reader.get_time_pattern(reader.get_patt_string(reader.__timp,0),time))
- err=ios_base::failbit;
-
- if (reader.reached_end)
- err|=ios_base::eofbit;
-
- return in;
- }
-
- template <class charT, class InputIterator >
- _TYPENAME time_get<charT,InputIterator>::iter_type
- time_get<charT,InputIterator>::do_get_weekday (InputIterator in,
- InputIterator end, ios_base& io, ios_base::iostate& err, tm* time) const
- {
- __RWSTD::time_reader<charT,InputIterator> reader(in,end,io,*__timp);
- int wd=reader.get_keyword(reader.get_day_map(reader.__timp));
- err=ios_base::goodbit;
-
- if (wd<0)
- err=ios_base::failbit;
- else
- time->tm_wday=wd;
-
- if (reader.reached_end)
- err|=ios_base::eofbit;
-
- return in;
- }
-
- template <class charT, class InputIterator >
- _TYPENAME time_get<charT,InputIterator>::iter_type
- time_get<charT,InputIterator>::do_get_monthname (InputIterator in,
- InputIterator end, ios_base& io, ios_base::iostate& err, tm* time) const
- {
- __RWSTD::time_reader<charT,InputIterator> reader(in,end,io,*__timp);
- int mo=reader.get_keyword(reader.get_month_map(reader.__timp));
- err=ios_base::goodbit;
-
- if (mo<0)
- err=ios_base::failbit;
- else
- time->tm_mon=mo;
-
- if (reader.reached_end)
- err|=ios_base::eofbit;
-
- return in;
- }
-
- template <class charT, class InputIterator >
- _TYPENAME time_get<charT,InputIterator>::iter_type
- time_get<charT,InputIterator>::do_get_year (InputIterator in,
- InputIterator end, ios_base& io, ios_base::iostate& err, tm* time) const
- {
- __RWSTD::time_reader<charT,InputIterator> reader(in,end,io,*__timp);
- int yr=reader.to_ulong(reader.get_int_digits());
- err=ios_base::goodbit;
-
- // 2-digit year numbers are accepted, but are not treated specially, and so
- // end up in the 1st century C.E.
- if (reader.error)
- err=ios_base::failbit;
- else
- time->tm_year=yr-1900;
-
- if (reader.reached_end)
- err|=ios_base::eofbit;
-
- return in;
- }
-
- // -----------------------------------------------------
- // Facet time_put<charT,InputIterator> member templates.
- // -----------------------------------------------------
-
- template <class charT, class OutputIterator>
- locale::id time_put<charT,OutputIterator>::id;
-
- template <class charT, class OutputIterator>
- time_put<charT,OutputIterator>::~time_put() { }
-
- template <class charT, class OutputIterator>
- OutputIterator time_put<charT,OutputIterator>::put
- (OutputIterator out, ios_base &io, charT fill, const tm *time,
- const charT* pattern, const charT* patt_end) const
- {
- size_t patt_len=patt_end-pattern;
- char scratch[40];
- char *narrow_patt=(patt_len<=sizeof scratch)? scratch : new char[patt_len];
-
- #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
- use_facet<ctype<charT> >(io.getloc()).narrow(pattern,patt_end,' ',narrow_patt);
- #else
- use_facet(io.getloc(),(ctype<charT>*)0).narrow(pattern,patt_end,' ',narrow_patt);
- #endif
-
- char *np=narrow_patt;
- for (const charT* wp=pattern; wp<patt_end; wp++,np++)
- if (*np!='%')
- *out++=*wp;
- else if (++wp<patt_end)
- switch (*++np) {
-
- case 'O':
- // POSIX-style modifier
- if (++wp<patt_end)
- out=do_put(out,io,fill,time,*++np,'O');
- break;
-
- case '%':
- // Literal percent sign
- *out++=*wp;
- break;
-
- default:
- // Treat everything else as a time format specifier.
- out=do_put(out,io,fill,time,*np,' ');
- }
-
- if (narrow_patt!=scratch)
- delete[] narrow_patt;
-
- return out;
- }
-
- template <class charT, class OutputIterator>
- OutputIterator time_put<charT,OutputIterator>::do_put
- (OutputIterator out, ios_base &io, charT fill, const tm *time,
- char format, char modifier) const
- {
-
- static const char do_as_pattern[]="xXcDrT";
- const char *p=strchr(do_as_pattern,format);
- if (p) {
- // Catch formats implemented as calls to the pattern-based method before
- // going to the expense of constructing a digit_writer.
- unsigned i=p-do_as_pattern;
- #ifndef _RWSTD_NO_NAMESPACE
- const _TYPENAME __RWSTD::timepunct<charT>::string_type& s =
- __RWSTD::keyword_cracker<charT>::get_patt_string(*__timp,i);
- #else
- const _TYPENAME timepunct<charT>::string_type& s =
- keyword_cracker<charT>::get_patt_string(*__timp,i);
- #endif
- return put(out,io,fill,time,s.c_str(),s.c_str()+s.length());
- }
-
- __RWSTD::digit_writer<charT,OutputIterator> writer(out,io);
- writer.width=0;
-
- if (modifier=='O') {
- // Uppercase letter O (not zero) -- requests ordinal string if defined.
- int n,m;
- switch (format) {
- case 'C':
- // Exclusive Rogue Wave extension: Lets you announce,
- // "Welcome to the %OC century!" (See note on unmodified 'C' below.)
- n=(time->tm_year+1999)/100;
- break;
- case 'd':
- case 'e':
- n=time->tm_mday;
- break;
- case 'H':
- n=time->tm_hour+1;
- break;
- case 'I':
- n=time->tm_hour+1;
- if (n>12)
- n-=12;
- break;
- case 'm':
- n=time->tm_mon+1;
- break;
- case 'M':
- n=time->tm_min+1;
- break;
- case 'S':
- n=time->tm_sec+1;
- break;
- case 'u':
- n=time->tm_wday;
- if (n==0) n=7;
- break;
- case 'w':
- n=time->tm_wday;
- break;
- case 'U':
- // Week number of year (assuming weeks start on Sunday).
- // set m to wday of first day of year
- m = (time->tm_wday)-((time->tm_yday)%7);
- // Correct m to account for "days before first Sunday"
- // and "Sunday first day of year" conditions
- if ( m <= 0 )
- m += 7;
- if ( m == 7 )
- // Sunday is first day of year
- n = ((time->tm_yday)/7)+1;
- else
- // if not, shift Sunday to first day of week 1
- n = ((time->tm_yday)+m)/7;
- break;
- case 'W':
- // Week number of year (assuming weeks start on Monday).
- // set m to wday of first day of year
- m = (time->tm_wday)-((time->tm_yday)%7);
- // Correct m to account for "days before first Monday"
- // and "Monday first day of year" conditions
- if ( m <= 0 )
- m += 7;
- if ( m == 1 )
- // Monday is first day of year
- n = ((time->tm_yday)/7)+1;
- else
- // if not, shift Monday to first day of week 1
- n = (((time->tm_yday)+(m-1))/7);
- break;
- case 'y':
- n=((time->tm_year+1900)%100)+1;
- break;
- default:
- n=999; // Cause error output.
- }
-
- writer.put_keyword(writer.get_ord_string(*__timp,n),fill);
-
- } else {
- bool abbrev=false;
- #ifndef _RWSTD_NO_NAMESPACE
- const _TYPENAME __RWSTD::timepunct<charT>::string_type *s=NULL;
- _TYPENAME __RWSTD::timepunct<charT>::string_type tzs;
- #else
- const _TYPENAME timepunct<charT>::string_type *s=NULL;
- _TYPENAME timepunct<charT>::string_type tzs;
- #endif
-
- int n,m;
-
- writer.radix=10;
- writer.separable=false;
-
- switch (format) {
- case 'a':
- abbrev=true;
- case 'A':
- // Week day name or abbreviation.
- s=&writer.get_day_string(*__timp,time->tm_wday,abbrev);
- break;
-
- case 'b':
- case 'h':
- abbrev=true;
- case 'B':
- // Month name or abbreviation.
- s=&writer.get_month_string(*__timp,time->tm_mon,abbrev);
- break;
-
- case 'C':
- // Century. Note that we begin the 20th century in 1901, not 1900.
- // The draft standard does not seem to address this controversy.
- n=(time->tm_year+1999)/100;
- break;
-
- case 'd':
- // Day of month with leading zero.
- writer.iprecision=2;
- case 'e':
- // Day of month with leading blank.
- n=time->tm_mday;
- writer.width=2;
- break;
-
- case 'H':
- // Hour (24-hour clock).
- n=time->tm_hour;
- writer.iprecision=2;
- break;
-
- case 'I':
- // Hour (12-hour clock, caller must append am/pm to resolve ambiguity).
- n=time->tm_hour;
- if (n==0)
- n=12;
- else if (n>12)
- n-=12;
- writer.iprecision=2;
- break;
-
- case 'j':
- // 3-digit day of year.
- n=time->tm_yday+1;
- writer.iprecision=3;
- break;
-
- case 'm':
- // Month number.
- n=time->tm_mon+1;
- writer.iprecision=2;
- break;
-
- case 'M':
- // Minutes.
- n=time->tm_min;
- writer.iprecision=2;
- break;
-
- case 'n':
- // Newline character.
- *out++=writer.ctyp.widen('\n');
- break;
-
- case 'p':
- // ante/post meridian string.
- s=&writer.get_ampm_string(*__timp,time->tm_hour>=12);
- break;
-
- case 'S':
- // Seconds.
- n=time->tm_sec;
- writer.iprecision=2;
- break;
-
- case 't':
- // Tab character.
- *out++=writer.ctyp.widen('\t');
- break;
-
- case 'u':
- // Weekday (1-7, 1==Monday)
- n=time->tm_wday;
- if (n==0)
- n=7;
- break;
-
- case 'U':
- // Week number of year (assuming weeks start on Sunday).
- // set m to wday of first day of year
- m = (time->tm_wday)-((time->tm_yday)%7);
- // Correct m to account for "days before first Sunday"
- // and "Sunday first day of year" conditions
- if ( m <= 0 )
- m += 7;
- if ( m == 7 )
- // Sunday is first day of year
- n = ((time->tm_yday)/7)+1;
- else
- // if not, shift Sunday to first day of week 1
- n = ((time->tm_yday)+m)/7;
- writer.iprecision=2;
- break;
-
- case 'w':
- // Weekday (0-6, 0==Sunday).
- n=time->tm_wday;
- break;
-
- case 'W':
- // Week number of year (assuming weeks start on Monday).
- // set m to wday of first day of year
- m = (time->tm_wday)-((time->tm_yday)%7);
- // Correct m to account for "days before first Monday"
- // and "Monday first day of year" conditions
- if ( m <= 0 )
- m += 7;
- if ( m == 1 )
- // Monday is first day of year
- n = ((time->tm_yday)/7)+1;
- else
- // if not, shift Monday to first day of week 1
- n = (((time->tm_yday)+(m-1))/7);
- writer.iprecision=2;
- break;
-
- case 'y':
- // Year without century.
- n=(time->tm_year+1900)%100;
- writer.iprecision=2;
- break;
-
- case 'Y':
- // Year with century.
- n=time->tm_year+1900;
- break;
-
- case 'Z':
-
- // Time zone name (This is really standard, isn't it?)
- #ifdef _RWSTD_STRUCT_TM_TZ
- tzs = __RWSTD::timepunct<charT>::string_type(
- writer.ctyp.widen(time->tm_zone));
- s = &tzs;
- break;
- #else
- # ifndef _RWSTD_NO_GLOBAL_TZ
- # ifndef _RWSTD_STRICT_ANSI
- # ifdef _RWSTD_NO_LEADING_UNDERSCORE
- tzs = __RWSTD::timepunct<charT>::string_type(
- writer.ctyp.widen(tzname[time->tm_isdst ? 1 : 0]));
- #else
- tzs = __RWSTD::timepunct<charT>::string_type(
- writer.ctyp.widen(_tzname[time->tm_isdst ? 1 : 0]));
- # endif
- # else
- charT* __temp;
- __temp = 0;
- # ifdef _RWSTD_NO_LEADING_UNDERSCORE
- writer.ctyp.widen(tzname[time->tm_isdst ? 1 : 0], tzname[time->tm_isdst ? 1 : 0] + strlen(tzname[time->tm_isdst ? 1 : 0]), __temp);
- # else
- writer.ctyp.widen(_tzname[time->tm_isdst ? 1 : 0], _tzname[time->tm_isdst ? 1 : 0] + strlen(_tzname[time->tm_isdst ? 1 : 0]), __temp);
- # endif
- tzs = __temp;
- # endif
- s = &tzs;
- break;
- # endif // _RWSTD_NO_GLOBAL_TZ
- #endif // _RWSTD_STRUCT_TM_TZ
-
- default:
- // Everything else is an error.
- s=&writer.get_day_string(*__timp,99,false);
- }
-
- if (s)
- writer.put_keyword(*s,fill);
- else {
- writer.digitize((unsigned long) n);
- writer.put_digits(fill);
- }
- }
-
- return out;
- }
- // --------------------------------------------------------------------
- // Time input by-name member templates: time_get<charT,InputIterator>
- // --------------------------------------------------------------------
-
- template <class charT, class InputIterator >
- time_get_byname<charT, InputIterator>::time_get_byname
- (const char* name, size_t refs): time_get<charT,InputIterator>(refs)
- {
- this->__name = name;
- }
-
- template <class charT, class InputIterator>
- time_get_byname<charT, InputIterator>::~time_get_byname()
- { }
-
- // --------------------------------------------------------------------
- // Time output by-name member templates: time_put<charT,InputIterator>
- // --------------------------------------------------------------------
-
- template <class charT, class OutputIterator>
- time_put_byname<charT,OutputIterator>::time_put_byname
- (const char* name, size_t refs): time_put<charT,OutputIterator>(refs)
- {
- this->__name = name;
- }
-
- template <class charT, class OutputIterator>
- time_put_byname<charT,OutputIterator>::~time_put_byname()
- { }
- #ifndef _RWSTD_NO_NAMESPACE
- }
- #endif
-
- #pragma option pop
- #endif /* __TIME_CC */
-