X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2FGlobal.cpp;h=17db27ceddf8048302e0507171d85b0c3f65d4bd;hb=4572f69d33ab22204102311b1cff6c4f00727d3a;hp=e94c4403a28b6d80f34b5bdc61c5eb79843d6534;hpb=d42da03bf1601c24d5005811cb5327e32fb8d62c;p=mutilities%2FMUtilities.git diff --git a/src/Global.cpp b/src/Global.cpp index e94c440..17db27c 100644 --- a/src/Global.cpp +++ b/src/Global.cpp @@ -26,18 +26,27 @@ //MUtils #include #include + +//Internal #include "DirLocker.h" +#include "3rd_party/strnatcmp/include/strnatcmp.h" //Qt #include #include #include +#include //CRT #include #include #include +//VLD +#ifdef _MSC_VER +#include +#endif + /////////////////////////////////////////////////////////////////////////////// // Random Support /////////////////////////////////////////////////////////////////////////////// @@ -105,7 +114,7 @@ QString MUtils::rand_str(const bool &bLong) /////////////////////////////////////////////////////////////////////////////// static QScopedPointer g_temp_folder_file; -static QReadWriteLock g_temp_folder_lock; +static QReadWriteLock g_temp_folder_lock; static QString try_create_subfolder(const QString &baseDir, const QString &postfix) { @@ -143,6 +152,17 @@ static MUtils::Internal::DirLock *try_init_temp_folder(const QString &baseDir) return NULL; } +static void temp_folder_cleaup(void) +{ + QWriteLocker writeLock(&g_temp_folder_lock); + + //Clean the directory + while(!g_temp_folder_file.isNull()) + { + g_temp_folder_file.reset(NULL); + } +} + const QString &MUtils::temp_folder(void) { QReadLocker readLock(&g_temp_folder_lock); @@ -150,7 +170,7 @@ const QString &MUtils::temp_folder(void) //Already initialized? if(!g_temp_folder_file.isNull()) { - return g_temp_folder_file->path(); + return g_temp_folder_file->getPath(); } //Obtain the write lock to initilaize @@ -160,14 +180,15 @@ const QString &MUtils::temp_folder(void) //Still uninitilaized? if(!g_temp_folder_file.isNull()) { - return g_temp_folder_file->path(); + return g_temp_folder_file->getPath(); } //Try the %TMP% or %TEMP% directory first if(MUtils::Internal::DirLock *lockFile = try_init_temp_folder(QDir::tempPath())) { g_temp_folder_file.reset(lockFile); - return lockFile->path(); + atexit(temp_folder_cleaup); + return lockFile->getPath(); } qWarning("%%TEMP%% directory not found -> trying fallback mode now!"); @@ -183,7 +204,8 @@ const QString &MUtils::temp_folder(void) if(MUtils::Internal::DirLock *lockFile = try_init_temp_folder(tempRoot)) { g_temp_folder_file.reset(lockFile); - return lockFile->path(); + atexit(temp_folder_cleaup); + return lockFile->getPath(); } } } @@ -209,17 +231,34 @@ bool MUtils::remove_file(const QString &fileName) { QFile file(fileName); file.setPermissions(QFile::ReadOther | QFile::WriteOther); - if(file.remove()) + if((!(fileInfo.exists() && fileInfo.isFile())) || file.remove()) { return true; } + fileInfo.refresh(); } qWarning("Could not delete \"%s\"", MUTILS_UTF8(fileName)); return false; } -bool MUtils::remove_directory(const QString &folderPath) +static bool remove_directory_helper(QDir folder) +{ + if(!folder.exists()) + { + return true; + } + + const QString dirName = folder.dirName(); + if(dirName.isEmpty() || (!folder.cdUp())) + { + return false; + } + + return folder.rmdir(dirName); +} + +bool MUtils::remove_directory(const QString &folderPath, const bool &recursive) { QDir folder(folderPath); if(!folder.exists()) @@ -227,25 +266,41 @@ bool MUtils::remove_directory(const QString &folderPath) return true; } - const QFileInfoList entryList = folder.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot | QDir::Hidden); - for(int i = 0; i < entryList.count(); i++) + if(recursive) { - if(entryList.at(i).isDir()) - { - remove_directory(entryList.at(i).canonicalFilePath()); - } - else + const QFileInfoList entryList = folder.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot | QDir::Hidden); + for(QFileInfoList::ConstIterator iter = entryList.constBegin(); iter != entryList.constEnd(); iter++) { - remove_file(entryList.at(i).canonicalFilePath()); + if(iter->isDir()) + { + remove_directory(iter->canonicalFilePath(), true); + } + else if(iter->isFile()) + { + remove_file(iter->canonicalFilePath()); + } } } for(int i = 0; i < 32; i++) { - if(folder.rmdir(".")) + if(!folder.exists()) { return true; } + const QString dirName = folder.dirName(); + if(!dirName.isEmpty()) + { + QDir parent(folder); + if(parent.cdUp()) + { + if(parent.rmdir(dirName)) + { + return true; + } + } + } + folder.refresh(); } qWarning("Could not rmdir \"%s\"", MUTILS_UTF8(folderPath)); @@ -302,14 +357,152 @@ void MUtils::init_process(QProcess &process, const QString &wokringDir, const bo } /////////////////////////////////////////////////////////////////////////////// +// NATURAL ORDER STRING COMPARISON +/////////////////////////////////////////////////////////////////////////////// + +static bool natural_string_sort_helper(const QString &str1, const QString &str2) +{ + return (MUtils::Internal::NaturalSort::strnatcmp(MUTILS_WCHR(str1), MUTILS_WCHR(str2)) < 0); +} + +static bool natural_string_sort_helper_fold_case(const QString &str1, const QString &str2) +{ + return (MUtils::Internal::NaturalSort::strnatcasecmp(MUTILS_WCHR(str1), MUTILS_WCHR(str2)) < 0); +} + +void MUtils::natural_string_sort(QStringList &list, const bool bIgnoreCase) +{ + qSort(list.begin(), list.end(), bIgnoreCase ? natural_string_sort_helper_fold_case : natural_string_sort_helper); +} + +/////////////////////////////////////////////////////////////////////////////// +// CLEAN FILE PATH +/////////////////////////////////////////////////////////////////////////////// + +static const struct +{ + const char *const search; + const char *const replace; +} +CLEAN_FILE_NAME[] = +{ + { "\\", "-" }, + { " / ", ", " }, + { "/", "," }, + { ":", "-" }, + { "*", "x" }, + { "?", "!" }, + { "<", "[" }, + { ">", "]" }, + { "|", "!" }, + { "\"", "'" }, + { NULL, NULL } +}; + +QString MUtils::clean_file_name(const QString &name) +{ + QString str = name.simplified(); + + for(size_t i = 0; CLEAN_FILE_NAME[i].search; i++) + { + str.replace(CLEAN_FILE_NAME[i].search, CLEAN_FILE_NAME[i].replace); + } + + QRegExp regExp("\"(.+)\""); + regExp.setMinimal(true); + str.replace(regExp, "`\\1ยด"); + + return str.simplified(); +} + +QString MUtils::clean_file_path(const QString &path) +{ + QStringList parts = path.simplified().replace("\\", "/").split("/", QString::SkipEmptyParts); + + for(int i = 0; i < parts.count(); i++) + { + parts[i] = MUtils::clean_file_name(parts[i]); + } + + return parts.join("/"); +} + +/////////////////////////////////////////////////////////////////////////////// +// REGULAR EXPESSION HELPER +/////////////////////////////////////////////////////////////////////////////// + +bool MUtils::regexp_parse_uint32(const QRegExp ®exp, quint32 &value) +{ + return regexp_parse_uint32(regexp, &value, 1); +} + +bool MUtils::regexp_parse_uint32(const QRegExp ®exp, quint32 *values, const size_t &count) +{ + const QStringList caps = regexp.capturedTexts(); + + if(caps.isEmpty() || (quint32(caps.count()) <= count)) + { + return false; + } + + for(size_t i = 0; i < count; i++) + { + bool ok = false; + values[i] = caps[i+1].toUInt(&ok); + if(!ok) + { + return false; + } + } + + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +// AVAILABLE CODEPAGES +/////////////////////////////////////////////////////////////////////////////// + +QStringList MUtils::available_codepages(const bool &noAliases) +{ + QStringList codecList; + QList availableCodecs = QTextCodec::availableCodecs(); + + while(!availableCodecs.isEmpty()) + { + const QByteArray current = availableCodecs.takeFirst(); + if(!current.toLower().startsWith("system")) + { + codecList << QString::fromLatin1(current.constData(), current.size()); + if(noAliases) + { + if(QTextCodec *const currentCodec = QTextCodec::codecForName(current.constData())) + { + const QList aliases = currentCodec->aliases(); + for(QList::ConstIterator iter = aliases.constBegin(); iter != aliases.constEnd(); iter++) + { + availableCodecs.removeAll(*iter); + } + } + } + } + } + + return codecList; +} + +/////////////////////////////////////////////////////////////////////////////// // SELF-TEST /////////////////////////////////////////////////////////////////////////////// -int MUtils::Internal::selfTest(const char *const date, const bool debug) +int MUtils::Internal::selfTest(const char *const buildKey, const bool debug) { - if(strncmp(date, __DATE__"@"__TIME__, 14) || (MUTILS_DEBUG != debug)) + static const bool MY_DEBUG_FLAG = MUTILS_DEBUG; + static const char *const MY_BUILD_KEY = __DATE__"@"__TIME__; + + if(strncmp(buildKey, MY_BUILD_KEY, 14) || (MY_DEBUG_FLAG != debug)) { MUtils::OS::system_message_err(L"MUtils", L"FATAL ERROR: MUtils library version mismatch detected!"); + MUtils::OS::system_message_wrn(L"MUtils", L"Please re-build the complete solution in order to fix this issue!"); abort(); } return 0;