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>