diff options
Diffstat (limited to '3rdparty/lzma/CPP/Windows/TimeUtils.cpp')
-rw-r--r-- | 3rdparty/lzma/CPP/Windows/TimeUtils.cpp | 251 |
1 files changed, 226 insertions, 25 deletions
diff --git a/3rdparty/lzma/CPP/Windows/TimeUtils.cpp b/3rdparty/lzma/CPP/Windows/TimeUtils.cpp index 7ef44d9cc50..e80ae13dcac 100644 --- a/3rdparty/lzma/CPP/Windows/TimeUtils.cpp +++ b/3rdparty/lzma/CPP/Windows/TimeUtils.cpp @@ -2,6 +2,10 @@ #include "StdAfx.h" +#ifndef _WIN32 +#include <sys/time.h> +#endif + #include "Defs.h" #include "TimeUtils.h" @@ -10,13 +14,15 @@ namespace NTime { static const UInt32 kNumTimeQuantumsInSecond = 10000000; static const UInt32 kFileTimeStartYear = 1601; +#if !defined(_WIN32) || defined(UNDER_CE) static const UInt32 kDosTimeStartYear = 1980; +#endif static const UInt32 kUnixTimeStartYear = 1970; static const UInt64 kUnixTimeOffset = (UInt64)60 * 60 * 24 * (89 + 365 * (kUnixTimeStartYear - kFileTimeStartYear)); static const UInt64 kNumSecondsInFileTime = (UInt64)(Int64)-1 / kNumTimeQuantumsInSecond; -bool DosTimeToFileTime(UInt32 dosTime, FILETIME &ft) throw() +bool DosTime_To_FileTime(UInt32 dosTime, FILETIME &ft) throw() { #if defined(_WIN32) && !defined(UNDER_CE) return BOOLToBool(::DosDateTimeToFileTime((UInt16)(dosTime >> 16), (UInt16)(dosTime & 0xFFFF), &ft)); @@ -37,11 +43,7 @@ bool DosTimeToFileTime(UInt32 dosTime, FILETIME &ft) throw() static const UInt32 kHighDosTime = 0xFF9FBF7D; static const UInt32 kLowDosTime = 0x210000; -#define PERIOD_4 (4 * 365 + 1) -#define PERIOD_100 (PERIOD_4 * 25 - 1) -#define PERIOD_400 (PERIOD_100 * 4 + 1) - -bool FileTimeToDosTime(const FILETIME &ft, UInt32 &dosTime) throw() +bool FileTime_To_DosTime(const FILETIME &ft, UInt32 &dosTime) throw() { #if defined(_WIN32) && !defined(UNDER_CE) @@ -55,6 +57,10 @@ bool FileTimeToDosTime(const FILETIME &ft, UInt32 &dosTime) throw() #else +#define PERIOD_4 (4 * 365 + 1) +#define PERIOD_100 (PERIOD_4 * 25 - 1) +#define PERIOD_400 (PERIOD_100 * 4 + 1) + unsigned year, mon, day, hour, min, sec; UInt64 v64 = ft.dwLowDateTime | ((UInt64)ft.dwHighDateTime << 32); Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; @@ -115,39 +121,86 @@ bool FileTimeToDosTime(const FILETIME &ft, UInt32 &dosTime) throw() return true; } -void UnixTimeToFileTime(UInt32 unixTime, FILETIME &ft) throw() + +bool UtcFileTime_To_LocalDosTime(const FILETIME &utc, UInt32 &dosTime) throw() { - UInt64 v = (kUnixTimeOffset + (UInt64)unixTime) * kNumTimeQuantumsInSecond; + FILETIME loc = { 0, 0 }; + const UInt64 u1 = FILETIME_To_UInt64(utc); + const UInt64 kDelta = ((UInt64)1 << 41); // it's larger than quantums in 1 sec. + if (u1 >= kDelta) + { + if (!FileTimeToLocalFileTime(&utc, &loc)) + loc = utc; + else + { + const UInt64 u2 = FILETIME_To_UInt64(loc); + const UInt64 delta = u1 < u2 ? (u2 - u1) : (u1 - u2); + if (delta > kDelta) // if FileTimeToLocalFileTime() overflow, we use UTC time + loc = utc; + } + } + return FileTime_To_DosTime(loc, dosTime); +} + +UInt64 UnixTime_To_FileTime64(UInt32 unixTime) throw() +{ + return (kUnixTimeOffset + (UInt64)unixTime) * kNumTimeQuantumsInSecond; +} + +void UnixTime_To_FileTime(UInt32 unixTime, FILETIME &ft) throw() +{ + const UInt64 v = UnixTime_To_FileTime64(unixTime); ft.dwLowDateTime = (DWORD)v; ft.dwHighDateTime = (DWORD)(v >> 32); } -bool UnixTime64ToFileTime(Int64 unixTime, FILETIME &ft) throw() +UInt64 UnixTime64_To_FileTime64(Int64 unixTime) throw() { - if (unixTime > kNumSecondsInFileTime - kUnixTimeOffset) + return (UInt64)((Int64)kUnixTimeOffset + unixTime) * kNumTimeQuantumsInSecond; +} + + +bool UnixTime64_To_FileTime64(Int64 unixTime, UInt64 &fileTime) throw() +{ + if (unixTime > (Int64)(kNumSecondsInFileTime - kUnixTimeOffset)) { - ft.dwLowDateTime = ft.dwHighDateTime = (UInt32)(Int32)-1; + fileTime = (UInt64)(Int64)-1; return false; } - Int64 v = (Int64)kUnixTimeOffset + unixTime; - if (v < 0) + if (unixTime < -(Int64)kUnixTimeOffset) { - ft.dwLowDateTime = ft.dwHighDateTime = 0; + fileTime = 0; return false; } - UInt64 v2 = (UInt64)v * kNumTimeQuantumsInSecond; - ft.dwLowDateTime = (DWORD)v2; - ft.dwHighDateTime = (DWORD)(v2 >> 32); + fileTime = UnixTime64_To_FileTime64(unixTime); return true; } -Int64 FileTimeToUnixTime64(const FILETIME &ft) throw() + +bool UnixTime64_To_FileTime(Int64 unixTime, FILETIME &ft) throw() +{ + UInt64 v; + const bool res = UnixTime64_To_FileTime64(unixTime, v); + ft.dwLowDateTime = (DWORD)v; + ft.dwHighDateTime = (DWORD)(v >> 32); + return res; +} + + +Int64 FileTime_To_UnixTime64(const FILETIME &ft) throw() +{ + const UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime; + return (Int64)(winTime / kNumTimeQuantumsInSecond) - (Int64)kUnixTimeOffset; +} + +Int64 FileTime_To_UnixTime64_and_Quantums(const FILETIME &ft, UInt32 &quantums) throw() { - UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime; - return (Int64)(winTime / kNumTimeQuantumsInSecond) - kUnixTimeOffset; + const UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime; + quantums = (UInt32)(winTime % kNumTimeQuantumsInSecond); + return (Int64)(winTime / kNumTimeQuantumsInSecond) - (Int64)kUnixTimeOffset; } -bool FileTimeToUnixTime(const FILETIME &ft, UInt32 &unixTime) throw() +bool FileTime_To_UnixTime(const FILETIME &ft, UInt32 &unixTime) throw() { UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime; winTime /= kNumTimeQuantumsInSecond; @@ -157,9 +210,9 @@ bool FileTimeToUnixTime(const FILETIME &ft, UInt32 &unixTime) throw() return false; } winTime -= kUnixTimeOffset; - if (winTime > 0xFFFFFFFF) + if (winTime > (UInt32)0xFFFFFFFF) { - unixTime = 0xFFFFFFFF; + unixTime = (UInt32)0xFFFFFFFF; return false; } unixTime = (UInt32)winTime; @@ -186,11 +239,13 @@ bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day, return true; } -void GetCurUtcFileTime(FILETIME &ft) throw() + +void GetCurUtc_FiTime(CFiTime &ft) throw() { + #ifdef _WIN32 + // Both variants provide same low resolution on WinXP: about 15 ms. // But GetSystemTimeAsFileTime is much faster. - #ifdef UNDER_CE SYSTEMTIME st; GetSystemTime(&st); @@ -198,6 +253,152 @@ void GetCurUtcFileTime(FILETIME &ft) throw() #else GetSystemTimeAsFileTime(&ft); #endif + + #else + + FiTime_Clear(ft); + struct timeval now; + if (gettimeofday(&now, NULL) == 0) + { + ft.tv_sec = now.tv_sec; + ft.tv_nsec = now.tv_usec * 1000; + } + + #endif } +#ifndef _WIN32 +void GetCurUtcFileTime(FILETIME &ft) throw() +{ + UInt64 v = 0; + struct timeval now; + if (gettimeofday(&now, NULL) == 0) + { + v = ((UInt64)now.tv_sec + kUnixTimeOffset) * + kNumTimeQuantumsInSecond + (UInt64)now.tv_usec * 10; + } + ft.dwLowDateTime = (DWORD)v; + ft.dwHighDateTime = (DWORD)(v >> 32); +} +#endif + + }} + + +#ifdef _WIN32 + +/* +void FiTime_Normalize_With_Prec(CFiTime &ft, unsigned prec) +{ + if (prec == k_PropVar_TimePrec_0 + || prec == k_PropVar_TimePrec_HighPrec + || prec >= k_PropVar_TimePrec_100ns) + return; + UInt64 v = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime; + + int numDigits = (int)prec - (int)k_PropVar_TimePrec_Base; + UInt32 d; + if (prec == k_PropVar_TimePrec_DOS) + { + // we round up as windows DosDateTimeToFileTime() + v += NWindows::NTime::kNumTimeQuantumsInSecond * 2 - 1; + d = NWindows::NTime::kNumTimeQuantumsInSecond * 2; + } + else + { + if (prec == k_PropVar_TimePrec_Unix) + numDigits = 0; + else if (numDigits < 0) + return; + d = 1; + for (unsigned k = numDigits; k < 7; k++) + d *= 10; + } + v /= d; + v *= d; + ft.dwLowDateTime = (DWORD)v; + ft.dwHighDateTime = (DWORD)(v >> 32); +} +*/ + +#else + +/* +void FiTime_Normalize_With_Prec(CFiTime &ft, unsigned prec) +{ + if (prec >= k_PropVar_TimePrec_1ns + || prec == k_PropVar_TimePrec_HighPrec) + return; + + int numDigits = (int)prec - (int)k_PropVar_TimePrec_Base; + UInt32 d; + if (prec == k_PropVar_TimePrec_Unix || + prec == (int)k_PropVar_TimePrec_Base) + { + ft.tv_nsec = 0; + return; + } + if (prec == k_PropVar_TimePrec_DOS) + { + // we round up as windows DosDateTimeToFileTime() + const unsigned sec1 = (ft.tv_sec & 1); + if (ft.tv_nsec == 0 && sec1 == 0) + return; + ft.tv_nsec = 0; + ft.tv_sec += 2 - sec1; + return; + } + { + if (prec == k_PropVar_TimePrec_0 + || numDigits < 0) + numDigits = 7; + d = 1; + for (unsigned k = numDigits; k < 9; k++) + d *= 10; + ft.tv_nsec /= d; + ft.tv_nsec *= d; + } +} +*/ + +int Compare_FiTime(const CFiTime *a1, const CFiTime *a2) +{ + if (a1->tv_sec < a2->tv_sec) return -1; + if (a1->tv_sec > a2->tv_sec) return 1; + if (a1->tv_nsec < a2->tv_nsec) return -1; + if (a1->tv_nsec > a2->tv_nsec) return 1; + return 0; +} + +bool FILETIME_To_timespec(const FILETIME &ft, timespec &ts) +{ + UInt32 quantums; + const Int64 sec = NWindows::NTime::FileTime_To_UnixTime64_and_Quantums(ft, quantums); + // time_t is long + const time_t sec2 = (time_t)sec; + if (sec2 == sec) + { + ts.tv_sec = sec2; + ts.tv_nsec = (long)(quantums * 100); + return true; + } + return false; +} + +void FiTime_To_FILETIME_ns100(const CFiTime &ts, FILETIME &ft, unsigned &ns100) +{ + const UInt64 v = NWindows::NTime::UnixTime64_To_FileTime64(ts.tv_sec) + ((UInt64)ts.tv_nsec / 100); + ns100 = (unsigned)((UInt64)ts.tv_nsec % 100); + ft.dwLowDateTime = (DWORD)v; + ft.dwHighDateTime = (DWORD)(v >> 32); +} + +void FiTime_To_FILETIME(const CFiTime &ts, FILETIME &ft) +{ + const UInt64 v = NWindows::NTime::UnixTime64_To_FileTime64(ts.tv_sec) + ((UInt64)ts.tv_nsec / 100); + ft.dwLowDateTime = (DWORD)v; + ft.dwHighDateTime = (DWORD)(v >> 32); +} + +#endif |