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

View file

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

View file

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

View file

@ -17,29 +17,28 @@ namespace Utils
{
namespace String
{
unsigned int chars2Unicode(const std::string& _string, size_t& _cursor);
std::string unicode2Chars(const unsigned int _unicode);
unsigned int chars2Unicode(const std::string& stringArg, size_t& cursor);
std::string unicode2Chars(const unsigned int unicodeArg);
// 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);
size_t nextCursor(const std::string& _string, const size_t _cursor);
size_t prevCursor(const std::string& _string, const size_t _cursor);
size_t moveCursor(const std::string& _string, const size_t _cursor, const int _amount);
std::string toLower(const std::string& _string);
std::string toUpper(const std::string& _string);
std::string trim(const std::string& _string);
std::string replace(const std::string& _string, const std::string& _replace,
const std::string& _with);
std::wstring stringToWideString(const std::string& _string);
std::string wideStringToString(const std::wstring& _string);
bool startsWith(const std::string& _string, const std::string& _start);
bool endsWith(const std::string& _string, const std::string& _end);
std::string removeParenthesis(const std::string& _string);
std::vector<std::string> delimitedStringToVector(const std::string& _string,
const std::string& _delimiter, bool sort = false, bool caseInsensitive = false);
std::string vectorToDelimitedString(std::vector<std::string> _vector,
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 getFirstCharacter(const std::string& stringArg, bool toUpper = true);
size_t nextCursor(const std::string& stringArg, const size_t cursor);
size_t prevCursor(const std::string& stringArg, const size_t cursor);
size_t moveCursor(const std::string& stringArg, const size_t cursor, const int amount);
std::string toLower(const std::string& stringArg);
std::string toUpper(const std::string& stringArg);
std::string trim(const std::string& stringArg);
std::string replace(const std::string& stringArg, const std::string& replace,
const std::string& with);
std::wstring stringToWideString(const std::string& stringArg);
std::string wideStringToString(const std::wstring& stringArg);
bool startsWith(const std::string& stringArg, const std::string& start);
bool endsWith(const std::string& stringArg, const std::string& end);
std::string removeParenthesis(const std::string& stringArg);
std::vector<std::string> delimitedStringToVector(const std::string& stringArg,
const std::string& delimiter, bool sort = false, bool caseInsensitive = false);
std::string vectorToDelimitedString(std::vector<std::string> vectorArg,
const std::string& delimiter, bool caseInsensitive = false);
std::string scramble(const std::string& input, const std::string& key);
}
}

View file

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

View file

@ -26,24 +26,24 @@ namespace Utils
{
public:
DateTime();
DateTime(const time_t& _time);
DateTime(const tm& _timeStruct);
DateTime(const std::string& _isoString);
DateTime(const time_t& time);
DateTime(const tm& timeStruct);
DateTime(const std::string& isoString);
~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 tm() const { return mTimeStruct; }
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; }
void setTimeStruct(const tm& _timeStruct);
void setTimeStruct(const tm& timeStruct);
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; }
private:
@ -55,7 +55,7 @@ namespace Utils
class Duration
{
public:
Duration(const time_t& _time);
Duration(const time_t& time);
~Duration();
unsigned int getDays() const { return mDays; }
@ -72,12 +72,10 @@ namespace Utils
};
time_t now();
time_t stringToTime(const std::string& _string,
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");
int daysInMonth(const int _year, const int _month);
int daysInYear(const int _year);
time_t stringToTime(const std::string& string, 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");
int daysInMonth(const int year, const int month);
int daysInYear(const int year);
}
} // Utils::