Return-Path: Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: (qmail 96751 invoked from network); 29 Aug 2009 06:57:05 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 29 Aug 2009 06:57:05 -0000 Received: (qmail 99016 invoked by uid 500); 29 Aug 2009 06:57:04 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 98931 invoked by uid 500); 29 Aug 2009 06:57:04 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 98922 invoked by uid 99); 29 Aug 2009 06:57:04 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 29 Aug 2009 06:57:04 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 29 Aug 2009 06:57:01 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id E343D23888E4; Sat, 29 Aug 2009 06:56:39 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: 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 Date: Sat, 29 Aug 2009 06:56:39 -0000 To: commits@commons.apache.org From: mturk@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20090829065639.E343D23888E4@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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 +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; +}