mirror of https://github.com/stenzek/duckstation
Sync filesystem.h/path.h
parent
f89529015c
commit
d2ca454576
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
// Fix glad.h including windows.h
|
||||
#ifdef _WIN32
|
||||
#include "../windows_headers.h"
|
||||
#endif
|
||||
|
||||
#include "glad.h"
|
||||
@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
namespace Path {
|
||||
/// Converts any forward slashes to backslashes on Win32.
|
||||
std::string ToNativePath(const std::string_view& path);
|
||||
void ToNativePath(std::string* path);
|
||||
|
||||
/// Builds a path relative to the specified file
|
||||
std::string BuildRelativePath(const std::string_view& filename, const std::string_view& new_filename);
|
||||
|
||||
/// Joins path components together, producing a new path.
|
||||
std::string Combine(const std::string_view& base, const std::string_view& next);
|
||||
|
||||
/// Removes all .. and . components from a path.
|
||||
std::string Canonicalize(const std::string_view& path);
|
||||
void Canonicalize(std::string* path);
|
||||
|
||||
/// Sanitizes a filename for use in a filesystem.
|
||||
void SanitizeFileName(char* Destination, u32 cbDestination, const char* FileName, bool StripSlashes /* = true */);
|
||||
void SanitizeFileName(std::string& Destination, bool StripSlashes = true);
|
||||
|
||||
/// Returns true if the specified path is an absolute path (C:\Path on Windows or /path on Unix).
|
||||
bool IsAbsolute(const std::string_view& path);
|
||||
|
||||
/// Makes the specified path relative to another (e.g. /a/b/c, /a/b -> ../c).
|
||||
/// Both paths must be relative, otherwise this function will just return the input path.
|
||||
std::string MakeRelative(const std::string_view& path, const std::string_view& relative_to);
|
||||
|
||||
/// Returns a view of the extension of a filename.
|
||||
std::string_view GetExtension(const std::string_view& path);
|
||||
|
||||
/// Removes the extension of a filename.
|
||||
std::string_view StripExtension(const std::string_view& path);
|
||||
|
||||
/// Replaces the extension of a filename with another.
|
||||
std::string ReplaceExtension(const std::string_view& path, const std::string_view& new_extension);
|
||||
|
||||
/// Returns the directory component of a filename.
|
||||
std::string_view GetDirectory(const std::string_view& path);
|
||||
|
||||
/// Returns the filename component of a filename.
|
||||
std::string_view GetFileName(const std::string_view& path);
|
||||
|
||||
/// Returns the file title (less the extension and path) from a filename.
|
||||
std::string_view GetFileTitle(const std::string_view& path);
|
||||
|
||||
/// Changes the filename in a path.
|
||||
std::string ChangeFileName(const std::string_view& path, const std::string_view& new_filename);
|
||||
void ChangeFileName(std::string* path, const std::string_view& new_filename);
|
||||
|
||||
/// Appends a directory to a path.
|
||||
std::string AppendDirectory(const std::string_view& path, const std::string_view& new_dir);
|
||||
void AppendDirectory(std::string* path, const std::string_view& new_dir);
|
||||
|
||||
/// Splits a path into its components, handling both Windows and Unix separators.
|
||||
std::vector<std::string_view> SplitWindowsPath(const std::string_view& path);
|
||||
std::string JoinWindowsPath(const std::vector<std::string_view>& components);
|
||||
|
||||
/// Splits a path into its components, only handling native separators.
|
||||
std::vector<std::string_view> SplitNativePath(const std::string_view& path);
|
||||
std::string JoinNativePath(const std::vector<std::string_view>& components);
|
||||
} // namespace Path
|
||||
@ -1,331 +0,0 @@
|
||||
#include "timestamp.h"
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <tuple>
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
static void UnixTimeToSystemTime(time_t t, LPSYSTEMTIME pst);
|
||||
static time_t SystemTimeToUnixTime(const SYSTEMTIME* pst);
|
||||
|
||||
#endif
|
||||
|
||||
Timestamp::Timestamp()
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
m_value.wYear = 1970;
|
||||
m_value.wMonth = 1;
|
||||
m_value.wDayOfWeek = 0;
|
||||
m_value.wDay = 1;
|
||||
m_value.wHour = 0;
|
||||
m_value.wMinute = 0;
|
||||
m_value.wSecond = 0;
|
||||
m_value.wMilliseconds = 0;
|
||||
#else
|
||||
m_value.tv_sec = 0;
|
||||
m_value.tv_usec = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
Timestamp::Timestamp(const Timestamp& copy)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
std::memcpy(&m_value, ©.m_value, sizeof(m_value));
|
||||
#else
|
||||
std::memcpy(&m_value, ©.m_value, sizeof(m_value));
|
||||
#endif
|
||||
}
|
||||
|
||||
double Timestamp::DifferenceInSeconds(Timestamp& other) const
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
FILETIME lft, rft;
|
||||
SystemTimeToFileTime(&m_value, &lft);
|
||||
SystemTimeToFileTime(&other.m_value, &rft);
|
||||
|
||||
u64 lval = ((u64)lft.dwHighDateTime) << 32 | (u64)lft.dwLowDateTime;
|
||||
u64 rval = ((u64)rft.dwHighDateTime) << 32 | (u64)rft.dwLowDateTime;
|
||||
s64 diff = ((s64)lval - (s64)rval);
|
||||
return double(diff / 10000000ULL) + (double(diff % 10000000ULL) / 10000000.0);
|
||||
|
||||
#else
|
||||
return (double)(m_value.tv_sec - other.m_value.tv_sec) +
|
||||
(((double)(m_value.tv_usec - other.m_value.tv_usec)) / 1000000.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
s64 Timestamp::DifferenceInSecondsInt(Timestamp& other) const
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
FILETIME lft, rft;
|
||||
SystemTimeToFileTime(&m_value, &lft);
|
||||
SystemTimeToFileTime(&other.m_value, &rft);
|
||||
|
||||
u64 lval = ((u64)lft.dwHighDateTime) << 32 | (u64)lft.dwLowDateTime;
|
||||
u64 rval = ((u64)rft.dwHighDateTime) << 32 | (u64)rft.dwLowDateTime;
|
||||
s64 diff = ((s64)lval - (s64)rval);
|
||||
return diff / 10000000ULL;
|
||||
|
||||
#else
|
||||
return static_cast<s64>(m_value.tv_sec - other.m_value.tv_sec);
|
||||
#endif
|
||||
}
|
||||
|
||||
Timestamp::UnixTimestampValue Timestamp::AsUnixTimestamp() const
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return (UnixTimestampValue)SystemTimeToUnixTime(&m_value);
|
||||
#else
|
||||
return (UnixTimestampValue)m_value.tv_sec;
|
||||
#endif
|
||||
}
|
||||
|
||||
Timestamp::ExpandedTime Timestamp::AsExpandedTime() const
|
||||
{
|
||||
ExpandedTime et;
|
||||
|
||||
#if defined(_WIN32)
|
||||
et.Year = m_value.wYear;
|
||||
et.Month = m_value.wMonth;
|
||||
et.DayOfMonth = m_value.wDay;
|
||||
et.DayOfWeek = m_value.wDayOfWeek;
|
||||
et.Hour = m_value.wHour;
|
||||
et.Minute = m_value.wMinute;
|
||||
et.Second = m_value.wSecond;
|
||||
et.Milliseconds = m_value.wMilliseconds;
|
||||
#else
|
||||
struct tm t;
|
||||
time_t unixTime = (time_t)m_value.tv_sec;
|
||||
gmtime_r(&unixTime, &t);
|
||||
et.Year = t.tm_year + 1900;
|
||||
et.Month = t.tm_mon + 1;
|
||||
et.DayOfMonth = t.tm_mday;
|
||||
et.DayOfWeek = t.tm_wday;
|
||||
et.Hour = t.tm_hour;
|
||||
et.Minute = t.tm_min;
|
||||
et.Second = t.tm_sec;
|
||||
et.Milliseconds = m_value.tv_usec / 1000;
|
||||
#endif
|
||||
|
||||
return et;
|
||||
}
|
||||
|
||||
void Timestamp::SetNow()
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
GetSystemTime(&m_value);
|
||||
#else
|
||||
gettimeofday(&m_value, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Timestamp::SetUnixTimestamp(UnixTimestampValue value)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
UnixTimeToSystemTime((time_t)value, &m_value);
|
||||
#else
|
||||
m_value.tv_sec = (time_t)value;
|
||||
m_value.tv_usec = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Timestamp::SetExpandedTime(const ExpandedTime& value)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
// bit of a hacky way to fill in the missing fields
|
||||
SYSTEMTIME st;
|
||||
st.wYear = (WORD)value.Year;
|
||||
st.wMonth = (WORD)value.Month;
|
||||
st.wDay = (WORD)value.DayOfMonth;
|
||||
st.wDayOfWeek = (WORD)0;
|
||||
st.wHour = (WORD)value.Hour;
|
||||
st.wMinute = (WORD)value.Minute;
|
||||
st.wSecond = (WORD)value.Second;
|
||||
st.wMilliseconds = (WORD)value.Milliseconds;
|
||||
FILETIME ft;
|
||||
SystemTimeToFileTime(&st, &ft);
|
||||
FileTimeToSystemTime(&ft, &m_value);
|
||||
#else
|
||||
struct tm t;
|
||||
std::memset(&t, 0, sizeof(t));
|
||||
t.tm_sec = value.Second;
|
||||
t.tm_min = value.Minute;
|
||||
t.tm_hour = value.Hour;
|
||||
t.tm_mday = value.DayOfMonth;
|
||||
t.tm_mon = value.Month - 1;
|
||||
t.tm_year = value.Year - 1900;
|
||||
time_t unixTime = mktime(&t);
|
||||
SetUnixTimestamp((UnixTimestampValue)unixTime);
|
||||
#endif
|
||||
}
|
||||
|
||||
String Timestamp::ToString(const char* format) const
|
||||
{
|
||||
SmallString destination;
|
||||
ToString(destination, format);
|
||||
return String(destination);
|
||||
}
|
||||
|
||||
void Timestamp::ToString(String& destination, const char* format) const
|
||||
{
|
||||
time_t unixTime = (time_t)AsUnixTimestamp();
|
||||
tm localTime;
|
||||
|
||||
#if defined(_WIN32)
|
||||
localtime_s(&localTime, &unixTime);
|
||||
#else
|
||||
localtime_r(&unixTime, &localTime);
|
||||
#endif
|
||||
|
||||
char buffer[256];
|
||||
strftime(buffer, countof(buffer) - 1, format, &localTime);
|
||||
buffer[countof(buffer) - 1] = 0;
|
||||
|
||||
destination.Clear();
|
||||
destination.AppendString(buffer);
|
||||
}
|
||||
|
||||
Timestamp Timestamp::Now()
|
||||
{
|
||||
Timestamp t;
|
||||
t.SetNow();
|
||||
return t;
|
||||
}
|
||||
|
||||
Timestamp Timestamp::FromUnixTimestamp(UnixTimestampValue value)
|
||||
{
|
||||
Timestamp t;
|
||||
t.SetUnixTimestamp(value);
|
||||
return t;
|
||||
}
|
||||
|
||||
Timestamp Timestamp::FromExpandedTime(const ExpandedTime& value)
|
||||
{
|
||||
Timestamp t;
|
||||
t.SetExpandedTime(value);
|
||||
return t;
|
||||
}
|
||||
|
||||
bool Timestamp::operator==(const Timestamp& other) const
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return std::memcmp(&m_value, &other.m_value, sizeof(m_value)) == 0;
|
||||
#else
|
||||
return std::memcmp(&m_value, &other.m_value, sizeof(m_value)) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Timestamp::operator!=(const Timestamp& other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
bool Timestamp::operator<(const Timestamp& other) const
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return std::tie(m_value.wYear, m_value.wMonth, m_value.wDay, m_value.wHour, m_value.wMinute, m_value.wSecond,
|
||||
m_value.wMilliseconds) < std::tie(other.m_value.wYear, other.m_value.wMonth, other.m_value.wDay,
|
||||
other.m_value.wHour, other.m_value.wMinute, other.m_value.wSecond,
|
||||
other.m_value.wMilliseconds);
|
||||
#else
|
||||
return std::tie(m_value.tv_sec, m_value.tv_usec) < std::tie(other.m_value.tv_sec, other.m_value.tv_usec);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Timestamp::operator<=(const Timestamp& other) const
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return std::tie(m_value.wYear, m_value.wMonth, m_value.wDay, m_value.wHour, m_value.wMinute, m_value.wSecond,
|
||||
m_value.wMilliseconds) <= std::tie(other.m_value.wYear, other.m_value.wMonth, other.m_value.wDay,
|
||||
other.m_value.wHour, other.m_value.wMinute, other.m_value.wSecond,
|
||||
other.m_value.wMilliseconds);
|
||||
#else
|
||||
return std::tie(m_value.tv_sec, m_value.tv_usec) <= std::tie(other.m_value.tv_sec, other.m_value.tv_usec);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Timestamp::operator>(const Timestamp& other) const
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return std::tie(m_value.wYear, m_value.wMonth, m_value.wDay, m_value.wHour, m_value.wMinute, m_value.wSecond,
|
||||
m_value.wMilliseconds) > std::tie(other.m_value.wYear, other.m_value.wMonth, other.m_value.wDay,
|
||||
other.m_value.wHour, other.m_value.wMinute, other.m_value.wSecond,
|
||||
other.m_value.wMilliseconds);
|
||||
#else
|
||||
return std::tie(m_value.tv_sec, m_value.tv_usec) > std::tie(other.m_value.tv_sec, other.m_value.tv_usec);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Timestamp::operator>=(const Timestamp& other) const
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return std::tie(m_value.wYear, m_value.wMonth, m_value.wDay, m_value.wHour, m_value.wMinute, m_value.wSecond,
|
||||
m_value.wMilliseconds) >= std::tie(other.m_value.wYear, other.m_value.wMonth, other.m_value.wDay,
|
||||
other.m_value.wHour, other.m_value.wMinute, other.m_value.wSecond,
|
||||
other.m_value.wMilliseconds);
|
||||
#else
|
||||
return std::tie(m_value.tv_sec, m_value.tv_usec) >= std::tie(other.m_value.tv_sec, other.m_value.tv_usec);
|
||||
#endif
|
||||
}
|
||||
|
||||
Timestamp& Timestamp::operator=(const Timestamp& other)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
std::memcpy(&m_value, &other.m_value, sizeof(m_value));
|
||||
#else
|
||||
std::memcpy(&m_value, &other.m_value, sizeof(m_value));
|
||||
#endif
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/sysinfo/converting-a-time-t-value-to-a-file-time
|
||||
static void UnixTimeToFileTime(time_t t, LPFILETIME pft)
|
||||
{
|
||||
ULARGE_INTEGER time_value;
|
||||
time_value.QuadPart = (t * 10000000LL) + 116444736000000000LL;
|
||||
pft->dwLowDateTime = time_value.LowPart;
|
||||
pft->dwHighDateTime = time_value.HighPart;
|
||||
}
|
||||
static void UnixTimeToSystemTime(time_t t, LPSYSTEMTIME pst)
|
||||
{
|
||||
FILETIME ft;
|
||||
UnixTimeToFileTime(t, &ft);
|
||||
FileTimeToSystemTime(&ft, pst);
|
||||
}
|
||||
static time_t FileTimeToUnixTime(const FILETIME* pft)
|
||||
{
|
||||
LONGLONG ll = ((LONGLONG)pft->dwHighDateTime) << 32 | (LONGLONG)pft->dwLowDateTime;
|
||||
ll -= 116444736000000000ULL;
|
||||
ll /= 10000000ULL;
|
||||
return (time_t)ll;
|
||||
}
|
||||
static time_t SystemTimeToUnixTime(const SYSTEMTIME* pst)
|
||||
{
|
||||
FILETIME ft;
|
||||
SystemTimeToFileTime(pst, &ft);
|
||||
return FileTimeToUnixTime(&ft);
|
||||
}
|
||||
|
||||
FILETIME Timestamp::AsFileTime()
|
||||
{
|
||||
FILETIME ft;
|
||||
SystemTimeToFileTime(&m_value, &ft);
|
||||
return ft;
|
||||
}
|
||||
|
||||
void Timestamp::SetWindowsFileTime(const FILETIME* pFileTime)
|
||||
{
|
||||
FileTimeToSystemTime(pFileTime, &m_value);
|
||||
}
|
||||
|
||||
Timestamp Timestamp::FromWindowsFileTime(const FILETIME* pFileTime)
|
||||
{
|
||||
Timestamp ts;
|
||||
ts.SetWindowsFileTime(pFileTime);
|
||||
return ts;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -1,75 +0,0 @@
|
||||
#pragma once
|
||||
#include "types.h"
|
||||
#include "string.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include "windows_headers.h"
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
class Timestamp
|
||||
{
|
||||
public:
|
||||
using UnixTimestampValue = u64;
|
||||
struct ExpandedTime
|
||||
{
|
||||
u32 Year; // 0-...
|
||||
u32 Month; // 1-12
|
||||
u32 DayOfMonth; // 1-31
|
||||
u32 DayOfWeek; // 0-6, starting at Sunday
|
||||
u32 Hour; // 0-23
|
||||
u32 Minute; // 0-59
|
||||
u32 Second; // 0-59
|
||||
u32 Milliseconds; // 0-999
|
||||
};
|
||||
|
||||
public:
|
||||
Timestamp();
|
||||
Timestamp(const Timestamp& copy);
|
||||
|
||||
// readers
|
||||
UnixTimestampValue AsUnixTimestamp() const;
|
||||
ExpandedTime AsExpandedTime() const;
|
||||
|
||||
// calculators
|
||||
double DifferenceInSeconds(Timestamp& other) const;
|
||||
s64 DifferenceInSecondsInt(Timestamp& other) const;
|
||||
|
||||
// setters
|
||||
void SetNow();
|
||||
void SetUnixTimestamp(UnixTimestampValue value);
|
||||
void SetExpandedTime(const ExpandedTime& value);
|
||||
|
||||
// string conversion
|
||||
String ToString(const char* format) const;
|
||||
void ToString(String& destination, const char* format) const;
|
||||
|
||||
// creators
|
||||
static Timestamp Now();
|
||||
static Timestamp FromUnixTimestamp(UnixTimestampValue value);
|
||||
static Timestamp FromExpandedTime(const ExpandedTime& value);
|
||||
|
||||
// windows-specific
|
||||
#ifdef _WIN32
|
||||
FILETIME AsFileTime();
|
||||
void SetWindowsFileTime(const FILETIME* pFileTime);
|
||||
static Timestamp FromWindowsFileTime(const FILETIME* pFileTime);
|
||||
#endif
|
||||
|
||||
// operators
|
||||
bool operator==(const Timestamp& other) const;
|
||||
bool operator!=(const Timestamp& other) const;
|
||||
bool operator<(const Timestamp& other) const;
|
||||
bool operator<=(const Timestamp& other) const;
|
||||
bool operator>(const Timestamp& other) const;
|
||||
bool operator>=(const Timestamp& other) const;
|
||||
Timestamp& operator=(const Timestamp& other);
|
||||
|
||||
private:
|
||||
#if defined(_WIN32)
|
||||
SYSTEMTIME m_value;
|
||||
#else
|
||||
struct timeval m_value;
|
||||
#endif
|
||||
};
|
||||
Loading…
Reference in New Issue