SDL file times are 64-bit integers representing nanoseconds since the Unix epoch
parent
9153287fa0
commit
747300b356
|
@ -244,16 +244,19 @@ typedef enum SDL_PathType
|
|||
SDL_PATHTYPE_OTHER /**< something completely different like a device node (not a symlink, those are always followed) */
|
||||
} SDL_PathType;
|
||||
|
||||
/* SDL file timestamps are 64-bit integers representing seconds since the Unix epoch (Jan 1, 1970) */
|
||||
typedef Sint64 SDL_FileTimestamp;
|
||||
/* SDL file times are 64-bit integers representing nanoseconds since the Unix epoch (Jan 1, 1970)
|
||||
*
|
||||
* They can be converted between to POSIX time_t values with SDL_NS_TO_SECONDS() and SDL_SECONDS_TO_NS(), and between Windows FILETIME values with SDL_FileTimeToWindows() and SDL_FileTimeFromWindows()
|
||||
*/
|
||||
typedef Sint64 SDL_FileTime;
|
||||
|
||||
typedef struct SDL_PathInfo
|
||||
{
|
||||
SDL_PathType type; /* the path type */
|
||||
Uint64 size; /* the file size in bytes */
|
||||
SDL_FileTimestamp create_time; /* the time when the path was created */
|
||||
SDL_FileTimestamp modify_time; /* the last time the path was modified */
|
||||
SDL_FileTimestamp access_time; /* the last time the path was read */
|
||||
SDL_PathType type; /* the path type */
|
||||
Uint64 size; /* the file size in bytes */
|
||||
SDL_FileTime create_time; /* the time when the path was created */
|
||||
SDL_FileTime modify_time; /* the last time the path was modified */
|
||||
SDL_FileTime access_time; /* the last time the path was read */
|
||||
} SDL_PathInfo;
|
||||
|
||||
/**
|
||||
|
@ -318,17 +321,29 @@ extern DECLSPEC int SDLCALL SDL_RenamePath(const char *oldpath, const char *newp
|
|||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_GetPathInfo(const char *path, SDL_PathInfo *info);
|
||||
|
||||
/* some helper functions ... */
|
||||
|
||||
/* Converts an SDL file timestamp into a Windows FILETIME (100-nanosecond intervals since January 1, 1601). Fills in the two 32-bit values of the FILETIME structure.
|
||||
/* Converts an SDL file time into a Windows FILETIME (100-nanosecond intervals since January 1, 1601).
|
||||
*
|
||||
* This function fills in the two 32-bit values of the FILETIME structure.
|
||||
*
|
||||
* \param ftime the time to convert
|
||||
* \param low a pointer filled in with the low portion of the Windows FILETIME value
|
||||
* \param high a pointer filled in with the high portion of the Windows FILETIME value
|
||||
* \param dwLowDateTime a pointer filled in with the low portion of the Windows FILETIME value
|
||||
* \param dwHighDateTime a pointer filled in with the high portion of the Windows FILETIME value
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*/
|
||||
extern DECLSPEC void SDLCALL SDL_FileTimeToWindows(Sint64 ftime, Uint32 *low, Uint32 *high);
|
||||
extern DECLSPEC void SDLCALL SDL_FileTimeToWindows(SDL_FileTime ftime, Uint32 *dwLowDateTime, Uint32 *dwHighDateTime);
|
||||
|
||||
/* Converts a Windows FILETIME (100-nanosecond intervals since January 1, 1601) to an SDL file time
|
||||
*
|
||||
* This function takes the two 32-bit values of the FILETIME structure as parameters.
|
||||
*
|
||||
* \param dwLowDateTime the low portion of the Windows FILETIME value
|
||||
* \param dwHighDateTime the high portion of the Windows FILETIME value
|
||||
* \returns the converted file time
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*/
|
||||
extern DECLSPEC SDL_FileTime SDLCALL SDL_FileTimeFromWindows(Uint32 dwLowDateTime, Uint32 dwHighDateTime);
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -45,10 +45,12 @@ extern "C" {
|
|||
#define SDL_NS_PER_SECOND 1000000000LL
|
||||
#define SDL_NS_PER_MS 1000000
|
||||
#define SDL_NS_PER_US 1000
|
||||
#define SDL_MS_TO_NS(MS) (((Uint64)(MS)) * SDL_NS_PER_MS)
|
||||
#define SDL_NS_TO_MS(NS) ((NS) / SDL_NS_PER_MS)
|
||||
#define SDL_US_TO_NS(US) (((Uint64)(US)) * SDL_NS_PER_US)
|
||||
#define SDL_NS_TO_US(NS) ((NS) / SDL_NS_PER_US)
|
||||
#define SDL_SECONDS_TO_NS(S) (((Uint64)(S)) * SDL_NS_PER_SECOND)
|
||||
#define SDL_NS_TO_SECONDS(NS) ((NS) / SDL_NS_PER_SECOND)
|
||||
#define SDL_MS_TO_NS(MS) (((Uint64)(MS)) * SDL_NS_PER_MS)
|
||||
#define SDL_NS_TO_MS(NS) ((NS) / SDL_NS_PER_MS)
|
||||
#define SDL_US_TO_NS(US) (((Uint64)(US)) * SDL_NS_PER_US)
|
||||
#define SDL_NS_TO_US(NS) ((NS) / SDL_NS_PER_US)
|
||||
|
||||
/**
|
||||
* Get the number of milliseconds since SDL library initialization.
|
||||
|
|
|
@ -999,6 +999,7 @@ SDL3_0.0.0 {
|
|||
SDL_RemoveStoragePath;
|
||||
SDL_RenameStoragePath;
|
||||
SDL_GetStoragePathInfo;
|
||||
SDL_FileTimeFromWindows;
|
||||
# extra symbols go here (don't modify this line)
|
||||
local: *;
|
||||
};
|
||||
|
|
|
@ -1024,3 +1024,4 @@
|
|||
#define SDL_RemoveStoragePath SDL_RemoveStoragePath_REAL
|
||||
#define SDL_RenameStoragePath SDL_RenameStoragePath_REAL
|
||||
#define SDL_GetStoragePathInfo SDL_GetStoragePathInfo_REAL
|
||||
#define SDL_FileTimeFromWindows SDL_FileTimeFromWindows_REAL
|
||||
|
|
|
@ -1049,3 +1049,4 @@ SDL_DYNAPI_PROC(int,SDL_EnumerateStorageDirectory,(SDL_Storage *a, const char *b
|
|||
SDL_DYNAPI_PROC(int,SDL_RemoveStoragePath,(SDL_Storage *a, const char *b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_RenameStoragePath,(SDL_Storage *a, const char *b, const char *c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_GetStoragePathInfo,(SDL_Storage *a, const char *b, SDL_PathInfo *c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(SDL_FileTime,SDL_FileTimeFromWindows,(Uint32 a, Uint32 b),(a,b),return)
|
||||
|
|
|
@ -22,27 +22,38 @@
|
|||
#include "SDL_internal.h"
|
||||
#include "SDL_sysfilesystem.h"
|
||||
|
||||
void SDL_FileTimeToWindows(Sint64 ftime, Uint32 *low, Uint32 *high)
|
||||
static const Sint64 delta_1601_epoch_100ns = 11644473600ll * 10000000ll; // [100 ns] (100 ns units between 1/1/1601 and 1/1/1970, 11644473600 seconds)
|
||||
|
||||
void SDL_FileTimeToWindows(SDL_FileTime ftime, Uint32 *dwLowDateTime, Uint32 *dwHighDateTime)
|
||||
{
|
||||
const Sint64 delta_1601_epoch_s = 11644473600ull; // [seconds] (seconds between 1/1/1601 and 1/1/1970, 11644473600 seconds)
|
||||
Uint64 wtime;
|
||||
|
||||
Sint64 cvt = (ftime + delta_1601_epoch_s) * (SDL_NS_PER_SECOND / 100ull); // [100ns] (adjust to epoch and convert nanoseconds to 1/100th nanosecond units).
|
||||
// Convert ftime to 100ns units
|
||||
Sint64 ftime_100ns = (ftime / 100);
|
||||
|
||||
// Windows FILETIME is unsigned, so if we're trying to show a timestamp from before before the
|
||||
// Windows epoch, (Jan 1, 1601), clamp it to zero so it doesn't go way into the future.
|
||||
if (cvt < 0) {
|
||||
cvt = 0;
|
||||
if (ftime_100ns < 0 && -ftime_100ns > delta_1601_epoch_100ns) {
|
||||
// If we're trying to show a timestamp from before before the Windows epoch, (Jan 1, 1601), clamp it to zero
|
||||
wtime = 0;
|
||||
} else {
|
||||
wtime = (Uint64)(delta_1601_epoch_100ns + ftime_100ns);
|
||||
}
|
||||
|
||||
if (low) {
|
||||
*low = (Uint32) cvt;
|
||||
if (dwLowDateTime) {
|
||||
*dwLowDateTime = (Uint32)wtime;
|
||||
}
|
||||
|
||||
if (high) {
|
||||
*high = (Uint32) (cvt >> 32);
|
||||
if (dwHighDateTime) {
|
||||
*dwHighDateTime = (Uint32)(wtime >> 32);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_FileTime SDL_FileTimeFromWindows(Uint32 dwLowDateTime, Uint32 dwHighDateTime)
|
||||
{
|
||||
Uint64 wtime = (((Uint64)dwHighDateTime << 32) | dwLowDateTime);
|
||||
|
||||
return (Sint64)(wtime - delta_1601_epoch_100ns) * 100;
|
||||
}
|
||||
|
||||
int SDL_RemovePath(const char *path)
|
||||
{
|
||||
if (!path) {
|
||||
|
|
|
@ -124,12 +124,9 @@ int SDL_SYS_GetPathInfo(const char *path, SDL_PathInfo *info)
|
|||
info->size = (Uint64) statbuf.st_size;
|
||||
}
|
||||
|
||||
// SDL file time is seconds since the Unix epoch, so we're already good here.
|
||||
// Note that this will fail on machines with 32-bit time_t in 2038, but that's not
|
||||
// an SDL bug; those machines need to be fixed or everything will fail in the same way.
|
||||
info->create_time = (Sint64) statbuf.st_ctime;
|
||||
info->modify_time = (Sint64) statbuf.st_mtime;
|
||||
info->access_time = (Sint64) statbuf.st_atime;
|
||||
info->create_time = (SDL_FileTime)SDL_SECONDS_TO_NS(statbuf.st_ctime);
|
||||
info->modify_time = (SDL_FileTime)SDL_SECONDS_TO_NS(statbuf.st_mtime);
|
||||
info->access_time = (SDL_FileTime)SDL_SECONDS_TO_NS(statbuf.st_atime);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -140,18 +140,6 @@ int SDL_SYS_CreateDirectory(const char *path)
|
|||
return !rc ? WIN_SetError("Couldn't create directory") : 0;
|
||||
}
|
||||
|
||||
static Sint64 FileTimeToSDLTime(const FILETIME *ft)
|
||||
{
|
||||
const Uint64 delta_1601_epoch_100ns = 11644473600ull * 10000000ull; // [100ns] (100-ns chunks between 1/1/1601 and 1/1/1970, 11644473600 seconds * 10000000)
|
||||
ULARGE_INTEGER large;
|
||||
large.LowPart = ft->dwLowDateTime;
|
||||
large.HighPart = ft->dwHighDateTime;
|
||||
if (large.QuadPart == 0) {
|
||||
return 0; // unsupported on this filesystem...0 is fine, I guess.
|
||||
}
|
||||
return (Sint64) ((((Uint64)large.QuadPart) - delta_1601_epoch_100ns) / (SDL_NS_PER_SECOND / 100ull)); // [secs] (adjust to epoch and convert 1/100th nanosecond units to seconds).
|
||||
}
|
||||
|
||||
int SDL_SYS_GetPathInfo(const char *path, SDL_PathInfo *info)
|
||||
{
|
||||
WCHAR *wpath = WIN_UTF8ToString(path);
|
||||
|
@ -177,9 +165,9 @@ int SDL_SYS_GetPathInfo(const char *path, SDL_PathInfo *info)
|
|||
info->size = ((((Uint64) winstat.nFileSizeHigh) << 32) | winstat.nFileSizeLow);
|
||||
}
|
||||
|
||||
info->create_time = FileTimeToSDLTime(&winstat.ftCreationTime);
|
||||
info->modify_time = FileTimeToSDLTime(&winstat.ftLastWriteTime);
|
||||
info->access_time = FileTimeToSDLTime(&winstat.ftLastAccessTime);
|
||||
info->create_time = SDL_FileTimeFromWindows(winstat.ftCreationTime.dwLowDateTime, winstat.ftCreationTime.dwHighDateTime);
|
||||
info->modify_time = SDL_FileTimeFromWindows(winstat.ftLastWriteTime.dwLowDateTime, winstat.ftLastWriteTime.dwHighDateTime);
|
||||
info->access_time = SDL_FileTimeFromWindows(winstat.ftLastAccessTime.dwLowDateTime, winstat.ftLastAccessTime.dwHighDateTime);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue