diff --git a/src/platform/osx_clock.c b/src/platform/osx_clock.c index 7b98026..1275cbd 100644 --- a/src/platform/osx_clock.c +++ b/src/platform/osx_clock.c @@ -85,6 +85,7 @@ void oc_clock_init() //RandomSeedFromDevice(); } +/* u64 oc_clock_timestamp(oc_clock_kind clock) { u64 ts = 0; @@ -120,16 +121,9 @@ u64 oc_clock_timestamp(oc_clock_kind clock) break; } - /* - //NOTE(martin): add a random fuzz between 0 and 1 times the system fuzz - //TODO(martin): ensure that we always return a value greater than the last value - f64 fuzz = RandomU32()/(f64)(~(0UL)) * OC_CLOCK_FUZZ; - ts_timediff tdfuzz = TimediffFromSeconds(fuzz); - ts = TimestampAdd(ts, tdfuzz); - */ - return (ts); } +*/ f64 oc_clock_time(oc_clock_kind clock) { diff --git a/src/platform/platform_clock.h b/src/platform/platform_clock.h index f5942e9..9dda8a4 100644 --- a/src/platform/platform_clock.h +++ b/src/platform/platform_clock.h @@ -13,20 +13,21 @@ #include "util/typedefs.h" #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif // __cplusplus - typedef enum - { - OC_CLOCK_MONOTONIC, // clock that increment monotonically - OC_CLOCK_UPTIME, // clock that increment monotonically during uptime - OC_CLOCK_DATE // clock that is driven by the platform time - } oc_clock_kind; +typedef enum +{ + OC_CLOCK_MONOTONIC, // clock that increment monotonically + OC_CLOCK_UPTIME, // clock that increment monotonically during uptime + OC_CLOCK_DATE // clock that is driven by the platform time +} oc_clock_kind; - ORCA_API void oc_clock_init(); // initialize the clock subsystem - ORCA_API u64 oc_clock_timestamp(oc_clock_kind clock); - ORCA_API f64 oc_clock_time(oc_clock_kind clock); +#if !defined(OC_PLATFORM_ORCA) || !OC_PLATFORM_ORCA +ORCA_API void oc_clock_init(); // initialize the clock subsystem +#endif + +ORCA_API f64 oc_clock_time(oc_clock_kind clock); #ifdef __cplusplus } // extern "C" diff --git a/src/platform/platform_io.h b/src/platform/platform_io.h index 8c85cdb..e6d9d0e 100644 --- a/src/platform/platform_io.h +++ b/src/platform/platform_io.h @@ -206,6 +206,13 @@ enum oc_file_perm OC_FILE_SET_UID = 1 << 11, }; +typedef struct oc_datestamp +{ + i64 seconds; // seconds relative to NTP epoch. + u64 fraction; // fraction of seconds elapsed since the time specified by seconds. + +} oc_datestamp; + typedef struct oc_file_status { u64 uid; @@ -213,7 +220,9 @@ typedef struct oc_file_status oc_file_perm perm; u64 size; - //TODO times + oc_datestamp creationDate; + oc_datestamp accessDate; + oc_datestamp modificationDate; } oc_file_status; diff --git a/src/platform/posix_io.c b/src/platform/posix_io.c index e765464..717597c 100644 --- a/src/platform/posix_io.c +++ b/src/platform/posix_io.c @@ -280,6 +280,17 @@ static oc_file_type oc_io_convert_type_from_stat(u16 mode) return (type); } +static const u64 OC_NTP_JAN_1970 = 2208988800ULL; // seconds from january 1900 to january 1970 + +oc_datestamp oc_datestamp_from_timespec(struct timespec ts) +{ + oc_datestamp d = { 0 }; + d.seconds = ts.tv_sec + OC_NTP_JAN_1970; + d.fraction = (ts.tv_nsec * (1ULL << 32)) / 1000000000; + + return (d); +} + oc_io_error oc_io_raw_fstat(oc_file_desc fd, oc_file_status* status) { oc_io_error error = OC_IO_OK; @@ -294,7 +305,10 @@ oc_io_error oc_io_raw_fstat(oc_file_desc fd, oc_file_status* status) status->perm = oc_io_convert_perm_from_stat(s.st_mode); status->type = oc_io_convert_type_from_stat(s.st_mode); status->size = s.st_size; - //TODO: times + + status->creationDate = oc_datestamp_from_timespec(s.st_birthtimespec); + status->accessDate = oc_datestamp_from_timespec(s.st_atimespec); + status->modificationDate = oc_datestamp_from_timespec(s.st_mtimespec); } return (error); } diff --git a/src/platform/win32_io.c b/src/platform/win32_io.c index 3e705d2..f667c24 100644 --- a/src/platform/win32_io.c +++ b/src/platform/win32_io.c @@ -229,6 +229,36 @@ bool oc_io_raw_file_exists_at(oc_file_desc dirFd, oc_str8 path, oc_file_open_fla return (result); } +enum +{ + OC_NTP_01_JAN_1601 = -9435484800LL, + OC_WIN32_TICKS_PER_SECOND = 10000000LL +}; + +oc_datestamp oc_datestamp_from_win32_filetime(FILETIME ft) +{ + oc_datestamp d = { 0 }; + + i64 win32Ticks = (((u64)ft.high) << 32) | (u64)ft.low; + + i64 win32Seconds = win32Ticks / OC_WIN32_TICKS_PER_SECOND; + u64 win32Rem = 0; + if(winTicks < 0) + { + win32Seconds -= OC_WIN32_TICKS_PER_SECOND; + win32Rem = win32Ticks - seconds * OC_WIN32_TICKS_PER_SECOND; + } + else + { + win32Rem = win32Ticks % OC_WIN32_TICKS_PER_SECOND; + } + + d.seconds = win32Seconds + OC_NTP_01_JAN_1601; + d.fraction = (win32Rem * (1ULL << 32)) / OC_WIN32_TICKS_PER_SECOND; + + return (d); +} + oc_io_error oc_io_raw_fstat(oc_file_desc fd, oc_file_status* status) { oc_io_error error = OC_IO_OK; @@ -290,7 +320,16 @@ oc_io_error oc_io_raw_fstat(oc_file_desc fd, oc_file_status* status) { status->perm = OC_FILE_OWNER_WRITE | OC_FILE_GROUP_WRITE | OC_FILE_OTHER_WRITE; } - //TODO: times + + FILETIME win32CreationDate; + FILETIME win32AccessDate; + FILETIME win32ModificationDate; + + GetFileTime(fd, &win32CreationDate, &win32AccessDate, &win32ModificationDate); + + status->creationDate = oc_datestamp_from_win32_filetime(win32CreationDate); + status->accessDate = oc_datestamp_from_win32_filetime(win32AccessDate); + status->modificationDate = oc_datestamp_from_win32_filetime(win32ModificationDate); } return (error); }