Substantial code cleanup of various utility functions.

This commit is contained in:
Leon Styhre 2021-05-30 20:46:17 +02:00
parent 9a8fd5c487
commit 4533409c65
6 changed files with 452 additions and 483 deletions

View file

@ -19,9 +19,9 @@
#include "utils/StringUtil.h" #include "utils/StringUtil.h"
#include "Log.h" #include "Log.h"
#include <fstream>
#include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fstream>
#include <string>
#if defined(_WIN64) #if defined(_WIN64)
#include <direct.h> #include <direct.h>
@ -61,17 +61,17 @@ namespace Utils
static std::string homePath = ""; static std::string homePath = "";
static std::string exePath = ""; static std::string exePath = "";
stringList getDirContent(const std::string& _path, const bool _recursive) stringList getDirContent(const std::string& path, const bool recursive)
{ {
std::string path = getGenericPath(_path); std::string genericPath = getGenericPath(path);
stringList contentList; stringList contentList;
// Only parse the directory, if it's a directory. // Only parse the directory, if it's a directory.
if (isDirectory(path)) { if (isDirectory(genericPath)) {
#if defined(_WIN64) #if defined(_WIN64)
WIN32_FIND_DATAW findData; WIN32_FIND_DATAW findData;
std::wstring wildcard = Utils::String::stringToWideString(path) + L"/*"; std::wstring wildcard = Utils::String::stringToWideString(genericPath) + L"/*";
HANDLE hFind = FindFirstFileW(wildcard.c_str(), &findData); HANDLE hFind = FindFirstFileW(wildcard.c_str(), &findData);
if (hFind != INVALID_HANDLE_VALUE) { if (hFind != INVALID_HANDLE_VALUE) {
@ -80,10 +80,10 @@ namespace Utils
std::string name = Utils::String::wideStringToString(findData.cFileName); std::string name = Utils::String::wideStringToString(findData.cFileName);
// Ignore "." and ".." // Ignore "." and ".."
if ((name != ".") && (name != "..")) { if ((name != ".") && (name != "..")) {
std::string fullName(getGenericPath(path + "/" + name)); std::string fullName(getGenericPath(genericPath + "/" + name));
contentList.push_back(fullName); contentList.push_back(fullName);
if (_recursive && isDirectory(fullName)) { if (recursive && isDirectory(fullName)) {
contentList.sort(); contentList.sort();
contentList.merge(getDirContent(fullName, true)); contentList.merge(getDirContent(fullName, true));
} }
@ -93,7 +93,7 @@ namespace Utils
FindClose(hFind); FindClose(hFind);
} }
#else #else
DIR* dir = opendir(path.c_str()); DIR* dir = opendir(genericPath.c_str());
if (dir != nullptr) { if (dir != nullptr) {
struct dirent* entry; struct dirent* entry;
@ -103,10 +103,10 @@ namespace Utils
// Ignore "." and ".." // Ignore "." and ".."
if ((name != ".") && (name != "..")) { if ((name != ".") && (name != "..")) {
std::string fullName(getGenericPath(path + "/" + name)); std::string fullName(getGenericPath(genericPath + "/" + name));
contentList.push_back(fullName); contentList.push_back(fullName);
if (_recursive && isDirectory(fullName)) { if (recursive && isDirectory(fullName)) {
contentList.sort(); contentList.sort();
contentList.merge(getDirContent(fullName, true)); contentList.merge(getDirContent(fullName, true));
} }
@ -120,29 +120,29 @@ namespace Utils
return contentList; return contentList;
} }
stringList getPathList(const std::string& _path) stringList getPathList(const std::string& path)
{ {
stringList pathList; stringList pathList;
std::string path = getGenericPath(_path); std::string genericPath = getGenericPath(path);
size_t start = 0; size_t start = 0;
size_t end = 0; size_t end = 0;
// Split at '/' // Split at '/'
while ((end = path.find("/", start)) != std::string::npos) { while ((end = genericPath.find("/", start)) != std::string::npos) {
if (end != start) if (end != start)
pathList.push_back(std::string(path, start, end - start)); pathList.push_back(std::string(genericPath, start, end - start));
start = end + 1; start = end + 1;
} }
// Add last folder / file to pathList. // Add last folder / file to pathList.
if (start != path.size()) if (start != genericPath.size())
pathList.push_back(std::string(path, start, path.size() - start)); pathList.push_back(std::string(genericPath, start, genericPath.size() - start));
return pathList; return pathList;
} }
void setHomePath(const std::string& _path) void setHomePath(const std::string& path)
{ {
homePath = getGenericPath(_path); homePath = getGenericPath(path);
} }
std::string getHomePath() std::string getHomePath()
@ -171,7 +171,7 @@ namespace Utils
"/" + Utils::String::wideStringToString(envHomePath)); "/" + Utils::String::wideStringToString(envHomePath));
} }
#else #else
// Check for HOME environment variable.
if (!homePath.length()) { if (!homePath.length()) {
std::string envHome = getenv("HOME"); std::string envHome = getenv("HOME");
if (envHome.length()) if (envHome.length())
@ -219,23 +219,23 @@ namespace Utils
#endif #endif
} }
void setExePath(const std::string& _path) void setExePath(const std::string& path)
{ {
constexpr int path_max = 32767; constexpr int pathMax = 32767;
#if defined(_WIN64) #if defined(_WIN64)
std::wstring result(path_max, 0); std::wstring result(pathMax, 0);
if (GetModuleFileNameW(nullptr, &result[0], path_max) != 0) if (GetModuleFileNameW(nullptr, &result[0], pathMax) != 0)
exePath = Utils::String::wideStringToString(result); exePath = Utils::String::wideStringToString(result);
#else #else
std::string result(path_max, 0); std::string result(pathMax, 0);
if (readlink("/proc/self/exe", &result[0], path_max) != -1) if (readlink("/proc/self/exe", &result[0], pathMax) != -1)
exePath = result; exePath = result;
#endif #endif
exePath = getCanonicalPath(exePath); exePath = getCanonicalPath(exePath);
// Fallback to argv[0] if everything else fails. // Fallback to argv[0] if everything else fails.
if (exePath.empty()) if (exePath.empty())
exePath = getCanonicalPath(_path); exePath = getCanonicalPath(path);
if (isRegularFile(exePath)) if (isRegularFile(exePath))
exePath = getParent(exePath); exePath = getParent(exePath);
} }
@ -254,49 +254,50 @@ namespace Utils
#endif #endif
} }
std::string getPreferredPath(const std::string& _path) std::string getPreferredPath(const std::string& path)
{ {
std::string path = _path; std::string preferredPath = path;
size_t offset = std::string::npos; size_t offset = std::string::npos;
#if defined(_WIN64) #if defined(_WIN64)
// Convert '/' to '\\' // Convert '/' to '\\'
while ((offset = path.find('/')) != std::string::npos) while ((offset = preferredPath.find('/')) != std::string::npos)
path.replace(offset, 1, "\\"); preferredPath.replace(offset, 1, "\\");
#endif #endif
return path; return preferredPath;
} }
std::string getGenericPath(const std::string& _path) std::string getGenericPath(const std::string& path)
{ {
std::string path = _path; std::string genericPath = path;
size_t offset = std::string::npos; size_t offset = std::string::npos;
// Remove "\\\\?\\" // Remove "\\\\?\\"
if ((path.find("\\\\?\\")) == 0) if ((genericPath.find("\\\\?\\")) == 0)
path.erase(0, 4); genericPath.erase(0, 4);
// Convert '\\' to '/' // Convert '\\' to '/'
while ((offset = path.find('\\')) != std::string::npos) while ((offset = genericPath.find('\\')) != std::string::npos)
path.replace(offset, 1 ,"/"); genericPath.replace(offset, 1 ,"/");
// Remove double '/' // Remove double '/'
while ((offset = path.find("//")) != std::string::npos) while ((offset = genericPath.find("//")) != std::string::npos)
path.erase(offset, 1); genericPath.erase(offset, 1);
// Remove trailing '/' when the path is more than a simple '/' // Remove trailing '/' when the path is more than a simple '/'
while (path.length() > 1 && ((offset = path.find_last_of('/')) == (path.length() - 1))) while (genericPath.length() > 1 && ((offset = genericPath.find_last_of('/')) ==
path.erase(offset, 1); (genericPath.length() - 1)))
genericPath.erase(offset, 1);
return path; return genericPath;
} }
std::string getEscapedPath(const std::string& _path) std::string getEscapedPath(const std::string& path)
{ {
std::string path = getGenericPath(_path); std::string escapedPath = getGenericPath(path);
#if defined(_WIN64) #if defined(_WIN64)
// Windows escapes stuff by just putting everything in quotes. // Windows escapes stuff by just putting everything in quotes.
return '"' + getPreferredPath(path) + '"'; return '"' + getPreferredPath(escapedPath) + '"';
#else #else
// Insert a backslash before most characters that would mess up a bash path. // Insert a backslash before most characters that would mess up a bash path.
const char* invalidChars = "\\ '\"!$^&*(){}[]?;<>"; const char* invalidChars = "\\ '\"!$^&*(){}[]?;<>";
@ -306,34 +307,34 @@ namespace Utils
size_t start = 0; size_t start = 0;
size_t offset = 0; size_t offset = 0;
while ((offset = path.find(*invalidChar, start)) != std::string::npos) { while ((offset = escapedPath.find(*invalidChar, start)) != std::string::npos) {
start = offset + 1; start = offset + 1;
if ((offset == 0) || (path[offset - 1] != '\\')) { if ((offset == 0) || (escapedPath[offset - 1] != '\\')) {
path.insert(offset, 1, '\\'); escapedPath.insert(offset, 1, '\\');
start++; start++;
} }
} }
invalidChar++; invalidChar++;
} }
return path; return escapedPath;
#endif #endif
} }
std::string getCanonicalPath(const std::string& _path) std::string getCanonicalPath(const std::string& path)
{ {
// Hack for builtin resources. // Hack for builtin resources.
if ((_path[0] == ':') && (_path[1] == '/')) if ((path[0] == ':') && (path[1] == '/'))
return _path; return path;
std::string path = exists(_path) ? getAbsolutePath(_path) : getGenericPath(_path); std::string canonicalPath = exists(path) ? getAbsolutePath(path) : getGenericPath(path);
// Cleanup path. // Cleanup path.
bool scan = true; bool scan = true;
while (scan) { while (scan) {
stringList pathList = getPathList(path); stringList pathList = getPathList(canonicalPath);
path.clear(); canonicalPath.clear();
scan = false; scan = false;
for (stringList::const_iterator it = pathList.cbegin(); for (stringList::const_iterator it = pathList.cbegin();
@ -348,87 +349,87 @@ namespace Utils
// Resolve "/../" // Resolve "/../"
if ((*it) == "..") { if ((*it) == "..") {
path = getParent(path); canonicalPath = getParent(canonicalPath);
continue; continue;
} }
#if defined(_WIN64) #if defined(_WIN64)
// Append folder to path. // Append folder to path.
path += (path.size() == 0) ? (*it) : ("/" + (*it)); canonicalPath += (canonicalPath.size() == 0) ? (*it) : ("/" + (*it));
#else #else
// Append folder to path. // Append folder to path.
path += ("/" + (*it)); canonicalPath += ("/" + (*it));
#endif #endif
// Resolve symlink. if (isSymlink(canonicalPath)) {
if (isSymlink(path)) { std::string resolved = resolveSymlink(canonicalPath);
std::string resolved = resolveSymlink(path);
if (resolved.empty()) if (resolved.empty())
return ""; return "";
if (isAbsolute(resolved)) if (isAbsolute(resolved))
path = resolved; canonicalPath = resolved;
else else
path = getParent(path) + "/" + resolved; canonicalPath = getParent(canonicalPath) + "/" + resolved;
for (++it; it != pathList.cend(); it++) for (++it; it != pathList.cend(); it++)
path += (path.size() == 0) ? (*it) : ("/" + (*it)); canonicalPath += (canonicalPath.size() == 0) ? (*it) : ("/" + (*it));
scan = true; scan = true;
break; break;
} }
} }
} }
return path; return canonicalPath;
} }
std::string getAbsolutePath(const std::string& _path, const std::string& _base) std::string getAbsolutePath(const std::string& path, const std::string& base)
{ {
std::string path = getGenericPath(_path); std::string absolutePath = getGenericPath(path);
std::string base = isAbsolute(_base) ? getGenericPath(_base) : getAbsolutePath(_base); std::string baseVar = isAbsolute(base) ? getGenericPath(base) : getAbsolutePath(base);
// Return absolute path. return isAbsolute(absolutePath) ? absolutePath :
return isAbsolute(path) ? path : getGenericPath(base + "/" + path); getGenericPath(baseVar + "/" + absolutePath);
} }
std::string getParent(const std::string& _path) std::string getParent(const std::string& path)
{ {
std::string path = getGenericPath(_path); std::string genericPath = getGenericPath(path);
size_t offset = std::string::npos; size_t offset = std::string::npos;
// Find last '/' and erase it. // Find last '/' and erase it.
if ((offset = path.find_last_of('/')) != std::string::npos) if ((offset = genericPath.find_last_of('/')) != std::string::npos)
return path.erase(offset); return genericPath.erase(offset);
// No parent found. // No parent found.
return path; return genericPath;
} }
std::string getFileName(const std::string& _path) std::string getFileName(const std::string& path)
{ {
std::string path = getGenericPath(_path); std::string genericPath = getGenericPath(path);
size_t offset = std::string::npos; size_t offset = std::string::npos;
// Find last '/' and return the filename. // Find last '/' and return the filename.
if ((offset = path.find_last_of('/')) != std::string::npos) if ((offset = genericPath.find_last_of('/')) != std::string::npos)
return ((path[offset + 1] == 0) ? "." : std::string(path, offset + 1)); return ((genericPath[offset + 1] == 0) ? "." :
std::string(genericPath, offset + 1));
// No '/' found, entire path is a filename. // No '/' found, entire path is a filename.
return path; return genericPath;
} }
std::string getStem(const std::string& _path) std::string getStem(const std::string& path)
{ {
std::string fileName = getFileName(_path); std::string fileName = getFileName(path);
size_t offset = std::string::npos; size_t offset = std::string::npos;
// Empty fileName. // Empty fileName.
if (fileName == ".") if (fileName == ".")
return fileName; return fileName;
if (!Utils::FileSystem::isDirectory(_path)) { if (!Utils::FileSystem::isDirectory(path)) {
// Find last '.' and erase the extension. // Find last '.' and erase the extension.
if ((offset = fileName.find_last_of('.')) != std::string::npos) if ((offset = fileName.find_last_of('.')) != std::string::npos)
return fileName.erase(offset); return fileName.erase(offset);
@ -438,9 +439,9 @@ namespace Utils
return fileName; return fileName;
} }
std::string getExtension(const std::string& _path) std::string getExtension(const std::string& path)
{ {
std::string fileName = getFileName(_path); std::string fileName = getFileName(path);
size_t offset = std::string::npos; size_t offset = std::string::npos;
// Empty fileName. // Empty fileName.
@ -455,82 +456,80 @@ namespace Utils
return "."; return ".";
} }
std::string expandHomePath(const std::string& _path) std::string expandHomePath(const std::string& path)
{ {
// Expand home path if ~ is used. // Expand home path if ~ is used.
std::string expandedPath = _path; std::string expandedPath = path;
expandedPath = Utils::String::replace(_path, "~", Utils::FileSystem::getHomePath()); expandedPath = Utils::String::replace(path, "~", Utils::FileSystem::getHomePath());
return expandedPath; return expandedPath;
} }
std::string resolveRelativePath(const std::string& _path, std::string resolveRelativePath(const std::string& path,
const std::string& _relativeTo, const bool _allowHome) const std::string& relativeTo, const bool allowHome)
{ {
std::string path = getGenericPath(_path); std::string genericPath = getGenericPath(path);
std::string relativeTo = isDirectory(_relativeTo) ? std::string relativeToVar = isDirectory(relativeTo) ?
getGenericPath(_relativeTo) : getParent(_relativeTo); getGenericPath(relativeTo) : getParent(relativeTo);
// Nothing to resolve. // Nothing to resolve.
if (!path.length()) if (!genericPath.length())
return path; return genericPath;
// Replace '.' with relativeTo. // Replace '.' with relativeToVar.
if ((path[0] == '.') && (path[1] == '/')) if ((genericPath[0] == '.') && (genericPath[1] == '/'))
return (relativeTo + &(path[1])); return (relativeToVar + &(genericPath[1]));
// Replace '~' with homePath. // Replace '~' with homePath.
if (_allowHome && (path[0] == '~') && (path[1] == '/')) if (allowHome && (genericPath[0] == '~') && (genericPath[1] == '/'))
return (getHomePath() + &(path[1])); return (getHomePath() + &(genericPath[1]));
// Nothing to resolve. // Nothing to resolve.
return path; return genericPath;
} }
std::string createRelativePath(const std::string& _path, std::string createRelativePath(const std::string& path,
const std::string& _relativeTo, const bool _allowHome) const std::string& relativeTo, const bool allowHome)
{ {
bool contains = false; bool contains = false;
std::string path = removeCommonPath(_path, _relativeTo, contains); std::string relativePath = removeCommonPath(path, relativeTo, contains);
if (contains) if (contains)
return ("./" + path); return ("./" + relativePath);
if (_allowHome) { if (allowHome) {
path = removeCommonPath(_path, getHomePath(), contains); relativePath = removeCommonPath(path, getHomePath(), contains);
if (contains) if (contains)
return ("~/" + path); return ("~/" + relativePath);
} }
return path; return relativePath;
} }
std::string removeCommonPath(const std::string& _path, std::string removeCommonPath(const std::string& path,
const std::string& _common, bool& _contains) const std::string& commonArg, bool& contains)
{ {
std::string path = getGenericPath(_path); std::string genericPath = getGenericPath(path);
std::string common = isDirectory(_common) ? std::string common = isDirectory(commonArg) ?
getGenericPath(_common) : getParent(_common); getGenericPath(commonArg) : getParent(commonArg);
// Check if path contains common. if (genericPath.find(common) == 0) {
if (path.find(common) == 0) { contains = true;
_contains = true; return genericPath.substr(common.length() + 1);
return path.substr(common.length() + 1);
} }
// It didn't. contains = false;
_contains = false; return genericPath;
return path;
} }
std::string resolveSymlink(const std::string& _path) std::string resolveSymlink(const std::string& path)
{ {
std::string path = getGenericPath(_path); std::string genericPath = getGenericPath(path);
std::string resolved; std::string resolved;
#if defined(_WIN64) #if defined(_WIN64)
std::wstring resolvedW; std::wstring resolvedW;
HANDLE hFile = CreateFileW(Utils::String::stringToWideString(path).c_str(), HANDLE hFile = CreateFileW(Utils::String::stringToWideString(genericPath).c_str(),
FILE_READ_ATTRIBUTES, FILE_SHARE_READ, 0, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, 0,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
if (hFile != INVALID_HANDLE_VALUE) { if (hFile != INVALID_HANDLE_VALUE) {
@ -547,9 +546,9 @@ namespace Utils
struct stat info; struct stat info;
// Check if lstat succeeded. // Check if lstat succeeded.
if (lstat(path.c_str(), &info) == 0) { if (lstat(genericPath.c_str(), &info) == 0) {
resolved.resize(info.st_size); resolved.resize(info.st_size);
if (readlink(path.c_str(), const_cast<char*>(resolved.data()), if (readlink(genericPath.c_str(), const_cast<char*>(resolved.data()),
resolved.size()) > 0) resolved.size()) > 0)
resolved = getGenericPath(resolved); resolved = getGenericPath(resolved);
} }
@ -557,50 +556,50 @@ namespace Utils
return resolved; return resolved;
} }
bool copyFile(const std::string& _source_path, bool copyFile(const std::string& sourcePath,
const std::string& _destination_path, bool _overwrite) const std::string& destinationPath, bool overwrite)
{ {
if (!exists(_source_path)) { if (!exists(sourcePath)) {
LOG(LogError) << "Can't copy file, source file does not exist:"; LOG(LogError) << "Can't copy file, source file does not exist:";
LOG(LogError) << _source_path; LOG(LogError) << sourcePath;
return true; return true;
} }
if (isDirectory(_destination_path)) { if (isDirectory(destinationPath)) {
LOG(LogError) << "Destination file is actually a directory:"; LOG(LogError) << "Destination file is actually a directory:";
LOG(LogError) << _destination_path; LOG(LogError) << destinationPath;
return true; return true;
} }
if (!_overwrite && exists(_destination_path)) { if (!overwrite && exists(destinationPath)) {
LOG(LogError) << "Destination file exists and the overwrite flag " LOG(LogError) << "Destination file exists and the overwrite flag "
"has not been set"; "has not been set";
return true; return true;
} }
#if defined(_WIN64) #if defined(_WIN64)
std::ifstream sourceFile(Utils::String::stringToWideString(_source_path).c_str(), std::ifstream sourceFile(
std::ios::binary); Utils::String::stringToWideString(sourcePath).c_str(), std::ios::binary);
#else #else
std::ifstream sourceFile(_source_path, std::ios::binary); std::ifstream sourceFile(sourcePath, std::ios::binary);
#endif #endif
if (sourceFile.fail()) { if (sourceFile.fail()) {
LOG(LogError) << "Couldn't read from source file \"" << _source_path << LOG(LogError) << "Couldn't read from source file \"" << sourcePath <<
"\", permission problems?"; "\", permission problems?";
sourceFile.close(); sourceFile.close();
return true; return true;
} }
#if defined(_WIN64) #if defined(_WIN64)
std::ofstream targetFile(Utils::String::stringToWideString(_destination_path).c_str(), std::ofstream targetFile(
std::ios::binary); Utils::String::stringToWideString(destinationPath).c_str(), std::ios::binary);
#else #else
std::ofstream targetFile(_destination_path, std::ios::binary); std::ofstream targetFile(destinationPath, std::ios::binary);
#endif #endif
if (targetFile.fail()) { if (targetFile.fail()) {
LOG(LogError) << "Couldn't write to target file \"" << _destination_path << LOG(LogError) << "Couldn't write to target file \"" << destinationPath <<
"\", permission problems?"; "\", permission problems?";
targetFile.close(); targetFile.close();
return true; return true;
@ -614,66 +613,65 @@ namespace Utils
return false; return false;
} }
bool renameFile(const std::string& _source_path, bool renameFile(const std::string& sourcePath,
const std::string& _destination_path, bool _overwrite) const std::string& destinationPath, bool overwrite)
{ {
// Don't print any error message for a missing source file as Log will use this // Don't print any error message for a missing source file as Log will use this
// function when initializing the logging. It would always generate an error in // function when initializing the logging. It would always generate an error in
// case it's the first application start (as an old log file would then not exist). // case it's the first application start (as an old log file would then not exist).
if (!exists(_source_path)) { if (!exists(sourcePath)) {
return true; return true;
} }
if (isDirectory(_destination_path)) { if (isDirectory(destinationPath)) {
LOG(LogError) << "Destination file is actually a directory:"; LOG(LogError) << "Destination file is actually a directory:";
LOG(LogError) << _destination_path; LOG(LogError) << destinationPath;
return true; return true;
} }
if (!_overwrite && exists(_destination_path)) { if (!overwrite && exists(destinationPath)) {
LOG(LogError) << "Destination file exists and the overwrite flag " LOG(LogError) << "Destination file exists and the overwrite flag "
"has not been set"; "has not been set";
return true; return true;
} }
#if defined(_WIN64) #if defined(_WIN64)
_wrename(Utils::String::stringToWideString(_source_path).c_str(), _wrename(Utils::String::stringToWideString(sourcePath).c_str(),
Utils::String::stringToWideString(_destination_path).c_str()); Utils::String::stringToWideString(destinationPath).c_str());
#else #else
std::rename(_source_path.c_str(), _destination_path.c_str()); std::rename(sourcePath.c_str(), destinationPath.c_str());
#endif #endif
return false; return false;
} }
bool removeFile(const std::string& _path) bool removeFile(const std::string& path)
{ {
std::string path = getGenericPath(_path); std::string genericPath = getGenericPath(path);
// Don't remove if it doesn't exists. // Don't remove if it doesn't exists.
if (!exists(path)) if (!exists(genericPath))
return true; return true;
// Try to remove file.
#if defined(_WIN64) #if defined(_WIN64)
if (_wunlink(Utils::String::stringToWideString(path).c_str()) != 0) { if (_wunlink(Utils::String::stringToWideString(genericPath).c_str()) != 0) {
LOG(LogError) << "Couldn't delete file, permission problems?"; LOG(LogError) << "Couldn't delete file, permission problems?";
LOG(LogError) << path; LOG(LogError) << genericPath;
return true; return true;
} }
else { else {
return false; return false;
} }
#else #else
if (unlink(path.c_str()) != 0) { if (unlink(genericPath.c_str()) != 0) {
LOG(LogError) << "Couldn't delete file, permission problems?"; LOG(LogError) << "Couldn't delete file, permission problems?";
LOG(LogError) << path; LOG(LogError) << genericPath;
return true; return true;
} }
else { else {
return false; return false;
} }
return (unlink(path.c_str()) == 0); return (unlink(genericPath.c_str()) == 0);
#endif #endif
} }
@ -701,99 +699,97 @@ namespace Utils
return true; return true;
} }
bool createDirectory(const std::string& _path) bool createDirectory(const std::string& path)
{ {
std::string path = getGenericPath(_path); std::string genericPath = getGenericPath(path);
// Don't create if it already exists. if (exists(genericPath))
if (exists(path))
return true; return true;
// Try to create directory.
#if defined(_WIN64) #if defined(_WIN64)
if (_wmkdir(Utils::String::stringToWideString(path).c_str()) == 0) if (_wmkdir(Utils::String::stringToWideString(genericPath).c_str()) == 0)
return true; return true;
#else #else
if (mkdir(path.c_str(), 0755) == 0) if (mkdir(genericPath.c_str(), 0755) == 0)
return true; return true;
#endif #endif
// Failed to create directory, try to create the parent. // Failed to create directory, try to create the parent.
std::string parent = getParent(path); std::string parent = getParent(genericPath);
// Only try to create parent if it's not identical to path. // Only try to create parent if it's not identical to genericPath.
if (parent != path) if (parent != genericPath)
createDirectory(parent); createDirectory(parent);
// Try to create directory again now that the parent should exist. // Try to create directory again now that the parent should exist.
#if defined(_WIN64) #if defined(_WIN64)
return (_wmkdir(Utils::String::stringToWideString(path).c_str()) == 0); return (_wmkdir(Utils::String::stringToWideString(genericPath).c_str()) == 0);
#else #else
return (mkdir(path.c_str(), 0755) == 0); return (mkdir(genericPath.c_str(), 0755) == 0);
#endif #endif
} }
bool exists(const std::string& _path) bool exists(const std::string& path)
{ {
std::string path = getGenericPath(_path); std::string genericPath = getGenericPath(path);
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
struct stat info; struct stat info;
return (stat(path.c_str(), &info) == 0); return (stat(genericPath.c_str(), &info) == 0);
#elif defined(_WIN64) #elif defined(_WIN64)
struct _stat64 info; struct _stat64 info;
return (_wstat64(Utils::String::stringToWideString(path).c_str(), &info) == 0); return (_wstat64(Utils::String::stringToWideString(genericPath).c_str(), &info) == 0);
#else #else
struct stat64 info; struct stat64 info;
return (stat64(path.c_str(), &info) == 0); return (stat64(genericPath.c_str(), &info) == 0);
#endif #endif
} }
bool driveExists(const std::string& _path) bool driveExists(const std::string& path)
{ {
#if defined(_WIN64) #if defined(_WIN64)
std::string path = getGenericPath(_path); std::string genericPath = getGenericPath(path);
// Try to add a dot or a backslash and a dot depending on how the drive // Try to add a dot or a backslash and a dot depending on how the drive
// letter was defined by the user. // letter was defined by the user.
if (path.length() == 2 && path.at(1) == ':') if (genericPath.length() == 2 && genericPath.at(1) == ':')
path += "\\."; genericPath += "\\.";
else if (path.length() == 3 && path.at(1) == ':') else if (genericPath.length() == 3 && genericPath.at(1) == ':')
path += "."; genericPath += ".";
struct _stat64 info; struct _stat64 info;
return (_wstat64(Utils::String::stringToWideString(path).c_str(), &info) == 0); return (_wstat64(Utils::String::stringToWideString(genericPath).c_str(), &info) == 0);
#else #else
return false; return false;
#endif #endif
} }
bool isAbsolute(const std::string& _path) bool isAbsolute(const std::string& path)
{ {
std::string path = getGenericPath(_path); std::string genericPath = getGenericPath(path);
#if defined(_WIN64) #if defined(_WIN64)
return ((path.size() > 1) && (path[1] == ':')); return ((genericPath.size() > 1) && (genericPath[1] == ':'));
#else #else
return ((path.size() > 0) && (path[0] == '/')); return ((genericPath.size() > 0) && (genericPath[0] == '/'));
#endif #endif
} }
bool isRegularFile(const std::string& _path) bool isRegularFile(const std::string& path)
{ {
std::string path = getGenericPath(_path); std::string genericPath = getGenericPath(path);
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
struct stat info; struct stat info;
if (stat(path.c_str(), &info) != 0) if (stat(genericPath.c_str(), &info) != 0)
return false; return false;
#elif defined(_WIN64) #elif defined(_WIN64)
struct stat64 info; struct stat64 info;
if (_wstat64(Utils::String::stringToWideString(path).c_str(), &info) != 0) if (_wstat64(Utils::String::stringToWideString(genericPath).c_str(), &info) != 0)
return false; return false;
#else #else
struct stat64 info; struct stat64 info;
if (stat64(path.c_str(), &info) != 0) if (stat64(genericPath.c_str(), &info) != 0)
return false; return false;
#endif #endif
@ -801,21 +797,21 @@ namespace Utils
return (S_ISREG(info.st_mode)); return (S_ISREG(info.st_mode));
} }
bool isDirectory(const std::string& _path) bool isDirectory(const std::string& path)
{ {
std::string path = getGenericPath(_path); std::string genericPath = getGenericPath(path);
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
struct stat info; struct stat info;
if (stat(path.c_str(), &info) != 0) if (stat(genericPath.c_str(), &info) != 0)
return false; return false;
#elif defined(_WIN64) #elif defined(_WIN64)
struct stat64 info; struct stat64 info;
if (_wstat64(Utils::String::stringToWideString(path).c_str(), &info) != 0) if (_wstat64(Utils::String::stringToWideString(genericPath).c_str(), &info) != 0)
return false; return false;
#else #else
struct stat64 info; struct stat64 info;
if (stat64(path.c_str(), &info) != 0) if (stat64(genericPath.c_str(), &info) != 0)
return false; return false;
#endif #endif
@ -823,14 +819,14 @@ namespace Utils
return (S_ISDIR(info.st_mode)); return (S_ISDIR(info.st_mode));
} }
bool isSymlink(const std::string& _path) bool isSymlink(const std::string& path)
{ {
std::string path = getGenericPath(_path); std::string genericPath = getGenericPath(path);
#if defined(_WIN64) #if defined(_WIN64)
// Check for symlink attribute. // Check for symlink attribute.
const DWORD Attributes = const DWORD Attributes =
GetFileAttributesW(Utils::String::stringToWideString(path).c_str()); GetFileAttributesW(Utils::String::stringToWideString(genericPath).c_str());
if ((Attributes != INVALID_FILE_ATTRIBUTES) && if ((Attributes != INVALID_FILE_ATTRIBUTES) &&
(Attributes & FILE_ATTRIBUTE_REPARSE_POINT)) (Attributes & FILE_ATTRIBUTE_REPARSE_POINT))
return true; return true;
@ -839,12 +835,12 @@ namespace Utils
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
struct stat info; struct stat info;
if (lstat(path.c_str(), &info) != 0) if (lstat(genericPath.c_str(), &info) != 0)
return false; return false;
#else #else
struct stat64 info; struct stat64 info;
if (lstat64(path.c_str(), &info) != 0) if (lstat64(genericPath.c_str(), &info) != 0)
return false; return false;
#endif #endif
@ -856,25 +852,26 @@ namespace Utils
return false; return false;
} }
bool isHidden(const std::string& _path) bool isHidden(const std::string& path)
{ {
std::string path = getGenericPath(_path); std::string genericPath = getGenericPath(path);
#if defined(_WIN64) #if defined(_WIN64)
// Check for hidden attribute. // Check for hidden attribute.
const DWORD Attributes = const DWORD Attributes =
GetFileAttributesW(Utils::String::stringToWideString(path).c_str()); GetFileAttributesW(Utils::String::stringToWideString(genericPath).c_str());
if ((Attributes != INVALID_FILE_ATTRIBUTES) && (Attributes & FILE_ATTRIBUTE_HIDDEN)) if ((Attributes != INVALID_FILE_ATTRIBUTES) && (Attributes & FILE_ATTRIBUTE_HIDDEN))
return true; return true;
#endif // _WIN64 #endif
// Filenames starting with . are hidden in Linux, but // Filenames starting with . are hidden in Linux, but
// we do this check for windows as well. // we do this check for windows as well.
if (getFileName(path)[0] == '.') if (getFileName(genericPath)[0] == '.')
return true; return true;
return false; return false;
} }
} // FileSystem:: } // FileSystem::
} // Utils:: } // Utils::

View file

@ -20,49 +20,47 @@ namespace Utils
{ {
typedef std::list<std::string> stringList; typedef std::list<std::string> stringList;
stringList getDirContent(const std::string& _path, stringList getDirContent(const std::string& path, const bool recursive = false);
const bool _recursive = false); stringList getPathList(const std::string& path);
stringList getPathList(const std::string& _path); void setHomePath(const std::string& path);
void setHomePath(const std::string& _path);
std::string getHomePath(); std::string getHomePath();
std::string getCWDPath(); std::string getCWDPath();
std::string getPathToBinary(const std::string& executable); std::string getPathToBinary(const std::string& executable);
void setExePath(const std::string& _path); void setExePath(const std::string& path);
std::string getExePath(); std::string getExePath();
std::string getProgramDataPath(); std::string getProgramDataPath();
std::string getPreferredPath(const std::string& _path); std::string getPreferredPath(const std::string& path);
std::string getGenericPath(const std::string& _path); std::string getGenericPath(const std::string& path);
std::string getEscapedPath(const std::string& _path); std::string getEscapedPath(const std::string& path);
std::string getCanonicalPath(const std::string& _path); std::string getCanonicalPath(const std::string& path);
std::string getAbsolutePath(const std::string& _path, std::string getAbsolutePath(const std::string& path,
const std::string& _base = getCWDPath()); const std::string& base = getCWDPath());
std::string getParent(const std::string& _path); std::string getParent(const std::string& path);
std::string getFileName(const std::string& _path); std::string getFileName(const std::string& path);
std::string getStem(const std::string& _path); std::string getStem(const std::string& path);
std::string getExtension(const std::string& _path); std::string getExtension(const std::string& path);
std::string expandHomePath(const std::string& _path); std::string expandHomePath(const std::string& path);
std::string resolveRelativePath(const std::string& _path, std::string resolveRelativePath(const std::string& path,
const std::string& _relativeTo, const bool _allowHome); const std::string& relativeTo, const bool allowHome);
std::string createRelativePath(const std::string& _path, std::string createRelativePath(const std::string& path,
const std::string& _relativeTo, const bool _allowHome); const std::string& relativeTo, const bool allowHome);
std::string removeCommonPath(const std::string& _path, std::string removeCommonPath(const std::string& path,
const std::string& _common, bool& _contains); const std::string& commonArg, bool& contains);
std::string resolveSymlink(const std::string& _path); std::string resolveSymlink(const std::string& path);
bool copyFile(const std::string& _source_path, bool copyFile(const std::string& sourcePath,
const std::string& _destination_path, bool _overwrite); const std::string& destinationPath, bool overwrite);
bool renameFile(const std::string& _source_path, bool renameFile(const std::string& sourcePath,
const std::string& _destination_path, bool _overwrite); const std::string& destinationPath, bool overwrite);
bool removeFile(const std::string& _path); bool removeFile(const std::string& path);
bool removeDirectory(const std::string& path); bool removeDirectory(const std::string& path);
bool createDirectory(const std::string& path);
bool createDirectory(const std::string& _path); bool exists(const std::string& path);
bool exists(const std::string& _path); bool driveExists(const std::string& path);
bool driveExists(const std::string& _path); bool isAbsolute(const std::string& path);
bool isAbsolute(const std::string& _path); bool isRegularFile(const std::string& path);
bool isRegularFile(const std::string& _path); bool isDirectory(const std::string& path);
bool isDirectory(const std::string& _path); bool isSymlink(const std::string& path);
bool isSymlink(const std::string& _path); bool isHidden(const std::string& path);
bool isHidden(const std::string& _path);
} }
} }

View file

@ -12,7 +12,6 @@
#include <algorithm> #include <algorithm>
#include <codecvt> #include <codecvt>
#include <locale> #include <locale>
#include <stdarg.h>
namespace Utils namespace Utils
{ {
@ -176,70 +175,70 @@ namespace Utils
(wchar_t)0xFF32, (wchar_t)0xFF33, (wchar_t)0xFF34, (wchar_t)0xFF35, (wchar_t)0xFF36, (wchar_t)0xFF37, (wchar_t)0xFF38, (wchar_t)0xFF39, (wchar_t)0xFF3A (wchar_t)0xFF32, (wchar_t)0xFF33, (wchar_t)0xFF34, (wchar_t)0xFF35, (wchar_t)0xFF36, (wchar_t)0xFF37, (wchar_t)0xFF38, (wchar_t)0xFF39, (wchar_t)0xFF3A
}; };
unsigned int chars2Unicode(const std::string& _string, size_t& _cursor) unsigned int chars2Unicode(const std::string& stringArg, size_t& cursor)
{ {
unsigned const char checkCharType = _string[_cursor]; unsigned const char checkCharType = stringArg[cursor];
unsigned int result = '?'; unsigned int result = '?';
// 0xxxxxxx, one byte character. // 0xxxxxxx, one byte character.
if (checkCharType <= 0x7F) { if (checkCharType <= 0x7F) {
// 0xxxxxxx // 0xxxxxxx
result = ((_string[_cursor++])); result = ((stringArg[cursor++]));
} }
// 11110xxx, four byte character. // 11110xxx, four byte character.
else if (checkCharType >= 0xF0) { else if (checkCharType >= 0xF0) {
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
result = (_string[_cursor++] & 0x07) << 18; result = (stringArg[cursor++] & 0x07) << 18;
result |= (_string[_cursor++] & 0x3F) << 12; result |= (stringArg[cursor++] & 0x3F) << 12;
result |= (_string[_cursor++] & 0x3F) << 6; result |= (stringArg[cursor++] & 0x3F) << 6;
result |= _string[_cursor++] & 0x3F; result |= stringArg[cursor++] & 0x3F;
} }
// 1110xxxx, three byte character. // 1110xxxx, three byte character.
else if (checkCharType >= 0xE0) { else if (checkCharType >= 0xE0) {
// 1110xxxx 10xxxxxx 10xxxxxx // 1110xxxx 10xxxxxx 10xxxxxx
result = (_string[_cursor++] & 0x0F) << 12; result = (stringArg[cursor++] & 0x0F) << 12;
result |= (_string[_cursor++] & 0x3F) << 6; result |= (stringArg[cursor++] & 0x3F) << 6;
result |= _string[_cursor++] & 0x3F; result |= stringArg[cursor++] & 0x3F;
} }
// 110xxxxx, two byte character. // 110xxxxx, two byte character.
else if (checkCharType >= 0xC0) { else if (checkCharType >= 0xC0) {
// 110xxxxx 10xxxxxx // 110xxxxx 10xxxxxx
result = (_string[_cursor++] & 0x1F) << 6; result = (stringArg[cursor++] & 0x1F) << 6;
result |= _string[_cursor++] & 0x3F; result |= stringArg[cursor++] & 0x3F;
} }
else { else {
// Error, invalid character. // Error, invalid character.
_cursor++; cursor++;
} }
return result; return result;
} }
std::string unicode2Chars(const unsigned int _unicode) std::string unicode2Chars(const unsigned int unicodeArg)
{ {
std::string result; std::string result;
// Normal UTF-8 ASCII character. // Normal UTF-8 ASCII character.
if (_unicode < 0x80) { if (unicodeArg < 0x80) {
result += ((_unicode ) & 0xFF); result += ((unicodeArg ) & 0xFF);
} }
// Two-byte character. // Two-byte character.
else if (_unicode < 0x800) { else if (unicodeArg < 0x800) {
result += ((_unicode >> 6) & 0xFF) | 0xC0; result += ((unicodeArg >> 6) & 0xFF) | 0xC0;
result += ((_unicode ) & 0x3F) | 0x80; result += ((unicodeArg ) & 0x3F) | 0x80;
} }
// Three-byte character. // Three-byte character.
else if (_unicode < 0xFFFF) { else if (unicodeArg < 0xFFFF) {
result += ((_unicode >> 12) & 0xFF) | 0xE0; result += ((unicodeArg >> 12) & 0xFF) | 0xE0;
result += ((_unicode >> 6) & 0x3F) | 0x80; result += ((unicodeArg >> 6) & 0x3F) | 0x80;
result += ((_unicode ) & 0x3F) | 0x80; result += ((unicodeArg ) & 0x3F) | 0x80;
} }
// Four-byte character. // Four-byte character.
else if (_unicode <= 0x1fffff) { else if (unicodeArg <= 0x1fffff) {
result += ((_unicode >> 18) & 0xFF) | 0xF0; result += ((unicodeArg >> 18) & 0xFF) | 0xF0;
result += ((_unicode >> 12) & 0x3F) | 0x80; result += ((unicodeArg >> 12) & 0x3F) | 0x80;
result += ((_unicode >> 6) & 0x3F) | 0x80; result += ((unicodeArg >> 6) & 0x3F) | 0x80;
result += ((_unicode ) & 0x3F) | 0x80; result += ((unicodeArg ) & 0x3F) | 0x80;
} }
else { else {
// Error, invalid character. // Error, invalid character.
@ -249,100 +248,100 @@ namespace Utils
return result; return result;
} }
std::string getFirstCharacter(const std::string& _string, bool _toUpper) std::string getFirstCharacter(const std::string& stringArg, bool toUpper)
{ {
std::string firstChar; std::string firstChar;
unsigned const char checkCharType = _string.front(); unsigned const char checkCharType = stringArg.front();
// Normal UTF-8 ASCII character. // Normal UTF-8 ASCII character.
if (checkCharType <= 0x7F) if (checkCharType <= 0x7F)
(_toUpper) ? firstChar = toupper(_string.front()) : firstChar = _string.front(); (toUpper) ? firstChar = toupper(stringArg.front()) : firstChar = stringArg.front();
// Four-byte Unicode character. // Four-byte Unicode character.
else if (checkCharType >= 0xF0) else if (checkCharType >= 0xF0)
firstChar = _string.substr(0, 4); firstChar = stringArg.substr(0, 4);
// Three-byte Unicode character. // Three-byte Unicode character.
else if (checkCharType >= 0xE0) else if (checkCharType >= 0xE0)
firstChar = _string.substr(0, 3); firstChar = stringArg.substr(0, 3);
// Two-byte Unicode character. // Two-byte Unicode character.
else if (checkCharType >= 0xC0) else if (checkCharType >= 0xC0)
firstChar = _string.substr(0, 2); firstChar = stringArg.substr(0, 2);
return firstChar; return firstChar;
} }
size_t nextCursor(const std::string& _string, const size_t _cursor) size_t nextCursor(const std::string& stringArg, const size_t cursor)
{ {
size_t result = _cursor; size_t result = cursor;
while (result < _string.length()) { while (result < stringArg.length()) {
result++; result++;
// Break if current character is not 10xxxxxx // Break if current character is not 10xxxxxx
if ((_string[result] & 0xC0) != 0x80) if ((stringArg[result] & 0xC0) != 0x80)
break; break;
} }
return result; return result;
} }
size_t prevCursor(const std::string& _string, const size_t _cursor) size_t prevCursor(const std::string& stringArg, const size_t cursor)
{ {
size_t result = _cursor; size_t result = cursor;
while (result > 0) { while (result > 0) {
--result; result--;
// Break if current character is not 10xxxxxx // Break if current character is not 10xxxxxx
if ((_string[result] & 0xC0) != 0x80) if ((stringArg[result] & 0xC0) != 0x80)
break; break;
} }
return result; return result;
} }
size_t moveCursor(const std::string& _string, const size_t _cursor, const int _amount) size_t moveCursor(const std::string& stringArg, const size_t cursor, const int amount)
{ {
size_t result = _cursor; size_t result = cursor;
if (_amount > 0) { if (amount > 0) {
for (int i = 0; i < _amount; i++) for (int i = 0; i < amount; i++)
result = nextCursor(_string, result); result = nextCursor(stringArg, result);
} }
else if (_amount < 0) { else if (amount < 0) {
for (int i = _amount; i < 0; i++) for (int i = amount; i < 0; i++)
result = prevCursor(_string, result); result = prevCursor(stringArg, result);
} }
return result; return result;
} }
std::string toLower(const std::string& _string) std::string toLower(const std::string& stringArg)
{ {
std::string string; std::string stringLower;
unsigned char checkCharType; unsigned char checkCharType;
for (size_t i = 0; i < _string.length();) { for (size_t i = 0; i < stringArg.length();) {
checkCharType = _string[i]; checkCharType = stringArg[i];
// Normal UTF-8 ASCII character. // Normal UTF-8 ASCII character.
if (checkCharType <= 0x7F) { if (checkCharType <= 0x7F) {
string += static_cast<char>(tolower(_string[i])); stringLower += static_cast<char>(tolower(stringArg[i]));
i++; i++;
} }
// Four-byte Unicode character, no case conversion done. // Four-byte Unicode character, no case conversion done.
else if (checkCharType >= 0xF0) { else if (checkCharType >= 0xF0) {
string += _string.substr(i, 4); stringLower += stringArg.substr(i, 4);
i += 4; i += 4;
} }
// Three-byte Unicode character, no case conversion done. // Three-byte Unicode character, no case conversion done.
else if (checkCharType >= 0xE0) { else if (checkCharType >= 0xE0) {
string += _string.substr(i, 3); stringLower += stringArg.substr(i, 3);
i += 3; i += 3;
} }
// Two-byte Unicode character. // Two-byte Unicode character.
else if (checkCharType >= 0xC0) { else if (checkCharType >= 0xC0) {
// Extract the Unicode code point from the two bytes. // Extract the Unicode code point from the two bytes.
wchar_t firstChar = (_string[i] & 0x1F) << 6; wchar_t firstChar = (stringArg[i] & 0x1F) << 6;
wchar_t secondChar = _string[i + 1] & 0x3F; wchar_t secondChar = stringArg[i + 1] & 0x3F;
wchar_t unicodeChar = firstChar | secondChar; wchar_t unicodeChar = firstChar | secondChar;
// Try to find an entry for the character in the Unicode uppercase table. // Try to find an entry for the character in the Unicode uppercase table.
@ -354,48 +353,48 @@ namespace Utils
typedef std::codecvt_utf8<wchar_t> convert_type; typedef std::codecvt_utf8<wchar_t> convert_type;
std::wstring_convert<convert_type, wchar_t> byteConverter; std::wstring_convert<convert_type, wchar_t> byteConverter;
string += byteConverter.to_bytes(lowerChar); stringLower += byteConverter.to_bytes(lowerChar);
} }
else { else {
// We normally end up here if the character is a space, or if it's // We normally end up here if the character is a space, or if it's
// already in lowercase. // already in lowercase.
string += _string[i]; stringLower += stringArg[i];
string += _string[i + 1]; stringLower += stringArg[i + 1];
} }
i += 2; i += 2;
} }
} }
return string; return stringLower;
} }
std::string toUpper(const std::string& _string) std::string toUpper(const std::string& stringArg)
{ {
std::string string; std::string stringUpper;
unsigned char checkCharType; unsigned char checkCharType;
for (size_t i = 0; i < _string.length();) { for (size_t i = 0; i < stringArg.length();) {
checkCharType = _string[i]; checkCharType = stringArg[i];
// Normal UTF-8 ASCII character. // Normal UTF-8 ASCII character.
if (checkCharType <= 0x7F) { if (checkCharType <= 0x7F) {
string += static_cast<char>(toupper(_string[i])); stringUpper += static_cast<char>(toupper(stringArg[i]));
i++; i++;
} }
// Four-byte Unicode character, no case conversion done. // Four-byte Unicode character, no case conversion done.
else if (checkCharType >= 0xF0) { else if (checkCharType >= 0xF0) {
string += _string.substr(i, 4); stringUpper += stringArg.substr(i, 4);
i += 4; i += 4;
} }
// Three-byte Unicode character, no case conversion done. // Three-byte Unicode character, no case conversion done.
else if (checkCharType >= 0xE0) { else if (checkCharType >= 0xE0) {
string += _string.substr(i, 3); stringUpper += stringArg.substr(i, 3);
i += 3; i += 3;
} }
// Two-byte Unicode character. // Two-byte Unicode character.
else if (checkCharType >= 0xC0) { else if (checkCharType >= 0xC0) {
// Extract the Unicode code point from the two bytes. // Extract the Unicode code point from the two bytes.
wchar_t firstChar = (_string[i] & 0x1F) << 6; wchar_t firstChar = (stringArg[i] & 0x1F) << 6;
wchar_t secondChar = _string[i + 1] & 0x3F; wchar_t secondChar = stringArg[i + 1] & 0x3F;
wchar_t unicodeChar = firstChar | secondChar; wchar_t unicodeChar = firstChar | secondChar;
// Try to find an entry for the character in the Unicode lowercase table. // Try to find an entry for the character in the Unicode lowercase table.
@ -407,74 +406,75 @@ namespace Utils
typedef std::codecvt_utf8<wchar_t> convert_type; typedef std::codecvt_utf8<wchar_t> convert_type;
std::wstring_convert<convert_type, wchar_t> byteConverter; std::wstring_convert<convert_type, wchar_t> byteConverter;
string += byteConverter.to_bytes(upperChar); stringUpper += byteConverter.to_bytes(upperChar);
} }
else { else {
// We normally end up here if the character is a space, or if it's // We normally end up here if the character is a space, or if it's
// already in uppercase. // already in uppercase.
string += _string[i]; stringUpper += stringArg[i];
string += _string[i + 1]; stringUpper += stringArg[i + 1];
} }
i += 2; i += 2;
} }
} }
return string; return stringUpper;
} }
std::string trim(const std::string& _string) std::string trim(const std::string& stringArg)
{ {
const size_t strBegin = _string.find_first_not_of(" \t"); const size_t strBegin = stringArg.find_first_not_of(" \t");
const size_t strEnd = _string.find_last_not_of(" \t"); const size_t strEnd = stringArg.find_last_not_of(" \t");
if (strBegin == std::string::npos) if (strBegin == std::string::npos)
return ""; return "";
return _string.substr(strBegin, strEnd - strBegin + 1); return stringArg.substr(strBegin, strEnd - strBegin + 1);
} }
std::string replace(const std::string& _string, const std::string& _replace, std::string replace(const std::string& stringArg, const std::string& replace,
const std::string& _with) const std::string& with)
{ {
std::string string = _string; std::string stringReplace = stringArg;
size_t pos; size_t pos;
while ((pos = string.find(_replace)) != std::string::npos) while ((pos = stringReplace.find(replace)) != std::string::npos)
string = string.replace(pos, _replace.length(), _with.c_str(), _with.length()); stringReplace = stringReplace.replace(pos, replace.length(),
with.c_str(), with.length());
return string; return stringReplace;
} }
std::wstring stringToWideString(const std::string& _string) std::wstring stringToWideString(const std::string& stringArg)
{ {
typedef std::codecvt_utf8<wchar_t> convert_type; typedef std::codecvt_utf8<wchar_t> convert_type;
std::wstring_convert<convert_type, wchar_t> stringConverter; std::wstring_convert<convert_type, wchar_t> stringConverter;
return stringConverter.from_bytes(_string); return stringConverter.from_bytes(stringArg);
} }
std::string wideStringToString(const std::wstring& _string) std::string wideStringToString(const std::wstring& stringArg)
{ {
typedef std::codecvt_utf8<wchar_t> convert_type; typedef std::codecvt_utf8<wchar_t> convert_type;
std::wstring_convert<convert_type, wchar_t> stringConverter; std::wstring_convert<convert_type, wchar_t> stringConverter;
return stringConverter.to_bytes(_string); return stringConverter.to_bytes(stringArg);
} }
bool startsWith(const std::string& _string, const std::string& _start) bool startsWith(const std::string& stringArg, const std::string& start)
{ {
return (_string.find(_start) == 0); return (stringArg.find(start) == 0);
} }
bool endsWith(const std::string& _string, const std::string& _end) bool endsWith(const std::string& stringArg, const std::string& end)
{ {
return (_string.find(_end) == (_string.size() - _end.size())); return (stringArg.find(end) == (stringArg.size() - end.size()));
} }
std::string removeParenthesis(const std::string& _string) std::string removeParenthesis(const std::string& stringArg)
{ {
static std::vector<char> remove = { '(', ')', '[', ']' }; static std::vector<char> remove = { '(', ')', '[', ']' };
std::string string = _string; std::string stringRemove = stringArg;
size_t start; size_t start;
size_t end; size_t end;
bool done = false; bool done = false;
@ -483,97 +483,74 @@ namespace Utils
done = true; done = true;
for (size_t i = 0; i < remove.size(); i += 2) { for (size_t i = 0; i < remove.size(); i += 2) {
end = string.find_first_of(remove[i + 1]); end = stringRemove.find_first_of(remove[i + 1]);
start = string.find_last_of(remove[i + 0], end); start = stringRemove.find_last_of(remove[i + 0], end);
if ((start != std::string::npos) && (end != std::string::npos)) { if ((start != std::string::npos) && (end != std::string::npos)) {
string.erase(start, end - start + 1); stringRemove.erase(start, end - start + 1);
done = false; done = false;
} }
} }
} }
return trim(string); return trim(stringRemove);
} }
std::vector<std::string> delimitedStringToVector(const std::string& _string, std::vector<std::string> delimitedStringToVector(const std::string& stringArg,
const std::string& _delimiter, bool sort, bool caseInsensitive) const std::string& delimiter, bool sort, bool caseInsensitive)
{ {
std::vector<std::string> vector; std::vector<std::string> vectorResult;
size_t start = 0; size_t start = 0;
size_t comma = _string.find(_delimiter); size_t delimPos = stringArg.find(delimiter);
while (comma != std::string::npos) { while (delimPos != std::string::npos) {
vector.push_back(_string.substr(start, comma - start)); vectorResult.push_back(stringArg.substr(start, delimPos - start));
start = comma + 1; start = delimPos + 1;
comma = _string.find(_delimiter, start); delimPos = stringArg.find(delimiter, start);
} }
vector.push_back(_string.substr(start)); vectorResult.push_back(stringArg.substr(start));
if (sort) { if (sort) {
if (caseInsensitive) if (caseInsensitive)
std::sort(std::begin(vector), std::end(vector), std::sort(std::begin(vectorResult), std::end(vectorResult),
[](std::string a, std::string b) { [](std::string a, std::string b) {
return std::toupper(a.front()) < std::toupper(b.front()); }); return std::toupper(a.front()) < std::toupper(b.front()); });
else else
std::sort(vector.begin(), vector.end()); std::sort(vectorResult.begin(), vectorResult.end());
} }
return vector; return vectorResult;
} }
std::string vectorToDelimitedString(std::vector<std::string> _vector, std::string vectorToDelimitedString(std::vector<std::string> vectorArg,
const std::string& _delimiter, bool caseInsensitive) const std::string& delimiter, bool caseInsensitive)
{ {
std::string string; std::string resultString;
if (caseInsensitive) if (caseInsensitive)
std::sort(std::begin(_vector), std::end(_vector), std::sort(std::begin(vectorArg), std::end(vectorArg),
[](std::string a, std::string b) { [](std::string a, std::string b) {
return std::toupper(a.front()) < std::toupper(b.front()); }); return std::toupper(a.front()) < std::toupper(b.front()); });
else else
std::sort(_vector.begin(), _vector.end()); std::sort(vectorArg.begin(), vectorArg.end());
for (std::vector<std::string>::const_iterator it = _vector.cbegin(); for (std::vector<std::string>::const_iterator it = vectorArg.cbegin();
it != _vector.cend(); it++) it != vectorArg.cend(); it++)
string += (string.length() ? _delimiter : "") + (*it); resultString += (resultString.length() ? delimiter : "") + (*it);
return string; return resultString;
} }
std::string format(const char* _format, ...) std::string scramble(const std::string& input, const std::string& key)
{ {
va_list args; std::string buffer = input;
va_list copy;
va_start(args, _format); for (size_t i = 0; i < input.size(); i++)
buffer[i] = input[i] ^ key[i];
va_copy(copy, args);
const int length = vsnprintf(nullptr, 0, _format, copy);
va_end(copy);
char* buffer = new char[length + 1];
va_copy(copy, args);
vsnprintf(buffer, length + 1, _format, copy);
va_end(copy);
va_end(args);
std::string out(buffer);
delete[] buffer;
return out;
}
std::string scramble(const std::string& _input, const std::string& _key)
{
std::string buffer = _input;
for (size_t i = 0; i < _input.size(); i++)
buffer[i] = _input[i] ^ _key[i];
return buffer; return buffer;
} }
} // String:: } // String::
} // Utils:: } // Utils::

View file

@ -17,29 +17,28 @@ namespace Utils
{ {
namespace String namespace String
{ {
unsigned int chars2Unicode(const std::string& _string, size_t& _cursor); unsigned int chars2Unicode(const std::string& stringArg, size_t& cursor);
std::string unicode2Chars(const unsigned int _unicode); std::string unicode2Chars(const unsigned int unicodeArg);
// Return the first character, which could be normal ASCII or 2, 3 or 4 byte Unicode. // Return the first character, which could be normal ASCII or 2, 3 or 4 byte Unicode.
std::string getFirstCharacter(const std::string& _string, bool _toUpper = true); std::string getFirstCharacter(const std::string& stringArg, bool toUpper = true);
size_t nextCursor(const std::string& _string, const size_t _cursor); size_t nextCursor(const std::string& stringArg, const size_t cursor);
size_t prevCursor(const std::string& _string, const size_t _cursor); size_t prevCursor(const std::string& stringArg, const size_t cursor);
size_t moveCursor(const std::string& _string, const size_t _cursor, const int _amount); size_t moveCursor(const std::string& stringArg, const size_t cursor, const int amount);
std::string toLower(const std::string& _string); std::string toLower(const std::string& stringArg);
std::string toUpper(const std::string& _string); std::string toUpper(const std::string& stringArg);
std::string trim(const std::string& _string); std::string trim(const std::string& stringArg);
std::string replace(const std::string& _string, const std::string& _replace, std::string replace(const std::string& stringArg, const std::string& replace,
const std::string& _with); const std::string& with);
std::wstring stringToWideString(const std::string& _string); std::wstring stringToWideString(const std::string& stringArg);
std::string wideStringToString(const std::wstring& _string); std::string wideStringToString(const std::wstring& stringArg);
bool startsWith(const std::string& _string, const std::string& _start); bool startsWith(const std::string& stringArg, const std::string& start);
bool endsWith(const std::string& _string, const std::string& _end); bool endsWith(const std::string& stringArg, const std::string& end);
std::string removeParenthesis(const std::string& _string); std::string removeParenthesis(const std::string& stringArg);
std::vector<std::string> delimitedStringToVector(const std::string& _string, std::vector<std::string> delimitedStringToVector(const std::string& stringArg,
const std::string& _delimiter, bool sort = false, bool caseInsensitive = false); const std::string& delimiter, bool sort = false, bool caseInsensitive = false);
std::string vectorToDelimitedString(std::vector<std::string> _vector, std::string vectorToDelimitedString(std::vector<std::string> vectorArg,
const std::string& _delimiter, bool caseInsensitive = false); const std::string& delimiter, bool caseInsensitive = false);
std::string format(const char* _string, ...); std::string scramble(const std::string& input, const std::string& key);
std::string scramble(const std::string& _input, const std::string& key);
} }
} }

View file

@ -22,28 +22,28 @@ namespace Utils
mIsoString = "00000000T000000"; mIsoString = "00000000T000000";
} }
DateTime::DateTime(const time_t& _time) DateTime::DateTime(const time_t& time)
{ {
setTime(_time); setTime(time);
} }
DateTime::DateTime(const tm& _timeStruct) DateTime::DateTime(const tm& timeStruct)
{ {
setTimeStruct(_timeStruct); setTimeStruct(timeStruct);
} }
DateTime::DateTime(const std::string& _isoString) DateTime::DateTime(const std::string& isoString)
{ {
setIsoString(_isoString); setIsoString(isoString);
} }
DateTime::~DateTime() DateTime::~DateTime()
{ {
} }
void DateTime::setTime(const time_t& _time) void DateTime::setTime(const time_t& time)
{ {
mTime = (_time < 0) ? 0 : _time; mTime = (time < 0) ? 0 : time;
#if defined(_WIN64) #if defined(_WIN64)
localtime_s(&mTimeStruct, &mTime); localtime_s(&mTimeStruct, &mTime);
#else #else
@ -52,22 +52,22 @@ namespace Utils
mIsoString = timeToString(mTime); mIsoString = timeToString(mTime);
} }
void DateTime::setTimeStruct(const tm& _timeStruct) void DateTime::setTimeStruct(const tm& timeStruct)
{ {
setTime(mktime((tm*)&_timeStruct)); setTime(mktime(const_cast<tm*>(&timeStruct)));
} }
void DateTime::setIsoString(const std::string& _isoString) void DateTime::setIsoString(const std::string& isoString)
{ {
setTime(stringToTime(_isoString)); setTime(stringToTime(isoString));
} }
Duration::Duration(const time_t& _time) Duration::Duration(const time_t& time)
{ {
mTotalSeconds = static_cast<unsigned int>(_time); mTotalSeconds = static_cast<unsigned int>(time);
mDays = (mTotalSeconds - (mTotalSeconds % (60*60*24))) / (60*60*24); mDays = (mTotalSeconds - (mTotalSeconds % (60 * 60 * 24))) / (60 * 60 * 24);
mHours = ((mTotalSeconds % (60*60*24)) - (mTotalSeconds % (60*60))) / (60*60); mHours = ((mTotalSeconds % (60 * 60 * 24)) - (mTotalSeconds % (60 * 60))) / (60 * 60);
mMinutes = ((mTotalSeconds % (60*60)) - (mTotalSeconds % (60))) / 60; mMinutes = ((mTotalSeconds % (60 * 60)) - (mTotalSeconds % (60))) / 60;
mSeconds = mTotalSeconds % 60; mSeconds = mTotalSeconds % 60;
} }
@ -82,24 +82,24 @@ namespace Utils
return time; return time;
} }
time_t stringToTime(const std::string& _string, const std::string& _format) time_t stringToTime(const std::string& string, const std::string& format)
{ {
const char* s = _string.c_str(); const char* s = string.c_str();
const char* f = _format.c_str(); const char* f = format.c_str();
tm timeStruct = { 0, 0, 0, 1, 0, 0, 0, 0, -1 }; tm timeStruct = { 0, 0, 0, 1, 0, 0, 0, 0, -1 };
size_t parsedChars = 0; size_t parsedChars = 0;
if (_string == "19700101T010000") if (string == "19700101T010000")
return mktime(&timeStruct); return mktime(&timeStruct);
while (*f && (parsedChars < _string.length())) { while (*f && (parsedChars < string.length())) {
if (*f == '%') { if (*f == '%') {
f++; f++;
switch (*f++) { switch (*f++) {
// The year [1970,xxxx] // Year, including century [1970,xxxx]
case 'Y': { case 'Y': {
if ((parsedChars + 4) <= _string.length()) { if ((parsedChars + 4) <= string.length()) {
timeStruct.tm_year = (*s++ - '0') * 1000; timeStruct.tm_year = (*s++ - '0') * 1000;
timeStruct.tm_year += (*s++ - '0') * 100; timeStruct.tm_year += (*s++ - '0') * 100;
timeStruct.tm_year += (*s++ - '0') * 10; timeStruct.tm_year += (*s++ - '0') * 10;
@ -111,9 +111,9 @@ namespace Utils
} }
break; break;
// The month number [01,12] // Month number [01,12]
case 'm': { case 'm': {
if ((parsedChars + 2) <= _string.length()) { if ((parsedChars + 2) <= string.length()) {
timeStruct.tm_mon = (*s++ - '0') * 10; timeStruct.tm_mon = (*s++ - '0') * 10;
timeStruct.tm_mon += (*s++ - '0'); timeStruct.tm_mon += (*s++ - '0');
if (timeStruct.tm_mon >= 1) if (timeStruct.tm_mon >= 1)
@ -123,9 +123,9 @@ namespace Utils
} }
break; break;
// The day of the month [01,31] // Day of the month [01,31]
case 'd': { case 'd': {
if ((parsedChars + 2) <= _string.length()) { if ((parsedChars + 2) <= string.length()) {
timeStruct.tm_mday = (*s++ - '0') * 10; timeStruct.tm_mday = (*s++ - '0') * 10;
timeStruct.tm_mday += (*s++ - '0'); timeStruct.tm_mday += (*s++ - '0');
} }
@ -133,9 +133,9 @@ namespace Utils
} }
break; break;
// The hour (24-hour clock) [00,23] // Hour (24-hour clock) [00,23]
case 'H': { case 'H': {
if ((parsedChars + 2) <= _string.length()) { if ((parsedChars + 2) <= string.length()) {
timeStruct.tm_hour = (*s++ - '0') * 10; timeStruct.tm_hour = (*s++ - '0') * 10;
timeStruct.tm_hour += (*s++ - '0'); timeStruct.tm_hour += (*s++ - '0');
} }
@ -143,9 +143,9 @@ namespace Utils
} }
break; break;
// The minute [00,59] // Minute [00,59]
case 'M': { case 'M': {
if ((parsedChars + 2) <= _string.length()) { if ((parsedChars + 2) <= string.length()) {
timeStruct.tm_min = (*s++ - '0') * 10; timeStruct.tm_min = (*s++ - '0') * 10;
timeStruct.tm_min += (*s++ - '0'); timeStruct.tm_min += (*s++ - '0');
} }
@ -153,9 +153,9 @@ namespace Utils
} }
break; break;
// The second [00,59] // Second [00,59]
case 'S': { case 'S': {
if ((parsedChars + 2) <= _string.length()) { if ((parsedChars + 2) <= string.length()) {
timeStruct.tm_sec = (*s++ - '0') * 10; timeStruct.tm_sec = (*s++ - '0') * 10;
timeStruct.tm_sec += (*s++ - '0'); timeStruct.tm_sec += (*s++ - '0');
} }
@ -172,14 +172,14 @@ namespace Utils
return mktime(&timeStruct); return mktime(&timeStruct);
} }
std::string timeToString(const time_t& _time, const std::string& _format) std::string timeToString(const time_t& time, const std::string& format)
{ {
const char* f = _format.c_str(); const char* f = format.c_str();
tm timeStruct; tm timeStruct;
#if defined(_WIN64) #if defined(_WIN64)
localtime_s(&timeStruct, &_time); localtime_s(&timeStruct, &_time);
#else #else
localtime_r(&_time, &timeStruct); localtime_r(&time, &timeStruct);
#endif #endif
char buf[256] = { '\0' }; char buf[256] = { '\0' };
char* s = buf; char* s = buf;
@ -189,7 +189,7 @@ namespace Utils
f++; f++;
switch (*f++) { switch (*f++) {
// The year, including the century (1900) // Year, including century [1970,xxxx]
case 'Y': { case 'Y': {
const int year = timeStruct.tm_year + 1900; const int year = timeStruct.tm_year + 1900;
*s++ = static_cast<char>((year - (year % 1000)) / 1000) + '0'; *s++ = static_cast<char>((year - (year % 1000)) / 1000) + '0';
@ -199,7 +199,7 @@ namespace Utils
} }
break; break;
// The month number [00,11] // Month number [00,11]
case 'm': { case 'm': {
const int mon = timeStruct.tm_mon + 1; const int mon = timeStruct.tm_mon + 1;
*s++ = static_cast<char>(mon / 10) + '0'; *s++ = static_cast<char>(mon / 10) + '0';
@ -207,28 +207,28 @@ namespace Utils
} }
break; break;
// The day of the month [01,31] // Day of the month [01,31]
case 'd': { case 'd': {
*s++ = static_cast<char>(timeStruct.tm_mday / 10) + '0'; *s++ = static_cast<char>(timeStruct.tm_mday / 10) + '0';
*s++ = static_cast<char>(timeStruct.tm_mday % 10) + '0'; *s++ = static_cast<char>(timeStruct.tm_mday % 10) + '0';
} }
break; break;
// The hour (24-hour clock) [00,23] // Hour (24-hour clock) [00,23]
case 'H': { case 'H': {
*s++ = static_cast<char>(timeStruct.tm_hour / 10) + '0'; *s++ = static_cast<char>(timeStruct.tm_hour / 10) + '0';
*s++ = static_cast<char>(timeStruct.tm_hour % 10) + '0'; *s++ = static_cast<char>(timeStruct.tm_hour % 10) + '0';
} }
break; break;
// The minute [00,59] // Minute [00,59]
case 'M': { case 'M': {
*s++ = static_cast<char>(timeStruct.tm_min / 10) + '0'; *s++ = static_cast<char>(timeStruct.tm_min / 10) + '0';
*s++ = static_cast<char>(timeStruct.tm_min % 10) + '0'; *s++ = static_cast<char>(timeStruct.tm_min % 10) + '0';
} }
break; break;
// The second [00,59] // Second [00,59]
case 'S': { case 'S': {
*s++ = static_cast<char>(timeStruct.tm_sec / 10) + '0'; *s++ = static_cast<char>(timeStruct.tm_sec / 10) + '0';
*s++ = static_cast<char>(timeStruct.tm_sec % 10) + '0'; *s++ = static_cast<char>(timeStruct.tm_sec % 10) + '0';
@ -244,17 +244,17 @@ namespace Utils
return std::string(buf); return std::string(buf);
} }
int daysInMonth(const int _year, const int _month) int daysInMonth(const int year, const int month)
{ {
tm timeStruct = { 0, 0, 0, 0, _month, _year - 1900, 0, 0, -1 }; tm timeStruct = { 0, 0, 0, 0, month, year - 1900, 0, 0, -1 };
mktime(&timeStruct); mktime(&timeStruct);
return timeStruct.tm_mday; return timeStruct.tm_mday;
} }
int daysInYear(const int _year) int daysInYear(const int year)
{ {
tm timeStruct = { 0, 0, 0, 0, 0, _year - 1900 + 1, 0, 0, -1 }; tm timeStruct = { 0, 0, 0, 0, 0, year - 1900 + 1, 0, 0, -1 };
mktime(&timeStruct); mktime(&timeStruct);
return timeStruct.tm_yday + 1; return timeStruct.tm_yday + 1;

View file

@ -26,24 +26,24 @@ namespace Utils
{ {
public: public:
DateTime(); DateTime();
DateTime(const time_t& _time); DateTime(const time_t& time);
DateTime(const tm& _timeStruct); DateTime(const tm& timeStruct);
DateTime(const std::string& _isoString); DateTime(const std::string& isoString);
~DateTime(); ~DateTime();
const bool operator<(const DateTime& _other) const { return (mTime < _other.mTime); } const bool operator<(const DateTime& other) const { return (mTime < other.mTime); }
const bool operator<=(const DateTime& _other) const { return (mTime <= _other.mTime); } const bool operator<=(const DateTime& other) const { return (mTime <= other.mTime); }
const bool operator>(const DateTime& _other) const { return (mTime > _other.mTime); } const bool operator>(const DateTime& other) const { return (mTime > other.mTime); }
const bool operator>=(const DateTime& _other) const { return (mTime >= _other.mTime); } const bool operator>=(const DateTime& other) const { return (mTime >= other.mTime); }
operator time_t() const { return mTime; } operator time_t() const { return mTime; }
operator tm() const { return mTimeStruct; } operator tm() const { return mTimeStruct; }
operator std::string() const { return mIsoString; } operator std::string() const { return mIsoString; }
void setTime(const time_t& _time); void setTime(const time_t& time);
const time_t& getTime() const { return mTime; } const time_t& getTime() const { return mTime; }
void setTimeStruct(const tm& _timeStruct); void setTimeStruct(const tm& timeStruct);
const tm& getTimeStruct() const { return mTimeStruct; } const tm& getTimeStruct() const { return mTimeStruct; }
void setIsoString (const std::string& _isoString); void setIsoString (const std::string& isoString);
const std::string& getIsoString () const { return mIsoString; } const std::string& getIsoString () const { return mIsoString; }
private: private:
@ -55,7 +55,7 @@ namespace Utils
class Duration class Duration
{ {
public: public:
Duration(const time_t& _time); Duration(const time_t& time);
~Duration(); ~Duration();
unsigned int getDays() const { return mDays; } unsigned int getDays() const { return mDays; }
@ -72,12 +72,10 @@ namespace Utils
}; };
time_t now(); time_t now();
time_t stringToTime(const std::string& _string, time_t stringToTime(const std::string& string, const std::string& format = "%Y%m%dT%H%M%S");
const std::string& _format = "%Y%m%dT%H%M%S"); std::string timeToString(const time_t& time, const std::string& format = "%Y%m%dT%H%M%S");
std::string timeToString(const time_t& _time, int daysInMonth(const int year, const int month);
const std::string& _format = "%Y%m%dT%H%M%S"); int daysInYear(const int year);
int daysInMonth(const int _year, const int _month);
int daysInYear(const int _year);
} }
} // Utils:: } // Utils::