mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-01-17 22:55:38 +00:00
Add getDirContent, getHomePath, getCWDPath, canonicalPath, absolutePath, resolvePath, resolveSymlink, getExtension, removeFile, isAbsolute, isRegularFile, isDirectory, isSymlink, isHidden and isEquivalent
Rename makeGeneric to genericPath and escapePath to escapedPath Add toUpper
This commit is contained in:
parent
05caef2f28
commit
18d6b9341e
|
@ -3,166 +3,528 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#if defined(WIN32)
|
#if defined(_WIN32)
|
||||||
// because windows...
|
// because windows...
|
||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
#define snprintf _snprintf
|
#include <Windows.h>
|
||||||
#define mkdir(x,y) _mkdir(x)
|
#define mkdir(x,y) _mkdir(x)
|
||||||
#endif // WIN32
|
#define snprintf _snprintf
|
||||||
|
#define unlink _unlink
|
||||||
|
#define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
|
||||||
|
#define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)
|
||||||
|
#else // _WIN32
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
namespace Utils
|
namespace Utils
|
||||||
{
|
{
|
||||||
namespace FileSystem
|
namespace FileSystem
|
||||||
{
|
{
|
||||||
bool createDirectory(const std::string& _path)
|
stringList getDirContent(const std::string& _path)
|
||||||
{
|
{
|
||||||
// don't create if it already exists
|
std::string path = genericPath(_path);
|
||||||
if(exists(_path))
|
stringList contentList;
|
||||||
return true;
|
|
||||||
|
|
||||||
// convert '\\' to '/'
|
// only parse the directory, if it's a directory
|
||||||
makeGeneric(_path);
|
if(isDirectory(path))
|
||||||
|
|
||||||
// try to create directory
|
|
||||||
if(mkdir(_path.c_str(), 0755) == 0)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// failed to create directory, try to create the parent
|
|
||||||
std::string parent = getParent(_path);
|
|
||||||
|
|
||||||
// only try to create parent if it's not identical to path
|
|
||||||
if(parent != _path)
|
|
||||||
createDirectory(parent);
|
|
||||||
|
|
||||||
// try to create directory again now that the parent should exist
|
|
||||||
return (mkdir(_path.c_str(), 0755) == 0);
|
|
||||||
|
|
||||||
} // createDirectory
|
|
||||||
|
|
||||||
void makeGeneric(const std::string& _path)
|
|
||||||
{
|
|
||||||
char* p = nullptr;
|
|
||||||
|
|
||||||
// convert '\\' to '/'
|
|
||||||
for(p = (char*)_path.c_str() + 1; *p; ++p)
|
|
||||||
{
|
{
|
||||||
if(*p == '\\')
|
|
||||||
*p = '/';
|
#if defined(_WIN32)
|
||||||
|
WIN32_FIND_DATA findData;
|
||||||
|
HANDLE hFind = FindFirstFile((path + "/*").c_str(), &findData);
|
||||||
|
|
||||||
|
if(hFind != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
// loop over all files in the directory
|
||||||
|
do
|
||||||
|
{
|
||||||
|
std::string name(findData.cFileName);
|
||||||
|
|
||||||
|
// ignore "." and ".."
|
||||||
|
if((name != ".") && (name != ".."))
|
||||||
|
contentList.push_back(name);
|
||||||
|
}
|
||||||
|
while(FindNextFile(hFind, &findData));
|
||||||
|
|
||||||
|
FindClose(hFind);
|
||||||
|
}
|
||||||
|
#else // _WIN32
|
||||||
|
DIR* dir = opendir(path.c_str());
|
||||||
|
|
||||||
|
if(dir != NULL)
|
||||||
|
{
|
||||||
|
struct dirent* entry;
|
||||||
|
|
||||||
|
// loop over all files in the directory
|
||||||
|
while((entry = readdir(dir)) != NULL)
|
||||||
|
{
|
||||||
|
std::string name(entry->d_name);
|
||||||
|
|
||||||
|
// ignore "." and ".."
|
||||||
|
if((name != ".") && (name != ".."))
|
||||||
|
contentList.push_back(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(dir);
|
||||||
|
}
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // makeGeneric
|
// sort the content list
|
||||||
|
contentList.sort();
|
||||||
|
|
||||||
std::string escapePath(const std::string& _path)
|
// return the content list
|
||||||
|
return contentList;
|
||||||
|
|
||||||
|
} // getDirContent
|
||||||
|
|
||||||
|
std::string getHomePath()
|
||||||
{
|
{
|
||||||
|
static std::string path;
|
||||||
|
|
||||||
#ifdef WIN32
|
// only construct the homepath once
|
||||||
|
if(!path.length())
|
||||||
|
{
|
||||||
|
// this should give us something like "/home/YOUR_USERNAME" on Linux and "C:/Users/YOUR_USERNAME/" on Windows
|
||||||
|
std::string envHome(getenv("HOME"));
|
||||||
|
if(envHome.length())
|
||||||
|
path = genericPath(envHome);
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
// but does not seem to work for Windows XP or Vista, so try something else
|
||||||
|
if(!path.length())
|
||||||
|
{
|
||||||
|
std::string envDir(getenv("HOMEDRIVE"));
|
||||||
|
std::string envPath(getenv("HOMEPATH"));
|
||||||
|
if(envDir.length() && envPath.length())
|
||||||
|
path = genericPath(envDir + "/" + envPath);
|
||||||
|
}
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// return constructed homepath
|
||||||
|
return path;
|
||||||
|
|
||||||
|
} // getHomePath
|
||||||
|
|
||||||
|
std::string getCWDPath()
|
||||||
|
{
|
||||||
|
char temp[512];
|
||||||
|
|
||||||
|
// return current working directory path
|
||||||
|
return (getcwd(temp, 512) ? genericPath(temp) : "");
|
||||||
|
|
||||||
|
} // getCWDPath
|
||||||
|
|
||||||
|
std::string genericPath(const std::string& _path)
|
||||||
|
{
|
||||||
|
std::string path = _path;
|
||||||
|
size_t offset = std::string::npos;
|
||||||
|
|
||||||
|
// remove "\\\\?\\"
|
||||||
|
if((path.find("\\\\?\\")) == 0)
|
||||||
|
path.erase(0, 4);
|
||||||
|
|
||||||
|
// convert '\\' to '/'
|
||||||
|
while((offset = path.find('\\')) != std::string::npos)
|
||||||
|
path.replace(offset, 1 ,"/");
|
||||||
|
|
||||||
|
// remove double '/'
|
||||||
|
while((offset = path.find("//")) != std::string::npos)
|
||||||
|
path.erase(offset, 1);
|
||||||
|
|
||||||
|
// return generic path
|
||||||
|
return path;
|
||||||
|
|
||||||
|
} // genericPath
|
||||||
|
|
||||||
|
std::string escapedPath(const std::string& _path)
|
||||||
|
{
|
||||||
|
std::string path = genericPath(_path);
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
// windows escapes stuff by just putting everything in quotes
|
// windows escapes stuff by just putting everything in quotes
|
||||||
return '"' + _path + '"';
|
return '"' + path + '"';
|
||||||
#else // WIN32
|
#else // _WIN32
|
||||||
// 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
|
||||||
std::string escapedPath = _path;
|
|
||||||
const char* invalidChars = "\\ '\"!$^&*(){}[]?;<>";
|
const char* invalidChars = "\\ '\"!$^&*(){}[]?;<>";
|
||||||
const char* invalidChar = invalidChars;
|
const char* invalidChar = invalidChars;
|
||||||
|
size_t offset = std::string::npos;
|
||||||
|
|
||||||
while(*invalidChar)
|
while(*invalidChar)
|
||||||
{
|
{
|
||||||
for(size_t i = 0; i < escapedPath.length(); ++i)
|
while((offset = path.find(*invalidChar)) != std::string::npos)
|
||||||
{
|
path.insert(offset, 1, '\\');
|
||||||
if(escapedPath[i] == *invalidChar)
|
|
||||||
{
|
|
||||||
escapedPath.insert(i, 1, '\\');
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
++invalidChar;
|
++invalidChar;
|
||||||
}
|
}
|
||||||
|
|
||||||
return escapedPath;
|
// return escaped path
|
||||||
#endif // WIN32
|
return path;
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
} // escapePath
|
} // escapedPath
|
||||||
|
|
||||||
std::string getParent(const std::string& _path)
|
std::string canonicalPath(const std::string& _path)
|
||||||
{
|
{
|
||||||
// convert '\\' to '/'
|
std::string path = absolutePath(_path);
|
||||||
makeGeneric(_path);
|
|
||||||
|
|
||||||
// make a copy of the path
|
// cleanup path
|
||||||
char temp[512];
|
bool scan = true;
|
||||||
size_t len = snprintf(temp, sizeof(temp), "%s", _path.c_str());
|
while(scan)
|
||||||
|
|
||||||
// find last '/' and end the new path
|
|
||||||
while(len > 1)
|
|
||||||
{
|
{
|
||||||
if(temp[--len] == '/')
|
stringList pathList;
|
||||||
|
size_t start = 0;
|
||||||
|
size_t end = 0;
|
||||||
|
|
||||||
|
// split at '/'
|
||||||
|
while((end = path.find("/", start)) != std::string::npos)
|
||||||
{
|
{
|
||||||
temp[len] = 0;
|
pathList.push_back(std::string(path, start, end - start));
|
||||||
return temp;
|
start = end + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add last folder / file to pathList
|
||||||
|
if(start != path.size())
|
||||||
|
pathList.push_back(std::string(path, start, path.size() - start));
|
||||||
|
|
||||||
|
path.clear();
|
||||||
|
scan = false;
|
||||||
|
|
||||||
|
for(stringList::const_iterator it = pathList.cbegin(); it != pathList.cend(); ++it)
|
||||||
|
{
|
||||||
|
// ignore empty
|
||||||
|
if((*it).empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// remove "/./"
|
||||||
|
if((*it) == ".")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// resolve "/../"
|
||||||
|
if((*it) == "..")
|
||||||
|
{
|
||||||
|
path = getParent(path);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
// append folder to path
|
||||||
|
path += (path.size() == 0) ? (*it) : ("/" + (*it));
|
||||||
|
#else // _WIN32
|
||||||
|
// append folder to path
|
||||||
|
path += ("/" + (*it));
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
|
// resolve symlink
|
||||||
|
if(isSymlink(path))
|
||||||
|
{
|
||||||
|
std::string resolved = resolveSymlink(path);
|
||||||
|
|
||||||
|
if(resolved.empty())
|
||||||
|
return "";
|
||||||
|
|
||||||
|
if(isAbsolute(resolved))
|
||||||
|
path = resolved;
|
||||||
|
else
|
||||||
|
path = getParent(path) + "/" + resolved;
|
||||||
|
|
||||||
|
for( ++it; it != pathList.cend(); ++it)
|
||||||
|
path += (path.size() == 0) ? (*it) : ("/" + (*it));
|
||||||
|
|
||||||
|
scan = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return canonical path
|
||||||
|
return path;
|
||||||
|
|
||||||
|
} // canonicalPath
|
||||||
|
|
||||||
|
std::string absolutePath(const std::string& _path, const std::string& _base)
|
||||||
|
{
|
||||||
|
std::string path = genericPath(_path);
|
||||||
|
std::string base = isAbsolute(_base) ? genericPath(_base) : absolutePath(_base);
|
||||||
|
|
||||||
|
// return absolute path
|
||||||
|
return isAbsolute(path) ? path : genericPath(base + "/" + path);
|
||||||
|
|
||||||
|
} // absolutePath
|
||||||
|
|
||||||
|
std::string resolvePath(const std::string& _path, const std::string& _relativeTo, const bool _allowHome)
|
||||||
|
{
|
||||||
|
std::string path = genericPath(_path);
|
||||||
|
std::string relativeTo = isDirectory(_relativeTo) ? _relativeTo : getParent(_relativeTo);
|
||||||
|
|
||||||
|
// nothing to resolve
|
||||||
|
if(!path.length())
|
||||||
|
return path;
|
||||||
|
|
||||||
|
// replace '.' with relativeTo
|
||||||
|
if(path[0] == '.')
|
||||||
|
return genericPath(relativeTo + "/" + &(path[1]));
|
||||||
|
|
||||||
|
// replace '~' with homePath
|
||||||
|
if(_allowHome && (path[0] == '~'))
|
||||||
|
return genericPath(getHomePath() + "/" + &(path[1]));
|
||||||
|
|
||||||
|
// nothing to resolve
|
||||||
|
return path;
|
||||||
|
|
||||||
|
} // resolvePath
|
||||||
|
|
||||||
|
std::string resolveSymlink(const std::string& _path)
|
||||||
|
{
|
||||||
|
std::string path = genericPath(_path);
|
||||||
|
std::string resolved;
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
HANDLE hFile = CreateFile(path.c_str(), FILE_READ_ATTRIBUTES, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
|
||||||
|
|
||||||
|
if(hFile != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
resolved.resize(GetFinalPathNameByHandle(hFile, nullptr, 0, FILE_NAME_NORMALIZED) + 1);
|
||||||
|
if(GetFinalPathNameByHandle(hFile, (LPSTR)resolved.data(), (DWORD)resolved.size(), FILE_NAME_NORMALIZED) > 0)
|
||||||
|
{
|
||||||
|
resolved.resize(resolved.size() - 1);
|
||||||
|
resolved = genericPath(resolved);
|
||||||
|
}
|
||||||
|
CloseHandle(hFile);
|
||||||
|
}
|
||||||
|
#else // _WIN32
|
||||||
|
struct stat info;
|
||||||
|
|
||||||
|
// check if lstat succeeded
|
||||||
|
if(lstat(path.c_str(), &info) == 0)
|
||||||
|
{
|
||||||
|
resolved.resize(info.st_size);
|
||||||
|
if(readlink(path.c_str(), (char*)resolved.data(), resolved.size()) > 0)
|
||||||
|
resolved = genericPath(resolved);
|
||||||
|
}
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
|
// return resolved path
|
||||||
|
return resolved;
|
||||||
|
|
||||||
|
} // resolveSymlink
|
||||||
|
|
||||||
|
std::string getParent(const std::string& _path)
|
||||||
|
{
|
||||||
|
std::string path = genericPath(_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);
|
||||||
|
|
||||||
// no parent found
|
// no parent found
|
||||||
return _path;
|
return path;
|
||||||
|
|
||||||
} // getParent
|
} // getParent
|
||||||
|
|
||||||
std::string getFileName(const std::string& _path)
|
std::string getFileName(const std::string& _path)
|
||||||
{
|
{
|
||||||
// convert '\\' to '/'
|
std::string path = genericPath(_path);
|
||||||
makeGeneric(_path);
|
size_t offset = std::string::npos;
|
||||||
|
|
||||||
// make a copy of the path
|
|
||||||
char temp[512];
|
|
||||||
size_t len = snprintf(temp, sizeof(temp), "%s", _path.c_str());
|
|
||||||
|
|
||||||
// find last '/' and return the filename
|
// find last '/' and return the filename
|
||||||
while(len > 1)
|
if((offset = path.find_last_of('/')) != std::string::npos)
|
||||||
{
|
return ((path[offset + 1] == 0) ? "." : std::string(path, offset + 1));
|
||||||
// return "." if this is the end of the path, otherwise return filename
|
|
||||||
if(temp[--len] == '/')
|
|
||||||
return ((temp[len + 1] == 0) ? "." : (temp + len + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
// no '/' found, entire path is a filename
|
// no '/' found, entire path is a filename
|
||||||
return _path;
|
return path;
|
||||||
|
|
||||||
} // getFileName
|
} // getFileName
|
||||||
|
|
||||||
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
|
// empty fileName
|
||||||
if(fileName == ".")
|
if(fileName == ".")
|
||||||
return fileName;
|
return fileName;
|
||||||
|
|
||||||
// make a copy of the filename
|
// find last '.' and erase the extension
|
||||||
char temp[512];
|
if((offset = fileName.find_last_of('.')) != std::string::npos)
|
||||||
size_t len = snprintf(temp, sizeof(temp), "%s", fileName.c_str());
|
return fileName.erase(offset);
|
||||||
|
|
||||||
// find last '.' and remove the extension
|
|
||||||
while(len > 1)
|
|
||||||
{
|
|
||||||
if(temp[--len] == '.')
|
|
||||||
{
|
|
||||||
temp[len] = 0;
|
|
||||||
return temp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// no '.' found, filename has no extension
|
// no '.' found, filename has no extension
|
||||||
return fileName;
|
return fileName;
|
||||||
|
|
||||||
} // getStem
|
} // getStem
|
||||||
|
|
||||||
|
std::string getExtension(const std::string& _path)
|
||||||
|
{
|
||||||
|
std::string fileName = getFileName(_path);
|
||||||
|
size_t offset = std::string::npos;
|
||||||
|
|
||||||
|
// empty fileName
|
||||||
|
if(fileName == ".")
|
||||||
|
return fileName;
|
||||||
|
|
||||||
|
// find last '.' and return the extension
|
||||||
|
if((offset = fileName.find_last_of('.')) != std::string::npos)
|
||||||
|
return std::string(fileName, offset);
|
||||||
|
|
||||||
|
// no '.' found, filename has no extension
|
||||||
|
return ".";
|
||||||
|
|
||||||
|
} // getExtension
|
||||||
|
|
||||||
|
bool removeFile(const std::string& _path)
|
||||||
|
{
|
||||||
|
std::string path = genericPath(_path);
|
||||||
|
|
||||||
|
// don't remove if it doesn't exists
|
||||||
|
if(!exists(path))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// try to remove file
|
||||||
|
return (unlink(path.c_str()) == 0);
|
||||||
|
|
||||||
|
} // removeFile
|
||||||
|
|
||||||
|
bool createDirectory(const std::string& _path)
|
||||||
|
{
|
||||||
|
std::string path = genericPath(_path);
|
||||||
|
|
||||||
|
// don't create if it already exists
|
||||||
|
if(exists(path))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// try to create directory
|
||||||
|
if(mkdir(path.c_str(), 0755) == 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// failed to create directory, try to create the parent
|
||||||
|
std::string parent = getParent(path);
|
||||||
|
|
||||||
|
// only try to create parent if it's not identical to path
|
||||||
|
if(parent != path)
|
||||||
|
createDirectory(parent);
|
||||||
|
|
||||||
|
// try to create directory again now that the parent should exist
|
||||||
|
return (mkdir(path.c_str(), 0755) == 0);
|
||||||
|
|
||||||
|
} // createDirectory
|
||||||
|
|
||||||
bool exists(const std::string& _path)
|
bool exists(const std::string& _path)
|
||||||
{
|
{
|
||||||
|
std::string path = genericPath(_path);
|
||||||
struct stat info;
|
struct stat info;
|
||||||
return (stat(_path.c_str(), &info) == 0);
|
|
||||||
|
// check if stat succeeded
|
||||||
|
return (stat(path.c_str(), &info) == 0);
|
||||||
|
|
||||||
} // exists
|
} // exists
|
||||||
|
|
||||||
|
bool isAbsolute(const std::string& _path)
|
||||||
|
{
|
||||||
|
std::string path = genericPath(_path);
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
return ((path.size() > 1) && (path[1] == ':'));
|
||||||
|
#else // _WIN32
|
||||||
|
return ((path.size() > 0) && (path[0] == '/'));
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
|
} // isAbsolute
|
||||||
|
|
||||||
|
bool isRegularFile(const std::string& _path)
|
||||||
|
{
|
||||||
|
std::string path = genericPath(_path);
|
||||||
|
struct stat info;
|
||||||
|
|
||||||
|
// check if stat succeeded
|
||||||
|
if(stat(path.c_str(), &info) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// check for S_IFREG attribute
|
||||||
|
return (S_ISREG(info.st_mode));
|
||||||
|
|
||||||
|
} // isRegularFile
|
||||||
|
|
||||||
|
bool isDirectory(const std::string& _path)
|
||||||
|
{
|
||||||
|
std::string path = genericPath(_path);
|
||||||
|
struct stat info;
|
||||||
|
|
||||||
|
// check if stat succeeded
|
||||||
|
if(stat(path.c_str(), &info) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// check for S_IFDIR attribute
|
||||||
|
return (S_ISDIR(info.st_mode));
|
||||||
|
|
||||||
|
} // isDirectory
|
||||||
|
|
||||||
|
bool isSymlink(const std::string& _path)
|
||||||
|
{
|
||||||
|
std::string path = genericPath(_path);
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
// check for symlink attribute
|
||||||
|
const DWORD Attributes = GetFileAttributes(path.c_str());
|
||||||
|
if((Attributes != INVALID_FILE_ATTRIBUTES) && (Attributes & FILE_ATTRIBUTE_REPARSE_POINT))
|
||||||
|
return true;
|
||||||
|
#else // _WIN32
|
||||||
|
struct stat info;
|
||||||
|
|
||||||
|
// check if lstat succeeded
|
||||||
|
if(lstat(path.c_str(), &info) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// check for S_IFLNK attribute
|
||||||
|
return (S_ISLNK(info.st_mode));
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
|
// not a symlink
|
||||||
|
return false;
|
||||||
|
|
||||||
|
} // isSymlink
|
||||||
|
|
||||||
|
bool isHidden(const std::string& _path)
|
||||||
|
{
|
||||||
|
std::string path = genericPath(_path);
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
// check for hidden attribute
|
||||||
|
const DWORD Attributes = GetFileAttributes(path.c_str());
|
||||||
|
if((Attributes != INVALID_FILE_ATTRIBUTES) && (Attributes & FILE_ATTRIBUTE_HIDDEN))
|
||||||
|
return true;
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
|
// filenames starting with . are hidden in linux, we do this check for windows as well
|
||||||
|
if(getFileName(path)[0] == '.')
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// not hidden
|
||||||
|
return false;
|
||||||
|
|
||||||
|
} // isHidden
|
||||||
|
|
||||||
|
bool isEquivalent(const std::string& _path1, const std::string& _path2)
|
||||||
|
{
|
||||||
|
std::string path1 = genericPath(_path1);
|
||||||
|
std::string path2 = genericPath(_path2);
|
||||||
|
struct stat info1;
|
||||||
|
struct stat info2;
|
||||||
|
|
||||||
|
// check if stat succeeded
|
||||||
|
if((stat(path1.c_str(), &info1) != 0) || (stat(path2.c_str(), &info2) != 0))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// check if attributes are identical
|
||||||
|
return ((info1.st_dev == info2.st_dev) && (info1.st_ino == info2.st_ino) && (info1.st_size == info2.st_size) && (info1.st_mtime == info2.st_mtime));
|
||||||
|
|
||||||
|
} // isEquivalent
|
||||||
|
|
||||||
} // FileSystem::
|
} // FileSystem::
|
||||||
|
|
||||||
} // Utils::
|
} // Utils::
|
||||||
|
|
|
@ -2,21 +2,39 @@
|
||||||
#ifndef ES_CORE_UTILS_FILE_SYSTEM_UTIL_H
|
#ifndef ES_CORE_UTILS_FILE_SYSTEM_UTIL_H
|
||||||
#define ES_CORE_UTILS_FILE_SYSTEM_UTIL_H
|
#define ES_CORE_UTILS_FILE_SYSTEM_UTIL_H
|
||||||
|
|
||||||
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace Utils
|
namespace Utils
|
||||||
{
|
{
|
||||||
namespace FileSystem
|
namespace FileSystem
|
||||||
{
|
{
|
||||||
bool createDirectory(const std::string& _path);
|
typedef std::list<std::string> stringList;
|
||||||
void makeGeneric (const std::string& _path);
|
|
||||||
std::string escapePath (const std::string& _path);
|
stringList getDirContent (const std::string& _path);
|
||||||
|
std::string getHomePath ();
|
||||||
|
std::string getCWDPath ();
|
||||||
|
std::string genericPath (const std::string& _path);
|
||||||
|
std::string escapedPath (const std::string& _path);
|
||||||
|
std::string canonicalPath (const std::string& _path);
|
||||||
|
std::string absolutePath (const std::string& _path, const std::string& _base = getCWDPath());
|
||||||
|
std::string resolvePath (const std::string& _path, const std::string& _relativeTo, const bool _allowHome);
|
||||||
|
std::string resolveSymlink (const std::string& _path);
|
||||||
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);
|
||||||
|
bool removeFile (const std::string& _path);
|
||||||
|
bool createDirectory(const std::string& _path);
|
||||||
bool exists (const std::string& _path);
|
bool exists (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 isEquivalent (const std::string& _path1, const std::string& _path2);
|
||||||
|
|
||||||
} // Utils::FileSystem::
|
} // FileSystem::
|
||||||
|
|
||||||
} // Utils::
|
} // Utils::
|
||||||
|
|
||||||
|
|
|
@ -132,15 +132,26 @@ namespace Utils
|
||||||
|
|
||||||
} // moveCursor
|
} // moveCursor
|
||||||
|
|
||||||
std::string trim(const std::string& _path)
|
std::string toUpper(const std::string& _string)
|
||||||
{
|
{
|
||||||
const size_t pathBegin = _path.find_first_not_of(" \t");
|
std::string string;
|
||||||
const size_t pathEnd = _path.find_last_not_of(" \t");
|
|
||||||
|
|
||||||
if(pathBegin == std::string::npos)
|
for(size_t i = 0; i < _string.length(); ++i)
|
||||||
|
string += (char)toupper(_string[i]);
|
||||||
|
|
||||||
|
return string;
|
||||||
|
|
||||||
|
} // toUpper
|
||||||
|
|
||||||
|
std::string trim(const std::string& _string)
|
||||||
|
{
|
||||||
|
const size_t strBegin = _string.find_first_not_of(" \t");
|
||||||
|
const size_t strEnd = _string.find_last_not_of(" \t");
|
||||||
|
|
||||||
|
if(strBegin == std::string::npos)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
return _path.substr(pathBegin, pathEnd - pathBegin + 1);
|
return _string.substr(strBegin, strEnd - strBegin + 1);
|
||||||
|
|
||||||
} // trim
|
} // trim
|
||||||
|
|
||||||
|
|
|
@ -13,11 +13,12 @@ namespace Utils
|
||||||
size_t nextCursor (const std::string& _string, const size_t _cursor);
|
size_t nextCursor (const std::string& _string, const size_t _cursor);
|
||||||
size_t prevCursor (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);
|
size_t moveCursor (const std::string& _string, const size_t _cursor, const int _amount);
|
||||||
std::string trim (const std::string& _path);
|
std::string toUpper (const std::string& _string);
|
||||||
|
std::string trim (const std::string& _string);
|
||||||
bool startsWith (const std::string& _string, const std::string& _test);
|
bool startsWith (const std::string& _string, const std::string& _test);
|
||||||
bool endsWith (const std::string& _string, const std::string& _test);
|
bool endsWith (const std::string& _string, const std::string& _test);
|
||||||
|
|
||||||
} // Utils::String::
|
} // String::
|
||||||
|
|
||||||
} // Utils::
|
} // Utils::
|
||||||
|
|
||||||
|
|
|
@ -12,30 +12,30 @@ namespace Utils
|
||||||
mTimeStruct = { 0, 0, 0, 1, 0, 0, 0, 0, -1 };
|
mTimeStruct = { 0, 0, 0, 1, 0, 0, 0, 0, -1 };
|
||||||
mIsoString = "00000000T000000";
|
mIsoString = "00000000T000000";
|
||||||
|
|
||||||
} // Time
|
} // DateTime::DateTime
|
||||||
|
|
||||||
DateTime::DateTime(const time_t& _time)
|
DateTime::DateTime(const time_t& _time)
|
||||||
{
|
{
|
||||||
setTime(_time);
|
setTime(_time);
|
||||||
|
|
||||||
} // Time
|
} // DateTime::DateTime
|
||||||
|
|
||||||
DateTime::DateTime(const tm& _timeStruct)
|
DateTime::DateTime(const tm& _timeStruct)
|
||||||
{
|
{
|
||||||
setTimeStruct(_timeStruct);
|
setTimeStruct(_timeStruct);
|
||||||
|
|
||||||
} // Time
|
} // DateTime::DateTime
|
||||||
|
|
||||||
DateTime::DateTime(const std::string& _isoString)
|
DateTime::DateTime(const std::string& _isoString)
|
||||||
{
|
{
|
||||||
setIsoString(_isoString);
|
setIsoString(_isoString);
|
||||||
|
|
||||||
} // Time
|
} // DateTime::DateTime
|
||||||
|
|
||||||
DateTime::~DateTime()
|
DateTime::~DateTime()
|
||||||
{
|
{
|
||||||
|
|
||||||
} // ~Time
|
} // DateTime::~DateTime
|
||||||
|
|
||||||
void DateTime::setTime(const time_t& _time)
|
void DateTime::setTime(const time_t& _time)
|
||||||
{
|
{
|
||||||
|
@ -44,19 +44,19 @@ namespace Utils
|
||||||
mTimeStruct = *localtime(&mTime);
|
mTimeStruct = *localtime(&mTime);
|
||||||
mIsoString = timeToString(mTime);
|
mIsoString = timeToString(mTime);
|
||||||
|
|
||||||
} // setTime
|
} // DateTime::setTime
|
||||||
|
|
||||||
void DateTime::setTimeStruct(const tm& _timeStruct)
|
void DateTime::setTimeStruct(const tm& _timeStruct)
|
||||||
{
|
{
|
||||||
setTime(mktime((tm*)&_timeStruct));
|
setTime(mktime((tm*)&_timeStruct));
|
||||||
|
|
||||||
} // setTimeStruct
|
} // DateTime::setTimeStruct
|
||||||
|
|
||||||
void DateTime::setIsoString(const std::string& _isoString)
|
void DateTime::setIsoString(const std::string& _isoString)
|
||||||
{
|
{
|
||||||
setTime(stringToTime(_isoString));
|
setTime(stringToTime(_isoString));
|
||||||
|
|
||||||
} // setIsoString
|
} // DateTime::setIsoString
|
||||||
|
|
||||||
Duration::Duration(const time_t& _time)
|
Duration::Duration(const time_t& _time)
|
||||||
{
|
{
|
||||||
|
@ -66,12 +66,12 @@ namespace Utils
|
||||||
mMinutes = ((mTotalSeconds % (60*60)) - (mTotalSeconds % (60))) / 60;
|
mMinutes = ((mTotalSeconds % (60*60)) - (mTotalSeconds % (60))) / 60;
|
||||||
mSeconds = mTotalSeconds % 60;
|
mSeconds = mTotalSeconds % 60;
|
||||||
|
|
||||||
} // Duration
|
} // Duration::Duration
|
||||||
|
|
||||||
Duration::~Duration()
|
Duration::~Duration()
|
||||||
{
|
{
|
||||||
|
|
||||||
} // ~Duration
|
} // Duration::~Duration
|
||||||
|
|
||||||
time_t now()
|
time_t now()
|
||||||
{
|
{
|
||||||
|
@ -86,7 +86,7 @@ namespace Utils
|
||||||
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 };
|
||||||
int parsedChars = 0;
|
size_t parsedChars = 0;
|
||||||
|
|
||||||
if(_string == "not-a-date-time")
|
if(_string == "not-a-date-time")
|
||||||
return mktime(&timeStruct);
|
return mktime(&timeStruct);
|
||||||
|
|
Loading…
Reference in a new issue