Merge pull request #336 from tomaz82/boost_filesystem

Utils::FileSystem
This commit is contained in:
Jools Wills 2018-01-03 14:22:13 +00:00 committed by GitHub
commit b2111300c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 589 additions and 219 deletions

View file

@ -16,7 +16,6 @@
#include <fstream> #include <fstream>
#include <unordered_map> #include <unordered_map>
namespace fs = boost::filesystem;
std::string myCollectionsName = "collections"; std::string myCollectionsName = "collections";
/* Handling the getting, initialization, deinitialization, saving and deletion of /* Handling the getting, initialization, deinitialization, saving and deletion of
@ -52,8 +51,8 @@ CollectionSystemManager::CollectionSystemManager(Window* window) : mWindow(windo
mCollectionEnvData->mPlatformIds = allPlatformIds; mCollectionEnvData->mPlatformIds = allPlatformIds;
std::string path = getCollectionsFolder(); std::string path = getCollectionsFolder();
if(!fs::exists(path)) if(!boost::filesystem::exists(path))
fs::create_directory(path); boost::filesystem::create_directory(path);
mIsEditingCustom = false; mIsEditingCustom = false;
mEditingCollection = "Favorites"; mEditingCollection = "Favorites";
@ -334,7 +333,7 @@ bool CollectionSystemManager::isThemeCustomCollectionCompatible(std::vector<std:
if(set != themeSets.cend()) if(set != themeSets.cend())
{ {
std::string defaultThemeFilePath = set->second.path.string() + "/theme.xml"; std::string defaultThemeFilePath = set->second.path.string() + "/theme.xml";
if (fs::exists(defaultThemeFilePath)) if (boost::filesystem::exists(defaultThemeFilePath))
{ {
return true; return true;
} }
@ -722,7 +721,7 @@ void CollectionSystemManager::populateCustomCollection(CollectionSystemData* sys
CollectionSystemDecl sysDecl = sysData->decl; CollectionSystemDecl sysDecl = sysData->decl;
std::string path = getCustomCollectionConfigPath(newSys->getName()); std::string path = getCustomCollectionConfigPath(newSys->getName());
if(!fs::exists(path)) if(!boost::filesystem::exists(path))
{ {
LOG(LogInfo) << "Couldn't find custom collection config file at " << path; LOG(LogInfo) << "Couldn't find custom collection config file at " << path;
return; return;
@ -829,7 +828,7 @@ std::vector<std::string> CollectionSystemManager::getSystemsFromConfig()
std::vector<std::string> systems; std::vector<std::string> systems;
std::string path = SystemData::getConfigPath(false); std::string path = SystemData::getConfigPath(false);
if(!fs::exists(path)) if(!boost::filesystem::exists(path))
{ {
return systems; return systems;
} }
@ -880,20 +879,20 @@ std::vector<std::string> CollectionSystemManager::getSystemsFromTheme()
Settings::getInstance()->setString("ThemeSet", set->first); Settings::getInstance()->setString("ThemeSet", set->first);
} }
fs::path themePath = set->second.path; boost::filesystem::path themePath = set->second.path;
if (fs::exists(themePath)) if (boost::filesystem::exists(themePath))
{ {
fs::directory_iterator end_itr; // default construction yields past-the-end boost::filesystem::directory_iterator end_itr; // default construction yields past-the-end
for (fs::directory_iterator itr(themePath); itr != end_itr; ++itr) for (boost::filesystem::directory_iterator itr(themePath); itr != end_itr; ++itr)
{ {
if (fs::is_directory(itr->status())) if (boost::filesystem::is_directory(itr->status()))
{ {
//... here you have a directory //... here you have a directory
std::string folder = itr->path().string(); std::string folder = itr->path().string();
folder = folder.substr(themePath.string().size()+1); folder = folder.substr(themePath.string().size()+1);
if(fs::exists(set->second.getThemePath(folder))) if(boost::filesystem::exists(set->second.getThemePath(folder)))
{ {
systems.push_back(folder); systems.push_back(folder);
} }
@ -940,14 +939,14 @@ std::vector<std::string> CollectionSystemManager::getUnusedSystemsFromTheme()
std::vector<std::string> CollectionSystemManager::getCollectionsFromConfigFolder() std::vector<std::string> CollectionSystemManager::getCollectionsFromConfigFolder()
{ {
std::vector<std::string> systems; std::vector<std::string> systems;
fs::path configPath = getCollectionsFolder(); boost::filesystem::path configPath = getCollectionsFolder();
if (fs::exists(configPath)) if (boost::filesystem::exists(configPath))
{ {
fs::directory_iterator end_itr; // default construction yields past-the-end boost::filesystem::directory_iterator end_itr; // default construction yields past-the-end
for (fs::directory_iterator itr(configPath); itr != end_itr; ++itr) for (boost::filesystem::directory_iterator itr(configPath); itr != end_itr; ++itr)
{ {
if (fs::is_regular_file(itr->status())) if (boost::filesystem::is_regular_file(itr->status()))
{ {
// it's a file // it's a file
std::string file = itr->path().string(); std::string file = itr->path().string();
@ -1013,7 +1012,7 @@ bool CollectionSystemManager::includeFileInAutoCollections(FileData* file)
std::string getCustomCollectionConfigPath(std::string collectionName) std::string getCustomCollectionConfigPath(std::string collectionName)
{ {
fs::path path = getCollectionsFolder() + "custom-" + collectionName + ".cfg"; boost::filesystem::path path = getCollectionsFolder() + "custom-" + collectionName + ".cfg";
return path.generic_string(); return path.generic_string();
} }

View file

@ -14,9 +14,7 @@
#include "Window.h" #include "Window.h"
#include <boost/filesystem/operations.hpp> #include <boost/filesystem/operations.hpp>
namespace fs = boost::filesystem; FileData::FileData(FileType type, const boost::filesystem::path& path, SystemEnvironmentData* envData, SystemData* system)
FileData::FileData(FileType type, const fs::path& path, SystemEnvironmentData* envData, SystemData* system)
: mType(type), mPath(path), mSystem(system), mEnvData(envData), mSourceFileData(NULL), mParent(NULL), metadata(type == GAME ? GAME_METADATA : FOLDER_METADATA) // metadata is REALLY set in the constructor! : mType(type), mPath(path), mSystem(system), mEnvData(envData), mSourceFileData(NULL), mParent(NULL), metadata(type == GAME ? GAME_METADATA : FOLDER_METADATA) // metadata is REALLY set in the constructor!
{ {
// metadata needs at least a name field (since that's what getName() will return) // metadata needs at least a name field (since that's what getName() will return)
@ -259,7 +257,7 @@ void FileData::launchGame(Window* window)
const std::string rom = escapePath(getPath()); const std::string rom = escapePath(getPath());
const std::string basename = getPath().stem().string(); const std::string basename = getPath().stem().string();
const std::string rom_raw = fs::path(getPath()).make_preferred().string(); const std::string rom_raw = boost::filesystem::path(getPath()).make_preferred().string();
command = strreplace(command, "%ROM%", rom); command = strreplace(command, "%ROM%", rom);
command = strreplace(command, "%BASENAME%", basename); command = strreplace(command, "%BASENAME%", basename);

View file

@ -3,7 +3,6 @@
#define ES_APP_FILE_DATA_H #define ES_APP_FILE_DATA_H
#include "MetaData.h" #include "MetaData.h"
#include <boost/filesystem/path.hpp>
#include <unordered_map> #include <unordered_map>
class SystemData; class SystemData;

View file

@ -7,17 +7,14 @@
#include "SystemData.h" #include "SystemData.h"
#include "Util.h" #include "Util.h"
#include <boost/filesystem/operations.hpp> #include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <pugixml/src/pugixml.hpp> #include <pugixml/src/pugixml.hpp>
namespace fs = boost::filesystem;
FileData* findOrCreateFile(SystemData* system, const boost::filesystem::path& path, FileType type, bool trustGamelist) FileData* findOrCreateFile(SystemData* system, const boost::filesystem::path& path, FileType type, bool trustGamelist)
{ {
// first, verify that path is within the system's root folder // first, verify that path is within the system's root folder
FileData* root = system->getRootFolder(); FileData* root = system->getRootFolder();
fs::path relative; boost::filesystem::path relative;
bool contains = false; bool contains = false;
if (trustGamelist) if (trustGamelist)
{ {
@ -111,7 +108,7 @@ void parseGamelist(SystemData* system)
return; return;
} }
fs::path relativeTo = system->getStartPath(); boost::filesystem::path relativeTo = system->getStartPath();
const char* tagList[2] = { "game", "folder" }; const char* tagList[2] = { "game", "folder" };
FileType typeList[2] = { GAME, FOLDER }; FileType typeList[2] = { GAME, FOLDER };
@ -121,7 +118,7 @@ void parseGamelist(SystemData* system)
FileType type = typeList[i]; FileType type = typeList[i];
for(pugi::xml_node fileNode = root.child(tag); fileNode; fileNode = fileNode.next_sibling(tag)) for(pugi::xml_node fileNode = root.child(tag); fileNode; fileNode = fileNode.next_sibling(tag))
{ {
fs::path path = resolvePath(fileNode.child("path").text().get(), relativeTo, false); boost::filesystem::path path = resolvePath(fileNode.child("path").text().get(), relativeTo, false);
if(!trustGamelist && !boost::filesystem::exists(path)) if(!trustGamelist && !boost::filesystem::exists(path))
{ {
@ -242,9 +239,9 @@ void updateGamelist(SystemData* system)
continue; continue;
} }
fs::path nodePath = resolvePath(pathNode.text().get(), system->getStartPath(), true); boost::filesystem::path nodePath = resolvePath(pathNode.text().get(), system->getStartPath(), true);
fs::path gamePath((*fit)->getPath()); boost::filesystem::path gamePath((*fit)->getPath());
if(nodePath == gamePath || (fs::exists(nodePath) && fs::exists(gamePath) && fs::equivalent(nodePath, gamePath))) if(nodePath == gamePath || (boost::filesystem::exists(nodePath) && boost::filesystem::exists(gamePath) && boost::filesystem::equivalent(nodePath, gamePath)))
{ {
// found it // found it
root.remove_child(fileNode); root.remove_child(fileNode);

View file

@ -4,8 +4,6 @@
#include "Util.h" #include "Util.h"
#include <pugixml/src/pugixml.hpp> #include <pugixml/src/pugixml.hpp>
namespace fs = boost::filesystem;
MetaDataDecl gameDecls[] = { MetaDataDecl gameDecls[] = {
// key, type, default, statistic, name in GuiMetaDataEd, prompt in GuiMetaDataEd // key, type, default, statistic, name in GuiMetaDataEd, prompt in GuiMetaDataEd
{"name", MD_STRING, "", false, "name", "enter game name"}, {"name", MD_STRING, "", false, "name", "enter game name"},
@ -69,7 +67,7 @@ MetaDataList::MetaDataList(MetaDataListType type)
} }
MetaDataList MetaDataList::createFromXML(MetaDataListType type, pugi::xml_node& node, const fs::path& relativeTo) MetaDataList MetaDataList::createFromXML(MetaDataListType type, pugi::xml_node& node, const boost::filesystem::path& relativeTo)
{ {
MetaDataList mdl(type); MetaDataList mdl(type);
@ -95,7 +93,7 @@ MetaDataList MetaDataList::createFromXML(MetaDataListType type, pugi::xml_node&
return mdl; return mdl;
} }
void MetaDataList::appendToXML(pugi::xml_node& parent, bool ignoreDefaults, const fs::path& relativeTo) const void MetaDataList::appendToXML(pugi::xml_node& parent, bool ignoreDefaults, const boost::filesystem::path& relativeTo) const
{ {
const std::vector<MetaDataDecl>& mdd = getMDD(); const std::vector<MetaDataDecl>& mdd = getMDD();

View file

@ -17,8 +17,6 @@
std::vector<SystemData*> SystemData::sSystemVector; std::vector<SystemData*> SystemData::sSystemVector;
namespace fs = boost::filesystem;
SystemData::SystemData(const std::string& name, const std::string& fullName, SystemEnvironmentData* envData, const std::string& themeFolder, bool CollectionSystem) : SystemData::SystemData(const std::string& name, const std::string& fullName, SystemEnvironmentData* envData, const std::string& themeFolder, bool CollectionSystem) :
mName(name), mFullName(fullName), mEnvData(envData), mThemeFolder(themeFolder), mIsCollectionSystem(CollectionSystem), mIsGameSystem(true) mName(name), mFullName(fullName), mEnvData(envData), mThemeFolder(themeFolder), mIsCollectionSystem(CollectionSystem), mIsGameSystem(true)
{ {
@ -70,21 +68,21 @@ void SystemData::setIsGameSystemStatus()
} }
// test to see if a file is hidden // test to see if a file is hidden
bool isHidden(const fs::path &filePath) bool isHidden(const boost::filesystem::path &filePath)
{ {
#ifdef WIN32 #ifdef WIN32
const DWORD Attributes = GetFileAttributes(filePath.generic_string().c_str()); const DWORD Attributes = GetFileAttributes(filePath.generic_string().c_str());
return (Attributes != INVALID_FILE_ATTRIBUTES) && (Attributes & FILE_ATTRIBUTE_HIDDEN); return (Attributes != INVALID_FILE_ATTRIBUTES) && (Attributes & FILE_ATTRIBUTE_HIDDEN);
#else #else
fs::path::string_type fileName = filePath.filename().string(); boost::filesystem::path::string_type fileName = filePath.filename().string();
return fileName[0] == '.'; return fileName[0] == '.';
#endif #endif
} }
void SystemData::populateFolder(FileData* folder) void SystemData::populateFolder(FileData* folder)
{ {
const fs::path& folderPath = folder->getPath(); const boost::filesystem::path& folderPath = folder->getPath();
if(!fs::is_directory(folderPath)) if(!boost::filesystem::is_directory(folderPath))
{ {
LOG(LogWarning) << "Error - folder with path \"" << folderPath << "\" is not a directory!"; LOG(LogWarning) << "Error - folder with path \"" << folderPath << "\" is not a directory!";
return; return;
@ -93,21 +91,21 @@ void SystemData::populateFolder(FileData* folder)
const std::string folderStr = folderPath.generic_string(); const std::string folderStr = folderPath.generic_string();
//make sure that this isn't a symlink to a thing we already have //make sure that this isn't a symlink to a thing we already have
if(fs::is_symlink(folderPath)) if(boost::filesystem::is_symlink(folderPath))
{ {
//if this symlink resolves to somewhere that's at the beginning of our path, it's gonna recurse //if this symlink resolves to somewhere that's at the beginning of our path, it's gonna recurse
if(folderStr.find(fs::canonical(folderPath).generic_string()) == 0) if(folderStr.find(boost::filesystem::canonical(folderPath).generic_string()) == 0)
{ {
LOG(LogWarning) << "Skipping infinitely recursive symlink \"" << folderPath << "\""; LOG(LogWarning) << "Skipping infinitely recursive symlink \"" << folderPath << "\"";
return; return;
} }
} }
fs::path filePath; boost::filesystem::path filePath;
std::string extension; std::string extension;
bool isGame; bool isGame;
bool showHidden = Settings::getInstance()->getBool("ShowHiddenFiles"); bool showHidden = Settings::getInstance()->getBool("ShowHiddenFiles");
for(fs::directory_iterator end, dir(folderPath); dir != end; ++dir) for(boost::filesystem::directory_iterator end, dir(folderPath); dir != end; ++dir)
{ {
filePath = (*dir).path(); filePath = (*dir).path();
@ -134,7 +132,7 @@ void SystemData::populateFolder(FileData* folder)
} }
//add directories that also do not match an extension as folders //add directories that also do not match an extension as folders
if(!isGame && fs::is_directory(filePath)) if(!isGame && boost::filesystem::is_directory(filePath))
{ {
FileData* newFolder = new FileData(FOLDER, filePath.generic_string(), mEnvData, this); FileData* newFolder = new FileData(FOLDER, filePath.generic_string(), mEnvData, this);
populateFolder(newFolder); populateFolder(newFolder);
@ -188,7 +186,7 @@ bool SystemData::loadConfig()
LOG(LogInfo) << "Loading system config file " << path << "..."; LOG(LogInfo) << "Loading system config file " << path << "...";
if(!fs::exists(path)) if(!boost::filesystem::exists(path))
{ {
LOG(LogError) << "es_systems.cfg file does not exist!"; LOG(LogError) << "es_systems.cfg file does not exist!";
writeExampleConfig(getConfigPath(true)); writeExampleConfig(getConfigPath(true));
@ -350,8 +348,8 @@ void SystemData::deleteSystems()
std::string SystemData::getConfigPath(bool forWrite) std::string SystemData::getConfigPath(bool forWrite)
{ {
fs::path path = getHomePath() + "/.emulationstation/es_systems.cfg"; boost::filesystem::path path = getHomePath() + "/.emulationstation/es_systems.cfg";
if(forWrite || fs::exists(path)) if(forWrite || boost::filesystem::exists(path))
return path.generic_string(); return path.generic_string();
return "/etc/emulationstation/es_systems.cfg"; return "/etc/emulationstation/es_systems.cfg";
@ -387,16 +385,16 @@ SystemData* SystemData::getPrev() const
std::string SystemData::getGamelistPath(bool forWrite) const std::string SystemData::getGamelistPath(bool forWrite) const
{ {
fs::path filePath; boost::filesystem::path filePath;
filePath = mRootFolder->getPath() / "gamelist.xml"; filePath = mRootFolder->getPath() / "gamelist.xml";
if(fs::exists(filePath)) if(boost::filesystem::exists(filePath))
return filePath.generic_string(); return filePath.generic_string();
filePath = getHomePath() + "/.emulationstation/gamelists/" + mName + "/gamelist.xml"; filePath = getHomePath() + "/.emulationstation/gamelists/" + mName + "/gamelist.xml";
if(forWrite) // make sure the directory exists if we're going to write to it, or crashes will happen if(forWrite) // make sure the directory exists if we're going to write to it, or crashes will happen
fs::create_directories(filePath.parent_path()); boost::filesystem::create_directories(filePath.parent_path());
if(forWrite || fs::exists(filePath)) if(forWrite || boost::filesystem::exists(filePath))
return filePath.generic_string(); return filePath.generic_string();
return "/etc/emulationstation/gamelists/" + mName + "/gamelist.xml"; return "/etc/emulationstation/gamelists/" + mName + "/gamelist.xml";
@ -410,14 +408,14 @@ std::string SystemData::getThemePath() const
// 3. default system theme from currently selected theme set [CURRENT_THEME_PATH]/theme.xml // 3. default system theme from currently selected theme set [CURRENT_THEME_PATH]/theme.xml
// first, check game folder // first, check game folder
fs::path localThemePath = mRootFolder->getPath() / "theme.xml"; boost::filesystem::path localThemePath = mRootFolder->getPath() / "theme.xml";
if(fs::exists(localThemePath)) if(boost::filesystem::exists(localThemePath))
return localThemePath.generic_string(); return localThemePath.generic_string();
// not in game folder, try system theme in theme sets // not in game folder, try system theme in theme sets
localThemePath = ThemeData::getThemeFromCurrentSet(mThemeFolder); localThemePath = ThemeData::getThemeFromCurrentSet(mThemeFolder);
if (fs::exists(localThemePath)) if (boost::filesystem::exists(localThemePath))
return localThemePath.generic_string(); return localThemePath.generic_string();
// not system theme, try default system theme in theme set // not system theme, try default system theme in theme set
@ -428,7 +426,7 @@ std::string SystemData::getThemePath() const
bool SystemData::hasGamelist() const bool SystemData::hasGamelist() const
{ {
return (fs::exists(getGamelistPath(false))); return (boost::filesystem::exists(getGamelistPath(false)));
} }
unsigned int SystemData::getGameCount() const unsigned int SystemData::getGameCount() const
@ -490,7 +488,7 @@ void SystemData::loadTheme()
std::string path = getThemePath(); std::string path = getThemePath();
if(!fs::exists(path)) // no theme available for this platform if(!boost::filesystem::exists(path)) // no theme available for this platform
return; return;
try try

View file

@ -25,8 +25,6 @@
#include <FreeImage.h> #include <FreeImage.h>
namespace fs = boost::filesystem;
bool scrape_cmdline = false; bool scrape_cmdline = false;
bool parseArgs(int argc, char* argv[]) bool parseArgs(int argc, char* argv[])
@ -160,11 +158,11 @@ bool verifyHomeFolderExists()
//make sure the config directory exists //make sure the config directory exists
std::string home = getHomePath(); std::string home = getHomePath();
std::string configDir = home + "/.emulationstation"; std::string configDir = home + "/.emulationstation";
if(!fs::exists(configDir)) if(!boost::filesystem::exists(configDir))
{ {
std::cout << "Creating config directory \"" << configDir << "\"\n"; std::cout << "Creating config directory \"" << configDir << "\"\n";
fs::create_directory(configDir); boost::filesystem::create_directory(configDir);
if(!fs::exists(configDir)) if(!boost::filesystem::exists(configDir))
{ {
std::cerr << "Config directory could not be created!\n"; std::cerr << "Config directory could not be created!\n";
return false; return false;
@ -326,7 +324,7 @@ int main(int argc, char* argv[])
//choose which GUI to open depending on if an input configuration already exists //choose which GUI to open depending on if an input configuration already exists
if(errorMsg == NULL) if(errorMsg == NULL)
{ {
if(fs::exists(InputManager::getConfigPath()) && InputManager::getInstance()->getNumConfiguredDevices() > 0) if(boost::filesystem::exists(InputManager::getConfigPath()) && InputManager::getInstance()->getNumConfiguredDevices() > 0)
{ {
ViewController::get()->goToStart(); ViewController::get()->goToStart();
}else{ }else{

View file

@ -8,6 +8,7 @@
#include <pugixml/src/pugixml.hpp> #include <pugixml/src/pugixml.hpp>
#include <SDL.h> #include <SDL.h>
#include <iostream> #include <iostream>
#include <assert.h>
#define KEYBOARD_GUID_STRING "-1" #define KEYBOARD_GUID_STRING "-1"
#define CEC_GUID_STRING "-2" #define CEC_GUID_STRING "-2"
@ -27,8 +28,6 @@
int SDL_USER_CECBUTTONDOWN = -1; int SDL_USER_CECBUTTONDOWN = -1;
int SDL_USER_CECBUTTONUP = -1; int SDL_USER_CECBUTTONUP = -1;
namespace fs = boost::filesystem;
InputManager* InputManager::mInstance = NULL; InputManager* InputManager::mInstance = NULL;
InputManager::InputManager() : mKeyboardInputConfig(NULL) InputManager::InputManager() : mKeyboardInputConfig(NULL)
@ -279,7 +278,7 @@ bool InputManager::parseEvent(const SDL_Event& ev, Window* window)
bool InputManager::loadInputConfig(InputConfig* config) bool InputManager::loadInputConfig(InputConfig* config)
{ {
std::string path = getConfigPath(); std::string path = getConfigPath();
if(!fs::exists(path)) if(!boost::filesystem::exists(path))
return false; return false;
pugi::xml_document doc; pugi::xml_document doc;
@ -334,7 +333,7 @@ void InputManager::writeDeviceConfig(InputConfig* config)
pugi::xml_document doc; pugi::xml_document doc;
if(fs::exists(path)) if(boost::filesystem::exists(path))
{ {
// merge files // merge files
pugi::xml_parse_result result = doc.load_file(path.c_str()); pugi::xml_parse_result result = doc.load_file(path.c_str());
@ -395,7 +394,7 @@ void InputManager::doOnFinish()
std::string path = getConfigPath(); std::string path = getConfigPath();
pugi::xml_document doc; pugi::xml_document doc;
if(fs::exists(path)) if(boost::filesystem::exists(path))
{ {
pugi::xml_parse_result result = doc.load_file(path.c_str()); pugi::xml_parse_result result = doc.load_file(path.c_str());
if(!result) if(!result)

View file

@ -123,8 +123,6 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>> The
{ "zIndex", FLOAT } } } { "zIndex", FLOAT } } }
}; };
namespace fs = boost::filesystem;
#define MINIMUM_THEME_FORMAT_VERSION 3 #define MINIMUM_THEME_FORMAT_VERSION 3
#define CURRENT_THEME_FORMAT_VERSION 5 #define CURRENT_THEME_FORMAT_VERSION 5
@ -151,12 +149,12 @@ unsigned int getHexColor(const char* str)
} }
// helper // helper
std::string resolvePath(const char* in, const fs::path& relative) std::string resolvePath(const char* in, const boost::filesystem::path& relative)
{ {
if(!in || in[0] == '\0') if(!in || in[0] == '\0')
return in; return in;
fs::path relPath = relative.parent_path(); boost::filesystem::path relPath = relative.parent_path();
boost::filesystem::path path(in); boost::filesystem::path path(in);
@ -207,7 +205,7 @@ void ThemeData::loadFile(std::map<std::string, std::string> sysDataMap, const st
ThemeException error; ThemeException error;
error.setFiles(mPaths); error.setFiles(mPaths);
if(!fs::exists(path)) if(!boost::filesystem::exists(path))
throw error << "File does not exist!"; throw error << "File does not exist!";
mVersion = 0; mVersion = 0;
@ -486,7 +484,7 @@ const std::shared_ptr<ThemeData>& ThemeData::getDefault()
theme = std::shared_ptr<ThemeData>(new ThemeData()); theme = std::shared_ptr<ThemeData>(new ThemeData());
const std::string path = getHomePath() + "/.emulationstation/es_theme_default.xml"; const std::string path = getHomePath() + "/.emulationstation/es_theme_default.xml";
if(fs::exists(path)) if(boost::filesystem::exists(path))
{ {
try try
{ {
@ -537,21 +535,21 @@ std::map<std::string, ThemeSet> ThemeData::getThemeSets()
std::map<std::string, ThemeSet> sets; std::map<std::string, ThemeSet> sets;
static const size_t pathCount = 2; static const size_t pathCount = 2;
fs::path paths[pathCount] = { boost::filesystem::path paths[pathCount] = {
"/etc/emulationstation/themes", "/etc/emulationstation/themes",
getHomePath() + "/.emulationstation/themes" getHomePath() + "/.emulationstation/themes"
}; };
fs::directory_iterator end; boost::filesystem::directory_iterator end;
for(size_t i = 0; i < pathCount; i++) for(size_t i = 0; i < pathCount; i++)
{ {
if(!fs::is_directory(paths[i])) if(!boost::filesystem::is_directory(paths[i]))
continue; continue;
for(fs::directory_iterator it(paths[i]); it != end; ++it) for(boost::filesystem::directory_iterator it(paths[i]); it != end; ++it)
{ {
if(fs::is_directory(*it)) if(boost::filesystem::is_directory(*it))
{ {
ThemeSet set = {*it}; ThemeSet set = {*it};
sets[set.getName()] = set; sets[set.getName()] = set;
@ -562,7 +560,7 @@ std::map<std::string, ThemeSet> ThemeData::getThemeSets()
return sets; return sets;
} }
fs::path ThemeData::getThemeFromCurrentSet(const std::string& system) boost::filesystem::path ThemeData::getThemeFromCurrentSet(const std::string& system)
{ {
auto themeSets = ThemeData::getThemeSets(); auto themeSets = ThemeData::getThemeSets();
if(themeSets.empty()) if(themeSets.empty())

View file

@ -3,8 +3,6 @@
#include "platform.h" #include "platform.h"
#include <boost/filesystem/operations.hpp> #include <boost/filesystem/operations.hpp>
namespace fs = boost::filesystem;
std::string strToUpper(const char* from) std::string strToUpper(const char* from)
{ {
std::string str(from); std::string str(from);
@ -37,7 +35,7 @@ std::string getCanonicalPath(const std::string& path)
// expands "./my/path.sfc" to "[relativeTo]/my/path.sfc" // expands "./my/path.sfc" to "[relativeTo]/my/path.sfc"
// if allowHome is true, also expands "~/my/path.sfc" to "/home/pi/my/path.sfc" // if allowHome is true, also expands "~/my/path.sfc" to "/home/pi/my/path.sfc"
fs::path resolvePath(const fs::path& path, const fs::path& relativeTo, bool allowHome) boost::filesystem::path resolvePath(const boost::filesystem::path& path, const boost::filesystem::path& relativeTo, bool allowHome)
{ {
// nothing here // nothing here
if(path.begin() == path.end()) if(path.begin() == path.end())
@ -45,7 +43,7 @@ fs::path resolvePath(const fs::path& path, const fs::path& relativeTo, bool allo
if(*path.begin() == ".") if(*path.begin() == ".")
{ {
fs::path ret = relativeTo; boost::filesystem::path ret = relativeTo;
for(auto it = ++path.begin(); it != path.end(); ++it) for(auto it = ++path.begin(); it != path.end(); ++it)
ret /= *it; ret /= *it;
return ret; return ret;
@ -53,7 +51,7 @@ fs::path resolvePath(const fs::path& path, const fs::path& relativeTo, bool allo
if(allowHome && *path.begin() == "~") if(allowHome && *path.begin() == "~")
{ {
fs::path ret = getHomePath(); boost::filesystem::path ret = getHomePath();
for(auto it = ++path.begin(); it != path.end(); ++it) for(auto it = ++path.begin(); it != path.end(); ++it)
ret /= *it; ret /= *it;
return ret; return ret;
@ -62,7 +60,7 @@ fs::path resolvePath(const fs::path& path, const fs::path& relativeTo, bool allo
return path; return path;
} }
fs::path removeCommonPathUsingStrings(const fs::path& path, const fs::path& relativeTo, bool& contains) boost::filesystem::path removeCommonPathUsingStrings(const boost::filesystem::path& path, const boost::filesystem::path& relativeTo, bool& contains)
{ {
#ifdef WIN32 #ifdef WIN32
std::wstring pathStr = path.c_str(); std::wstring pathStr = path.c_str();
@ -82,18 +80,18 @@ fs::path removeCommonPathUsingStrings(const fs::path& path, const fs::path& rela
} }
// example: removeCommonPath("/home/pi/roms/nes/foo/bar.nes", "/home/pi/roms/nes/") returns "foo/bar.nes" // example: removeCommonPath("/home/pi/roms/nes/foo/bar.nes", "/home/pi/roms/nes/") returns "foo/bar.nes"
fs::path removeCommonPath(const fs::path& path, const fs::path& relativeTo, bool& contains) boost::filesystem::path removeCommonPath(const boost::filesystem::path& path, const boost::filesystem::path& relativeTo, bool& contains)
{ {
// if either of these doesn't exist, fs::canonical() is going to throw an error // if either of these doesn't exist, boost::filesystem::canonical() is going to throw an error
if(!fs::exists(path) || !fs::exists(relativeTo)) if(!boost::filesystem::exists(path) || !boost::filesystem::exists(relativeTo))
{ {
contains = false; contains = false;
return path; return path;
} }
// if it's a symlink we don't want to apply fs::canonical on it, otherwise we'll lose the current parent_path // if it's a symlink we don't want to apply boost::filesystem::canonical on it, otherwise we'll lose the current parent_path
fs::path p = (fs::is_symlink(path) ? fs::canonical(path.parent_path()) / path.filename() : fs::canonical(path)); boost::filesystem::path p = (boost::filesystem::is_symlink(path) ? boost::filesystem::canonical(path.parent_path()) / path.filename() : boost::filesystem::canonical(path));
fs::path r = fs::canonical(relativeTo); boost::filesystem::path r = boost::filesystem::canonical(relativeTo);
if(p.root_path() != r.root_path()) if(p.root_path() != r.root_path())
{ {
@ -101,7 +99,7 @@ fs::path removeCommonPath(const fs::path& path, const fs::path& relativeTo, bool
return p; return p;
} }
fs::path result; boost::filesystem::path result;
// find point of divergence // find point of divergence
auto itr_path = p.begin(); auto itr_path = p.begin();
@ -120,7 +118,7 @@ fs::path removeCommonPath(const fs::path& path, const fs::path& relativeTo, bool
while(itr_path != p.end()) while(itr_path != p.end())
{ {
if(*itr_path != fs::path(".")) if(*itr_path != boost::filesystem::path("."))
result = result / *itr_path; result = result / *itr_path;
++itr_path; ++itr_path;
@ -132,11 +130,11 @@ fs::path removeCommonPath(const fs::path& path, const fs::path& relativeTo, bool
// usage: makeRelativePath("/path/to/my/thing.sfc", "/path/to") -> "./my/thing.sfc" // usage: makeRelativePath("/path/to/my/thing.sfc", "/path/to") -> "./my/thing.sfc"
// usage: makeRelativePath("/home/pi/my/thing.sfc", "/path/to", true) -> "~/my/thing.sfc" // usage: makeRelativePath("/home/pi/my/thing.sfc", "/path/to", true) -> "~/my/thing.sfc"
fs::path makeRelativePath(const fs::path& path, const fs::path& relativeTo, bool allowHome) boost::filesystem::path makeRelativePath(const boost::filesystem::path& path, const boost::filesystem::path& relativeTo, bool allowHome)
{ {
bool contains = false; bool contains = false;
fs::path ret = removeCommonPath(path, relativeTo, contains); boost::filesystem::path ret = removeCommonPath(path, relativeTo, contains);
if(contains) if(contains)
{ {
// success // success
@ -177,7 +175,7 @@ std::string escapePath(const boost::filesystem::path& path)
{ {
#ifdef WIN32 #ifdef WIN32
// windows escapes stuff by just putting everything in quotes // windows escapes stuff by just putting everything in quotes
return '"' + fs::path(path).make_preferred().string() + '"'; return '"' + boost::filesystem::path(path).make_preferred().string() + '"';
#else #else
// a quick and dirty way to insert a backslash before most characters that would mess up a bash path // a quick and dirty way to insert a backslash before most characters that would mess up a bash path
std::string pathStr = path.string(); std::string pathStr = path.string();

View file

@ -11,8 +11,6 @@
#define HOLD_TIME 1000 #define HOLD_TIME 1000
namespace fs = boost::filesystem;
GuiDetectDevice::GuiDetectDevice(Window* window, bool firstRun, const std::function<void()>& doneCallback) : GuiComponent(window), mFirstRun(firstRun), GuiDetectDevice::GuiDetectDevice(Window* window, bool firstRun, const std::function<void()>& doneCallback) : GuiComponent(window), mFirstRun(firstRun),
mBackground(window, ":/frame.png"), mGrid(window, Vector2i(1, 5)) mBackground(window, ":/frame.png"), mGrid(window, Vector2i(1, 5))
{ {
@ -104,7 +102,7 @@ void GuiDetectDevice::update(int deltaTime)
if(mHoldingConfig) if(mHoldingConfig)
{ {
// If ES starts and if a known device is connected after startup skip controller configuration // If ES starts and if a known device is connected after startup skip controller configuration
if(mFirstRun && fs::exists(InputManager::getConfigPath()) && InputManager::getInstance()->getNumConfiguredDevices() > 0) if(mFirstRun && boost::filesystem::exists(InputManager::getConfigPath()) && InputManager::getInstance()->getNumConfiguredDevices() > 0)
{ {
if(mDoneCallback) if(mDoneCallback)
mDoneCallback(); mDoneCallback();

View file

@ -4,8 +4,6 @@
#include <boost/filesystem/operations.hpp> #include <boost/filesystem/operations.hpp>
#include <fstream> #include <fstream>
namespace fs = boost::filesystem;
auto array_deleter = [](unsigned char* p) { delete[] p; }; auto array_deleter = [](unsigned char* p) { delete[] p; };
auto nop_deleter = [](unsigned char* /*p*/) { }; auto nop_deleter = [](unsigned char* /*p*/) { };
@ -39,7 +37,7 @@ const ResourceData ResourceManager::getFileData(const std::string& path) const
} }
//it's not embedded; load the file //it's not embedded; load the file
if(!fs::exists(path)) if(!boost::filesystem::exists(path))
{ {
//if the file doesn't exist, return an "empty" ResourceData //if the file doesn't exist, return an "empty" ResourceData
ResourceData data = {NULL, 0}; ResourceData data = {NULL, 0};
@ -73,7 +71,7 @@ bool ResourceManager::fileExists(const std::string& path) const
if(res2hMap.find(path) != res2hMap.cend()) if(res2hMap.find(path) != res2hMap.cend())
return true; return true;
return fs::exists(path); return boost::filesystem::exists(path);
} }
void ResourceManager::unloadAll() void ResourceManager::unloadAll()

View file

@ -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 '/' #if defined(_WIN32)
for(p = (char*)_path.c_str() + 1; *p; ++p) WIN32_FIND_DATA findData;
HANDLE hFind = FindFirstFile((path + "/*").c_str(), &findData);
if(hFind != INVALID_HANDLE_VALUE)
{ {
if(*p == '\\') // loop over all files in the directory
*p = '/'; 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);
} }
} // makeGeneric closedir(dir);
}
#endif // _WIN32
std::string escapePath(const std::string& _path) }
// sort the content list
contentList.sort();
// 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 canonicalPath(const std::string& _path)
{
std::string path = absolutePath(_path);
// cleanup path
bool scan = true;
while(scan)
{
stringList pathList;
size_t start = 0;
size_t end = 0;
// split at '/'
while((end = path.find("/", start)) != std::string::npos)
{
pathList.push_back(std::string(path, 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));
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 getParent(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 // find last '/' and erase it
char temp[512]; if((offset = path.find_last_of('/')) != std::string::npos)
size_t len = snprintf(temp, sizeof(temp), "%s", _path.c_str()); return path.erase(offset);
// find last '/' and end the new path
while(len > 1)
{
if(temp[--len] == '/')
{
temp[len] = 0;
return temp;
}
}
// 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::

View file

@ -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::

View file

@ -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

View file

@ -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::

View file

@ -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);