Annotation of embedaddon/ntp/lib/isc/win32/time.c, revision 1.1.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>