GCC Code Coverage Report


Directory: src/gate/
File: src/gate/times.c
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 335 362 92.5%
Functions: 28 28 100.0%
Branches: 152 220 69.1%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 #include "gate/times.h"
30 #include "gate/debugging.h"
31 #include "gate/results.h"
32 #include "gate/strings.h"
33
34 #if defined(GATE_SYS_WIN16)
35 # define GATE_CORE_TIMES_C_IMPL 1
36 #elif defined(GATE_SYS_WIN)
37 # define GATE_CORE_TIMES_WINAPI_IMPL 1
38 #elif defined(GATE_SYS_BEOS)
39 # define GATE_CORE_TIMES_BEOS_IMPL 1
40 #elif defined(GATE_SYS_POSIX)
41 # define GATE_CORE_TIMES_POSIX_IMPL 1
42 #elif defined(GATE_SYS_DOS)
43 # define GATE_CORE_TIMES_DOS_IMPL 1
44 #elif defined(GATE_SYS_EFI)
45 # define GATE_CORE_TIMES_EFI_IMPL 1
46 #elif defined(GATE_SYS_WASM)
47 # define GATE_CORE_TIMES_WASM_IMPL 1
48 #else
49 # define GATE_CORE_TIMES_C_IMPL 1
50 #endif
51
52
53 static gate_int64_t const gate_time_microseconds_per_day = 86400000000;
54
55 static gate_int64_t const gate_time_unix_start = 11644473600000000;
56
57
58 30073 static gate_bool_t gate_time_is_leap_year(gate_uint16_t year)
59 {
60
2/2
✓ Branch 0 taken 61 times.
✓ Branch 1 taken 30012 times.
30073 if (0 == (year % 400)) return true;
61
2/2
✓ Branch 0 taken 219 times.
✓ Branch 1 taken 29793 times.
30012 if (0 == (year % 100)) return false;
62
2/2
✓ Branch 0 taken 7200 times.
✓ Branch 1 taken 22593 times.
29793 if (0 == (year % 4)) return true;
63 22593 return false;
64 }
65 30008 static gate_uint16_t gate_time_get_days_of_year(gate_uint16_t year)
66 {
67
2/2
✓ Branch 1 taken 7261 times.
✓ Branch 2 taken 22747 times.
30008 return gate_time_is_leap_year(year) ? 366 : 365;
68 }
69 496 static gate_uint8_t gate_time_get_days_of_month(gate_uint16_t year, gate_uint8_t month)
70 {
71
3/4
✓ Branch 0 taken 293 times.
✓ Branch 1 taken 138 times.
✓ Branch 2 taken 65 times.
✗ Branch 3 not taken.
496 switch (month)
72 {
73 293 case GATE_DATE_JAN:
74 case GATE_DATE_MAR:
75 case GATE_DATE_MAY:
76 case GATE_DATE_JUL:
77 case GATE_DATE_AUG:
78 case GATE_DATE_OCT:
79 case GATE_DATE_DEC:
80 293 return 31;
81 138 case GATE_DATE_APR:
82 case GATE_DATE_JUN:
83 case GATE_DATE_SEP:
84 case GATE_DATE_NOV:
85 138 return 30;
86 65 case GATE_DATE_FEB:
87
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 65 times.
65 return gate_time_is_leap_year(year) ? 29 : 28;
88 default:
89 return 0;
90 }
91 }
92
93
94 45 gate_result_t gate_time_to_datetime(gate_time_t const* source, gate_datetime_t* dest)
95 {
96 45 gate_int64_t timestamp = source->timestamp + ((gate_int64_t)source->bias) * 60000000;
97 45 gate_int64_t timecounter = 0;
98 45 gate_uint16_t year = 1601;
99 45 gate_uint8_t month = 1;
100 45 gate_uint8_t day = 1;
101 45 gate_uint8_t hour = 0;
102 45 gate_uint8_t minute = 0;
103 45 gate_uint8_t second = 0;
104 45 gate_uint32_t microsecond = 0;
105 gate_int64_t tmp;
106
107
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 15 times.
45 if (timestamp >= gate_time_unix_start)
108 {
109 30 timecounter = gate_time_unix_start;
110 30 year = 1970;
111 }
112
113 for (;;)
114 {
115 /* lenght of current year in microseconds */
116 3855 tmp = gate_time_microseconds_per_day * (gate_int64_t)gate_time_get_days_of_year(year);
117
2/2
✓ Branch 0 taken 3810 times.
✓ Branch 1 taken 45 times.
3855 if (timecounter + tmp <= timestamp)
118 {
119 3810 ++year;
120 3810 timecounter += tmp;
121 }
122 else
123 {
124 45 break;
125 }
126 }
127 /* year is fixed */
128 45 for (month = 1; ;)
129 {
130 263 tmp = gate_time_microseconds_per_day * (gate_int64_t)gate_time_get_days_of_month(year, month);
131
2/2
✓ Branch 0 taken 218 times.
✓ Branch 1 taken 45 times.
263 if (timecounter + tmp <= timestamp)
132 {
133 218 ++month;
134 218 timecounter += tmp;
135 }
136 else
137 {
138 45 break;
139 }
140 }
141
1/2
✓ Branch 0 taken 467 times.
✗ Branch 1 not taken.
467 for (day = 1; day < 32;)
142 {
143
2/2
✓ Branch 0 taken 422 times.
✓ Branch 1 taken 45 times.
467 if (timecounter + gate_time_microseconds_per_day <= timestamp)
144 {
145 422 ++day;
146 422 timecounter += gate_time_microseconds_per_day;
147 }
148 else
149 {
150 45 break;
151 }
152 }
153
154 45 timecounter = timestamp - timecounter;
155
156 45 hour = (gate_uint8_t)(timecounter / 3600000000);
157 45 tmp = timecounter % 3600000000;
158 45 minute = (gate_uint8_t)(tmp / 60000000);
159 45 tmp = tmp % 60000000;
160 45 second = (gate_uint8_t)(tmp / 1000000);
161 45 microsecond = (gate_uint32_t)(tmp % 1000000);
162
163 45 dest->date.year = year;
164 45 dest->date.month = month;
165 45 dest->date.day = day;
166 45 dest->time.hour = hour;
167 45 dest->time.minute = minute;
168 45 dest->time.second = second;
169 45 dest->time.microsecond = microsecond;
170
171 45 return GATE_RESULT_OK;
172 }
173
174
175 static gate_uint64_t const SECONDS_PER_DAY = 86400;
176 static gate_uint64_t const SECONDS_PER_HOUR = 3600;
177 static gate_uint64_t const SECONDS_PER_MINUTE = 60;
178
179
180 87 gate_result_t gate_date_to_time(gate_datetime_t const* source, gate_time_t* dest)
181 {
182 gate_result_t ret;
183 gate_uint16_t year;
184 gate_uint8_t month;
185 gate_int64_t daycounter;
186 gate_uint64_t seconds;
187
188 do
189 {
190
6/10
✓ Branch 0 taken 85 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 85 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 85 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 85 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 85 times.
87 if ((source->date.year < 1601) || (source->date.month < 1) || (source->date.month > 12) || (source->date.day < 1) || (source->date.day > 31)
191 )
192 {
193 2 ret = GATE_RESULT_INVALIDARG;
194 2 break;
195 }
196 85 daycounter = 0;
197
2/2
✓ Branch 0 taken 26153 times.
✓ Branch 1 taken 85 times.
26238 for (year = 1601; year < source->date.year; ++year)
198 {
199 26153 daycounter += gate_time_get_days_of_year(year);
200 }
201
2/2
✓ Branch 0 taken 206 times.
✓ Branch 1 taken 85 times.
291 for (month = 1; month < source->date.month; ++month)
202 {
203 206 daycounter += gate_time_get_days_of_month(source->date.year, month);
204 }
205 85 daycounter += (source->date.day - 1);
206
207 170 seconds = (gate_uint64_t)daycounter * SECONDS_PER_DAY
208 85 + (gate_uint64_t)source->time.hour * SECONDS_PER_HOUR
209 85 + (gate_uint64_t)source->time.minute * SECONDS_PER_MINUTE
210 85 + (gate_uint64_t)source->time.second;
211
212 85 dest->bias = 0;
213 dest->timestamp
214 170 = seconds * ((gate_uint64_t)1000000)
215 85 + source->time.microsecond;
216 ;
217 85 ret = GATE_RESULT_OK;
218 } while (0);
219
220 87 return ret;
221 }
222
223 typedef struct month_mapping_class
224 {
225 unsigned month;
226 unsigned name_len;
227 char const* name;
228 } month_mapping_t;
229
230 static month_mapping_t short_months[] = {
231 { GATE_DATE_JAN, 3, "Jan" },
232 { GATE_DATE_FEB, 3, "Feb" },
233 { GATE_DATE_MAR, 3, "Mar" },
234 { GATE_DATE_APR, 3, "Apr" },
235 { GATE_DATE_MAY, 3, "May" },
236 { GATE_DATE_JUN, 3, "Jun" },
237 { GATE_DATE_JUL, 3, "Jul" },
238 { GATE_DATE_AUG, 3, "Aug" },
239 { GATE_DATE_SEP, 3, "Sep" },
240 { GATE_DATE_OCT, 3, "Oct" },
241 { GATE_DATE_NOV, 3, "Nov" },
242 { GATE_DATE_DEC, 3, "Dec" }
243 };
244
245 static month_mapping_t long_months[] = {
246 { GATE_DATE_JAN, 7, "January" },
247 { GATE_DATE_FEB, 8, "February" },
248 { GATE_DATE_MAR, 5, "March" },
249 { GATE_DATE_APR, 5, "April" },
250 { GATE_DATE_MAY, 3, "May" },
251 { GATE_DATE_JUN, 4, "June" },
252 { GATE_DATE_JUL, 4, "July" },
253 { GATE_DATE_AUG, 6, "August" },
254 { GATE_DATE_SEP, 9, "September" },
255 { GATE_DATE_OCT, 7, "October" },
256 { GATE_DATE_NOV, 8, "November" },
257 { GATE_DATE_DEC, 8, "December" }
258 };
259
260 2 gate_size_t gate_time_print_month(char* dest, gate_size_t destlength, gate_uint8_t month, gate_bool_t shortname)
261 {
262
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (shortname)
263 {
264
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 if ((month >= 1) && (month <= 12))
265 {
266 1 return gate_str_print_text(dest, destlength, short_months[month - 1].name, short_months[month - 1].name_len);
267 }
268 }
269 else
270 {
271
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 if ((month >= 1) && (month <= 12))
272 {
273 1 return gate_str_print_text(dest, destlength, long_months[month - 1].name, long_months[month - 1].name_len);
274 }
275 }
276 return 0;
277 }
278
279 36 gate_size_t gate_date_parse_month(char const* source, gate_size_t sourcelen, gate_uint8_t* mon)
280 {
281 unsigned n;
282
1/2
✓ Branch 0 taken 165 times.
✗ Branch 1 not taken.
165 for (n = 0; n < 12; ++n)
283 {
284
2/2
✓ Branch 1 taken 129 times.
✓ Branch 2 taken 36 times.
165 if ((0 == gate_str_compare(short_months[n].name, short_months[n].name_len, source, sourcelen))
285
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 129 times.
129 || (0 == gate_str_compare(long_months[n].name, long_months[n].name_len, source, sourcelen))
286 )
287 {
288 36 *mon = (gate_uint8_t)(n + 1);
289 36 return sourcelen;
290 }
291 }
292 return 0;
293 }
294
295
296 13 gate_size_t gate_time_print_bias(char* dest, gate_size_t destlength, gate_int16_t bias)
297 {
298 13 gate_size_t ret = 0;
299 gate_bool_t neg;
300 gate_uint8_t hour;
301 gate_uint8_t minute;
302 /*+hh:mm*/
303
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 12 times.
13 if (destlength < 6)
304 {
305 1 ret = 0;
306 }
307 else
308 {
309
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (bias < 0)
310 {
311 neg = true;
312 bias = -bias;
313 }
314 else
315 {
316 12 neg = false;
317 }
318
319 12 hour = (gate_uint8_t)(bias / 60);
320 12 minute = (gate_uint8_t)(bias % 60);
321
322
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 dest[0] = neg ? '-' : '+';
323 12 gate_str_print_uint(&dest[1], 2, hour, 2);
324 12 dest[3] = ':';
325 12 gate_str_print_uint(&dest[4], 2, minute, 2);
326
327 12 ret = 6;
328 }
329
330 13 return ret;
331 }
332
333 static gate_string8_t const gate_time_token_year4 = { "{YYYY}", 6, NULL };
334 static gate_string8_t const gate_time_token_year2 = { "{YY}" , 4 };
335 static gate_string8_t const gate_time_token_month2 = { "{MM}" , 4 };
336 static gate_string8_t const gate_time_token_month1 = { "{M}" , 3 };
337 static gate_string8_t const gate_time_token_monthname = { "{MNA}" , 5 };
338 static gate_string8_t const gate_time_token_monthnameshort = { "{MN}" , 4 };
339 static gate_string8_t const gate_time_token_day2 = { "{DD}" , 4 };
340 static gate_string8_t const gate_time_token_day1 = { "{D}" , 3 };
341 static gate_string8_t const gate_time_token_hour2 = { "{hh}" , 4 };
342 static gate_string8_t const gate_time_token_hour1 = { "{h}" , 3 };
343 static gate_string8_t const gate_time_token_hour2_12 = { "{kk}" , 4 };
344 static gate_string8_t const gate_time_token_hour1_12 = { "{k}" , 3 };
345 static gate_string8_t const gate_time_token_ampm = { "{ampm}" , 6 };
346 static gate_string8_t const gate_time_token_minute2 = { "{mm}" , 4 };
347 static gate_string8_t const gate_time_token_minute1 = { "{m}" , 3 };
348 static gate_string8_t const gate_time_token_second2 = { "{ss}" , 4 };
349 static gate_string8_t const gate_time_token_second1 = { "{s}" , 3 };
350 static gate_string8_t const gate_time_token_fraction1 = { "{S}" , 3 };
351 static gate_string8_t const gate_time_token_fraction2 = { "{SS}" , 4 };
352 static gate_string8_t const gate_time_token_fraction3 = { "{SSS}" , 5 };
353 static gate_string8_t const gate_time_token_fraction4 = { "{SSSS}" , 6 };
354 static gate_string8_t const gate_time_token_fraction5 = { "{SSSSS}" , 7 };
355 static gate_string8_t const gate_time_token_fraction6 = { "{SSSSSS}" , 8 };
356 static gate_string8_t const gate_time_token_bias = { "{bias}" , 6 };
357
358 20 gate_result_t gate_date_to_string(gate_datetime_t const* date, gate_int16_t bias_minutes, char const* format, char* dest, gate_size_t* destsize)
359 {
360 static char const* const formatISO1801 = "{YYYY}-{MM}-{DD}T{hh}:{mm}:{ss}.{SSS}{bias}";
361 gate_string_t token;
362
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 gate_size_t destlength = destsize ? *destsize : 0;
363 20 gate_size_t tmptokenlen = 0;
364 20 gate_size_t used = 0;
365 20 gate_size_t lenprinted = 0;
366
367
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 8 times.
20 if (format == NULL)
368 {
369 12 format = formatISO1801;
370 }
371
372 20 gate_string_create_static(&token, format);
373
374
2/2
✓ Branch 0 taken 268 times.
✓ Branch 1 taken 16 times.
284 while (token.length != 0)
375 {
376
2/2
✓ Branch 1 taken 17 times.
✓ Branch 2 taken 251 times.
268 if (gate_string_starts_with(&token, &gate_time_token_year4))
377 {
378 17 lenprinted = gate_str_print_uint(dest, destlength, date->date.year, 4);
379 17 tmptokenlen = gate_time_token_year4.length;
380 }
381
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 249 times.
251 else if (gate_string_starts_with(&token, &gate_time_token_year2))
382 {
383 2 lenprinted = gate_str_print_uint(dest, destlength, date->date.year, 2);
384 2 tmptokenlen = gate_time_token_year2.length;
385 }
386
2/2
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 234 times.
249 else if (gate_string_starts_with(&token, &gate_time_token_month2))
387 {
388 15 lenprinted = gate_str_print_uint(dest, destlength, date->date.month, 2);
389 15 tmptokenlen = gate_time_token_month2.length;
390 }
391
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 232 times.
234 else if (gate_string_starts_with(&token, &gate_time_token_month1))
392 {
393 2 lenprinted = gate_str_print_uint16(dest, destlength, date->date.month);
394 2 tmptokenlen = gate_time_token_month1.length;
395 }
396
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 231 times.
232 else if (gate_string_starts_with(&token, &gate_time_token_monthname))
397 {
398 1 lenprinted = gate_time_print_month(dest, destlength, date->date.month, false);
399 1 tmptokenlen = gate_time_token_monthname.length;
400 }
401
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 230 times.
231 else if (gate_string_starts_with(&token, &gate_time_token_monthnameshort))
402 {
403 1 lenprinted = gate_time_print_month(dest, destlength, date->date.month, true);
404 1 tmptokenlen = gate_time_token_monthnameshort.length;
405 }
406
2/2
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 214 times.
230 else if (gate_string_starts_with(&token, &gate_time_token_day2))
407 {
408 16 lenprinted = gate_str_print_uint(dest, destlength, date->date.day, 2);
409 16 tmptokenlen = gate_time_token_day2.length;
410 }
411
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 211 times.
214 else if (gate_string_starts_with(&token, &gate_time_token_day1))
412 {
413 3 lenprinted = gate_str_print_uint16(dest, destlength, date->date.day);
414 3 tmptokenlen = gate_time_token_day1.length;
415 }
416
2/2
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 196 times.
211 else if (gate_string_starts_with(&token, &gate_time_token_hour2))
417 {
418 15 lenprinted = gate_str_print_uint(dest, destlength, date->time.hour, 2);
419 15 tmptokenlen = gate_time_token_hour2.length;
420 }
421
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 194 times.
196 else if (gate_string_starts_with(&token, &gate_time_token_hour1))
422 {
423 2 lenprinted = gate_str_print_uint16(dest, destlength, date->time.hour);
424 2 tmptokenlen = gate_time_token_hour1.length;
425 }
426
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 193 times.
194 else if (gate_string_starts_with(&token, &gate_time_token_hour2_12))
427 {
428
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 lenprinted = gate_str_print_uint(dest, destlength, date->time.hour > 12 ? date->time.hour - 12 : date->time.hour, 2);
429 1 tmptokenlen = gate_time_token_hour2_12.length;
430 }
431
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 192 times.
193 else if (gate_string_starts_with(&token, &gate_time_token_hour1_12))
432 {
433
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 lenprinted = gate_str_print_uint16(dest, destlength, (gate_uint16_t)((date->time.hour > 12) ? (date->time.hour - 12) : date->time.hour));
434 1 tmptokenlen = gate_time_token_hour1_12.length;
435 }
436
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 190 times.
192 else if (gate_string_starts_with(&token, &gate_time_token_ampm))
437 {
438
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (date->time.hour > 12)
439 {
440 lenprinted = gate_str_print_text(dest, destlength, "pm", 2);
441 }
442 else
443 {
444 2 lenprinted = gate_str_print_text(dest, destlength, "am", 2);
445 }
446 2 tmptokenlen = gate_time_token_ampm.length;
447 }
448
2/2
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 174 times.
190 else if (gate_string_starts_with(&token, &gate_time_token_minute2))
449 {
450 16 lenprinted = gate_str_print_uint(dest, destlength, date->time.minute, 2);
451 16 tmptokenlen = gate_time_token_minute2.length;
452 }
453
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 171 times.
174 else if (gate_string_starts_with(&token, &gate_time_token_minute1))
454 {
455 3 lenprinted = gate_str_print_uint16(dest, destlength, date->time.minute);
456 3 tmptokenlen = gate_time_token_minute1.length;
457 }
458
2/2
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 155 times.
171 else if (gate_string_starts_with(&token, &gate_time_token_second2))
459 {
460 16 lenprinted = gate_str_print_uint(dest, destlength, date->time.second, 2);
461 16 tmptokenlen = gate_time_token_second2.length;
462 }
463
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 152 times.
155 else if (gate_string_starts_with(&token, &gate_time_token_second1))
464 {
465 3 lenprinted = gate_str_print_uint16(dest, destlength, date->time.second);
466 3 tmptokenlen = gate_time_token_second1.length;
467 }
468
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 150 times.
152 else if (gate_string_starts_with(&token, &gate_time_token_fraction1))
469 {
470 2 lenprinted = gate_str_print_uint(dest, destlength, date->time.microsecond / 100000, 1);
471 2 tmptokenlen = gate_time_token_fraction1.length;
472 }
473
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 149 times.
150 else if (gate_string_starts_with(&token, &gate_time_token_fraction2))
474 {
475 1 lenprinted = gate_str_print_uint(dest, destlength, date->time.microsecond / 10000, 2);
476 1 tmptokenlen = gate_time_token_fraction2.length;
477 }
478
2/2
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 136 times.
149 else if (gate_string_starts_with(&token, &gate_time_token_fraction3))
479 {
480 13 lenprinted = gate_str_print_uint(dest, destlength, date->time.microsecond / 1000, 3);
481 13 tmptokenlen = gate_time_token_fraction3.length;
482 }
483
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 135 times.
136 else if (gate_string_starts_with(&token, &gate_time_token_fraction4))
484 {
485 1 lenprinted = gate_str_print_uint(dest, destlength, date->time.microsecond / 100, 4);
486 1 tmptokenlen = gate_time_token_fraction4.length;
487 }
488
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 134 times.
135 else if (gate_string_starts_with(&token, &gate_time_token_fraction5))
489 {
490 1 lenprinted = gate_str_print_uint(dest, destlength, date->time.microsecond / 10, 5);
491 1 tmptokenlen = gate_time_token_fraction5.length;
492 }
493
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 133 times.
134 else if (gate_string_starts_with(&token, &gate_time_token_fraction6))
494 {
495 1 lenprinted = gate_str_print_uint(dest, destlength, date->time.microsecond, 6);
496 1 tmptokenlen = gate_time_token_fraction6.length;
497 }
498
2/2
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 120 times.
133 else if (gate_string_starts_with(&token, &gate_time_token_bias))
499 {
500 13 lenprinted = gate_time_print_bias(dest, destlength, bias_minutes);
501 13 tmptokenlen = gate_time_token_bias.length;
502 }
503 else
504 {
505
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 1 times.
120 if (destlength != 0)
506 {
507 119 *dest = *token.str;
508 119 lenprinted = 1;
509 119 tmptokenlen = 1;
510 }
511 else
512 {
513 1 lenprinted = 0;
514 }
515 }
516
517
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 264 times.
268 if (lenprinted == 0)
518 {
519 4 break;
520 }
521 264 token.str += tmptokenlen;
522 264 token.length -= tmptokenlen;
523 264 used += lenprinted;
524 264 dest += lenprinted;
525 264 destlength -= lenprinted;
526 };
527
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 2 times.
20 if (destlength != 0)
528 {
529 18 *dest = '\0';
530 }
531
532
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 if (destsize)
533 {
534 20 *destsize = used;
535 }
536 20 return GATE_RESULT_OK;
537
538 }
539
540 11 gate_result_t gate_time_to_string(gate_time_t const* source, char const* format, char* dest, gate_size_t* destsize)
541 {
542 gate_result_t result;
543 gate_datetime_t date;
544 11 result = gate_time_to_datetime(source, &date);
545
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if (GATE_SUCCEEDED(result))
546 {
547 11 result = gate_date_to_string(&date, source->bias, format, dest, destsize);
548 }
549 11 return result;
550 }
551
552 15 static gate_bool_t get_time_u8(char const* text, gate_size_t len, gate_uint8_t* ptr)
553 {
554 gate_uint64_t tmp;
555
1/2
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
15 if (len == gate_str_parse_uint64(text, len, &tmp))
556 {
557 15 *ptr = (gate_uint8_t)tmp;
558 15 return true;
559 }
560 else
561 {
562 return false;
563 }
564 }
565 3 static gate_bool_t get_time_u16(char const* text, gate_size_t len, gate_uint16_t* ptr)
566 {
567 gate_uint64_t tmp;
568
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 if (len == gate_str_parse_uint64(text, len, &tmp))
569 {
570 3 *ptr = (gate_uint16_t)tmp;
571 3 return true;
572 }
573 else
574 {
575 return false;
576 }
577 }
578
579 11 gate_size_t gate_date_parse_string(char const* source, gate_size_t sourcelen, gate_datetime_t* dest, gate_int16_t* bias)
580 {
581 11 gate_size_t ret = 0;
582 gate_uint8_t tmp;
583 char const* ptr;
584 gate_size_t ptrlen;
585 11 gate_uint32_t microsec_factor = 100000;
586 11 gate_int16_t local_bias = 0;
587
588 /*YYYY-MM-DDThh:mm:ss.iii+HH:MM */
589 do
590 {
591 11 gate_mem_clear(dest, sizeof(gate_datetime_t));
592
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 3 times.
11 if (sourcelen < 10) break;
593
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 if ((source[4] != '-') || (source[7] != '-')) break;
594
595
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (!get_time_u16(&source[0], 4, &dest->date.year)) break;
596
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (!get_time_u8(&source[5], 2, &dest->date.month)) break;
597
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (!get_time_u8(&source[8], 2, &dest->date.day)) break;
598 3 ret = 10;
599
600
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (sourcelen < 13) break;
601
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
3 if ((source[10] != ' ') && (source[10] != 'T')) break;
602
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (!get_time_u8(&source[11], 2, &dest->time.hour)) break;
603 3 ret = 13;
604
605
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (sourcelen < 16) break;
606
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (source[13] != ':') break;
607
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (!get_time_u8(&source[14], 2, &dest->time.minute)) break;
608 3 ret = 16;
609
610
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (sourcelen < 19) break;
611
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (source[16] != ':') break;
612
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (!get_time_u8(&source[17], 2, &dest->time.second)) break;
613 3 ret = 19;
614
615
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (sourcelen > 19)
616 {
617 3 ptr = &source[19];
618 3 ptrlen = sourcelen - 19;
619
620
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (*ptr == '.')
621 {
622 3 ++ret;
623 3 --ptrlen;
624
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 while ((ptrlen != 0) && (microsec_factor > 0))
625 {
626
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 if (!gate_char_is_digit(*ptr)) break;
627 dest->time.microsecond += (gate_uint32_t)(*ptr - '0') * microsec_factor;
628 microsec_factor /= 10;
629 ++ptr;
630 --ptrlen;
631 ++ret;
632 }
633 }
634
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (ptrlen >= 3)
635 {
636
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
3 if ((ptr[0] == '+') || (ptr[0] == '-'))
637 {
638 if (!get_time_u8(&ptr[1], 2, &tmp)) break;
639 local_bias = (gate_int16_t)tmp * 60;
640 ret += 3;
641
642 if ((ptrlen >= 6) && (ptr[3] == ':'))
643 {
644 if (get_time_u8(&ptr[4], 2, &tmp))
645 {
646 local_bias += (gate_int16_t)tmp;
647 ret += 3;
648 }
649 }
650 if (ptr[0] == '-')
651 {
652 local_bias *= -1;
653 }
654 }
655 }
656 }
657
658 } while (0);
659
660
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if (bias)
661 {
662 11 *bias = local_bias;
663 }
664
665 11 return ret;
666 }
667
668 3 gate_day_id_t gate_date_to_day_id(gate_date_t const* date)
669 {
670 gate_datetime_t dt;
671 gate_time_t tm;
672 gate_result_t res;
673
674 3 dt.date = *date;
675 3 gate_mem_clear(&dt.time, sizeof(dt.time));
676 3 res = gate_date_to_time(&dt, &tm);
677
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (GATE_SUCCEEDED(res))
678 {
679 3 return gate_time_to_day_id(tm.timestamp);
680 }
681 else
682 {
683 return 0;
684 }
685 }
686
687 1 gate_result_t gate_date_from_day_id(gate_day_id_t day_id, gate_date_t* date)
688 {
689 gate_result_t ret;
690 1 gate_time_t tm = GATE_INIT_EMPTY;
691 1 gate_datetime_t dt = GATE_INIT_EMPTY;
692 do
693 {
694 1 ret = gate_time_from_day_id(day_id, &tm.timestamp);
695
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_BREAK_IF_FAILED(ret);
696 1 ret = gate_time_to_datetime(&tm, &dt);
697
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_BREAK_IF_FAILED(ret);
698 1 *date = dt.date;
699 } while (0);
700 1 return ret;
701 }
702
703 3 gate_uint8_t gate_date_day_of_week(gate_day_id_t day_id)
704 {
705 3 return (gate_uint8_t)((gate_uint32_t)day_id % 7);
706 }
707
708 3 gate_uint16_t gate_date_day_of_year(gate_date_t const* date)
709 {
710 3 gate_uint16_t ret = 0;
711 gate_uint8_t month;
712
713
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 3 times.
30 for (month = 1; month != date->month; ++month)
714 {
715 27 ret += gate_time_get_days_of_month(date->year, month);
716 }
717 3 ret += date->day;
718
719 3 return ret;
720 }
721
722 2 gate_uint8_t gate_date_week_of_year(gate_date_t const* date, gate_bool_t monday_starts_week)
723 {
724 2 gate_uint8_t ret = 0;
725 2 gate_uint16_t day_of_year = gate_date_day_of_year(date);
726 2 gate_uint8_t day_of_week = gate_date_day_of_week(gate_date_to_day_id(date));
727
728
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (monday_starts_week)
729 {
730 1 ret = (gate_uint8_t)(((day_of_year + 5 - ((day_of_week + 1) % 7)) / 7) + 1);
731 }
732 else
733 {
734 1 ret = (gate_uint8_t)(((day_of_year + 5 - day_of_week + 1) / 7) + 1);
735 }
736 2 return ret;
737 }
738
739 4 gate_day_id_t gate_time_to_day_id(gate_timestamp_t timestamp)
740 {
741 4 gate_int32_t days_since_1601 = (gate_int32_t)(timestamp / gate_time_microseconds_per_day);
742 4 return days_since_1601 + 1;
743 }
744
745 2 gate_result_t gate_time_from_day_id(gate_day_id_t day_id, gate_timestamp_t* dest)
746 {
747
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (day_id <= 0)
748 {
749 return GATE_RESULT_INVALIDARG;
750 }
751 else
752 {
753 2 *dest = (((gate_timestamp_t)(day_id)-1) * gate_time_microseconds_per_day);
754 2 return GATE_RESULT_OK;
755 }
756 }
757
758
759
760 3 gate_result_t gate_time_parse_string(char const* source, gate_size_t sourcelen, gate_time_t* dest)
761 {
762 3 gate_result_t ret = GATE_RESULT_FAILED;
763 3 gate_datetime_t date = GATE_INIT_EMPTY;
764 3 gate_int16_t bias = 0;
765 3 gate_size_t bytes_parsed = gate_date_parse_string(source, sourcelen, &date, &bias);
766
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (bytes_parsed != 0)
767 {
768 3 gate_mem_clear(dest, sizeof(gate_time_t));
769 3 ret = gate_date_to_time(&date, dest);
770 3 dest->bias = bias;
771 }
772 3 return ret;
773 }
774
775 3 gate_result_t gate_time_from_timestamp(gate_timestamp_t source, gate_time_t* dest)
776 {
777 gate_result_t ret;
778 /* should return local BIAS of timestamp, but at the moment
779 we only return the current bias */
780 3 ret = gate_time_now(dest);
781 3 dest->timestamp = source;
782
783 3 return ret;
784 }
785
786 /* 0x00295E9648864000 or ‭11644473600000000‬ == 1970-01-01T00:00 */
787 static gate_int64_t const unix_epoche = 11644473600000000;
788
789 101 gate_result_t gate_time_from_unix(gate_int64_t sourceunixseconds, gate_timestamp_t* dest)
790 {
791 101 gate_result_t ret = GATE_RESULT_OK;
792 101 *dest = unix_epoche + (sourceunixseconds * 1000000);
793 101 return ret;
794 }
795 33 gate_result_t gate_time_to_unix(gate_timestamp_t sourcetime, gate_int64_t* destunixseconds)
796 {
797 33 gate_result_t ret = GATE_RESULT_OK;
798 33 *destunixseconds = (sourcetime - unix_epoche) / 1000000;
799 33 return ret;
800 }
801
802
803 #if defined(GATE_CORE_TIMES_WINAPI_IMPL)
804
805 #include "gate/platforms.h"
806 #include "gate/platform/windows/wince_patches.h"
807
808 gate_result_t gate_timecounter_now(gate_timecounter_t* now)
809 {
810 ULONGLONG tc = gate_win32_get_tick_count();
811 *now = (gate_int64_t)tc * 1000;
812 return GATE_RESULT_OK;
813 }
814 gate_int64_t gate_timecounter_diff(gate_timecounter_t tc1, gate_timecounter_t tc2)
815 {
816 return (tc1 - tc2);
817 }
818
819 gate_timecounter_t gate_timecounter_add(gate_timecounter_t tc, gate_int64_t microseconds)
820 {
821 return tc + microseconds;
822 }
823
824 gate_result_t gate_time_now(gate_time_t* now)
825 {
826 gate_result_t ret = GATE_RESULT_FAILED;
827 FILETIME sft;
828 FILETIME lft;
829 gate_uint64_t global_time;
830 gate_uint64_t local_time;
831 GetSystemTimeAsFileTime(&sft);
832 FileTimeToLocalFileTime(&sft, &lft);
833 global_time = ((((gate_uint64_t)sft.dwHighDateTime) << 32) | (gate_uint64_t)sft.dwLowDateTime) / 10;
834 local_time = ((((gate_uint64_t)lft.dwHighDateTime) << 32) | (gate_uint64_t)lft.dwLowDateTime) / 10;
835
836 now->timestamp = global_time;
837 now->bias = (gate_int32_t)(((gate_int64_t)local_time - (gate_int64_t)global_time) / 60000000);
838 ret = GATE_RESULT_OK;
839 return ret;
840 }
841
842 #endif /* GATE_CORE_TIMES_WINAPI_IMPL */
843
844
845
846 #if defined(GATE_CORE_TIMES_POSIX_IMPL)
847
848 #include <time.h>
849 #include <sys/time.h>
850
851 14 gate_result_t gate_timecounter_now(gate_timecounter_t* now)
852 {
853 struct timespec ts;
854
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 if (0 == clock_gettime(CLOCK_MONOTONIC, &ts))
855 {
856 14 *now = (gate_int64_t)ts.tv_sec * 1000000LL + (gate_int64_t)ts.tv_nsec / 1000;
857 14 return GATE_RESULT_OK;
858 }
859 else
860 {
861 return GATE_RESULT_FAILED;
862 }
863 }
864 20 gate_int64_t gate_timecounter_diff(gate_timecounter_t tc1, gate_timecounter_t tc2)
865 {
866 20 return (tc1 - tc2);
867 }
868 8 gate_timecounter_t gate_timecounter_add(gate_timecounter_t tc, gate_int64_t microseconds)
869 {
870 8 return tc + microseconds;
871 }
872
873 25 gate_result_t gate_time_now(gate_time_t* now)
874 {
875 struct timeval tv;
876 time_t rawtime;
877 time_t loctime;
878 time_t tret;
879 struct tm globtm;
880 struct tm loctm;
881 struct tm* tmp;
882 25 int result = gettimeofday(&tv, NULL);
883
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 if (result == -1)
884 {
885 return GATE_RESULT_FAILED;
886 }
887 25 now->timestamp = gate_time_unix_start + ((gate_int64_t)tv.tv_sec) * 1000000LL + tv.tv_usec;
888 25 now->bias = 0;
889 25 tret = time(&rawtime);
890
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 if (tret != (time_t)-1)
891 {
892 25 tmp = gmtime_r(&rawtime, &globtm);
893
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 if (tmp != NULL)
894 {
895
1/2
✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
25 if (localtime_r(&rawtime, &loctm))
896 {
897 25 globtm.tm_isdst = loctm.tm_isdst;
898 }
899 25 loctime = mktime(&globtm);
900
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 if (loctime != (time_t)-1)
901 {
902 25 now->bias = (rawtime - loctime) / 60;
903 }
904 }
905 }
906
907 25 return GATE_RESULT_OK;
908 }
909
910 #endif /* GATE_CORE_TIMES_POSIX_IMPL */
911
912
913
914 #if defined(GATE_CORE_TIMES_BEOS_IMPL)
915
916 #include <kernel/OS.h>
917
918 gate_result_t gate_timecounter_now(gate_timecounter_t* now)
919 {
920 bigtime_t tc = system_time();
921 *now = (gate_timecounter_t)tc;
922 return GATE_RESULT_OK;
923 }
924 gate_int64_t gate_timecounter_diff(gate_timecounter_t tc1, gate_timecounter_t tc2)
925 {
926 return (tc1 - tc2);
927 }
928 gate_timecounter_t gate_timecounter_add(gate_timecounter_t tc, gate_int64_t microseconds)
929 {
930 return tc + microseconds;
931 }
932
933 gate_result_t gate_time_now(gate_time_t* now)
934 {
935 gate_result_t result;
936 gate_timestamp_t ts;
937 bigtime_t unix_time_us = real_time_clock_usecs();
938 gate_int64_t unix_time_sec = (gate_int64_t)unix_time_us / 1000000;
939 gate_int64_t usec = unix_time_us % 1000000;
940
941 result = gate_time_from_unix(unix_time_sec, &ts);
942 if (GATE_SUCCEEDED(result))
943 {
944 now->bias = 0;
945 now->timestamp += ts + usec;
946 }
947 return result;
948 }
949
950 #endif /* GATE_CORE_TIMES_BEOS_IMPL */
951
952
953
954 #if defined(GATE_CORE_TIMES_DOS_IMPL)
955
956 #include <dos.h>
957 #include <time.h>
958 #include "gate/platforms.h"
959
960 gate_result_t gate_timecounter_now(gate_timecounter_t* now)
961 {
962 gate_uint32_t clock_ms;
963 if (now)
964 {
965 clock_ms = gate_dos_clock_get();
966 *now = (gate_int64_t)clock_ms * 1000;
967 }
968 return GATE_RESULT_OK;
969 }
970
971 gate_int64_t gate_timecounter_diff(gate_timecounter_t tc1, gate_timecounter_t tc2)
972 {
973 return (tc1 - tc2);
974 }
975
976 gate_timecounter_t gate_timecounter_add(gate_timecounter_t tc, gate_int64_t microseconds)
977 {
978 return tc + microseconds;
979 }
980
981
982 gate_result_t gate_time_now(gate_time_t* now)
983 {
984 gate_datetime_t dt;
985 struct dosdate_t dosdate;
986 struct dostime_t dostime;
987
988 _dos_getdate(&dosdate);
989 _dos_gettime(&dostime);
990
991 dt.date.year = dosdate.year + 1980;
992 dt.date.month = dosdate.month;
993 dt.date.day = dosdate.day;
994 dt.time.hour = dostime.hour;
995 dt.time.minute = dostime.minute;
996 dt.time.second = dostime.second;
997 dt.time.microsecond = (gate_uint32_t)dostime.hsecond * 10000;
998
999 return gate_date_to_time(&dt, now);
1000 }
1001
1002 #endif /* GATE_CORE_TIMES_DOS_IMPL */
1003
1004
1005 #if defined(GATE_CORE_TIMES_EFI_IMPL)
1006
1007 #include "gate/platform/efi/efi_gate.h"
1008
1009 gate_result_t gate_timecounter_now(gate_timecounter_t* now)
1010 {
1011 gate_time_t tm_now;
1012 gate_result_t ret = gate_time_now(&tm_now);
1013 if (GATE_SUCCEEDED(ret))
1014 {
1015 if (now)
1016 {
1017 *now = tm_now.timestamp;
1018 }
1019 }
1020 return ret;
1021 }
1022 gate_int64_t gate_timecounter_diff(gate_timecounter_t tc1, gate_timecounter_t tc2)
1023 {
1024 return (tc1 - tc2);
1025 }
1026
1027 gate_timecounter_t gate_timecounter_add(gate_timecounter_t tc, gate_int64_t microseconds)
1028 {
1029 return tc + microseconds;
1030 }
1031
1032 gate_result_t gate_time_now(gate_time_t* now)
1033 {
1034 gate_int64_t ms_since_epoche = 0;
1035 gate_timestamp_t ts = 0;
1036 gate_result_t ret = gate_platform_efi_time_now(&ms_since_epoche);
1037 if (GATE_SUCCEEDED(ret))
1038 {
1039 ret = gate_time_from_unix(ms_since_epoche / 1000, &ts);
1040 if (GATE_SUCCEEDED(ret))
1041 {
1042 if (now)
1043 {
1044 now->timestamp += (ms_since_epoche % 1000) * 1000;
1045 now->timestamp = ts;
1046 now->bias = 0;
1047 }
1048 }
1049 }
1050 return ret;
1051 }
1052
1053 #endif /* GATE_CORE_TIMES_EFI_IMPL */
1054
1055
1056
1057 #if defined(GATE_CORE_TIMES_WASM_IMPL)
1058
1059 #include "gate/platform/wasm/wasm_gate.h"
1060 #include <emscripten/html5.h>
1061
1062 gate_result_t gate_timecounter_now(gate_timecounter_t* now)
1063 {
1064 double us = (emscripten_performance_now() * 1000.0);
1065 if (now)
1066 {
1067 *now = (gate_timecounter_t)(gate_int64_t)us;
1068 }
1069 return GATE_RESULT_OK;
1070 }
1071 gate_int64_t gate_timecounter_diff(gate_timecounter_t tc1, gate_timecounter_t tc2)
1072 {
1073 return (tc1 - tc2);
1074 }
1075
1076 gate_timecounter_t gate_timecounter_add(gate_timecounter_t tc, gate_int64_t microseconds)
1077 {
1078 return tc + microseconds;
1079 }
1080
1081 gate_result_t gate_time_now(gate_time_t* now)
1082 {
1083 double unix_us = emscripten_date_now() * 1000.0;
1084 gate_timestamp_t ts = (gate_timestamp_t)(gate_time_unix_start + (gate_int64_t)unix_us);
1085 if (now)
1086 {
1087 now->timestamp = ts;
1088 now->bias = 0;
1089 }
1090 return GATE_RESULT_OK;
1091 }
1092
1093 #endif /* GATE_CORE_TIMES_WASM_IMPL */
1094
1095
1096
1097 #if defined(GATE_CORE_TIMES_C_IMPL)
1098
1099 #include <time.h>
1100
1101 gate_result_t gate_timecounter_now(gate_timecounter_t* now)
1102 {
1103 double micro_seconds = ((double)clock() / (double)CLOCKS_PER_SEC) * 1000000.0;
1104
1105 gate_int64_t us = (gate_int64_t)micro_seconds;
1106 if (now)
1107 {
1108 *now = (gate_timecounter_t)us;
1109 }
1110 return GATE_RESULT_OK;
1111 }
1112 gate_int64_t gate_timecounter_diff(gate_timecounter_t tc1, gate_timecounter_t tc2)
1113 {
1114 return (tc1 - tc2);
1115 }
1116
1117 gate_timecounter_t gate_timecounter_add(gate_timecounter_t tc, gate_int64_t microseconds)
1118 {
1119 return tc + microseconds;
1120 }
1121
1122 gate_result_t gate_time_now(gate_time_t* now)
1123 {
1124 gate_int64_t t = (gate_int64_t)time(NULL) * 1000000LL;
1125
1126 gate_timestamp_t ts = (gate_timestamp_t)(gate_time_unix_start + t);
1127 if (now)
1128 {
1129 now->timestamp = ts;
1130 now->bias = 0;
1131 }
1132 return GATE_RESULT_OK;
1133 }
1134
1135 #endif /* GATE_CORE_TIMES_C_IMPL */
1136