Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions cel-c/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,31 @@
#include <stdlib.h> // IWYU pragma: keep
#endif

#ifdef _CEL_IS_BIG_ENDIAN
#error _CEL_IS_BIG_ENDIAN cannot be directly set
#endif

#ifdef _CEL_IS_LITTLE_ENDIAN
#error _CEL_IS_LITTLE_ENDIAN cannot be directly set
#endif

#if defined(__BIG_ENDIAN__) || defined(__ARMEB__) || defined(__THUMBEB__) || \
defined(__AARCH64EB__) || defined(_MIPSEB) || defined(__MIPSEB) || \
defined(__MIPSEB__) || \
(defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \
__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
#define _CEL_IS_BIG_ENDIAN 1
#elif defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || \
defined(__THUMBEL__) || defined(__AARCH64EL__) || defined(_MIPSEL) || \
defined(__MIPSEL) || defined(__MIPSEL__) || \
(defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \
defined(_WIN32)
#define _CEL_IS_LITTLE_ENDIAN 1
#else
#error Endian detection needs to be set up for your environment.
#endif

#ifdef CEL_STATIC_ASSERT
#error CEL_STATIC_ASSERT cannot be directly set
#endif
Expand Down
24 changes: 12 additions & 12 deletions cel-c/duration.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,15 @@ extern "C" bool cel_Duration_Normalize(int64_t* cel_nonnull sec,
extern "C" bool cel_Duration_Add(cel_Duration* cel_nonnull out,
cel_Duration lhs, cel_Duration rhs) {
CEL_ASSERT_NOT_NULL(out);
CEL_ASSERT(cel_Duration_Valid(lhs.sec, lhs.nsec));
CEL_ASSERT(cel_Duration_Valid(rhs.sec, rhs.nsec));

int64_t lhs_sec = lhs.sec;
int64_t rhs_sec = rhs.sec;
int64_t lhs_sec;
int64_t rhs_sec;
int64_t sec;
int32_t nsec;
int32_t lhs_nsec = lhs.nsec;
int32_t rhs_nsec = rhs.nsec;
int32_t lhs_nsec;
int32_t rhs_nsec;
cel_Duration_ToUnix(lhs, &lhs_sec, &lhs_nsec);
cel_Duration_ToUnix(rhs, &rhs_sec, &rhs_nsec);

if (CEL_UNLIKELY(_cel_ckd_add(&sec, lhs_sec, rhs_sec))) {
return false;
Expand All @@ -82,15 +82,15 @@ extern "C" bool cel_Duration_Add(cel_Duration* cel_nonnull out,
extern "C" bool cel_Duration_Sub(cel_Duration* cel_nonnull out,
cel_Duration lhs, cel_Duration rhs) {
CEL_ASSERT_NOT_NULL(out);
CEL_ASSERT(cel_Duration_Valid(lhs.sec, lhs.nsec));
CEL_ASSERT(cel_Duration_Valid(rhs.sec, rhs.nsec));

int64_t lhs_sec = lhs.sec;
int64_t rhs_sec = rhs.sec;
int64_t lhs_sec;
int64_t rhs_sec;
int64_t sec;
int32_t nsec;
int32_t lhs_nsec = lhs.nsec;
int32_t rhs_nsec = rhs.nsec;
int32_t lhs_nsec;
int32_t rhs_nsec;
cel_Duration_ToUnix(lhs, &lhs_sec, &lhs_nsec);
cel_Duration_ToUnix(rhs, &rhs_sec, &rhs_nsec);

if (CEL_UNLIKELY(_cel_ckd_sub(&sec, lhs_sec, rhs_sec))) {
return false;
Expand Down
88 changes: 54 additions & 34 deletions cel-c/duration.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,26 +58,50 @@ CEL_BEGIN_DECLS
#define cel_Duration_kMinNanos INT32_C(-999999999)
#define cel_Duration_kMaxNanos INT32_C(999999999)

#define cel_Duration_kZero ((cel_Duration){INT64_C(0), INT32_C(0)})
#define cel_Duration_kMin \
((cel_Duration){cel_Duration_kMinSeconds, cel_Duration_kMinNanos})
#define cel_Duration_kMax \
((cel_Duration){cel_Duration_kMaxSeconds, cel_Duration_kMaxNanos})

#ifdef _MSC_VER
#pragma pack(push, 4)
#ifdef _CEL_IS_BIG_ENDIAN
#define cel_Duration_kZero \
((cel_Duration){{INT32_C(0), UINT32_C{0}}, INT32_C(0)})
#define cel_Duration_kMin \
((cel_Duration){ \
{(int32_t)(uint32_t)(((uint64_t)cel_Duration_kMinSeconds) >> 32), \
((uint32_t)(uint64_t)cel_Duration_kMinSeconds)}, \
cel_Duration_kMinNanos})
#define cel_Duration_kMax \
((cel_Duration){ \
{(int32_t)(uint32_t)(((uint64_t)cel_Duration_kMaxSeconds) >> 32), \
((uint32_t)(uint64_t)cel_Duration_kMaxSeconds)}, \
cel_Duration_kMaxNanos})
#endif
#ifdef _CEL_IS_LITTLE_ENDIAN
#define cel_Duration_kZero \
((cel_Duration){{UINT32_C(0), INT32_C(0)}, INT32_C(0)})
#define cel_Duration_kMin \
((cel_Duration){ \
{((uint32_t)(uint64_t)cel_Duration_kMinSeconds), \
(int32_t)(uint32_t)(((uint64_t)cel_Duration_kMinSeconds) >> 32)}, \
cel_Duration_kMinNanos})
#define cel_Duration_kMax \
((cel_Duration){ \
{((uint32_t)(uint64_t)cel_Duration_kMaxSeconds), \
(int32_t)(uint32_t)(((uint64_t)cel_Duration_kMaxSeconds) >> 32)}, \
cel_Duration_kMaxNanos})
#endif

typedef struct CEL_ATTRIBUTE_PACKED(4) {
// As this structure is packed, do not access these members directly.
int64_t sec;
typedef struct {
// Alter layout based on endianness for consistency.
struct {
#ifdef _CEL_IS_BIG_ENDIAN
int32_t hi;
uint32_t lo;
#endif
#ifdef _CEL_IS_LITTLE_ENDIAN
uint32_t lo;
int32_t hi;
#endif
} sec;
int32_t nsec;
} cel_Duration;

#ifdef _MSC_VER
#pragma pack(pop)
#endif

CEL_STATIC_ASSERT(sizeof(cel_Duration) == 12);
CEL_STATIC_ASSERT(alignof(cel_Duration) == 4);

Expand All @@ -101,7 +125,8 @@ static CEL_INLINE cel_Duration cel_Duration_FromUnix(int64_t sec,
CEL_ASSERT(cel_Duration_Valid(sec, nsec));

cel_Duration d;
d.sec = sec;
d.sec.hi = (int32_t)(uint32_t)(((uint64_t)sec) >> 32);
d.sec.lo = (uint32_t)(uint64_t)sec;
d.nsec = nsec;
return d;
}
Expand All @@ -112,47 +137,42 @@ static CEL_INLINE cel_Duration cel_Duration_FromUnix(int64_t sec,
// in `sec` and `nsec` respectively.
static CEL_INLINE void cel_Duration_ToUnix(cel_Duration d,
int64_t* cel_nonnull sec,
int32_t* cel_nullable nsec) {
CEL_ASSERT(cel_Duration_Valid(d.sec, d.nsec));

*sec = d.sec;
if (nsec != cel_nullptr) {
*nsec = d.nsec;
}
int32_t* cel_nonnull nsec) {
*sec = (int64_t)((((uint64_t)(uint32_t)d.sec.hi) << 32) | d.sec.lo);
*nsec = d.nsec;
CEL_ASSERT(cel_Duration_Valid(*sec, *nsec));
}

// cel_Duration_ToUnixSeconds
//
// Returns the seconds part of the cel_Duration.
CEL_ATTRIBUTE_NODISCARD
static CEL_INLINE int64_t cel_Duration_ToUnixSeconds(cel_Duration d) {
CEL_ASSERT(cel_Duration_Valid(d.sec, d.nsec));
return d.sec;
int64_t sec = (int64_t)((((uint64_t)(uint32_t)d.sec.hi) << 32) | d.sec.lo);
CEL_ASSERT(cel_Duration_Valid(sec, d.nsec));
return sec;
}

// cel_Duration_Equals
//
// Tests the two durations for equality.
CEL_ATTRIBUTE_NODISCARD
static CEL_INLINE bool cel_Duration_Equals(cel_Duration lhs, cel_Duration rhs) {
CEL_ASSERT(cel_Duration_Valid(lhs.sec, lhs.nsec));
CEL_ASSERT(cel_Duration_Valid(rhs.sec, rhs.nsec));

return lhs.sec == rhs.sec && lhs.nsec == rhs.nsec;
return lhs.sec.hi == rhs.sec.hi && lhs.sec.lo == rhs.sec.lo &&
lhs.nsec == rhs.nsec;
}

// cel_Duration_Compare
//
// Compares the two durations.
CEL_ATTRIBUTE_NODISCARD
static CEL_INLINE int cel_Duration_Compare(cel_Duration lhs, cel_Duration rhs) {
CEL_ASSERT(cel_Duration_Valid(lhs.sec, lhs.nsec));
CEL_ASSERT(cel_Duration_Valid(rhs.sec, rhs.nsec));

if (lhs.sec < rhs.sec) {
int64_t lhs_sec = cel_Duration_ToUnixSeconds(lhs);
int64_t rhs_sec = cel_Duration_ToUnixSeconds(rhs);
if (lhs_sec < rhs_sec) {
return -1;
}
if (lhs.sec > rhs.sec) {
if (lhs_sec > rhs_sec) {
return 1;
}
if (lhs.nsec < rhs.nsec) {
Expand Down
17 changes: 0 additions & 17 deletions cel-c/internal/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,6 @@

#include "cel-c/config.h" // IWYU pragma: export

#if defined(__BIG_ENDIAN__) || defined(__ARMEB__) || defined(__THUMBEB__) || \
defined(__AARCH64EB__) || defined(_MIPSEB) || defined(__MIPSEB) || \
defined(__MIPSEB__) || \
(defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \
__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
#define _CEL_IS_BIG_ENDIAN 1
#elif defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || \
defined(__THUMBEL__) || defined(__AARCH64EL__) || defined(_MIPSEL) || \
defined(__MIPSEL) || defined(__MIPSEL__) || \
(defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \
defined(_WIN32)
#define _CEL_IS_LITTLE_ENDIAN 1
#else
#error Endian detection needs to be set up for your environment.
#endif

#if (defined(__clang__) && !defined(_WIN32)) || \
(defined(__CUDACC__) && __CUDACC_VER_MAJOR__ >= 9) || \
(defined(__GNUC__) && !defined(__clang__) && !defined(__CUDACC__)) || \
Expand Down
11 changes: 5 additions & 6 deletions cel-c/internal/timestampconv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "cel-c/arena.h"
#include "cel-c/assert.h"
#include "cel-c/internal/config.h"
#include "cel-c/string_view.h"
#include "cel-c/string_view_absl.h"
Expand All @@ -32,8 +31,10 @@ CEL_ATTRIBUTE_NODISCARD
CEL_ATTRIBUTE_NOTHROW
bool _cel_Timestamp_ToRFC3339(cel_Timestamp ts, cel_StringView* cel_nonnull out,
CEL_NONNULL(cel_Arena*) arena) {
CEL_ASSERT(cel_Timestamp_Valid(ts.sec, ts.nsec));
absl::Time time = absl::FromUnixSeconds(ts.sec) + absl::Nanoseconds(ts.nsec);
int64_t sec;
int32_t nsec;
cel_Timestamp_ToUnix(ts, &sec, &nsec);
absl::Time time = absl::FromUnixSeconds(sec) + absl::Nanoseconds(nsec);
absl::TimeZone utc = absl::UTCTimeZone();

std::string rfc3339 = absl::FormatTime("%Y-%m-%d%ET%H:%M:%E*SZ", time, utc);
Expand Down Expand Up @@ -64,9 +65,7 @@ bool _cel_Timestamp_FromRFC3339(cel_Timestamp* cel_nonnull out,
if (!cel_Timestamp_Valid(seconds, nanos)) {
return false;
}

out->sec = seconds;
out->nsec = nanos;
*out = cel_Timestamp_FromUnix(seconds, nanos);
return true;
}

Expand Down
36 changes: 18 additions & 18 deletions cel-c/timestamp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ extern "C" bool cel_Timestamp_Normalize(int64_t* cel_nonnull sec,
extern "C" bool cel_Timestamp_Add(cel_Timestamp* cel_nonnull out,
cel_Timestamp lhs, cel_Duration rhs) {
CEL_ASSERT_NOT_NULL(out);
CEL_ASSERT(cel_Timestamp_Valid(lhs.sec, lhs.nsec));
CEL_ASSERT(cel_Duration_Valid(rhs.sec, rhs.nsec));

int64_t lhs_sec = lhs.sec;
int64_t rhs_sec = rhs.sec;
int64_t lhs_sec;
int64_t rhs_sec;
int64_t sec;
int32_t nsec;
int32_t lhs_nsec = lhs.nsec;
int32_t rhs_nsec = rhs.nsec;
int32_t lhs_nsec;
int32_t rhs_nsec;
cel_Timestamp_ToUnix(lhs, &lhs_sec, &lhs_nsec);
cel_Duration_ToUnix(rhs, &rhs_sec, &rhs_nsec);

if (CEL_UNLIKELY(_cel_ckd_add(&sec, lhs_sec, rhs_sec))) {
return false;
Expand All @@ -78,15 +78,15 @@ extern "C" bool cel_Timestamp_Add(cel_Timestamp* cel_nonnull out,
extern "C" bool cel_Timestamp_Sub(cel_Timestamp* cel_nonnull out,
cel_Timestamp lhs, cel_Duration rhs) {
CEL_ASSERT_NOT_NULL(out);
CEL_ASSERT(cel_Timestamp_Valid(lhs.sec, lhs.nsec));
CEL_ASSERT(cel_Duration_Valid(rhs.sec, rhs.nsec));

int64_t lhs_sec = lhs.sec;
int64_t rhs_sec = rhs.sec;
int64_t lhs_sec;
int64_t rhs_sec;
int64_t sec;
int32_t nsec;
int32_t lhs_nsec = lhs.nsec;
int32_t rhs_nsec = rhs.nsec;
int32_t lhs_nsec;
int32_t rhs_nsec;
cel_Timestamp_ToUnix(lhs, &lhs_sec, &lhs_nsec);
cel_Duration_ToUnix(rhs, &rhs_sec, &rhs_nsec);

if (CEL_UNLIKELY(_cel_ckd_sub(&sec, lhs_sec, rhs_sec))) {
return false;
Expand All @@ -107,15 +107,15 @@ extern "C" bool cel_Timestamp_Sub(cel_Timestamp* cel_nonnull out,
extern "C" bool cel_Timestamp_Diff(cel_Duration* cel_nonnull out,
cel_Timestamp lhs, cel_Timestamp rhs) {
CEL_ASSERT_NOT_NULL(out);
CEL_ASSERT(cel_Timestamp_Valid(lhs.sec, lhs.nsec));
CEL_ASSERT(cel_Timestamp_Valid(rhs.sec, rhs.nsec));

int64_t lhs_sec = lhs.sec;
int64_t rhs_sec = rhs.sec;
int64_t lhs_sec;
int64_t rhs_sec;
int64_t sec;
int32_t nsec;
int32_t lhs_nsec = lhs.nsec;
int32_t rhs_nsec = rhs.nsec;
int32_t lhs_nsec;
int32_t rhs_nsec;
cel_Timestamp_ToUnix(lhs, &lhs_sec, &lhs_nsec);
cel_Timestamp_ToUnix(rhs, &rhs_sec, &rhs_nsec);

if (CEL_UNLIKELY(_cel_ckd_sub(&sec, lhs_sec, rhs_sec))) {
return false;
Expand Down
Loading