You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mt...@apache.org on 2009/08/29 08:56:39 UTC

svn commit: r809086 - in /commons/sandbox/runtime/trunk/src/main/native: include/acr_time.h include/arch/windows/acr_arch.h os/unix/time.c os/win32/time.c

Author: mturk
Date: Sat Aug 29 06:56:39 2009
New Revision: 809086

URL: http://svn.apache.org/viewvc?rev=809086&view=rev
Log:
Implement DOS time conversions. Used for zip time formats

Modified:
    commons/sandbox/runtime/trunk/src/main/native/include/acr_time.h
    commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h
    commons/sandbox/runtime/trunk/src/main/native/os/unix/time.c
    commons/sandbox/runtime/trunk/src/main/native/os/win32/time.c

Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr_time.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr_time.h?rev=809086&r1=809085&r2=809086&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr_time.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr_time.h Sat Aug 29 06:56:39 2009
@@ -31,6 +31,39 @@
  *
  */
 
+/** @see apr_time_exp_t */
+typedef struct acr_tm_t acr_tm_t;
+
+/**
+ * a structure similar to ANSI struct tm with the following differences:
+ *  - tm_usec isn't an ANSI field
+ *  - tm_gmtoff isn't an ANSI field (it's a bsdism)
+ */
+struct acr_tm_t {
+    /** microseconds past tm_sec */
+    acr_int32_t tm_usec;
+    /** (0-61) seconds past tm_min */
+    acr_int32_t tm_sec;
+    /** (0-59) minutes past tm_hour */
+    acr_int32_t tm_min;
+    /** (0-23) hours past midnight */
+    acr_int32_t tm_hour;
+    /** (1-31) day of the month */
+    acr_int32_t tm_mday;
+    /** (0-11) month of the year */
+    acr_int32_t tm_mon;
+    /** year since 1900 */
+    acr_int32_t tm_year;
+    /** (0-6) days since sunday */
+    acr_int32_t tm_wday;
+    /** (0-365) days since jan 1 */
+    acr_int32_t tm_yday;
+    /** daylight saving time */
+    acr_int32_t tm_isdst;
+    /** seconds east of UTC */
+    acr_int32_t tm_gmtoff;
+};
+
 /**
  * Mechanism to properly type acr_time_t literals
  */
@@ -46,9 +79,18 @@
  */
 #define ACR_USEC_PER_SEC ACR_TIME_C(1000000)
 
+/**
+ * Convert DOS time format to ACR Time
+ */
+ACR_DECLARE(acr_time_t) ACR_Dos2AcrTime(acr_uint32_t t);
+
+/**
+ * Convert ACR time format to DOS time
+ */
+ACR_DECLARE(acr_uint32_t) ACR_Acr2DosTime(acr_time_t t);
+
 #ifdef __cplusplus
 }
 #endif
 
 #endif /* _ACR_TIME_H */
-

Modified: commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h?rev=809086&r1=809085&r2=809086&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h Sat Aug 29 06:56:39 2009
@@ -300,7 +300,7 @@
 #define ACR_IOH_FLAGS(H)    acr_ioh_tab[(H) & acr_ioh_mask].flags
 #define ACR_IOH(H)          acr_ioh_tab[(H) & acr_ioh_mask].h
 
-static ACR_INLINE void FileTimeToAprTime(acr_time_t *result, LPFILETIME input)
+static ACR_INLINE void FileTimeToUsecTime(acr_time_t *result, LPFILETIME input)
 {
     /* Convert FILETIME one 64 bit number so we can work with it. */
     *result  = ((LARGE_INTEGER *)input)->QuadPart;
@@ -312,7 +312,7 @@
 }
 
 
-static ACR_INLINE void AprTimeToFileTime(LPFILETIME result, acr_time_t t)
+static ACR_INLINE void UsecTimeToFileTime(LPFILETIME result, acr_time_t t)
 {
     ((LARGE_INTEGER *)result)->QuadPart = (t + ACR_DELTA_EPOCH_IN_USEC) * 10;
     return;

Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/time.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/time.c?rev=809086&r1=809085&r2=809086&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/time.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/time.c Sat Aug 29 06:56:39 2009
@@ -25,6 +25,54 @@
 
 #include <sys/time.h>
 
+static acr_time_t tm2time(acr_tm_t *xt)
+{
+    acr_time_t year = xt->tm_year;
+    acr_time_t days;
+    static const int dayoffset[12] =
+    { 306, 337, 0, 31, 61, 92, 122, 153, 184, 214, 245, 275 };
+
+    /* shift new year to 1st March in order to make leap year calc easy */
+
+    if (xt->tm_mon < 2)
+        year--;
+
+    /* Find number of days since 1st March 1900 (in the Gregorian calendar). */
+    days = year * 365 + year / 4 - year / 100 + (year / 100 + 3) / 4;
+    days += dayoffset[xt->tm_mon] + xt->tm_mday - 1;
+    days -= 25508;              /* 1 jan 1970 is 25508 days since 1 mar 1900 */
+    days = ((days * 24 + xt->tm_hour) * 60 + xt->tm_min) * 60 + xt->tm_sec;
+
+    if (days < 0) {
+        return 0;
+    }
+    return days * ACR_USEC_PER_SEC + xt->tm_usec;
+}
+
+static void time2gmtime(acr_tm_t *xt, acr_time_t t)
+{
+    struct tm tm;
+    time_t tt   = t / ACR_USEC_PER_SEC;
+    xt->tm_usec = t % ACR_USEC_PER_SEC;
+
+#if 1
+    gmtime_r(&tt, &tm);
+#else
+    tm = *gmtime(&tt);
+#endif
+
+    xt->tm_sec    = tm.tm_sec;
+    xt->tm_min    = tm.tm_min;
+    xt->tm_hour   = tm.tm_hour;
+    xt->tm_mday   = tm.tm_mday;
+    xt->tm_mon    = tm.tm_mon;
+    xt->tm_year   = tm.tm_year;
+    xt->tm_wday   = tm.tm_wday;
+    xt->tm_yday   = tm.tm_yday;
+    xt->tm_isdst  = tm.tm_isdst;
+    xt->tm_gmtoff = 0;
+}
+
 ACR_DECLARE(acr_time_t) ACR_TimeNow(void)
 {
     struct timeval tv;
@@ -33,3 +81,33 @@
     return tv.tv_sec * ACR_USEC_PER_SEC + tv.tv_usec;
 }
 
+ACR_DECLARE(acr_time_t) ACR_Dos2AcrTime(acr_uint32_t t)
+{
+    acr_tm_t     xt;
+    acr_uint32_t ud = (t >> 16);
+
+    xt.tm_mday = ud & 0x1F;
+    xt.tm_mon  = (acr_uint32_t)(((ud & 0x01E0) / 0x0020) - 1);
+    xt.tm_year = (acr_uint32_t)(((ud & 0xFE00) / 0x0200) + 80);
+    xt.tm_hour = (acr_uint32_t)((t & 0xF800)   / 0x0800);
+    xt.tm_min  = (acr_uint32_t)((t & 0x07E0)   / 0x0020);
+    xt.tm_sec  = (acr_uint32_t)((t & 0x001F) << 1);
+    xt.tm_usec = 0;
+
+    return tm2time(&xt);
+}
+
+ACR_DECLARE(acr_uint32_t) ACR_Acr2DosTime(acr_time_t t)
+{
+    acr_tm_t     gm;
+    acr_uint32_t rv;
+
+    time2gmtime(&gm, t);
+    if (gm.tm_year > 1980)
+        gm.tm_year -= 1980;
+    else if (gm.tm_year > 80)
+        gm.tm_year -= 80;
+    rv = (((gm.tm_mday) + (32 * (gm.tm_mon+1)) + (512 * gm.tm_year)) << 16) |
+         ((gm.tm_sec / 2) + (32 * gm.tm_min) + (2048 * gm.tm_hour));
+    return rv;
+}

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/time.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/time.c?rev=809086&r1=809085&r2=809086&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/time.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/time.c Sat Aug 29 06:56:39 2009
@@ -23,14 +23,114 @@
 #include "acr_descriptor.h"
 #include "acr_time.h"
 
+/* Leap year is any year divisible by four, but not by 100 unless also
+ * divisible by 400
+ */
+#define IsLeapYear(y) ((!(y % 4)) ? (((!(y % 400)) && (y % 100)) ? 1 : 0) : 0)
+
+static acr_time_t tm2time(acr_tm_t *xt)
+{
+    acr_time_t year = xt->tm_year;
+    acr_time_t days;
+    static const int dayoffset[12] =
+    { 306, 337, 0, 31, 61, 92, 122, 153, 184, 214, 245, 275 };
+
+    /* shift new year to 1st March in order to make leap year calc easy */
+
+    if (xt->tm_mon < 2)
+        year--;
+
+    /* Find number of days since 1st March 1900 (in the Gregorian calendar). */
+    days = year * 365 + year / 4 - year / 100 + (year / 100 + 3) / 4;
+    days += dayoffset[xt->tm_mon] + xt->tm_mday - 1;
+    days -= 25508;              /* 1 jan 1970 is 25508 days since 1 mar 1900 */
+    days = ((days * 24 + xt->tm_hour) * 60 + xt->tm_min) * 60 + xt->tm_sec;
+
+    if (days < 0) {
+        return 0;
+    }
+    return days * ACR_USEC_PER_SEC + xt->tm_usec;
+}
+
+static void SystemTimeToAprExpTime(apr_tm_t *xt, SYSTEMTIME *tm)
+{
+    static const int dayoffset[12] =
+    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+
+    /* Note; the caller is responsible for filling in detailed tm_usec,
+     * tm_gmtoff and tm_isdst data when applicable.
+     */
+    xt->tm_usec = tm->wMilliseconds * 1000;
+    xt->tm_sec  = tm->wSecond;
+    xt->tm_min  = tm->wMinute;
+    xt->tm_hour = tm->wHour;
+    xt->tm_mday = tm->wDay;
+    xt->tm_mon  = tm->wMonth - 1;
+    xt->tm_year = tm->wYear - 1900;
+    xt->tm_wday = tm->wDayOfWeek;
+    xt->tm_yday = dayoffset[xt->tm_mon] + (tm->wDay - 1);
+    xt->tm_isdst = 0;
+    xt->tm_gmtoff = 0;
+
+    /* If this is a leap year, and we're past the 28th of Feb. (the
+     * 58th day after Jan. 1), we'll increment our tm_yday by one.
+     */
+    if (IsLeapYear(tm->wYear) && (xt->tm_yday > 58))
+        xt->tm_yday++;
+}
+
+static void time2gmtime(acr_tm_t *xt, acr_time_t t)
+{
+    FILETIME ft;
+    SYSTEMTIME st;
+
+    UsecTimeToFileTime(&ft, t);
+    FileTimeToSystemTime(&ft, &st);
+    /* The Platform SDK documents that SYSTEMTIME/FILETIME are
+     * generally UTC, so no timezone info needed
+     */
+    SystemTimeToAprExpTime(xt, &st);
+    xt->tm_usec = (acr_int32_t) (input % ACR_USEC_PER_SEC);
+}
+
 ACR_DECLARE(acr_time_t) ACR_TimeNow(void)
 {
     LONGLONG   aprtime = 0;
     FILETIME   time;
 
     GetSystemTimeAsFileTime(&time);
-    FileTimeToAprTime(&aprtime, &time);
+    FileTimeToUsecTime(&aprtime, &time);
 
     return aprtime;
 }
 
+ACR_DECLARE(acr_time_t) ACR_Dos2AcrTime(acr_uint32_t t)
+{
+    acr_tm_t     xt;
+    acr_uint32_t ud = (t >> 16);
+
+    xt.tm_mday = ud & 0x1F;
+    xt.tm_mon  = (acr_uint32_t)(((ud & 0x01E0) / 0x0020) - 1);
+    xt.tm_year = (acr_uint32_t)(((ud & 0xFE00) / 0x0200) + 80);
+    xt.tm_hour = (acr_uint32_t)((t & 0xF800)   / 0x0800);
+    xt.tm_min  = (acr_uint32_t)((t & 0x07E0)   / 0x0020);
+    xt.tm_sec  = (acr_uint32_t)((t & 0x001F) << 1);
+    xt.tm_usec = 0;
+
+    return tm2time(&xt);
+}
+
+ACR_DECLARE(acr_uint32_t) ACR_Acr2DosTime(acr_time_t t)
+{
+    acr_tm_t     gm;
+    acr_uint32_t rv;
+
+    time2gmtime(&gm, t);
+    if (gm.tm_year > 1980)
+        gm.tm_year -= 1980;
+    else if (gm.tm_year > 80)
+        gm.tm_year -= 80;
+    rv = (((gm.tm_mday) + (32 * (gm.tm_mon+1)) + (512 * gm.tm_year)) << 16) |
+         ((gm.tm_sec / 2) + (32 * gm.tm_min) + (2048 * gm.tm_hour));
+    return rv;
+}