summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/lzma/CPP/Windows/TimeUtils.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/lzma/CPP/Windows/TimeUtils.cpp')
-rw-r--r--3rdparty/lzma/CPP/Windows/TimeUtils.cpp251
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