Annotation of embedaddon/ntp/lib/isc/win32/time.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2004, 2006-2008 Internet Systems Consortium, Inc. ("ISC")
! 3: * Copyright (C) 1998-2001, 2003 Internet Software Consortium.
! 4: *
! 5: * Permission to use, copy, modify, and/or distribute this software for any
! 6: * purpose with or without fee is hereby granted, provided that the above
! 7: * copyright notice and this permission notice appear in all copies.
! 8: *
! 9: * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
! 10: * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
! 11: * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
! 12: * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
! 13: * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
! 14: * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
! 15: * PERFORMANCE OF THIS SOFTWARE.
! 16: */
! 17:
! 18: /* $Id: time.c,v 1.48 2008/09/08 23:47:10 tbox Exp $ */
! 19:
! 20: #include <config.h>
! 21:
! 22: #include <errno.h>
! 23: #include <limits.h>
! 24: #include <stddef.h>
! 25: #include <stdlib.h>
! 26: #include <string.h>
! 27: #include <time.h>
! 28:
! 29: #include <windows.h>
! 30:
! 31: #include <isc/assertions.h>
! 32: #include <isc/time.h>
! 33: #include <isc/util.h>
! 34:
! 35: /*
! 36: * struct FILETIME uses "100-nanoseconds intervals".
! 37: * NS / S = 1000000000 (10^9).
! 38: * While it is reasonably obvious that this makes the needed
! 39: * conversion factor 10^7, it is coded this way for additional clarity.
! 40: */
! 41: #define NS_PER_S 1000000000
! 42: #define NS_INTERVAL 100
! 43: #define INTERVALS_PER_S (NS_PER_S / NS_INTERVAL)
! 44: #define UINT64_MAX _UI64_MAX
! 45:
! 46: /***
! 47: *** Absolute Times
! 48: ***/
! 49:
! 50: static isc_time_t epoch = { { 0, 0 } };
! 51: LIBISC_EXTERNAL_DATA isc_time_t *isc_time_epoch = &epoch;
! 52:
! 53: /***
! 54: *** Intervals
! 55: ***/
! 56:
! 57: static isc_interval_t zero_interval = { 0 };
! 58: LIBISC_EXTERNAL_DATA isc_interval_t *isc_interval_zero = &zero_interval;
! 59:
! 60: void
! 61: isc_interval_set(isc_interval_t *i, unsigned int seconds,
! 62: unsigned int nanoseconds)
! 63: {
! 64: REQUIRE(i != NULL);
! 65: REQUIRE(nanoseconds < NS_PER_S);
! 66:
! 67: /*
! 68: * This rounds nanoseconds up not down.
! 69: */
! 70: i->interval = (LONGLONG)seconds * INTERVALS_PER_S
! 71: + (nanoseconds + NS_INTERVAL - 1) / NS_INTERVAL;
! 72: }
! 73:
! 74: isc_boolean_t
! 75: isc_interval_iszero(const isc_interval_t *i) {
! 76: REQUIRE(i != NULL);
! 77: if (i->interval == 0)
! 78: return (ISC_TRUE);
! 79:
! 80: return (ISC_FALSE);
! 81: }
! 82:
! 83: void
! 84: isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds) {
! 85: SYSTEMTIME epoch = { 1970, 1, 4, 1, 0, 0, 0, 0 };
! 86: FILETIME temp;
! 87: ULARGE_INTEGER i1;
! 88:
! 89: REQUIRE(t != NULL);
! 90: REQUIRE(nanoseconds < NS_PER_S);
! 91:
! 92: SystemTimeToFileTime(&epoch, &temp);
! 93:
! 94: i1.LowPart = t->absolute.dwLowDateTime;
! 95: i1.HighPart = t->absolute.dwHighDateTime;
! 96:
! 97: i1.QuadPart += (unsigned __int64)nanoseconds/100;
! 98: i1.QuadPart += (unsigned __int64)seconds*10000000;
! 99:
! 100: t->absolute.dwLowDateTime = i1.LowPart;
! 101: t->absolute.dwHighDateTime = i1.HighPart;
! 102: }
! 103:
! 104: void
! 105: isc_time_settoepoch(isc_time_t *t) {
! 106: REQUIRE(t != NULL);
! 107:
! 108: t->absolute.dwLowDateTime = 0;
! 109: t->absolute.dwHighDateTime = 0;
! 110: }
! 111:
! 112: isc_boolean_t
! 113: isc_time_isepoch(const isc_time_t *t) {
! 114: REQUIRE(t != NULL);
! 115:
! 116: if (t->absolute.dwLowDateTime == 0 &&
! 117: t->absolute.dwHighDateTime == 0)
! 118: return (ISC_TRUE);
! 119:
! 120: return (ISC_FALSE);
! 121: }
! 122:
! 123: isc_result_t
! 124: isc_time_now(isc_time_t *t) {
! 125: REQUIRE(t != NULL);
! 126:
! 127: GetSystemTimeAsFileTime(&t->absolute);
! 128:
! 129: return (ISC_R_SUCCESS);
! 130: }
! 131:
! 132: isc_result_t
! 133: isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i) {
! 134: ULARGE_INTEGER i1;
! 135:
! 136: REQUIRE(t != NULL);
! 137: REQUIRE(i != NULL);
! 138:
! 139: GetSystemTimeAsFileTime(&t->absolute);
! 140:
! 141: i1.LowPart = t->absolute.dwLowDateTime;
! 142: i1.HighPart = t->absolute.dwHighDateTime;
! 143:
! 144: if (UINT64_MAX - i1.QuadPart < (unsigned __int64)i->interval)
! 145: return (ISC_R_RANGE);
! 146:
! 147: i1.QuadPart += i->interval;
! 148:
! 149: t->absolute.dwLowDateTime = i1.LowPart;
! 150: t->absolute.dwHighDateTime = i1.HighPart;
! 151:
! 152: return (ISC_R_SUCCESS);
! 153: }
! 154:
! 155: int
! 156: isc_time_compare(const isc_time_t *t1, const isc_time_t *t2) {
! 157: REQUIRE(t1 != NULL && t2 != NULL);
! 158:
! 159: return ((int)CompareFileTime(&t1->absolute, &t2->absolute));
! 160: }
! 161:
! 162: isc_result_t
! 163: isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result)
! 164: {
! 165: ULARGE_INTEGER i1;
! 166:
! 167: REQUIRE(t != NULL && i != NULL && result != NULL);
! 168:
! 169: i1.LowPart = t->absolute.dwLowDateTime;
! 170: i1.HighPart = t->absolute.dwHighDateTime;
! 171:
! 172: if (UINT64_MAX - i1.QuadPart < (unsigned __int64)i->interval)
! 173: return (ISC_R_RANGE);
! 174:
! 175: i1.QuadPart += i->interval;
! 176:
! 177: result->absolute.dwLowDateTime = i1.LowPart;
! 178: result->absolute.dwHighDateTime = i1.HighPart;
! 179:
! 180: return (ISC_R_SUCCESS);
! 181: }
! 182:
! 183: isc_result_t
! 184: isc_time_subtract(const isc_time_t *t, const isc_interval_t *i,
! 185: isc_time_t *result) {
! 186: ULARGE_INTEGER i1;
! 187:
! 188: REQUIRE(t != NULL && i != NULL && result != NULL);
! 189:
! 190: i1.LowPart = t->absolute.dwLowDateTime;
! 191: i1.HighPart = t->absolute.dwHighDateTime;
! 192:
! 193: if (i1.QuadPart < (unsigned __int64) i->interval)
! 194: return (ISC_R_RANGE);
! 195:
! 196: i1.QuadPart -= i->interval;
! 197:
! 198: result->absolute.dwLowDateTime = i1.LowPart;
! 199: result->absolute.dwHighDateTime = i1.HighPart;
! 200:
! 201: return (ISC_R_SUCCESS);
! 202: }
! 203:
! 204: isc_uint64_t
! 205: isc_time_microdiff(const isc_time_t *t1, const isc_time_t *t2) {
! 206: ULARGE_INTEGER i1, i2;
! 207: LONGLONG i3;
! 208:
! 209: REQUIRE(t1 != NULL && t2 != NULL);
! 210:
! 211: i1.LowPart = t1->absolute.dwLowDateTime;
! 212: i1.HighPart = t1->absolute.dwHighDateTime;
! 213: i2.LowPart = t2->absolute.dwLowDateTime;
! 214: i2.HighPart = t2->absolute.dwHighDateTime;
! 215:
! 216: if (i1.QuadPart <= i2.QuadPart)
! 217: return (0);
! 218:
! 219: /*
! 220: * Convert to microseconds.
! 221: */
! 222: i3 = (i1.QuadPart - i2.QuadPart) / 10;
! 223:
! 224: return (i3);
! 225: }
! 226:
! 227: isc_uint32_t
! 228: isc_time_seconds(const isc_time_t *t) {
! 229: SYSTEMTIME st;
! 230:
! 231: /*
! 232: * Convert the time to a SYSTEMTIME structure and the grab the
! 233: * milliseconds
! 234: */
! 235: FileTimeToSystemTime(&t->absolute, &st);
! 236:
! 237: return ((isc_uint32_t)(st.wMilliseconds / 1000));
! 238: }
! 239:
! 240: isc_uint32_t
! 241: isc_time_nanoseconds(const isc_time_t *t) {
! 242: SYSTEMTIME st;
! 243:
! 244: /*
! 245: * Convert the time to a SYSTEMTIME structure and the grab the
! 246: * milliseconds
! 247: */
! 248: FileTimeToSystemTime(&t->absolute, &st);
! 249:
! 250: return ((isc_uint32_t)(st.wMilliseconds * 1000000));
! 251: }
! 252:
! 253: void
! 254: isc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len) {
! 255: FILETIME localft;
! 256: SYSTEMTIME st;
! 257: char DateBuf[50];
! 258: char TimeBuf[50];
! 259:
! 260: static const char badtime[] = "99-Bad-9999 99:99:99.999";
! 261:
! 262: REQUIRE(len > 0);
! 263: if (FileTimeToLocalFileTime(&t->absolute, &localft) &&
! 264: FileTimeToSystemTime(&localft, &st)) {
! 265: GetDateFormat(LOCALE_USER_DEFAULT, 0, &st, "dd-MMM-yyyy",
! 266: DateBuf, 50);
! 267: GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOTIMEMARKER|
! 268: TIME_FORCE24HOURFORMAT, &st, NULL, TimeBuf, 50);
! 269:
! 270: snprintf(buf, len, "%s %s.%03u", DateBuf, TimeBuf,
! 271: st.wMilliseconds);
! 272:
! 273: } else
! 274: snprintf(buf, len, badtime);
! 275: }
! 276:
! 277: void
! 278: isc_time_formathttptimestamp(const isc_time_t *t, char *buf, unsigned int len) {
! 279: SYSTEMTIME st;
! 280: char DateBuf[50];
! 281: char TimeBuf[50];
! 282:
! 283: REQUIRE(len > 0);
! 284: if (FileTimeToSystemTime(&t->absolute, &st)) {
! 285: GetDateFormat(LOCALE_USER_DEFAULT, 0, &st, "ddd',', dd-MMM-yyyy",
! 286: DateBuf, 50);
! 287: GetTimeFormat(LOCALE_USER_DEFAULT,
! 288: TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT,
! 289: &st, "hh':'mm':'ss", TimeBuf, 50);
! 290:
! 291: snprintf(buf, len, "%s %s GMT", DateBuf, TimeBuf);
! 292: } else {
! 293: buf[0] = 0;
! 294: }
! 295: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>