diff --git a/MUtilities_VS2013.vcxproj b/MUtilities_VS2013.vcxproj
index 3ab810e..794fdc5 100644
--- a/MUtilities_VS2013.vcxproj
+++ b/MUtilities_VS2013.vcxproj
@@ -27,6 +27,7 @@
+
"$(QTDIR)\bin\moc.exe" -o "$(SolutionDir)tmp\$(ProjectName)\MOC_%(Filename).cpp" "%(FullPath)"
MOC "$(SolutionDir)tmp\$(ProjectName)\MOC_%(Filename).cpp"
diff --git a/MUtilities_VS2013.vcxproj.filters b/MUtilities_VS2013.vcxproj.filters
index bde2a89..e231689 100644
--- a/MUtilities_VS2013.vcxproj.filters
+++ b/MUtilities_VS2013.vcxproj.filters
@@ -59,6 +59,9 @@
Public Headers
+
+ Header Files
+
diff --git a/include/MUtils/Global.h b/include/MUtils/Global.h
index 797604d..c235b88 100644
--- a/include/MUtils/Global.h
+++ b/include/MUtils/Global.h
@@ -50,17 +50,24 @@ class QProcess;
//Check Debug Flags
#if defined(_DEBUG) || defined(DEBUG) || (!defined(NDEBUG))
-# define MUTILS_DEBUG 1
+# define MUTILS_DEBUG (1)
# if defined(NDEBUG) || defined(QT_NO_DEBUG) || (!defined(QT_DEBUG))
# error Inconsistent DEBUG flags have been detected!
# endif
#else
-# define MUTILS_DEBUG 0
+# define MUTILS_DEBUG (0)
# if (!defined(NDEBUG)) || (!defined(QT_NO_DEBUG)) || defined(QT_DEBUG)
# error Inconsistent DEBUG flags have been detected!
# endif
#endif
+//Check CPU options
+#if defined(_MSC_VER) && (!defined(_M_X64)) && defined(_M_IX86_FP)
+ #if (_M_IX86_FP != 0)
+ #error We should not enabled SSE or SSE2 in release builds!
+ #endif
+#endif
+
///////////////////////////////////////////////////////////////////////////////
namespace MUtils
@@ -77,9 +84,14 @@ namespace MUtils
MUTILS_API quint32 next_rand32(void);
MUTILS_API quint64 next_rand64(void);
+ //Remove File/Dir
+ MUTILS_API bool remove_file(const QString &fileName);
+ MUTILS_API bool remove_directory(const QString &folderPath);
+
//Version
MUTILS_API const char* mutils_build_date(void);
MUTILS_API const char* mutils_build_time(void);
+
//Internal
namespace Internal
{
@@ -110,6 +122,10 @@ while(0)
} \
while(0)
-#define MUTILS_QSTR2WCHAR(STR) (reinterpret_cast((STR).utf16()))
-#define MUTILS_QSTR2QUTF8(STR) ((STR).toUtf8().constData())
-#define MUTILS_WCHAR2QSTR(STR) (QString::fromUtf16(reinterpret_cast((STR))))
+//String conversion macros
+#define MUTILS_WCHR(STR) (reinterpret_cast((STR).utf16()))
+#define MUTILS_UTF8(STR) ((STR).toUtf8().constData())
+#define MUTILS_QSTR(STR) (QString::fromUtf16(reinterpret_cast((STR))))
+
+//Boolean helper
+#define MUTILS_BOOL2STR(X) ((X) ? "1" : "0")
diff --git a/include/MUtils/Version.h b/include/MUtils/Version.h
index dfae3e9..a0d9e7f 100644
--- a/include/MUtils/Version.h
+++ b/include/MUtils/Version.h
@@ -31,17 +31,17 @@
namespace MUtils
{
- class MUTILS_API Version
+ class Version
{
public:
//Get Build Date
- static const QDate build_date(const char *const date_str = build_date_raw());
+ MUTILS_API static const QDate build_date(const char *const date_str = build_date_raw());
//Get Build Time
- static const QTime build_time(const char *const time_str = build_time_raw());
+ MUTILS_API static const QTime build_time(const char *const time_str = build_time_raw());
//Compiler detection
- static const char *const compiler_version(void)
+ MUTILS_API static const char *const compiler_version(void)
{
#if defined(__INTEL_COMPILER)
#if (__INTEL_COMPILER >= 1500)
@@ -109,7 +109,7 @@ namespace MUtils
}
//Architecture detection
- static const char *const compiler_arch(void)
+ MUTILS_API static const char *const compiler_arch(void)
{
#if defined(_M_X64)
static const char *const COMPILER_ARCH = "x64";
@@ -130,7 +130,7 @@ namespace MUtils
return RAW_BUILD_DATE;
}
- //Raw Build date
+ //Raw Build time
static const char *const build_time_raw(void)
{
static const char *const RAW_BUILD_TIME = __TIME__;
diff --git a/src/CriticalSection_Win32.h b/src/CriticalSection_Win32.h
index e6f7b84..78bc2d4 100644
--- a/src/CriticalSection_Win32.h
+++ b/src/CriticalSection_Win32.h
@@ -29,70 +29,76 @@
// CRITICAL SECTION
///////////////////////////////////////////////////////////////////////////////
-/*
- * wrapper for native Win32 critical sections
- */
-class CriticalSection
+namespace MUtils
{
-public:
- inline CriticalSection(void)
+ namespace Internal
{
- InitializeCriticalSection(&m_win32criticalSection);
- }
-
- inline ~CriticalSection(void)
- {
- DeleteCriticalSection(&m_win32criticalSection);
- }
-
- inline void enter(void)
- {
- EnterCriticalSection(&m_win32criticalSection);
- }
-
- inline bool tryEnter(void)
- {
- return TryEnterCriticalSection(&m_win32criticalSection);
- }
-
- inline void leave(void)
- {
- LeaveCriticalSection(&m_win32criticalSection);
- }
-
-protected:
- CRITICAL_SECTION m_win32criticalSection;
-};
-
-/*
- * RAII-style critical section locker
- */
-class CSLocker
-{
-public:
- inline CSLocker(CriticalSection &criticalSection)
- :
- m_locked(false),
- m_criticalSection(criticalSection)
- {
- m_criticalSection.enter();
- m_locked = true;
- }
-
- inline ~CSLocker(void)
- {
- forceUnlock();
- }
-
- inline void forceUnlock(void)
- {
- if(m_locked)
+ /*
+ * wrapper for native Win32 critical sections
+ */
+ class CriticalSection
{
- m_criticalSection.leave();
- m_locked = false;
- }
+ public:
+ inline CriticalSection(void)
+ {
+ InitializeCriticalSection(&m_win32criticalSection);
+ }
+
+ inline ~CriticalSection(void)
+ {
+ DeleteCriticalSection(&m_win32criticalSection);
+ }
+
+ inline void enter(void)
+ {
+ EnterCriticalSection(&m_win32criticalSection);
+ }
+
+ inline bool tryEnter(void)
+ {
+ return TryEnterCriticalSection(&m_win32criticalSection);
+ }
+
+ inline void leave(void)
+ {
+ LeaveCriticalSection(&m_win32criticalSection);
+ }
+
+ protected:
+ CRITICAL_SECTION m_win32criticalSection;
+ };
+
+ /*
+ * RAII-style critical section locker
+ */
+ class CSLocker
+ {
+ public:
+ inline CSLocker(CriticalSection &criticalSection)
+ :
+ m_locked(false),
+ m_criticalSection(criticalSection)
+ {
+ m_criticalSection.enter();
+ m_locked = true;
+ }
+
+ inline ~CSLocker(void)
+ {
+ forceUnlock();
+ }
+
+ inline void forceUnlock(void)
+ {
+ if(m_locked)
+ {
+ m_criticalSection.leave();
+ m_locked = false;
+ }
+ }
+ protected:
+ volatile bool m_locked;
+ CriticalSection &m_criticalSection;
+ };
}
-protected:
- volatile bool m_locked;
- CriticalSection &m_criticalSection;
-};
+}
diff --git a/src/DirLocker.h b/src/DirLocker.h
new file mode 100644
index 0000000..f4a683f
--- /dev/null
+++ b/src/DirLocker.h
@@ -0,0 +1,112 @@
+///////////////////////////////////////////////////////////////////////////////
+// MuldeR's Utilities for Qt
+// Copyright (C) 2004-2014 LoRd_MuldeR
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+// http://www.gnu.org/licenses/lgpl-2.1.txt
+//////////////////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+//MUtils
+#include
+
+//StdLib
+#include
+
+//Qt
+#include
+#include
+
+///////////////////////////////////////////////////////////////////////////////
+// Directory Locker
+///////////////////////////////////////////////////////////////////////////////
+
+namespace MUtils
+{
+ namespace Internal
+ {
+ class DirLockException : public std::runtime_error
+ {
+ public:
+ DirLockException(const char *const message)
+ :
+ std::runtime_error(message)
+ {
+ }
+ };
+
+ class DirLock
+ {
+ public:
+ DirLock(const QString dirPath)
+ :
+ m_dirPath(dirPath)
+ {
+ if(m_dirPath.isEmpty())
+ {
+ throw DirLockException("Path must not be empty!");
+ }
+ const QByteArray testData = QByteArray(TEST_DATA);
+ bool okay = false;
+ for(int i = 0; i < 32; i++)
+ {
+ m_lockFile.reset(new QFile(QString("%1/~%2.lck").arg(m_dirPath, MUtils::rand_str())));
+ if(m_lockFile->open(QIODevice::WriteOnly | QIODevice::Truncate))
+ {
+ if(m_lockFile->write(testData) >= testData.size())
+ {
+ okay = true;
+ break;
+ }
+ m_lockFile->remove();
+ }
+ }
+ if(!okay)
+ {
+ throw DirLockException("Locking has failed!");
+ }
+ }
+
+ ~DirLock(void)
+ {
+ if(!m_lockFile.isNull())
+ {
+ m_lockFile->remove();
+ }
+ for(int i = 0; i < 8; i++)
+ {
+ if(MUtils::remove_directory(m_dirPath))
+ {
+ break;
+ }
+ }
+ }
+
+ inline const QString &path(void) const
+ {
+ return m_dirPath;
+ }
+
+ private:
+ static const char *const TEST_DATA;
+ const QString m_dirPath;
+ QScopedPointer m_lockFile;
+ };
+
+ const char *const DirLock::TEST_DATA = "7QtDxPWotHGQYv1xHyQHFKjTB5u5VYKHE20NMDAgLRYoy16CZN7mEYijbjCJpORnoBbtHCzqyy1a6BLCMMiTUZpLzgjg4qnN505egUBqk3wMhPsYjFpkng9i37mWd1iF";
+ }
+}
diff --git a/src/Global.cpp b/src/Global.cpp
index b560432..e889041 100644
--- a/src/Global.cpp
+++ b/src/Global.cpp
@@ -23,8 +23,10 @@
#define _CRT_RAND_S 1
#endif
+//MUtils
#include
#include
+#include "DirLocker.h"
//Qt
#include
@@ -102,9 +104,8 @@ QString MUtils::rand_str(const bool &bLong)
// TEMP FOLDER
///////////////////////////////////////////////////////////////////////////////
-static QScopedPointer g_temp_folder_file;
-static QScopedPointer g_temp_folder_path;
-static QReadWriteLock g_temp_folder_lock;
+static QScopedPointer g_temp_folder_file;
+static QReadWriteLock g_temp_folder_lock;
static QString try_create_subfolder(const QString &baseDir, const QString &postfix)
{
@@ -120,29 +121,26 @@ static QString try_create_subfolder(const QString &baseDir, const QString &postf
return QString();
}
-static QString try_init_temp_folder(const QString &baseDir)
+static MUtils::Internal::DirLock *try_init_temp_folder(const QString &baseDir)
{
- static const char *TEST_DATA = "Lorem ipsum dolor sit amet, consectetur, adipisci velit!";
-
- QString tempPath = try_create_subfolder(baseDir, MUtils::rand_str());
+ const QString tempPath = try_create_subfolder(baseDir, MUtils::rand_str());
if(!tempPath.isEmpty())
{
- const QByteArray testData = QByteArray(TEST_DATA);
for(int i = 0; i < 32; i++)
{
- g_temp_folder_file.reset(new QFile(QString("%1/~%2.lck").arg(tempPath, MUtils::rand_str())));
- if(g_temp_folder_file->open(QIODevice::ReadWrite | QIODevice::Truncate))
+ MUtils::Internal::DirLock *lockFile = NULL;
+ try
{
- if(g_temp_folder_file->write(testData) >= testData.size())
- {
- return tempPath;
- }
- g_temp_folder_file->remove();
+ lockFile = new MUtils::Internal::DirLock(tempPath);
+ return lockFile;
+ }
+ catch(MUtils::Internal::DirLockException&)
+ {
+ /*ignore error and try again*/
}
}
}
-
- return QString();
+ return NULL;
}
const QString &MUtils::temp_folder(void)
@@ -150,9 +148,9 @@ const QString &MUtils::temp_folder(void)
QReadLocker readLock(&g_temp_folder_lock);
//Already initialized?
- if((!g_temp_folder_path.isNull()) && (!g_temp_folder_path->isEmpty()))
+ if(!g_temp_folder_file.isNull())
{
- return (*g_temp_folder_path.data());
+ return g_temp_folder_file->path();
}
//Obtain the write lock to initilaize
@@ -160,17 +158,16 @@ const QString &MUtils::temp_folder(void)
QWriteLocker writeLock(&g_temp_folder_lock);
//Still uninitilaized?
- if((!g_temp_folder_path.isNull()) && (!g_temp_folder_path->isEmpty()))
+ if(!g_temp_folder_file.isNull())
{
- return (*g_temp_folder_path.data());
+ return g_temp_folder_file->path();
}
//Try the %TMP% or %TEMP% directory first
- QString tempPath = try_init_temp_folder(QDir::tempPath());
- if(!tempPath.isEmpty())
+ if(MUtils::Internal::DirLock *lockFile = try_init_temp_folder(QDir::tempPath()))
{
- g_temp_folder_path.reset(new QString(tempPath));
- return (*g_temp_folder_path.data());
+ g_temp_folder_file.reset(lockFile);
+ return lockFile->path();
}
qWarning("%%TEMP%% directory not found -> trying fallback mode now!");
@@ -183,11 +180,10 @@ const QString &MUtils::temp_folder(void)
const QString tempRoot = try_create_subfolder(knownFolder, QLatin1String("TEMP"));
if(!tempRoot.isEmpty())
{
- tempPath = try_init_temp_folder(tempRoot);
- if(!tempPath.isEmpty())
+ if(MUtils::Internal::DirLock *lockFile = try_init_temp_folder(tempRoot))
{
- g_temp_folder_path.reset(new QString(tempPath));
- return (*g_temp_folder_path.data());
+ g_temp_folder_file.reset(lockFile);
+ return lockFile->path();
}
}
}
@@ -197,6 +193,65 @@ const QString &MUtils::temp_folder(void)
return (*((QString*)NULL));
}
+///////////////////////////////////////////////////////////////////////////////
+// REMOVE DIRECTORY / FILE
+///////////////////////////////////////////////////////////////////////////////
+
+bool MUtils::remove_file(const QString &fileName)
+{
+ QFileInfo fileInfo(fileName);
+ if(!(fileInfo.exists() && fileInfo.isFile()))
+ {
+ return true;
+ }
+
+ for(int i = 0; i < 32; i++)
+ {
+ QFile file(fileName);
+ file.setPermissions(QFile::ReadOther | QFile::WriteOther);
+ if(file.remove())
+ {
+ return true;
+ }
+ }
+
+ qWarning("Could not delete \"%s\"", MUTILS_UTF8(fileName));
+ return false;
+}
+
+bool MUtils::remove_directory(const QString &folderPath)
+{
+ QDir folder(folderPath);
+ if(!folder.exists())
+ {
+ return true;
+ }
+
+ const QFileInfoList entryList = folder.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot | QDir::Hidden);
+ for(int i = 0; i < entryList.count(); i++)
+ {
+ if(entryList.at(i).isDir())
+ {
+ remove_directory(entryList.at(i).canonicalFilePath());
+ }
+ else
+ {
+ remove_file(entryList.at(i).canonicalFilePath());
+ }
+ }
+
+ for(int i = 0; i < 32; i++)
+ {
+ if(folder.rmdir("."))
+ {
+ return true;
+ }
+ }
+
+ qWarning("Could not rmdir \"%s\"", MUTILS_UTF8(folderPath));
+ return false;
+}
+
///////////////////////////////////////////////////////////////////////////////
// PROCESS UTILS
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/OSSupport_Win32.cpp b/src/OSSupport_Win32.cpp
index c8145d5..1b9698d 100644
--- a/src/OSSupport_Win32.cpp
+++ b/src/OSSupport_Win32.cpp
@@ -153,7 +153,7 @@ const QString &MUtils::OS::known_folder(known_folder_t folder_id)
if(g_known_folders_fpGetKnownFolderPath(s_folders[folderId].guid, KF_FLAG_CREATE, NULL, &path) == S_OK)
{
//MessageBoxW(0, path, L"SHGetKnownFolderPath", MB_TOPMOST);
- QDir folderTemp = QDir(QDir::fromNativeSeparators(MUTILS_WCHAR2QSTR(path)));
+ QDir folderTemp = QDir(QDir::fromNativeSeparators(MUTILS_QSTR(path)));
if(folderTemp.exists())
{
folderPath = folderTemp.canonicalPath();
@@ -167,7 +167,7 @@ const QString &MUtils::OS::known_folder(known_folder_t folder_id)
if(g_known_folders_fpGetFolderPath(NULL, s_folders[folderId].csidl | CSIDL_FLAG_CREATE, NULL, NULL, path.data()) == S_OK)
{
//MessageBoxW(0, path, L"SHGetFolderPathW", MB_TOPMOST);
- QDir folderTemp = QDir(QDir::fromNativeSeparators(MUTILS_WCHAR2QSTR(path.data())));
+ QDir folderTemp = QDir(QDir::fromNativeSeparators(MUTILS_QSTR(path.data())));
if(folderTemp.exists())
{
folderPath = folderTemp.canonicalPath();
@@ -259,8 +259,8 @@ int MUtils::OS::network_status(void)
// FATAL EXIT
///////////////////////////////////////////////////////////////////////////////
-static CriticalSection g_fatal_exit_lock;
-static volatile bool g_fatal_exit_flag = true;
+static MUtils::Internal::CriticalSection g_fatal_exit_lock;
+static volatile bool g_fatal_exit_flag = true;
static DWORD WINAPI fatal_exit_helper(LPVOID lpParameter)
{
diff --git a/src/Version.cpp b/src/Version.cpp
index a5a40b5..e958ce9 100644
--- a/src/Version.cpp
+++ b/src/Version.cpp
@@ -58,18 +58,19 @@ const QDate MUtils::Version::build_date(const char *const date_str)
ok = ok && (_snscanf(&date_str[0x0], 3, "%s", &month_s) == 1);
ok = ok && ((date[1] = month2int(month_s)) > 0);
- ok = ok && (_snscanf(&date_str[0x4], 2, "%d", &date[0]) == 1);
- ok = ok && (_snscanf(&date_str[0x7], 4, "%d", &date[2]) == 1);
+ ok = ok && (_snscanf(&date_str[0x4], 2, "%d", &date[2]) == 1);
+ ok = ok && (_snscanf(&date_str[0x7], 4, "%d", &date[0]) == 1);
if(!ok)
{
MUTILS_THROW("Internal error: Date format could not be recognized!");
}
+ //qWarning("MUtils::Version::build_date: y=%d, m=%d, d=%d", date[0], date[1], date[2]);
return QDate(date[0], date[1], date[2]);
}
-static const QTime build_time(const char *const time_str)
+const QTime MUtils::Version::build_time(const char *const time_str)
{
bool ok = true;
int time[3] = {0, 0, 0};
@@ -83,6 +84,7 @@ static const QTime build_time(const char *const time_str)
MUTILS_THROW("Internal error: Time format could not be recognized!");
}
+ //qWarning("MUtils::Version::build_date: h=%d, m=%d, s=%d", time[0], time[1], time[2]);
return QTime(time[0], time[1], time[2]);
}