1 /**
2  * libdmtx - Data Matrix Encoding/Decoding Library
3  * Copyright 2008, 2009 Mike Laughton. All rights reserved.
4  * Copyright 2012-2016 Vadim A. Misbakh-Soloviov. All rights reserved.
5  *
6  * See LICENSE file in the main project directory for full
7  * terms of use and distribution.
8  *
9  * Contact:
10  * Vadim A. Misbakh-Soloviov <dmtx@mva.name>
11  * Mike Laughton <mike@dragonflylogic.com>
12  *
13  * \file dmtxtime.c
14  * \brief Time handling
15  */
16 
17 #define DMTX_USEC_PER_SEC 1000000
18 
19 #if defined(HAVE_SYS_TIME_H) && defined(HAVE_GETTIMEOFDAY)
20 
21 #include <sys/time.h>
22 #include <time.h>
23 #define DMTX_TIME_PREC_USEC 1
24 
25 /**
26  * \brief  GETTIMEOFDAY version
27  * \return Time now
28  */
29 extern DmtxTime
dmtxTimeNow(void)30 dmtxTimeNow(void)
31 {
32    DmtxPassFail err;
33    struct timeval tv;
34    DmtxTime tNow;
35 
36    err = gettimeofday(&tv, NULL);
37    if(err != 0)
38       ; /* XXX handle error better here */
39 
40    tNow.sec = tv.tv_sec;
41    tNow.usec = tv.tv_usec;
42 
43    return tNow;
44 }
45 
46 #elif defined(_MSC_VER)
47 
48 #include <Windows.h>
49 #define DMTX_TIME_PREC_USEC 1
50 
51 /**
52  * \brief  MICROSOFT VC++ version
53  * \return Time now
54  */
55 extern DmtxTime
dmtxTimeNow(void)56 dmtxTimeNow(void)
57 {
58    FILETIME ft;
59    unsigned __int64 tm;
60    DmtxTime tNow;
61 
62    GetSystemTimeAsFileTime(&ft);
63 
64    tm = ft.dwHighDateTime;
65    tm <<= 32;
66    tm |= ft.dwLowDateTime;
67    tm /= 10;
68 
69    tNow.sec = tm / 1000000UL;
70    tNow.usec = tm % 1000000UL;
71 
72    return tNow;
73 }
74 
75 #else
76 
77 #include <time.h>
78 #define DMTX_TIME_PREC_USEC 1000000
79 
80 /**
81  * \brief  Generic 1 second resolution version
82  * \return Time now
83  */
84 extern DmtxTime
dmtxTimeNow(void)85 dmtxTimeNow(void)
86 {
87    time_t s;
88    DmtxTime tNow;
89 
90    s = time(NULL);
91    if(errno != 0)
92       ; /* XXX handle error better here */
93 
94    tNow.sec = s;
95    tNow.usec = 0;
96 
97    return tNow;
98 }
99 
100 #endif
101 
102 /**
103  * \brief  Add milliseconds to time t
104  * \param  t
105  * \param  msec
106  * \return Adjusted time
107  */
108 extern DmtxTime
dmtxTimeAdd(DmtxTime t,long msec)109 dmtxTimeAdd(DmtxTime t, long msec)
110 {
111    int usec;
112 
113    usec = msec * 1000;
114 
115    /* Ensure that time difference will register on local system */
116    if(usec > 0 && usec < DMTX_TIME_PREC_USEC)
117       usec = DMTX_TIME_PREC_USEC;
118 
119    /* Add time */
120    t.sec += usec/DMTX_USEC_PER_SEC;
121    t.usec += usec%DMTX_USEC_PER_SEC;
122 
123    /* Roll extra usecs into secs */
124    while(t.usec >= DMTX_USEC_PER_SEC) {
125       t.sec++;
126       t.usec -= DMTX_USEC_PER_SEC;
127    }
128 
129    return t;
130 }
131 
132 /**
133  * \brief  Determine whether the received timeout has been exceeded
134  * \param  timeout
135  * \return 1 (true) | 0 (false)
136  */
137 extern int
dmtxTimeExceeded(DmtxTime timeout)138 dmtxTimeExceeded(DmtxTime timeout)
139 {
140    DmtxTime now;
141 
142    now = dmtxTimeNow();
143 
144    return (now.sec > timeout.sec || (now.sec == timeout.sec && now.usec > timeout.usec));
145 }
146 
147 #undef DMTX_TIME_PREC_USEC
148 #undef DMTX_USEC_PER_SEC
149