GCC Code Coverage Report


Directory: src/gate/
File: src/gate/times.c
Date: 2026-02-03 22:06:38
Exec Total Coverage
Lines: 335 362 92.5%
Functions: 28 28 100.0%
Branches: 153 220 69.5%

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