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 <unordered_map>
namespace fs = boost::filesystem;
std::string myCollectionsName = "collections";
/* Handling the getting, initialization, deinitialization, saving and deletion of
@ -52,8 +51,8 @@ CollectionSystemManager::CollectionSystemManager(Window* window) : mWindow(windo
mCollectionEnvData->mPlatformIds = allPlatformIds;
std::string path = getCollectionsFolder();
if(!fs::exists(path))
fs::create_directory(path);
if(!boost::filesystem::exists(path))
boost::filesystem::create_directory(path);
mIsEditingCustom = false;
mEditingCollection = "Favorites";
@ -334,7 +333,7 @@ bool CollectionSystemManager::isThemeCustomCollectionCompatible(std::vector<std:
if(set != themeSets.cend())
{
std::string defaultThemeFilePath = set->second.path.string() + "/theme.xml";
if (fs::exists(defaultThemeFilePath))
if (boost::filesystem::exists(defaultThemeFilePath))
{
return true;
}
@ -722,7 +721,7 @@ void CollectionSystemManager::populateCustomCollection(CollectionSystemData* sys
CollectionSystemDecl sysDecl = sysData->decl;
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;
return;
@ -829,7 +828,7 @@ std::vector<std::string> CollectionSystemManager::getSystemsFromConfig()
std::vector<std::string> systems;
std::string path = SystemData::getConfigPath(false);
if(!fs::exists(path))
if(!boost::filesystem::exists(path))
{
return systems;
}
@ -880,20 +879,20 @@ std::vector<std::string> CollectionSystemManager::getSystemsFromTheme()
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
for (fs::directory_iterator itr(themePath); itr != end_itr; ++itr)
boost::filesystem::directory_iterator end_itr; // default construction yields past-the-end
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
std::string folder = itr->path().string();
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);
}
@ -940,14 +939,14 @@ std::vector<std::string> CollectionSystemManager::getUnusedSystemsFromTheme()
std::vector<std::string> CollectionSystemManager::getCollectionsFromConfigFolder()
{
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
for (fs::directory_iterator itr(configPath); itr != end_itr; ++itr)
boost::filesystem::directory_iterator end_itr; // default construction yields past-the-end
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
std::string file = itr->path().string();
@ -1013,7 +1012,7 @@ bool CollectionSystemManager::includeFileInAutoCollections(FileData* file)
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();
}

View file

@ -14,9 +14,7 @@
#include "Window.h"
#include <boost/filesystem/operations.hpp>
namespace fs = boost::filesystem;
FileData::FileData(FileType type, const fs::path& path, SystemEnvironmentData* envData, SystemData* system)
FileData::FileData(FileType type, const boost::filesystem::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!
{
// 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 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, "%BASENAME%", basename);

View file

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

View file

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

View file

@ -4,8 +4,6 @@
#include "Util.h"
#include <pugixml/src/pugixml.hpp>
namespace fs = boost::filesystem;
MetaDataDecl gameDecls[] = {
// key, type, default, statistic, name in GuiMetaDataEd, prompt in GuiMetaDataEd
{"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);
@ -95,7 +93,7 @@ MetaDataList MetaDataList::createFromXML(MetaDataListType type, pugi::xml_node&
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();

View file

@ -17,8 +17,6 @@
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) :
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
bool isHidden(const fs::path &filePath)
bool isHidden(const boost::filesystem::path &filePath)
{
#ifdef WIN32
const DWORD Attributes = GetFileAttributes(filePath.generic_string().c_str());
return (Attributes != INVALID_FILE_ATTRIBUTES) && (Attributes & FILE_ATTRIBUTE_HIDDEN);
#else
fs::path::string_type fileName = filePath.filename().string();
boost::filesystem::path::string_type fileName = filePath.filename().string();
return fileName[0] == '.';
#endif
}
void SystemData::populateFolder(FileData* folder)
{
const fs::path& folderPath = folder->getPath();
if(!fs::is_directory(folderPath))
const boost::filesystem::path& folderPath = folder->getPath();
if(!boost::filesystem::is_directory(folderPath))
{
LOG(LogWarning) << "Error - folder with path \"" << folderPath << "\" is not a directory!";
return;
@ -93,21 +91,21 @@ void SystemData::populateFolder(FileData* folder)
const std::string folderStr = folderPath.generic_string();
//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(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 << "\"";
return;
}
}
fs::path filePath;
boost::filesystem::path filePath;
std::string extension;
bool isGame;
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();
@ -134,7 +132,7 @@ void SystemData::populateFolder(FileData* folder)
}
//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);
populateFolder(newFolder);
@ -188,7 +186,7 @@ bool SystemData::loadConfig()
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!";
writeExampleConfig(getConfigPath(true));
@ -350,8 +348,8 @@ void SystemData::deleteSystems()
std::string SystemData::getConfigPath(bool forWrite)
{
fs::path path = getHomePath() + "/.emulationstation/es_systems.cfg";
if(forWrite || fs::exists(path))
boost::filesystem::path path = getHomePath() + "/.emulationstation/es_systems.cfg";
if(forWrite || boost::filesystem::exists(path))
return path.generic_string();
return "/etc/emulationstation/es_systems.cfg";
@ -387,16 +385,16 @@ SystemData* SystemData::getPrev() const
std::string SystemData::getGamelistPath(bool forWrite) const
{
fs::path filePath;
boost::filesystem::path filePath;
filePath = mRootFolder->getPath() / "gamelist.xml";
if(fs::exists(filePath))
if(boost::filesystem::exists(filePath))
return filePath.generic_string();
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
fs::create_directories(filePath.parent_path());
if(forWrite || fs::exists(filePath))
boost::filesystem::create_directories(filePath.parent_path());
if(forWrite || boost::filesystem::exists(filePath))
return filePath.generic_string();
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
// first, check game folder
fs::path localThemePath = mRootFolder->getPath() / "theme.xml";
if(fs::exists(localThemePath))
boost::filesystem::path localThemePath = mRootFolder->getPath() / "theme.xml";
if(boost::filesystem::exists(localThemePath))
return localThemePath.generic_string();
// not in game folder, try system theme in theme sets
localThemePath = ThemeData::getThemeFromCurrentSet(mThemeFolder);
if (fs::exists(localThemePath))
if (boost::filesystem::exists(localThemePath))
return localThemePath.generic_string();
// not system theme, try default system theme in theme set
@ -428,7 +426,7 @@ std::string SystemData::getThemePath() const
bool SystemData::hasGamelist() const
{
return (fs::exists(getGamelistPath(false)));
return (boost::filesystem::exists(getGamelistPath(false)));
}
unsigned int SystemData::getGameCount() const
@ -490,7 +488,7 @@ void SystemData::loadTheme()
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;
try

View file

@ -25,8 +25,6 @@
#include <FreeImage.h>
namespace fs = boost::filesystem;
bool scrape_cmdline = false;
bool parseArgs(int argc, char* argv[])
@ -160,11 +158,11 @@ bool verifyHomeFolderExists()
//make sure the config directory exists
std::string home = getHomePath();
std::string configDir = home + "/.emulationstation";
if(!fs::exists(configDir))
if(!boost::filesystem::exists(configDir))
{
std::cout << "Creating config directory \"" << configDir << "\"\n";
fs::create_directory(configDir);
if(!fs::exists(configDir))
boost::filesystem::create_directory(configDir);
if(!boost::filesystem::exists(configDir))
{
std::cerr << "Config directory could not be created!\n";
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
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();
}else{

View file

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

View file

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

View file

@ -3,8 +3,6 @@
#include "platform.h"
#include <boost/filesystem/operations.hpp>
namespace fs = boost::filesystem;
std::string strToUpper(const char* 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"
// 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
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() == ".")
{
fs::path ret = relativeTo;
boost::filesystem::path ret = relativeTo;
for(auto it = ++path.begin(); it != path.end(); ++it)
ret /= *it;
return ret;
@ -53,7 +51,7 @@ fs::path resolvePath(const fs::path& path, const fs::path& relativeTo, bool allo
if(allowHome && *path.begin() == "~")
{
fs::path ret = getHomePath();
boost::filesystem::path ret = getHomePath();
for(auto it = ++path.begin(); it != path.end(); ++it)
ret /= *it;
return ret;
@ -62,7 +60,7 @@ fs::path resolvePath(const fs::path& path, const fs::path& relativeTo, bool allo
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
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"
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(!fs::exists(path) || !fs::exists(relativeTo))
// if either of these doesn't exist, boost::filesystem::canonical() is going to throw an error
if(!boost::filesystem::exists(path) || !boost::filesystem::exists(relativeTo))
{
contains = false;
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
fs::path p = (fs::is_symlink(path) ? fs::canonical(path.parent_path()) / path.filename() : fs::canonical(path));
fs::path r = fs::canonical(relativeTo);
// if it's a symlink we don't want to apply boost::filesystem::canonical on it, otherwise we'll lose the current parent_path
boost::filesystem::path p = (boost::filesystem::is_symlink(path) ? boost::filesystem::canonical(path.parent_path()) / path.filename() : boost::filesystem::canonical(path));
boost::filesystem::path r = boost::filesystem::canonical(relativeTo);
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;
}
fs::path result;
boost::filesystem::path result;
// find point of divergence
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())
{
if(*itr_path != fs::path("."))
if(*itr_path != boost::filesystem::path("."))
result = result / *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("/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;
fs::path ret = removeCommonPath(path, relativeTo, contains);
boost::filesystem::path ret = removeCommonPath(path, relativeTo, contains);
if(contains)
{
// success
@ -177,7 +175,7 @@ std::string escapePath(const boost::filesystem::path& path)
{
#ifdef WIN32
// 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
// a quick and dirty way to insert a backslash before most characters that would mess up a bash path
std::string pathStr = path.string();

View file

@ -11,8 +11,6 @@
#define HOLD_TIME 1000
namespace fs = boost::filesystem;
GuiDetectDevice::GuiDetectDevice(Window* window, bool firstRun, const std::function<void()>& doneCallback) : GuiComponent(window), mFirstRun(firstRun),
mBackground(window, ":/frame.png"), mGrid(window, Vector2i(1, 5))
{
@ -104,7 +102,7 @@ void GuiDetectDevice::update(int deltaTime)
if(mHoldingConfig)
{
// 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)
mDoneCallback();

View file

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

View file

@ -3,166 +3,528 @@
#include <sys/stat.h>
#include <string.h>
#if defined(WIN32)
#if defined(_WIN32)
// because windows...
#include <direct.h>
#define snprintf _snprintf
#include <Windows.h>
#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 FileSystem
{
bool createDirectory(const std::string& _path)
stringList getDirContent(const std::string& _path)
{
// don't create if it already exists
if(exists(_path))
return true;
std::string path = genericPath(_path);
stringList contentList;
// convert '\\' to '/'
makeGeneric(_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)
// only parse the directory, if it's a directory
if(isDirectory(path))
{
char* p = nullptr;
// convert '\\' to '/'
for(p = (char*)_path.c_str() + 1; *p; ++p)
#if defined(_WIN32)
WIN32_FIND_DATA findData;
HANDLE hFind = FindFirstFile((path + "/*").c_str(), &findData);
if(hFind != INVALID_HANDLE_VALUE)
{
if(*p == '\\')
*p = '/';
// 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);
}
} // 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
return '"' + _path + '"';
#else // WIN32
return '"' + path + '"';
#else // _WIN32
// insert a backslash before most characters that would mess up a bash path
std::string escapedPath = _path;
const char* invalidChars = "\\ '\"!$^&*(){}[]?;<>";
const char* invalidChar = invalidChars;
size_t offset = std::string::npos;
while(*invalidChar)
{
for(size_t i = 0; i < escapedPath.length(); ++i)
{
if(escapedPath[i] == *invalidChar)
{
escapedPath.insert(i, 1, '\\');
++i;
}
}
while((offset = path.find(*invalidChar)) != std::string::npos)
path.insert(offset, 1, '\\');
++invalidChar;
}
return escapedPath;
#endif // WIN32
// return escaped path
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)
{
// convert '\\' to '/'
makeGeneric(_path);
std::string path = genericPath(_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 end the new path
while(len > 1)
{
if(temp[--len] == '/')
{
temp[len] = 0;
return temp;
}
}
// find last '/' and erase it
if((offset = path.find_last_of('/')) != std::string::npos)
return path.erase(offset);
// no parent found
return _path;
return path;
} // getParent
std::string getFileName(const std::string& _path)
{
// convert '\\' to '/'
makeGeneric(_path);
// make a copy of the path
char temp[512];
size_t len = snprintf(temp, sizeof(temp), "%s", _path.c_str());
std::string path = genericPath(_path);
size_t offset = std::string::npos;
// find last '/' and return the filename
while(len > 1)
{
// return "." if this is the end of the path, otherwise return filename
if(temp[--len] == '/')
return ((temp[len + 1] == 0) ? "." : (temp + len + 1));
}
if((offset = path.find_last_of('/')) != std::string::npos)
return ((path[offset + 1] == 0) ? "." : std::string(path, offset + 1));
// no '/' found, entire path is a filename
return _path;
return path;
} // getFileName
std::string getStem(const std::string& _path)
{
std::string fileName = getFileName(_path);
size_t offset = std::string::npos;
// empty fileName
if(fileName == ".")
return fileName;
// make a copy of the filename
char temp[512];
size_t len = snprintf(temp, sizeof(temp), "%s", fileName.c_str());
// find last '.' and remove the extension
while(len > 1)
{
if(temp[--len] == '.')
{
temp[len] = 0;
return temp;
}
}
// find last '.' and erase the extension
if((offset = fileName.find_last_of('.')) != std::string::npos)
return fileName.erase(offset);
// no '.' found, filename has no extension
return fileName;
} // 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)
{
std::string path = genericPath(_path);
struct stat info;
return (stat(_path.c_str(), &info) == 0);
// check if stat succeeded
return (stat(path.c_str(), &info) == 0);
} // 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::
} // Utils::

View file

@ -2,21 +2,39 @@
#ifndef ES_CORE_UTILS_FILE_SYSTEM_UTIL_H
#define ES_CORE_UTILS_FILE_SYSTEM_UTIL_H
#include <list>
#include <string>
namespace Utils
{
namespace FileSystem
{
bool createDirectory(const std::string& _path);
void makeGeneric (const std::string& _path);
std::string escapePath (const std::string& _path);
typedef std::list<std::string> stringList;
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 getFileName (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 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::

View file

@ -132,15 +132,26 @@ namespace Utils
} // 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");
const size_t pathEnd = _path.find_last_not_of(" \t");
std::string string;
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 _path.substr(pathBegin, pathEnd - pathBegin + 1);
return _string.substr(strBegin, strEnd - strBegin + 1);
} // trim

View file

@ -13,11 +13,12 @@ namespace Utils
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 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 endsWith (const std::string& _string, const std::string& _test);
} // Utils::String::
} // String::
} // Utils::

View file

@ -12,30 +12,30 @@ namespace Utils
mTimeStruct = { 0, 0, 0, 1, 0, 0, 0, 0, -1 };
mIsoString = "00000000T000000";
} // Time
} // DateTime::DateTime
DateTime::DateTime(const time_t& _time)
{
setTime(_time);
} // Time
} // DateTime::DateTime
DateTime::DateTime(const tm& _timeStruct)
{
setTimeStruct(_timeStruct);
} // Time
} // DateTime::DateTime
DateTime::DateTime(const std::string& _isoString)
{
setIsoString(_isoString);
} // Time
} // DateTime::DateTime
DateTime::~DateTime()
{
} // ~Time
} // DateTime::~DateTime
void DateTime::setTime(const time_t& _time)
{
@ -44,19 +44,19 @@ namespace Utils
mTimeStruct = *localtime(&mTime);
mIsoString = timeToString(mTime);
} // setTime
} // DateTime::setTime
void DateTime::setTimeStruct(const tm& _timeStruct)
{
setTime(mktime((tm*)&_timeStruct));
} // setTimeStruct
} // DateTime::setTimeStruct
void DateTime::setIsoString(const std::string& _isoString)
{
setTime(stringToTime(_isoString));
} // setIsoString
} // DateTime::setIsoString
Duration::Duration(const time_t& _time)
{
@ -66,12 +66,12 @@ namespace Utils
mMinutes = ((mTotalSeconds % (60*60)) - (mTotalSeconds % (60))) / 60;
mSeconds = mTotalSeconds % 60;
} // Duration
} // Duration::Duration
Duration::~Duration()
{
} // ~Duration
} // Duration::~Duration
time_t now()
{
@ -86,7 +86,7 @@ namespace Utils
const char* s = _string.c_str();
const char* f = _format.c_str();
tm timeStruct = { 0, 0, 0, 1, 0, 0, 0, 0, -1 };
int parsedChars = 0;
size_t parsedChars = 0;
if(_string == "not-a-date-time")
return mktime(&timeStruct);