~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/pbms/src/cslib/CSTime.cc

  • Committer: Mark Atwood
  • Date: 2011-12-20 02:32:53 UTC
  • mfrom: (2469.1.1 drizzle-build)
  • Revision ID: me@mark.atwood.name-20111220023253-bvu0kr14kwsdvz7g
mergeĀ lp:~brianaker/drizzle/deprecate-pbms

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2008 PrimeBase Technologies GmbH, Germany
2
 
 *
3
 
 * PrimeBase Media Stream for MySQL
4
 
 *
5
 
 * This program is free software; you can redistribute it and/or modify
6
 
 * it under the terms of the GNU General Public License as published by
7
 
 * the Free Software Foundation; either version 2 of the License, or
8
 
 * (at your option) any later version.
9
 
 *
10
 
 * This program is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 * GNU General Public License for more details.
14
 
 *
15
 
 * You should have received a copy of the GNU General Public License
16
 
 * along with this program; if not, write to the Free Software
17
 
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
 
 *
19
 
 * Original author: Paul McCullagh (H&G2JCtL)
20
 
 * Continued development: Barry Leslie
21
 
 *
22
 
 * 2007-05-20
23
 
 *
24
 
 *
25
 
 */
26
 
 
27
 
#include "CSConfig.h"
28
 
 
29
 
#include <string.h>
30
 
 
31
 
#ifdef OS_WINDOWS
32
 
#include <Windows.h>
33
 
extern int gettimeofday(struct timeval *tv, struct timezone *tz);
34
 
#else
35
 
#include <sys/time.h>
36
 
#endif
37
 
 
38
 
#include "CSTime.h"
39
 
#include "CSGlobal.h"
40
 
#include "CSStrUtil.h"
41
 
 
42
 
/*
43
 
 * timegm() is a none portable function so....
44
 
 * This is an implimentation of timegm() based on one found
45
 
 * here: http://www.opensync.org/changeset/1769
46
 
 *
47
 
 * Note to self: There is a better way to do this.
48
 
 * Since this is just used internally and tm_isdst is always 0
49
 
 * we only need to calculate the timezone offset to GM time once.
50
 
 */
51
 
static time_t my_timegm(struct tm *my_time)
52
 
{
53
 
        time_t local_secs, gm_secs;
54
 
        struct tm gm__rec, *gm_time;
55
 
 
56
 
        // Interpret 't' as the local time and convert it to seconds since the Epoch
57
 
        local_secs = mktime(my_time);
58
 
        if (local_secs == -1) {
59
 
                my_time->tm_hour--;
60
 
                local_secs = mktime (my_time);
61
 
                if (local_secs == -1)
62
 
                        return -1; 
63
 
                local_secs += 3600;
64
 
        }
65
 
        
66
 
        // Get the gmtime based on the local seconds since the Epoch
67
 
        gm_time = gmtime_r(&local_secs, &gm__rec);
68
 
        gm_time->tm_isdst = 0;
69
 
        
70
 
        // Interpret gmtime as the local time and convert it to seconds since the Epoch
71
 
        gm_secs = mktime (gm_time);
72
 
        if (gm_secs == -1) {
73
 
                gm_time->tm_hour--;
74
 
                gm_secs = mktime (gm_time);
75
 
                if (gm_secs == -1)
76
 
                        return -1; 
77
 
                gm_secs += 3600;
78
 
        }
79
 
        
80
 
        // Return the local time adjusted by the difference from GM time.
81
 
        return (local_secs - (gm_secs - local_secs));
82
 
}
83
 
 
84
 
CSTime::CSTime(s_int year, s_int mon, s_int day, s_int hour, s_int min, s_int sec, s_int nsec)
85
 
{
86
 
        setLocal(year, mon, day, hour, min, sec, nsec);
87
 
}
88
 
 
89
 
bool CSTime::isNull()
90
 
{
91
 
        return iIsNull;
92
 
}
93
 
 
94
 
void CSTime::setNull()
95
 
{
96
 
        iIsNull = true;
97
 
        iSeconds = 0;
98
 
        iNanoSeconds = 0;
99
 
}
100
 
 
101
 
void CSTime::setLocal(s_int year, s_int mon, s_int day, s_int hour, s_int min, s_int sec, s_int nsec)
102
 
{
103
 
        struct tm       ltime;
104
 
        time_t          secs;
105
 
        
106
 
        memset(&ltime, 0, sizeof(ltime));
107
 
 
108
 
        ltime.tm_sec = sec;
109
 
        ltime.tm_min = min;
110
 
        ltime.tm_hour = hour;
111
 
        ltime.tm_mday = day;
112
 
        ltime.tm_mon = mon - 1;
113
 
        ltime.tm_year = year - 1900;
114
 
        secs = mktime(&ltime);
115
 
        setUTC1970(secs, nsec);
116
 
}
117
 
 
118
 
void CSTime::getLocal(s_int& year, s_int& mon, s_int& day, s_int& hour, s_int& min, s_int& sec, s_int& nsec)
119
 
{
120
 
        struct tm       ltime;
121
 
        time_t          secs;
122
 
 
123
 
        memset(&ltime, 0, sizeof(ltime));
124
 
        
125
 
        getUTC1970(secs, nsec);
126
 
        localtime_r(&secs, &ltime);
127
 
        sec = ltime.tm_sec;
128
 
        min = ltime.tm_min;
129
 
        hour = ltime.tm_hour;
130
 
        day = ltime.tm_mday;
131
 
        mon = ltime.tm_mon + 1;
132
 
        year = ltime.tm_year + 1900;
133
 
}
134
 
 
135
 
void CSTime::setUTC(s_int year, s_int mon, s_int day, s_int hour, s_int min, s_int sec, s_int nsec)
136
 
{
137
 
        iNanoSeconds = nsec;
138
 
        iSeconds = sec;
139
 
        iMinutes = min;
140
 
        iHours = hour;
141
 
        iDay = day;
142
 
        iMonth = mon;
143
 
        iYear = year;
144
 
        iIsNull = false;
145
 
}
146
 
 
147
 
void CSTime::getUTC(s_int& year, s_int& mon, s_int& day, s_int& hour, s_int& min, s_int& sec, s_int& nsec)
148
 
{
149
 
        nsec = iNanoSeconds;
150
 
        sec = iSeconds;
151
 
        min = iMinutes;
152
 
        hour = iHours;
153
 
        day = iDay;
154
 
        mon = iMonth;
155
 
        year = iYear;
156
 
}
157
 
 
158
 
char *CSTime::getCString(const char *format)
159
 
{
160
 
        if (iIsNull)
161
 
                strcpy(iCString, "NULL");
162
 
        else {
163
 
                struct tm       ltime;
164
 
                time_t          secs;
165
 
                s_int           nsec;
166
 
 
167
 
                memset(&ltime, 0, sizeof(ltime));
168
 
        
169
 
                getUTC1970(secs, nsec);
170
 
                localtime_r(&secs, &ltime);
171
 
                strftime(iCString, 100, format, &ltime);
172
 
        }
173
 
        return iCString;
174
 
}
175
 
 
176
 
char *CSTime::getCString()
177
 
{
178
 
        return getCString("%Y-%m-%d %H:%M:%S");
179
 
}
180
 
 
181
 
void CSTime::setUTC1970(time_t sec, s_int nsec)
182
 
{
183
 
        struct tm       ltime;
184
 
 
185
 
        memset(&ltime, 0, sizeof(ltime));
186
 
 
187
 
        gmtime_r(&sec, &ltime);
188
 
        setUTC(ltime.tm_year + 1900, ltime.tm_mon + 1, ltime.tm_mday, ltime.tm_hour, ltime.tm_min, ltime.tm_sec, nsec);
189
 
}
190
 
 
191
 
bool CSTime::olderThen(time_t max_age)
192
 
{
193
 
        time_t secs, now;
194
 
        s_int nsec;
195
 
        
196
 
        getUTC1970(secs, nsec);
197
 
        
198
 
        now = time(NULL);
199
 
        
200
 
        return ((now - secs) > max_age);
201
 
}
202
 
 
203
 
void CSTime::getUTC1970(time_t& sec, s_int& nsec)
204
 
{
205
 
#ifdef OS_WINDOWS
206
 
        uint64_t nsec100;
207
 
 
208
 
        /* Get the number of seconds since 1 Jan 1970 */
209
 
        nsec100 = getUTC1601();
210
 
        nsec100 = nsec100 - get1970as1601();
211
 
        sec = (time_t) (nsec100 / 10000000);
212
 
#else
213
 
        struct tm       ltime;
214
 
 
215
 
        memset(&ltime, 0, sizeof(ltime));
216
 
 
217
 
        ltime.tm_sec = iSeconds;
218
 
        ltime.tm_min = iMinutes;
219
 
        ltime.tm_hour = iHours;
220
 
        ltime.tm_mday = iDay;
221
 
        ltime.tm_mon = iMonth - 1;
222
 
        ltime.tm_year = iYear - 1900;
223
 
        sec = my_timegm(&ltime);
224
 
#endif
225
 
        nsec = iNanoSeconds;
226
 
}
227
 
 
228
 
#ifdef OS_WINDOWS
229
 
 
230
 
void CSTime::setUTC1601(uint64_t nsec100)
231
 
{
232
 
        FILETIME                ftime;
233
 
        SYSTEMTIME              stime;
234
 
 
235
 
        /* The input is actually a FILETIME value: */
236
 
        memcpy(&ftime, &nsec100, sizeof(ftime));
237
 
 
238
 
        if (!FileTimeToSystemTime(&ftime, &stime))
239
 
                CSException::throwLastError(CS_CONTEXT);
240
 
        setUTC((s_int) stime.wYear, (s_int) stime.wMonth, (s_int) stime.wDay,
241
 
                (s_int) stime.wHour, (s_int) stime.wMinute, (s_int) stime.wSecond, (s_int) stime.wMilliseconds * 1000);
242
 
}
243
 
 
244
 
uint64_t CSTime::getUTC1601()
245
 
{
246
 
        FILETIME        ftime;
247
 
        SYSTEMTIME      stime;
248
 
        uint64_t                nsec100;
249
 
 
250
 
        stime.wYear = iYear;
251
 
        stime.wMonth = iMonth;
252
 
        stime.wDay = iDay;
253
 
        stime.wHour = iHours;
254
 
        stime.wMinute = iMinutes;
255
 
        stime.wSecond = iSeconds;
256
 
        stime.wMilliseconds = iNanoSeconds / 1000;
257
 
        if (!SystemTimeToFileTime(&stime, &ftime))
258
 
                CSException::throwLastError(CS_CONTEXT);
259
 
        memcpy(&nsec100, &ftime, sizeof(nsec100));
260
 
        return nsec100;
261
 
}
262
 
 
263
 
uint64_t CSTime::get1970as1601()
264
 
{
265
 
        FILETIME        ftime;
266
 
        SYSTEMTIME      stime;
267
 
        uint64_t                nsec100;
268
 
 
269
 
        stime.wYear = 1970;
270
 
        stime.wMonth = 1;
271
 
        stime.wDay = 1;
272
 
        stime.wHour = 0;
273
 
        stime.wMinute = 0;
274
 
        stime.wSecond = 0;
275
 
        stime.wMilliseconds = 0;
276
 
        if (!SystemTimeToFileTime(&stime, &ftime))
277
 
                CSException::throwLastError(CS_CONTEXT);
278
 
        memcpy(&nsec100, &ftime, sizeof(nsec100));
279
 
        return nsec100;
280
 
}
281
 
 
282
 
#endif
283
 
 
284
 
uint64_t CSTime::getTimeCurrentTicks()
285
 
{
286
 
        struct timeval  now;
287
 
 
288
 
        /* Get the current time in microseconds: */
289
 
        gettimeofday(&now, NULL);
290
 
        return (uint64_t) now.tv_sec * (uint64_t) 1000000 + (uint64_t) now.tv_usec;
291
 
}
292
 
 
293
 
 
294