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