enum KEKSErr
KEKSTAI64ToTimespec(struct timespec *ts, const unsigned char *buf, const size_t len)
{
- if (len > 12) {
+ switch (len) {
+ case 8:
+ case 12:
+ break;
+ case 16:
+ default:
return KEKSErrTAI64BadAsec;
}
- int64_t v = (int64_t)keksFromBE(buf, 8);
+ assert(buf != NULL);
+ int64_t v = 0;
+ {
+ uint64_t uv = keksFromBE(buf, 8);
+ if (((uint64_t)1 << ((sizeof(time_t) * 8) - 1)) < uv) {
+ return KEKSErrTAI64TooBig;
+ }
+ v = (int64_t)uv;
+ }
v -= 0x4000000000000000;
if (v <= 0) {
return KEKSErrTAI64InPast;
}
- if (((uint64_t)1 << ((sizeof(time_t) * 8) - 1)) < (uint64_t)v) {
- return KEKSErrTAI64TooBig;
- }
+ assert(ts != NULL);
ts->tv_sec = (time_t)v;
if (len > 8) {
uint32_t n = (uint32_t)keksFromBE(buf + 8, 4);
+ if (n >= 1000000000) {
+ return KEKSErrTAI64BadNsec;
+ }
ts->tv_nsec = n;
}
return KEKSErrNo;
enum KEKSErr
KEKSTimespecToUTC(struct timespec *ts)
{
- int64_t v = (int64_t)(ts->tv_sec);
+ assert(ts != NULL);
+ if (ts->tv_sec < 0) {
+ return KEKSErrTAI64InPast;
+ }
+ uint64_t v = (uint64_t)(ts->tv_sec);
enum KEKSErr err = KEKSErrNo;
{
- int64_t diff = 10;
- for (int64_t i = 0; i < KEKSLeapsecsN; i++) {
+ uint64_t diff = 10;
+ for (size_t i = 0; i < KEKSLeapsecsN; i++) {
if (v < KEKSLeapsecs[i]) {
break;
}
break;
}
}
+ if (diff > v) {
+ return KEKSErrTAI64InPast;
+ }
v -= diff;
}
- if (v <= 0) {
- return KEKSErrTAI64InPast;
- }
ts->tv_sec = (time_t)v;
return err;
}
assert(buf != NULL);
keksToBE(buf, 8, val);
if (ts->tv_nsec != 0) {
+ if (ts->tv_nsec >= 1000000000) {
+ return false;
+ }
keksToBE(buf + 8, 4, (uint64_t)(ts->tv_nsec));
}
return true;
bool
KEKSTimespecToTAI(struct timespec *ts)
{
- int64_t v = 10 + (int64_t)(ts->tv_sec);
- for (int64_t i = 0; i < KEKSLeapsecsN; i++) {
+ assert(ts != NULL);
+ if (ts->tv_sec < 0) {
+ return false;
+ }
+ uint64_t v = 10 + (uint64_t)(ts->tv_sec);
+ for (size_t i = 0; i < KEKSLeapsecsN; i++) {
if (v >= KEKSLeapsecs[i]) {
v++;
}
}
- if (((uint64_t)1 << ((sizeof(time_t) * 8) - 1)) < (uint64_t)v) {
+ if ((v < (uint64_t)(ts->tv_sec)) ||
+ (((uint64_t)1 << ((sizeof(time_t) * 8) - 1)) < v)) {
return false;
}
ts->tv_sec = (time_t)v;
+#include <stddef.h>
#include <stdint.h>
#include "leapsecs.h"
-const int64_t KEKSLeapsecsN = 27;
-const int64_t KEKSLeapsecs[] = {
+const size_t KEKSLeapsecsN = 27;
+const uint64_t KEKSLeapsecs[] = {
78796810, // 1972-07
94694411, // 1973-01
126230412, // 1974-01
#ifndef KEKS_LEAPSECS_H
#define KEKS_LEAPSECS_H
+#include <stddef.h>
#include <stdint.h>
// TEXINFO: KEKSLeapsecs
// second was added. @var{KEKSLeapsecsN} variable holds the length of
// that list.
// @end deftypevar
-extern const int64_t KEKSLeapsecsN;
-extern const int64_t KEKSLeapsecs[];
+extern const size_t KEKSLeapsecsN;
+extern const uint64_t KEKSLeapsecs[];
#endif // KEKS_LEAPSECS_H