diff options
Diffstat (limited to 'time')
-rw-r--r-- | time/win32/time.c | 185 |
1 files changed, 121 insertions, 64 deletions
diff --git a/time/win32/time.c b/time/win32/time.c index 571774a0e..e2ad9c18e 100644 --- a/time/win32/time.c +++ b/time/win32/time.c @@ -60,98 +60,155 @@ #include <time.h> #include <errno.h> #include <string.h> +#include <winbase.h> -ap_status_t ap_make_time(struct atime_t **new, ap_context_t *cont) +/* Number of micro-seconds between the beginning of the Windows epoch + * (Jan. 1, 1601) and the Unix epoch (Jan. 1, 1970) + */ +#define AP_DELTA_EPOCH_IN_USEC 11644473600000000; + +static void FileTimeToAprTime(ap_time_t *result, FILETIME *input) { - (*new) = (struct atime_t *)ap_palloc(cont, sizeof(struct atime_t)); + /* Convert FILETIME one 64 bit number so we can work with it. */ + *result = input->dwHighDateTime; + *result = (*result) << 32; + *result |= input->dwLowDateTime; + *result /= 10; /* Convert from 100 nano-sec periods to micro-seconds. */ + *result -= AP_DELTA_EPOCH_IN_USEC; /* Convert from Windows epoch to Unix epoch */ + //printf("FileTimeToAprTime: aprtime - %I64d\n", *result); + return; +} +static void AprTimeToFileTime(LPFILETIME pft, ap_time_t t) +{ + LONGLONG ll; + //printf("AprTimeToFileTime: aprtime - %I64d\n", t); + t += AP_DELTA_EPOCH_IN_USEC; + ll = t * 10; + pft->dwLowDateTime = (DWORD)ll; + pft->dwHighDateTime = (DWORD) (ll >> 32); + return; +} - if ((*new) == NULL) { - return APR_ENOMEM; - } +static void SystemTimeToAprExpTime(ap_exploded_time_t *xt, SYSTEMTIME *tm) +{ + 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 = 0; /* ToDo: need to compute this */ + xt->tm_isdst = 0; /* ToDo: need to compute this */ + xt->tm_gmtoff = 0; /* ToDo: maybe the caller should set this explicitly */ + return; +} - (*new)->cntxt = cont; - (*new)->currtime = -1; - (*new)->explodedtime = NULL; +ap_status_t ap_ansi_time_to_ap_time(ap_time_t *result, time_t input) +{ + *result = (ap_time_t) input * AP_USEC_PER_SEC; return APR_SUCCESS; } -ap_status_t ap_current_time(struct atime_t *new) +/* Return micro-seconds since the Unix epoch (jan. 1, 1970) */ +ap_time_t ap_now(void) { - if (!new) { - return APR_ENOTIME; - } - if (new->explodedtime == NULL) { - new->explodedtime = (SYSTEMTIME *)ap_palloc(new->cntxt, sizeof(SYSTEMTIME)); - } - GetSystemTime(new->explodedtime); - return APR_SUCCESS; -} + ULONGLONG aprtime = 0; + FILETIME time; + GetSystemTimeAsFileTime(&time); + FileTimeToAprTime(&aprtime, &time); + return aprtime; +} -ap_status_t ap_explode_time(struct atime_t *atime, ap_timetype_e type) +ap_status_t ap_explode_gmt(ap_exploded_time_t *result, ap_time_t input) { - if (!atime || !atime->explodedtime) { - return APR_ENOTIME; - } + FILETIME ft; + SYSTEMTIME st; + AprTimeToFileTime(&ft, input); + FileTimeToSystemTime(&ft, &st); + SystemTimeToAprExpTime(result, &st); + result->tm_gmtoff = 0; return APR_SUCCESS; } -ap_status_t ap_implode_time(struct atime_t *atime) +ap_status_t ap_explode_localtime(ap_exploded_time_t *result, ap_time_t input) { - FILETIME temp; - - if (!atime || !atime->explodedtime) { - return APR_ENOTIME; - } + SYSTEMTIME st; + FILETIME ft, localft; - if (SystemTimeToFileTime(atime->explodedtime, &temp) == 0) { - return APR_EEXIST; - } - atime->currtime = WinTimeToUnixTime(&temp); + AprTimeToFileTime(&ft, input); + FileTimeToLocalFileTime(&ft, &localft); + FileTimeToSystemTime(&localft, &st); + SystemTimeToAprExpTime(result, &st); return APR_SUCCESS; } -ap_status_t ap_get_os_time(ap_os_time_t **atime, struct atime_t *thetime) +ap_status_t ap_implode_time(ap_time_t *t, ap_exploded_time_t *xt) { - if (thetime == NULL) { - return APR_ENOTIME; + int year; + time_t days; + static const int dayoffset[12] = + {306, 337, 0, 31, 61, 92, 122, 153, 184, 214, 245, 275}; + + year = xt->tm_year; + + if (year < 70 || ((sizeof(time_t) <= 4) && (year >= 138))) { + return APR_EBADDATE; } - if (thetime->explodedtime == NULL) { - ap_explode_time(thetime, APR_LOCALTIME); + + /* 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 APR_EBADDATE; } - *atime = thetime->explodedtime; + days -= xt->tm_gmtoff; + *t = days * AP_USEC_PER_SEC + xt->tm_usec; return APR_SUCCESS; } -ap_status_t ap_put_os_time(struct atime_t **thetime, ap_os_time_t *atime, - ap_context_t *cont) +ap_status_t ap_get_os_imp_time(ap_os_imp_time_t **ostime, ap_time_t *aprtime) { - if (cont == NULL) { - return APR_ENOCONT; - } - if (thetime == NULL) { - (*thetime) = (struct atime_t *)ap_palloc(cont, sizeof(struct atime_t)); - (*thetime)->cntxt = cont; - } - (*thetime)->explodedtime = atime; + /* TODO: Consider not passing in pointer to ap_time_t (e.g., call by value) */ + AprTimeToFileTime(*ostime, *aprtime); + return APR_SUCCESS; +} + +ap_status_t ap_get_os_exp_time(ap_os_exp_time_t **ostime, ap_exploded_time_t *aprexptime) +{ + (*ostime)->wYear = aprexptime->tm_year + 1900; + (*ostime)->wMonth = aprexptime->tm_mon + 1; + (*ostime)->wDayOfWeek = aprexptime->tm_wday; + (*ostime)->wDay = aprexptime->tm_mday; + (*ostime)->wHour = aprexptime->tm_hour; + (*ostime)->wMinute = aprexptime->tm_min; + (*ostime)->wSecond = aprexptime->tm_sec; + (*ostime)->wMilliseconds = aprexptime->tm_usec / 1000; + return APR_SUCCESS; +} + +ap_status_t ap_put_os_imp_time(ap_time_t *aprtime, ap_os_imp_time_t **ostime, + ap_context_t *cont) +{ + FileTimeToAprTime(aprtime, *ostime); return APR_SUCCESS; } -ap_status_t ap_timediff(struct atime_t *a, struct atime_t *b, ap_int32_t *rv) +ap_status_t ap_put_os_exp_time(ap_exploded_time_t *aprtime, + ap_os_exp_time_t **ostime, ap_context_t *cont) { - FILETIME fa, fb; - LONGLONG ia = 0, ib = 0; - - SystemTimeToFileTime(a->explodedtime, &fa); - SystemTimeToFileTime(b->explodedtime, &fb); - - ia = fa.dwHighDateTime; - ia = ia << 32; - ia |= fa.dwLowDateTime; - - ib = fb.dwHighDateTime; - ib = ib << 32; - ib |= fb.dwLowDateTime; - - *rv = (int)((ia - ib) / 10000); + SystemTimeToAprExpTime(aprtime, *ostime); return APR_SUCCESS; } + |