summaryrefslogtreecommitdiffstats
path: root/src/libs/7zip
diff options
context:
space:
mode:
authorKarsten Heimrich <karsten.heimrich@theqtcompany.com>2015-06-23 12:09:55 +0200
committerKarsten Heimrich <karsten.heimrich@theqtcompany.com>2015-06-23 10:30:57 +0000
commit65a5d4d33c7dcb27ce99ce59535733a28991c544 (patch)
tree1adf04729140e3ceca7ae159b9adba2851f6d4ea /src/libs/7zip
parent94df4a43b671bff1ca3f31fff16c335ab12e6640 (diff)
Follow description on MSDN to implement time utils.
Task-number: QTIFW-445 Change-Id: I8c3bc221f57043cc876f1927edf0d591303b5687 Reviewed-by: Kai Koehne <kai.koehne@theqtcompany.com>
Diffstat (limited to 'src/libs/7zip')
-rw-r--r--src/libs/7zip/unix/CPP/Common/MyWindows.h12
-rw-r--r--src/libs/7zip/unix/CPP/myWindows/myDateAndTime.cpp160
2 files changed, 110 insertions, 62 deletions
diff --git a/src/libs/7zip/unix/CPP/Common/MyWindows.h b/src/libs/7zip/unix/CPP/Common/MyWindows.h
index 3376dd6aa..83a896283 100644
--- a/src/libs/7zip/unix/CPP/Common/MyWindows.h
+++ b/src/libs/7zip/unix/CPP/Common/MyWindows.h
@@ -40,7 +40,17 @@ typedef UINT32 DWORD;
typedef Int64 LONGLONG;
typedef UInt64 ULONGLONG;
-typedef struct LARGE_INTEGER { LONGLONG QuadPart; }LARGE_INTEGER;
+typedef union _LARGE_INTEGER {
+ struct {
+ DWORD LowPart;
+ LONG HighPart;
+ };
+ struct {
+ DWORD LowPart;
+ LONG HighPart;
+ } u;
+ LONGLONG QuadPart;
+} LARGE_INTEGER;
typedef struct _ULARGE_INTEGER { ULONGLONG QuadPart;} ULARGE_INTEGER;
typedef const CHAR *LPCSTR;
diff --git a/src/libs/7zip/unix/CPP/myWindows/myDateAndTime.cpp b/src/libs/7zip/unix/CPP/myWindows/myDateAndTime.cpp
index 48cb17c9a..000544046 100644
--- a/src/libs/7zip/unix/CPP/myWindows/myDateAndTime.cpp
+++ b/src/libs/7zip/unix/CPP/myWindows/myDateAndTime.cpp
@@ -38,102 +38,130 @@
#include <chrono>
-void FileTimeToDateTime(const FILETIME *source, QDateTime *target)
-{
- ULARGE_INTEGER store;
- store.QuadPart = source->dwHighDateTime;
- store.QuadPart = store.QuadPart << 32;
- store.QuadPart += source->dwLowDateTime;
+/*
+ MSDN description about FILETIME structure:
- const QDateTime tempDateTime(QDate(1601, 1, 1), QTime(0, 0, 0, 0), Qt::UTC);
- *target = tempDateTime.addMSecs(store.QuadPart / 10000);
-}
+ The FILETIME structure is a 64-bit value representing the number of 100-nanosecond intervals
+ since January 1, 1601 (UTC).
+
+ The DeltaToEpochInMsec can be calculated like this:
-void DateTimeToSystemTime(const QDateTime *source, SYSTEMTIME *target)
+ \code
+ quint64 delta = quint64(QDateTime(QDate(1601, 1, 1)).msecsTo(QDateTime(QDate(1970, 1, 1))))
+ * 10000ULL;
+ \endcode
+
+ But since the value is static, we use a precalculated number here.
+*/
+static const ULONGLONG DeltaToEpochInMsec = 116444736000000000ULL;
+
+inline void LocalDateTimeToFileTime(const QDateTime &dt, ULONGLONG utcOffsetInMsec, FILETIME *ft)
{
- target->wYear = source->date().year();
- target->wMonth = source->date().month();
- target->wDayOfWeek = source->date().dayOfWeek();
- target->wDay = source->date().day();
- target->wHour = source->time().hour();
- target->wMinute = source->time().minute();
- target->wSecond = source->time().second();
- target->wMilliseconds = source->time().msec();
+ const ULONGLONG msec = dt.toMSecsSinceEpoch() + utcOffsetInMsec;
+ const ULONGLONG nano100 = (msec * 10000ULL) + DeltaToEpochInMsec;
+
+ ft->dwLowDateTime = nano100;
+ ft->dwHighDateTime = nano100 >> 32;
+
}
-void DateTimeToFileTime(const QDateTime &dateTime, FILETIME *target)
+inline void UTCDateTimeToSystemTime(const QDateTime &dt, SYSTEMTIME *st)
{
- const qint64 nsecs = QDateTime(QDate(1601, 1, 1), QTime(0, 0, 0, 0), Qt::UTC)
- .msecsTo(dateTime) * 10000;
- target->dwLowDateTime = nsecs;
- target->dwHighDateTime = nsecs >> 32;
+ const QDate date = dt.date();
+ const QTime time = dt.time();
+
+ st->wYear = date.year();
+ st->wMonth = date.month();
+ st->wDayOfWeek = date.dayOfWeek();
+ st->wDay = date.day();
+ st->wHour = time.hour();
+ st->wMinute = time.minute();
+ st->wSecond = time.second();
+ st->wMilliseconds = time.msec();
}
+
+// -- WINAPI
+
BOOL WINAPI FileTimeToSystemTime(CONST FILETIME *source,SYSTEMTIME *target)
{
- QDateTime tempDateTime;
- FileTimeToDateTime(source, &tempDateTime);
- DateTimeToSystemTime(&tempDateTime, target);
-
+ const QDateTime dt = QDateTime(QDate(1601, 1, 1), QTime(0, 0, 0, 1), Qt::UTC).addMSecs
+ ((ULONGLONG(source->dwLowDateTime) + (ULONGLONG(source->dwHighDateTime) << 32)) / 10000ULL);
+ UTCDateTimeToSystemTime(dt.toUTC(), target);
return TRUE;
}
BOOL WINAPI FileTimeToLocalFileTime(CONST FILETIME *source,FILETIME *target)
{
- target->dwHighDateTime = source->dwHighDateTime;
- target->dwLowDateTime = source->dwLowDateTime;
-
- QDateTime tempDateTime;
- FileTimeToDateTime(source, &tempDateTime);
-
- tempDateTime = tempDateTime.toLocalTime();
+ const QDateTime dt = QDateTime(QDate(1601, 1, 1), QTime(0, 0, 0, 1), Qt::UTC).addMSecs
+ ((ULONGLONG(source->dwLowDateTime) + (ULONGLONG(source->dwHighDateTime) << 32)) / 10000ULL);
+ LocalDateTimeToFileTime(dt.toLocalTime(), ULONGLONG(QDateTime::currentDateTime()
+ .offsetFromUtc()) * 1000ULL, target);
return TRUE;
}
BOOLEAN WINAPI RtlTimeToSecondsSince1970(const LARGE_INTEGER *Time, DWORD *Seconds)
{
- SYSTEMTIME tempSystemTime;
- FILETIME fileTime;
-
- fileTime.dwLowDateTime = Time->QuadPart;
- fileTime.dwHighDateTime = Time->QuadPart >> 32;
-
- FileTimeToSystemTime(&fileTime, &tempSystemTime);
-
- QDate targetDate(tempSystemTime.wYear, tempSystemTime.wMonth, tempSystemTime.wDay);
- QTime targetTime(tempSystemTime.wHour, tempSystemTime.wMinute, tempSystemTime.wSecond, tempSystemTime.wMilliseconds);
- QDateTime targetDateTime(targetDate, targetTime, Qt::UTC);
-
- quint64 secsSince1970 = targetDateTime.toMSecsSinceEpoch() / 1000;
-
- *Seconds = secsSince1970;
+ /*
+ MSDN suggests to implement the function like this:
+
+ 1. Call SystemTimeToFileTime to copy the system time to a FILETIME structure. Call
+ GetSystemTime to get the current system time to pass to SystemTimeToFileTime.
+ 2. Copy the contents of the FILETIME structure to a ULARGE_INTEGER structure.
+ 3. Initialize a SYSTEMTIME structure with the date and time of the first second of
+ January 1, 1970.
+ 4. Call SystemTimeToFileTime, passing the SYSTEMTIME structure initialized in Step 3
+ to the call.
+ 5. Copy the contents of the FILETIME structure returned by SystemTimeToFileTime in Step 4
+ to a second ULARGE_INTEGER. The copied value should be less than or equal to the value
+ copied in Step 2.
+ 6. Subtract the 64-bit value in the ULARGE_INTEGER structure initialized in Step 5
+ (January 1, 1970) from the 64-bit value of the ULARGE_INTEGER structure initialized
+ in Step 2 (the current system time). This produces a value in 100-nanosecond intervals
+ since January 1, 1970. To convert this value to seconds, divide by 10,000,000.
+
+ We can omit step 1 and 2, cause we get the LARGE_INTEGER passed as function argument.
+ */
+ SYSTEMTIME stFirstSecondOf1979;
+ stFirstSecondOf1979.wSecond = 1;
+ stFirstSecondOf1979.wMinute = 0;
+ stFirstSecondOf1979.wHour = 0;
+ stFirstSecondOf1979.wDay = 1;
+ stFirstSecondOf1979.wMonth = 1;
+ stFirstSecondOf1979.wYear = 1970;
+ stFirstSecondOf1979.wDayOfWeek = 4;
+
+ FILETIME ftFirstSecondOf1979;
+ SystemTimeToFileTime(&stFirstSecondOf1979, &ftFirstSecondOf1979);
+
+ LARGE_INTEGER liFirstSecondOf1979;
+ liFirstSecondOf1979.LowPart = ftFirstSecondOf1979.dwLowDateTime;
+ liFirstSecondOf1979.HighPart = ftFirstSecondOf1979.dwHighDateTime;
+
+ const ULONGLONG diffNano100 = Time->QuadPart - liFirstSecondOf1979.QuadPart;
+ *Seconds = diffNano100 / 10000000ULL;
return TRUE;
}
void WINAPI RtlSecondsSince1970ToFileTime(DWORD Seconds, FILETIME *ft)
{
- QDateTime fileTimeStartDate(QDate(1601, 1, 1));
- quint64 hnseconds = Seconds;
- QDateTime sourceDateTime = QDateTime::fromMSecsSinceEpoch(hnseconds * 1000);
-
- hnseconds = fileTimeStartDate.msecsTo(sourceDateTime);
- hnseconds *= 10000;
-
- ft->dwLowDateTime = hnseconds;
- ft->dwHighDateTime = hnseconds >> 32;
+ const ULONGLONG nano100 = (ULONGLONG(Seconds) * 10000000ULL) + DeltaToEpochInMsec;
+ ft->dwLowDateTime = nano100;
+ ft->dwHighDateTime = nano100 >> 32;
}
VOID WINAPI GetSystemTime(SYSTEMTIME *st)
{
- QDateTime nowDateTime = QDateTime::currentDateTimeUtc();
- DateTimeToSystemTime(&nowDateTime, st);
+ UTCDateTimeToSystemTime(QDateTime::currentDateTimeUtc(), st);
}
VOID WINAPI GetSystemTimeAsFileTime(FILETIME *time)
{
- DateTimeToFileTime(QDateTime::currentDateTimeUtc(), time);
+ SYSTEMTIME st;
+ GetSystemTime(&st);
+ SystemTimeToFileTime(&st, time);
}
DWORD WINAPI GetTickCount()
@@ -141,3 +169,13 @@ DWORD WINAPI GetTickCount()
using namespace std::chrono;
return duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
}
+
+BOOL WINAPI SystemTimeToFileTime(const SYSTEMTIME *lpSystemTime, FILETIME *lpFileTime)
+{
+ const QDateTime dt(QDate(lpSystemTime->wYear, lpSystemTime->wMonth, lpSystemTime->wDay),
+ QTime(lpSystemTime->wHour, lpSystemTime->wMinute, lpSystemTime->wSecond,
+ lpSystemTime->wMilliseconds), Qt::UTC);
+
+ LocalDateTimeToFileTime(dt.toLocalTime(), 0ULL, lpFileTime);
+ return TRUE;
+}