00001 
00002 
00003 #include "ace/OS_NS_time.h"
00004 
00005 ACE_RCSID(ace, OS_NS_time, "$Id: OS_NS_time.cpp 79134 2007-07-31 18:23:50Z johnnyw $")
00006 
00007 #if !defined (ACE_HAS_INLINED_OSCALLS)
00008 # include "ace/OS_NS_time.inl"
00009 #endif 
00010 
00011 #if defined (ACE_LACKS_STRPTIME)
00012 # include "ace/os_include/os_ctype.h"
00013 #endif 
00014 
00015 #include "ace/OS_NS_Thread.h"
00016 #include "ace/Object_Manager_Base.h"
00017 
00018 #if defined (ACE_HAS_WINCE)
00019 #  include "ace/OS_NS_stdio.h"     
00020 
00021 namespace
00022 {
00023   ACE_TCHAR const * const ACE_OS_day_of_week_name[] =
00024     {
00025       ACE_TEXT ("Sun"),
00026       ACE_TEXT ("Mon"),
00027       ACE_TEXT ("Tue"),
00028       ACE_TEXT ("Wed"),
00029       ACE_TEXT ("Thu"),
00030       ACE_TEXT ("Fri"),
00031       ACE_TEXT ("Sat")
00032     };
00033 
00034   ACE_TCHAR const * const ACE_OS_month_name[] =
00035     {
00036       ACE_TEXT ("Jan"),
00037       ACE_TEXT ("Feb"),
00038       ACE_TEXT ("Mar"),
00039       ACE_TEXT ("Apr"),
00040       ACE_TEXT ("May"),
00041       ACE_TEXT ("Jun"),
00042       ACE_TEXT ("Jul"),
00043       ACE_TEXT ("Aug"),
00044       ACE_TEXT ("Sep"),
00045       ACE_TEXT ("Oct"),
00046       ACE_TEXT ("Nov"),
00047       ACE_TEXT ("Dec")
00048     };
00049 
00050   static ACE_TCHAR const ACE_OS_CTIME_R_FMTSTR[] = ACE_TEXT ("%3s %3s %02d %02d:%02d:%02d %04d\n");
00051 } 
00052 #endif 
00053 
00054 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00055 
00056 # if defined (ACE_HAS_WINCE)
00057 ACE_TCHAR *
00058 ACE_OS::ctime_r (const time_t *clock, ACE_TCHAR *buf, int buflen)
00059 {
00060   
00061   if (buflen < 26)              
00062     {
00063       errno = ERANGE;
00064       return 0;
00065     }
00066   
00067   
00068   
00069   ULARGE_INTEGER _100ns;
00070   _100ns.QuadPart = (DWORDLONG) *clock * 10000 * 1000
00071                      + ACE_Time_Value::FILETIME_to_timval_skew;
00072   FILETIME file_time;
00073   file_time.dwLowDateTime = _100ns.LowPart;
00074   file_time.dwHighDateTime = _100ns.HighPart;
00075 
00076   FILETIME localtime;
00077   SYSTEMTIME systime;
00078   FileTimeToLocalFileTime (&file_time, &localtime);
00079   FileTimeToSystemTime (&localtime, &systime);
00080   ACE_OS::sprintf (buf, ACE_OS_CTIME_R_FMTSTR,
00081                    ACE_OS_day_of_week_name[systime.wDayOfWeek],
00082                    ACE_OS_month_name[systime.wMonth - 1],
00083                    systime.wDay,
00084                    systime.wHour,
00085                    systime.wMinute,
00086                    systime.wSecond,
00087                    systime.wYear);
00088   return buf;
00089 }
00090 # endif 
00091 
00092 # if defined (ACE_LACKS_DIFFTIME)
00093 double
00094 ACE_OS::difftime (time_t t1, time_t t0)
00095 {
00096   
00097   struct tm tms[2], *ptms[2], temp;
00098   double seconds;
00099   int swap = 0;
00100 
00101   
00102   ptms[1] = ::gmtime_r (&t1, &tms[1]);
00103   if (ptms[1] == 0) return 0.0;
00104 
00105   ptms[0] = ::gmtime_r (&t0, &tms[0]);
00106   if (ptms[0] == 0) return 0.0;
00107 
00108     
00109   if (tms[1].tm_year < tms[0].tm_year)
00110     swap = 1;
00111   else if (tms[1].tm_year == tms[0].tm_year)
00112     {
00113       if (tms[1].tm_yday < tms[0].tm_yday)
00114         swap = 1;
00115       else if (tms[1].tm_yday == tms[0].tm_yday)
00116         {
00117           if (tms[1].tm_hour < tms[0].tm_hour)
00118             swap = 1;
00119           else if (tms[1].tm_hour == tms[0].tm_hour)
00120             {
00121               if (tms[1].tm_min < tms[0].tm_min)
00122                 swap = 1;
00123               else if (tms[1].tm_min == tms[0].tm_min)
00124                 {
00125                   if (tms[1].tm_sec < tms[0].tm_sec)
00126                     swap = 1;
00127                 }
00128             }
00129         }
00130     }
00131 
00132   if (swap)
00133     temp = tms[0], tms[0] = tms[1], tms[1] = temp;
00134 
00135   seconds = 0.0;
00136   if (tms[1].tm_year > tms[0].tm_year)
00137     {
00138       
00139       seconds = 60 - tms[0].tm_sec;
00140       tms[0].tm_sec = 0;
00141       tms[0].tm_min += 1;
00142       seconds += 60 * (60 - tms[0].tm_min);
00143       tms[0].tm_min = 0;
00144       tms[0].tm_hour += 1;
00145       seconds += 60*60 * (24 - tms[0].tm_hour);
00146       tms[0].tm_hour = 0;
00147       tms[0].tm_yday += 1;
00148 
00149 #   define ISLEAPYEAR(y) ((y)&3u?0:(y)%25u?1:(y)/25u&12?0:1)
00150 
00151       if (ISLEAPYEAR(tms[0].tm_year))
00152         seconds += 60*60*24 * (366 - tms[0].tm_yday);
00153       else
00154         seconds += 60*60*24 * (365 - tms[0].tm_yday);
00155 
00156       tms[0].tm_yday = 0;
00157       tms[0].tm_year += 1;
00158 
00159       while (tms[1].tm_year > tms[0].tm_year)
00160         {
00161           if (ISLEAPYEAR(tms[0].tm_year))
00162             seconds += 60*60*24 * 366;
00163           else
00164             seconds += 60*60*24 * 365;
00165 
00166           tms[0].tm_year += 1;
00167         }
00168 
00169 #   undef ISLEAPYEAR
00170 
00171     }
00172   else
00173     {
00174       
00175       if (tms[1].tm_sec < tms[0].tm_sec)
00176         {
00177           if (tms[1].tm_min == 0)
00178             {
00179               if (tms[1].tm_hour == 0)
00180                 {
00181                   tms[1].tm_yday -= 1;
00182                   tms[1].tm_hour += 24;
00183                 }
00184               tms[1].tm_hour -= 1;
00185               tms[1].tm_min += 60;
00186             }
00187           tms[1].tm_min -= 1;
00188           tms[1].tm_sec += 60;
00189         }
00190       tms[1].tm_sec -= tms[0].tm_sec;
00191 
00192       if (tms[1].tm_min < tms[0].tm_min)
00193         {
00194           if (tms[1].tm_hour == 0)
00195             {
00196               tms[1].tm_yday -= 1;
00197               tms[1].tm_hour += 24;
00198             }
00199           tms[1].tm_hour -= 1;
00200           tms[1].tm_min += 60;
00201         }
00202       tms[1].tm_min -= tms[0].tm_min;
00203 
00204       if (tms[1].tm_hour < tms[0].tm_hour)
00205         {
00206           tms[1].tm_yday -= 1;
00207           tms[1].tm_hour += 24;
00208         }
00209       tms[1].tm_hour -= tms[0].tm_hour;
00210 
00211       tms[1].tm_yday -= tms[0].tm_yday;
00212     }
00213 
00214   
00215   seconds += tms[1].tm_sec;
00216   seconds += 60 * tms[1].tm_min;
00217   seconds += 60*60 * tms[1].tm_hour;
00218   seconds += 60*60*24 * tms[1].tm_yday;
00219 
00220   return seconds;
00221 }
00222 # endif 
00223 
00224 struct tm *
00225 ACE_OS::localtime_r (const time_t *t, struct tm *res)
00226 {
00227   ACE_OS_TRACE ("ACE_OS::localtime_r");
00228 #if defined (ACE_HAS_REENTRANT_FUNCTIONS)
00229 # if defined (DIGITAL_UNIX)
00230   ACE_OSCALL_RETURN (::_Plocaltime_r (t, res), struct tm *, 0);
00231 # else
00232   ACE_OSCALL_RETURN (::localtime_r (t, res), struct tm *, 0);
00233 # endif 
00234 #elif defined (ACE_HAS_TR24731_2005_CRT)
00235   ACE_SECURECRTCALL (localtime_s (res, t), struct tm *, 0, res);
00236   return res;
00237 #elif !defined (ACE_HAS_WINCE)
00238   ACE_OS_GUARD
00239 
00240   ACE_UNUSED_ARG (res);
00241   struct tm * res_ptr;
00242   ACE_OSCALL (::localtime (t), struct tm *, 0, res_ptr);
00243   if (res_ptr == 0)
00244     return 0;
00245   else
00246     {
00247       *res = *res_ptr;
00248       return res;
00249     }
00250 #elif defined (ACE_HAS_WINCE)
00251   
00252   
00253   
00254 
00255   TIME_ZONE_INFORMATION pTz;
00256 
00257   const unsigned short int __mon_yday[2][13] =
00258   {
00259     
00260     { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
00261     
00262     { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
00263   };
00264 
00265   ULARGE_INTEGER _100ns;
00266   ::GetTimeZoneInformation (&pTz);
00267 
00268   _100ns.QuadPart = (DWORDLONG) *t * 10000 * 1000 + ACE_Time_Value::FILETIME_to_timval_skew;
00269   FILETIME file_time;
00270   file_time.dwLowDateTime = _100ns.LowPart;
00271   file_time.dwHighDateTime = _100ns.HighPart;
00272 
00273   FILETIME localtime;
00274   SYSTEMTIME systime;
00275   FileTimeToLocalFileTime (&file_time, &localtime);
00276   FileTimeToSystemTime (&localtime, &systime);
00277 
00278   res->tm_hour = systime.wHour;
00279 
00280   if(pTz.DaylightBias!=0)
00281     res->tm_isdst = 1;
00282   else
00283     res->tm_isdst = 1;
00284 
00285    int iLeap;
00286    iLeap = (res->tm_year % 4 == 0 && (res->tm_year% 100 != 0 || res->tm_year % 400 == 0));
00287    
00288 
00289    res->tm_mday = systime.wDay;
00290    res->tm_min = systime.wMinute;
00291    res->tm_mon = systime.wMonth - 1;
00292    res->tm_sec = systime.wSecond;
00293    res->tm_wday = systime.wDayOfWeek;
00294    res->tm_yday = __mon_yday[iLeap][systime.wMonth] + systime.wDay;
00295    res->tm_year = systime.wYear;
00296    res->tm_year = res->tm_year - 1900;
00297 
00298    return res;
00299 #else
00300   
00301   
00302   ACE_UNUSED_ARG (t);
00303   ACE_UNUSED_ARG (res);
00304   ACE_NOTSUP_RETURN (0);
00305 #endif 
00306 }
00307 
00308 time_t
00309 ACE_OS::mktime (struct tm *t)
00310 {
00311   ACE_OS_TRACE ("ACE_OS::mktime");
00312 #   if defined (ACE_HAS_WINCE)
00313   SYSTEMTIME t_sys;
00314   FILETIME t_file;
00315   t_sys.wSecond = t->tm_sec;
00316   t_sys.wMinute = t->tm_min;
00317   t_sys.wHour = t->tm_hour;
00318   t_sys.wDay = t->tm_mday;
00319   t_sys.wMonth = t->tm_mon + 1;  
00320   t_sys.wYear = t->tm_year + 1900; 
00321   t_sys.wDayOfWeek = t->tm_wday;  
00322   if (SystemTimeToFileTime (&t_sys, &t_file) == 0)
00323     return -1;
00324   ACE_Time_Value tv (t_file);
00325   return tv.sec ();
00326 #   else
00327 #     if defined (ACE_HAS_THREADS)  &&  !defined (ACE_HAS_MT_SAFE_MKTIME)
00328   ACE_OS_GUARD
00329 #     endif 
00330 
00331   ACE_OSCALL_RETURN (ACE_STD_NAMESPACE::mktime (t), time_t, (time_t) -1);
00332 #   endif 
00333 }
00334 
00335 #if defined (ACE_HAS_POWERPC_TIMER) && defined (ghs)
00336 void
00337 ACE_OS::readPPCTimeBase (u_long &most, u_long &least)
00338 {
00339   ACE_OS_TRACE ("ACE_OS::readPPCTimeBase");
00340 
00341   
00342   
00343   
00344   
00345   asm("aclock:");
00346   asm("mftb  r5,TBU");
00347   asm("mftb  r6,TBL");
00348   asm("mftb  r7,TBU");
00349   asm("cmpw  r5,r7");
00350   asm("bne   aclock");
00351 
00352   asm("stw r5, 0(r3)");
00353   asm("stw r6, 0(r4)");
00354 }
00355 #endif 
00356 
00357 #if defined (ACE_LACKS_STRPTIME) && !defined (ACE_REFUSE_STRPTIME_EMULATION)
00358 char *
00359 ACE_OS::strptime_emulation (const char *buf, const char *format, struct tm *tm)
00360 {
00361   int bi = 0;
00362   int fi = 0;
00363   int percent = 0;
00364 
00365   if (!buf || !format)
00366     return 0;
00367 
00368   while (format[fi] != '\0')
00369     {
00370       if (percent)
00371         {
00372           percent = 0;
00373           switch (format[fi])
00374             {
00375             case '%':                        
00376               if (buf[bi] == '%')
00377                 {
00378                   fi++; bi++;
00379                 }
00380               else
00381                 return const_cast<char*> (buf + bi);
00382               break;
00383 
00384               
00385 
00386 
00387 
00388 
00389 
00390 
00391               
00392 
00393 
00394 
00395 
00396 
00397 
00398 
00399 
00400               
00401 
00402 
00403 
00404 
00405               
00406 
00407 
00408 
00409 
00410 
00411             case 'd':                        
00412               
00413             case 'e':
00414               if (!ACE_OS::strptime_getnum
00415                      (buf + bi, &tm->tm_mday, &bi, &fi, 1, 31))
00416                 return const_cast<char*> (buf + bi);
00417 
00418               break;
00419 
00420             case 'D':                        
00421               if (!ACE_OS::strptime_getnum
00422                      (buf + bi, &tm->tm_mon, &bi, &fi, 1, 12))
00423                 return const_cast<char*> (buf + bi);
00424 
00425               fi--;
00426               tm->tm_mon--;
00427 
00428               if (buf[bi] != '/')
00429                 return const_cast<char*> (buf + bi);
00430 
00431               bi++;
00432 
00433               if (!ACE_OS::strptime_getnum
00434                      (buf + bi, &tm->tm_mday, &bi, &fi, 1, 31))
00435                 return const_cast<char*> (buf + bi);
00436 
00437               fi--;
00438               if (buf[bi] != '/')
00439                 return const_cast<char*> (buf + bi);
00440               bi++;
00441               if (!ACE_OS::strptime_getnum
00442                      (buf + bi, &tm->tm_year, &bi, &fi, 0, 99))
00443                 return const_cast<char*> (buf + bi);
00444               if (tm->tm_year < 69)
00445                 tm->tm_year += 100;
00446               break;
00447 
00448             case 'H':                        
00449               
00450             case 'k':
00451               if (!ACE_OS::strptime_getnum
00452                      (buf + bi, &tm->tm_hour, &bi, &fi, 0, 23))
00453                 return const_cast<char*> (buf + bi);
00454               break;
00455 
00456               
00457 
00458 
00459 
00460 
00461 
00462 
00463             case 'j':                        
00464               if (!ACE_OS::strptime_getnum
00465                      (buf + bi, &tm->tm_yday, &bi, &fi, 1, 366))
00466                 return const_cast<char*> (buf + bi);
00467 
00468               tm->tm_yday--;
00469               break;
00470 
00471             case 'm':                        
00472               if (!ACE_OS::strptime_getnum
00473                      (buf + bi, &tm->tm_mon, &bi, &fi, 1, 12))
00474                 return const_cast<char*> (buf + bi);
00475 
00476               tm->tm_mon--;
00477               break;
00478 
00479             case 'M':                        
00480               if (!ACE_OS::strptime_getnum
00481                      (buf + bi, &tm->tm_min, &bi, &fi, 0, 59))
00482                 return const_cast<char*> (buf + bi);
00483 
00484               break;
00485 
00486               
00487 
00488 
00489 
00490 
00491               
00492 
00493 
00494 
00495 
00496             case 'R':                        
00497               if (!ACE_OS::strptime_getnum
00498                      (buf + bi, &tm->tm_hour, &bi, &fi, 0, 23))
00499                 return const_cast<char*> (buf + bi);
00500 
00501               fi--;
00502               if (buf[bi] != ':')
00503                 return const_cast<char*> (buf + bi);
00504               bi++;
00505               if (!ACE_OS::strptime_getnum
00506                      (buf + bi, &tm->tm_min, &bi, &fi, 0, 59))
00507                 return const_cast<char*> (buf + bi);
00508 
00509               break;
00510 
00511             case 'S':                        
00512               if (!ACE_OS::strptime_getnum
00513                      (buf + bi, &tm->tm_sec, &bi, &fi, 0, 61))
00514                 return const_cast<char*> (buf + bi);
00515               break;
00516 
00517             case 'T':                        
00518               if (!ACE_OS::strptime_getnum
00519                      (buf + bi, &tm->tm_hour, &bi, &fi, 0, 23))
00520                 return const_cast<char*> (buf + bi);
00521 
00522               fi--;
00523               if (buf[bi] != ':')
00524                 return const_cast<char*> (buf + bi);
00525               bi++;
00526               if (!ACE_OS::strptime_getnum
00527                      (buf + bi, &tm->tm_min, &bi, &fi, 0, 59))
00528                 return const_cast<char*> (buf + bi);
00529 
00530               fi--;
00531               if (buf[bi] != ':')
00532                 return const_cast<char*> (buf + bi);
00533               bi++;
00534               if (!ACE_OS::strptime_getnum
00535                      (buf + bi, &tm->tm_sec, &bi, &fi, 0, 61))
00536                 return const_cast<char*> (buf + bi);
00537 
00538               break;
00539 
00540             case 'w':                        
00541               if (!ACE_OS::strptime_getnum
00542                      (buf + bi, &tm->tm_wday, &bi, &fi, 0, 6))
00543                 return const_cast<char*> (buf + bi);
00544 
00545               break;
00546 
00547               
00548 
00549 
00550 
00551 
00552               
00553 
00554 
00555 
00556 
00557             case 'y':                        
00558               if (!ACE_OS::strptime_getnum
00559                      (buf + bi, &tm->tm_year, &bi, &fi, 0, 99))
00560                 return const_cast<char*> (buf + bi);
00561 
00562               if (tm->tm_year < 69)
00563                 tm->tm_year += 100;
00564               break;
00565 
00566             case 'Y':                        
00567               if (!ACE_OS::strptime_getnum
00568                      (buf + bi, &tm->tm_year, &bi, &fi, 0, 0))
00569                 return const_cast<char*> (buf + bi);
00570 
00571               tm->tm_year -= 1900;
00572               break;
00573 
00574             default:                        
00575               return const_cast<char*> (buf + bi);
00576             } 
00577 
00578         }
00579       else
00580         { 
00581           if (format[fi] == '%')
00582             {
00583               percent = 1;
00584               fi++;
00585             }
00586           else
00587             {
00588               if (format[fi] == buf[bi])
00589                 {
00590                   fi++;
00591                   bi++;
00592                 }
00593               else
00594                 return const_cast<char*> (buf + bi);
00595             }
00596         } 
00597     } 
00598 
00599   return const_cast<char*> (buf + bi);
00600 }
00601 
00602 int
00603 ACE_OS::strptime_getnum (const char *buf,
00604                          int *num,
00605                          int *bi,
00606                          int *fi,
00607                          int min,
00608                          int max)
00609 {
00610   int i = 0, tmp = 0;
00611 
00612   while (isdigit (buf[i]))
00613     {
00614       tmp = (tmp * 10) + (buf[i] - '0');
00615       if (max && (tmp > max))
00616         return 0;
00617       i++;
00618     }
00619 
00620   if (tmp < min)
00621     return 0;
00622   else if (i)
00623     {
00624       *num = tmp;
00625       (*fi)++;
00626       *bi += i;
00627       return 1;
00628     }
00629   else
00630     return 0;
00631 }
00632 #endif 
00633 
00634 ACE_END_VERSIONED_NAMESPACE_DECL