Merge pull request #356 from tomaz82/boost_filesystem

More boost cleanup
This commit is contained in:
John Rassa 2018-01-27 05:17:38 -08:00 committed by GitHub
commit c18d699914
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 146 additions and 325 deletions

View file

@ -144,7 +144,7 @@ void CollectionSystemManager::loadCollectionSystems()
void CollectionSystemManager::loadEnabledListFromSettings() void CollectionSystemManager::loadEnabledListFromSettings()
{ {
// we parse the auto collection settings list // we parse the auto collection settings list
std::vector<std::string> autoSelected = commaStringToVector(Settings::getInstance()->getString("CollectionSystemsAuto")); std::vector<std::string> autoSelected = Utils::String::commaStringToVector(Settings::getInstance()->getString("CollectionSystemsAuto"));
// iterate the map // iterate the map
for(std::map<std::string, CollectionSystemData>::iterator it = mAutoCollectionSystemsData.begin() ; it != mAutoCollectionSystemsData.end() ; it++ ) for(std::map<std::string, CollectionSystemData>::iterator it = mAutoCollectionSystemsData.begin() ; it != mAutoCollectionSystemsData.end() ; it++ )
@ -153,7 +153,7 @@ void CollectionSystemManager::loadEnabledListFromSettings()
} }
// we parse the custom collection settings list // we parse the custom collection settings list
std::vector<std::string> customSelected = commaStringToVector(Settings::getInstance()->getString("CollectionSystemsCustom")); std::vector<std::string> customSelected = Utils::String::commaStringToVector(Settings::getInstance()->getString("CollectionSystemsCustom"));
// iterate the map // iterate the map
for(std::map<std::string, CollectionSystemData>::iterator it = mCustomCollectionSystemsData.begin() ; it != mCustomCollectionSystemsData.end() ; it++ ) for(std::map<std::string, CollectionSystemData>::iterator it = mCustomCollectionSystemsData.begin() ; it != mCustomCollectionSystemsData.end() ; it++ )
@ -509,11 +509,11 @@ bool CollectionSystemManager::toggleGameInCollection(FileData* file)
} }
if (adding) if (adding)
{ {
s = new GuiInfoPopup(mWindow, "Added '" + removeParenthesis(name) + "' to '" + strToUpper(sysName) + "'", 4000); s = new GuiInfoPopup(mWindow, "Added '" + Utils::String::removeParenthesis(name) + "' to '" + strToUpper(sysName) + "'", 4000);
} }
else else
{ {
s = new GuiInfoPopup(mWindow, "Removed '" + removeParenthesis(name) + "' from '" + strToUpper(sysName) + "'", 4000); s = new GuiInfoPopup(mWindow, "Removed '" + Utils::String::removeParenthesis(name) + "' from '" + strToUpper(sysName) + "'", 4000);
} }
mWindow->setInfoPopup(s); mWindow->setInfoPopup(s);
return true; return true;

View file

@ -45,7 +45,7 @@ std::string FileData::getDisplayName() const
std::string FileData::getCleanName() const std::string FileData::getCleanName() const
{ {
return removeParenthesis(this->getDisplayName()); return Utils::String::removeParenthesis(this->getDisplayName());
} }
const std::string FileData::getThumbnailPath() const const std::string FileData::getThumbnailPath() const
@ -255,7 +255,7 @@ void FileData::launchGame(Window* window)
std::string command = mEnvData->mLaunchCommand; std::string command = mEnvData->mLaunchCommand;
const std::string rom = escapePath(getPath()); const std::string rom = Utils::FileSystem::getEscapedPath(getPath().generic_string());
const std::string basename = getPath().stem().string(); const std::string basename = getPath().stem().string();
const std::string rom_raw = boost::filesystem::path(getPath()).make_preferred().string(); const std::string rom_raw = boost::filesystem::path(getPath()).make_preferred().string();
@ -324,8 +324,7 @@ void CollectionFileData::refreshMetadata()
const std::string& CollectionFileData::getName() const std::string& CollectionFileData::getName()
{ {
if (mDirty) { if (mDirty) {
mCollectionFileName = removeParenthesis(mSourceFileData->metadata.get("name")); mCollectionFileName = Utils::String::removeParenthesis(mSourceFileData->metadata.get("name"));
Utils::String::trim(mCollectionFileName);
mCollectionFileName += " [" + strToUpper(mSourceFileData->getSystem()->getName()) + "]"; mCollectionFileName += " [" + strToUpper(mSourceFileData->getSystem()->getName()) + "]";
mDirty = false; mDirty = false;
} }

View file

@ -94,7 +94,7 @@ std::string FileFilterIndex::getIndexableKey(FileData* game, FilterIndexType typ
case GENRE_FILTER: case GENRE_FILTER:
{ {
key = strToUpper(game->metadata.get("genre")); key = strToUpper(game->metadata.get("genre"));
Utils::String::trim(key); key = Utils::String::trim(key);
if (getSecondary && !key.empty()) { if (getSecondary && !key.empty()) {
std::istringstream f(key); std::istringstream f(key);
std::string newKey; std::string newKey;
@ -121,7 +121,7 @@ std::string FileFilterIndex::getIndexableKey(FileData* game, FilterIndexType typ
case PUBDEV_FILTER: case PUBDEV_FILTER:
{ {
key = strToUpper(game->metadata.get("publisher")); key = strToUpper(game->metadata.get("publisher"));
Utils::String::trim(key); key = Utils::String::trim(key);
if ((getSecondary && !key.empty()) || (!getSecondary && key.empty())) if ((getSecondary && !key.empty()) || (!getSecondary && key.empty()))
key = strToUpper(game->metadata.get("developer")); key = strToUpper(game->metadata.get("developer"));
@ -173,7 +173,7 @@ std::string FileFilterIndex::getIndexableKey(FileData* game, FilterIndexType typ
break; break;
} }
} }
Utils::String::trim(key); key = Utils::String::trim(key);
if (key.empty() || (type == RATINGS_FILTER && key == "0 STARS")) { if (key.empty() || (type == RATINGS_FILTER && key == "0 STARS")) {
key = UNKNOWN_LABEL; key = UNKNOWN_LABEL;
} }

View file

@ -10,21 +10,13 @@
#include <boost/filesystem/operations.hpp> #include <boost/filesystem/operations.hpp>
#include <pugixml/src/pugixml.hpp> #include <pugixml/src/pugixml.hpp>
FileData* findOrCreateFile(SystemData* system, const boost::filesystem::path& path, FileType type, bool trustGamelist) FileData* findOrCreateFile(SystemData* system, const boost::filesystem::path& path, FileType type)
{ {
// 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();
boost::filesystem::path relative;
bool contains = false; bool contains = false;
if (trustGamelist) boost::filesystem::path relative = Utils::FileSystem::removeCommonPath(path.generic_string(), root->getPath().generic_string(), contains);
{
relative = removeCommonPathUsingStrings(path, root->getPath(), contains);
}
else
{
relative = removeCommonPath(path, root->getPath(), contains);
}
if(!contains) if(!contains)
{ {
LOG(LogError) << "File path \"" << path << "\" is outside system path \"" << system->getStartPath() << "\""; LOG(LogError) << "File path \"" << path << "\" is outside system path \"" << system->getStartPath() << "\"";
@ -85,7 +77,6 @@ FileData* findOrCreateFile(SystemData* system, const boost::filesystem::path& pa
void parseGamelist(SystemData* system) void parseGamelist(SystemData* system)
{ {
bool trustGamelist = Settings::getInstance()->getBool("ParseGamelistOnly");
std::string xmlpath = system->getGamelistPath(false); std::string xmlpath = system->getGamelistPath(false);
if(!Utils::FileSystem::exists(xmlpath)) if(!Utils::FileSystem::exists(xmlpath))
@ -119,15 +110,15 @@ 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))
{ {
boost::filesystem::path path = resolvePath(fileNode.child("path").text().get(), relativeTo, false); boost::filesystem::path path = Utils::FileSystem::resolveRelativePath(fileNode.child("path").text().get(), relativeTo.generic_string(), false);
if(!trustGamelist && !Utils::FileSystem::exists(path.generic_string())) if(!Utils::FileSystem::exists(path.generic_string()))
{ {
LOG(LogWarning) << "File \"" << path << "\" does not exist! Ignoring."; LOG(LogWarning) << "File \"" << path << "\" does not exist! Ignoring.";
continue; continue;
} }
FileData* file = findOrCreateFile(system, path, type, trustGamelist); FileData* file = findOrCreateFile(system, path, type);
if(!file) if(!file)
{ {
LOG(LogError) << "Error finding/creating FileData for \"" << path << "\", skipping."; LOG(LogError) << "Error finding/creating FileData for \"" << path << "\", skipping.";
@ -166,7 +157,7 @@ void addFileDataNode(pugi::xml_node& parent, const FileData* file, const char* t
//there's something useful in there so we'll keep the node, add the path //there's something useful in there so we'll keep the node, add the path
// try and make the path relative if we can so things still work if we change the rom folder location in the future // try and make the path relative if we can so things still work if we change the rom folder location in the future
newNode.prepend_child("path").text().set(makeRelativePath(file->getPath(), system->getStartPath(), false).generic_string().c_str()); newNode.prepend_child("path").text().set(Utils::FileSystem::createRelativePath(file->getPath().generic_string(), system->getStartPath(), false).c_str());
} }
} }
@ -240,7 +231,7 @@ void updateGamelist(SystemData* system)
continue; continue;
} }
boost::filesystem::path nodePath = resolvePath(pathNode.text().get(), system->getStartPath(), true); boost::filesystem::path nodePath = Utils::FileSystem::resolveRelativePath(pathNode.text().get(), system->getStartPath(), true);
boost::filesystem::path gamePath((*fit)->getPath()); boost::filesystem::path gamePath((*fit)->getPath());
if(nodePath == gamePath || (Utils::FileSystem::exists(nodePath.generic_string()) && Utils::FileSystem::exists(gamePath.generic_string()) && boost::filesystem::equivalent(nodePath, gamePath))) if(nodePath == gamePath || (Utils::FileSystem::exists(nodePath.generic_string()) && Utils::FileSystem::exists(gamePath.generic_string()) && boost::filesystem::equivalent(nodePath, gamePath)))
{ {

View file

@ -1,5 +1,6 @@
#include "MetaData.h" #include "MetaData.h"
#include "utils/FileSystemUtil.h"
#include "Log.h" #include "Log.h"
#include "Util.h" #include "Util.h"
#include <pugixml/src/pugixml.hpp> #include <pugixml/src/pugixml.hpp>
@ -82,7 +83,7 @@ MetaDataList MetaDataList::createFromXML(MetaDataListType type, pugi::xml_node&
std::string value = md.text().get(); std::string value = md.text().get();
if (iter->type == MD_PATH) if (iter->type == MD_PATH)
{ {
value = resolvePath(value, relativeTo, true).generic_string(); value = Utils::FileSystem::resolveRelativePath(value, relativeTo.generic_string(), true);
} }
mdl.set(iter->key, value); mdl.set(iter->key, value);
}else{ }else{
@ -110,7 +111,7 @@ void MetaDataList::appendToXML(pugi::xml_node& parent, bool ignoreDefaults, cons
// try and make paths relative if we can // try and make paths relative if we can
std::string value = mapIter->second; std::string value = mapIter->second;
if (mddIter->type == MD_PATH) if (mddIter->type == MD_PATH)
value = makeRelativePath(value, relativeTo, true).generic_string(); value = Utils::FileSystem::createRelativePath(value, relativeTo.generic_string(), true);
parent.append_child(mapIter->first.c_str()).text().set(value.c_str()); parent.append_child(mapIter->first.c_str()).text().set(value.c_str());
} }

View file

@ -339,7 +339,7 @@ void SystemScreenSaver::pickGameListNode(unsigned long index, const char *nodeNa
if (index-- == 0) if (index-- == 0)
{ {
// Yes. Resolve to a full path // Yes. Resolve to a full path
path = resolvePath(node.text().get(), (*it)->getStartPath(), true).generic_string(); path = Utils::FileSystem::resolveRelativePath(node.text().get(), (*it)->getStartPath(), true);
mSystemName = (*it)->getFullName(); mSystemName = (*it)->getFullName();
mGameName = fileNode.child("name").text().get(); mGameName = fileNode.child("name").text().get();
@ -347,7 +347,7 @@ void SystemScreenSaver::pickGameListNode(unsigned long index, const char *nodeNa
// try the easy way. Should work for the majority of cases, unless in subfolders // try the easy way. Should work for the majority of cases, unless in subfolders
FileData* rootFileData = (*it)->getRootFolder(); FileData* rootFileData = (*it)->getRootFolder();
std::string gamePath = resolvePath(fileNode.child("path").text().get(), (*it)->getStartPath(), false).string(); std::string gamePath = Utils::FileSystem::resolveRelativePath(fileNode.child("path").text().get(), (*it)->getStartPath(), false);
std::string shortPath = gamePath; std::string shortPath = gamePath;
shortPath = shortPath.replace(0, (*it)->getStartPath().length()+1, ""); shortPath = shortPath.replace(0, (*it)->getStartPath().length()+1, "");

View file

@ -4,6 +4,7 @@
#include "components/SwitchComponent.h" #include "components/SwitchComponent.h"
#include "guis/GuiSettings.h" #include "guis/GuiSettings.h"
#include "guis/GuiTextEditPopup.h" #include "guis/GuiTextEditPopup.h"
#include "utils/StringUtil.h"
#include "views/ViewController.h" #include "views/ViewController.h"
#include "CollectionSystemManager.h" #include "CollectionSystemManager.h"
#include "Window.h" #include "Window.h"
@ -110,8 +111,8 @@ void GuiCollectionSystemsOptions::createCollection(std::string inName) {
std::string name = CollectionSystemManager::get()->getValidNewCollectionName(inName); std::string name = CollectionSystemManager::get()->getValidNewCollectionName(inName);
SystemData* newSys = CollectionSystemManager::get()->addNewCustomCollection(name); SystemData* newSys = CollectionSystemManager::get()->addNewCustomCollection(name);
customOptionList->add(name, name, true); customOptionList->add(name, name, true);
std::string outAuto = vectorToCommaString(autoOptionList->getSelectedObjects()); std::string outAuto = Utils::String::vectorToCommaString(autoOptionList->getSelectedObjects());
std::string outCustom = vectorToCommaString(customOptionList->getSelectedObjects()); std::string outCustom = Utils::String::vectorToCommaString(customOptionList->getSelectedObjects());
updateSettings(outAuto, outCustom); updateSettings(outAuto, outCustom);
ViewController::get()->goToSystemView(newSys); ViewController::get()->goToSystemView(newSys);
@ -161,9 +162,9 @@ void GuiCollectionSystemsOptions::addSystemsToMenu()
void GuiCollectionSystemsOptions::applySettings() void GuiCollectionSystemsOptions::applySettings()
{ {
std::string outAuto = vectorToCommaString(autoOptionList->getSelectedObjects()); std::string outAuto = Utils::String::vectorToCommaString(autoOptionList->getSelectedObjects());
std::string prevAuto = Settings::getInstance()->getString("CollectionSystemsAuto"); std::string prevAuto = Settings::getInstance()->getString("CollectionSystemsAuto");
std::string outCustom = vectorToCommaString(customOptionList->getSelectedObjects()); std::string outCustom = Utils::String::vectorToCommaString(customOptionList->getSelectedObjects());
std::string prevCustom = Settings::getInstance()->getString("CollectionSystemsCustom"); std::string prevCustom = Settings::getInstance()->getString("CollectionSystemsCustom");
bool outSort = sortAllSystemsSwitch->getState(); bool outSort = sortAllSystemsSwitch->getState();
bool prevSort = Settings::getInstance()->getBool("SortAllSystems"); bool prevSort = Settings::getInstance()->getBool("SortAllSystems");

View file

@ -1,9 +1,5 @@
#include "Util.h" #include "Util.h"
#include "utils/FileSystemUtil.h"
#include "platform.h"
#include <boost/filesystem/operations.hpp>
std::string strToUpper(const char* from) std::string strToUpper(const char* from)
{ {
std::string str(from); std::string str(from);
@ -25,141 +21,6 @@ std::string strToUpper(const std::string& str)
return strToUpper(str.c_str()); return strToUpper(str.c_str());
} }
// embedded resources, e.g. ":/font.ttf", need to be properly handled too
std::string getCanonicalPath(const std::string& path)
{
if(path.empty() || !Utils::FileSystem::exists(path))
return path;
return boost::filesystem::canonical(path).generic_string();
}
// expands "./my/path.sfc" to "[relativeTo]/my/path.sfc"
// if allowHome is true, also expands "~/my/path.sfc" to "/home/pi/my/path.sfc"
boost::filesystem::path resolvePath(const boost::filesystem::path& path, const boost::filesystem::path& relativeTo, bool allowHome)
{
// nothing here
if(path.begin() == path.end())
return path;
if(*path.begin() == ".")
{
boost::filesystem::path ret = relativeTo;
for(auto it = ++path.begin(); it != path.end(); ++it)
ret /= *it;
return ret;
}
if(allowHome && *path.begin() == "~")
{
boost::filesystem::path ret = getHomePath();
for(auto it = ++path.begin(); it != path.end(); ++it)
ret /= *it;
return ret;
}
return path;
}
boost::filesystem::path removeCommonPathUsingStrings(const boost::filesystem::path& path, const boost::filesystem::path& relativeTo, bool& contains)
{
#ifdef WIN32
std::wstring pathStr = path.c_str();
std::wstring relativeToStr = relativeTo.c_str();
#else
std::string pathStr = path.c_str();
std::string relativeToStr = relativeTo.c_str();
#endif
if (pathStr.find_first_of(relativeToStr) == 0) {
contains = true;
return pathStr.substr(relativeToStr.size() + 1);
}
else {
contains = false;
return path;
}
}
// example: removeCommonPath("/home/pi/roms/nes/foo/bar.nes", "/home/pi/roms/nes/") returns "foo/bar.nes"
boost::filesystem::path removeCommonPath(const boost::filesystem::path& path, const boost::filesystem::path& relativeTo, bool& contains)
{
// if either of these doesn't exist, boost::filesystem::canonical() is going to throw an error
if(!Utils::FileSystem::exists(path.generic_string()) || !Utils::FileSystem::exists(relativeTo.generic_string()))
{
contains = false;
return 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
boost::filesystem::path p = (Utils::FileSystem::isSymlink(path.generic_string()) ? 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())
{
contains = false;
return p;
}
boost::filesystem::path result;
// find point of divergence
auto itr_path = p.begin();
auto itr_relative_to = r.begin();
while(*itr_path == *itr_relative_to && itr_path != p.end() && itr_relative_to != r.end())
{
++itr_path;
++itr_relative_to;
}
if(itr_relative_to != r.end())
{
contains = false;
return p;
}
while(itr_path != p.end())
{
if(*itr_path != boost::filesystem::path("."))
result = result / *itr_path;
++itr_path;
}
contains = true;
return result;
}
// 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"
boost::filesystem::path makeRelativePath(const boost::filesystem::path& path, const boost::filesystem::path& relativeTo, bool allowHome)
{
bool contains = false;
boost::filesystem::path ret = removeCommonPath(path, relativeTo, contains);
if(contains)
{
// success
ret = "." / ret;
return ret;
}
if(allowHome)
{
contains = false;
std::string homePath = getHomePath();
ret = removeCommonPath(path, homePath, contains);
if(contains)
{
// success
ret = "~" / ret;
return ret;
}
}
// nothing could be resolved
return path;
}
std::string strreplace(std::string str, const std::string& replace, const std::string& with) std::string strreplace(std::string str, const std::string& replace, const std::string& with)
{ {
size_t pos; size_t pos;
@ -168,108 +29,3 @@ std::string strreplace(std::string str, const std::string& replace, const std::s
return str; return str;
} }
// plaform-specific escape path function
// on windows: just puts the path in quotes
// everything else: assume bash and escape special characters with backslashes
std::string escapePath(const boost::filesystem::path& path)
{
#ifdef WIN32
// windows escapes stuff by just putting everything in quotes
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();
const char* invalidChars = " '\"\\!$^&*(){}[]?;<>";
for(unsigned int i = 0; i < pathStr.length(); i++)
{
char c;
unsigned int charNum = 0;
do {
c = invalidChars[charNum];
if(pathStr[i] == c)
{
pathStr.insert(i, "\\");
i++;
break;
}
charNum++;
} while(c != '\0');
}
return pathStr;
#endif
}
std::string removeParenthesis(const std::string& str)
{
// remove anything in parenthesis or brackets
// should be roughly equivalent to the regex replace "\((.*)\)|\[(.*)\]" with ""
// I would love to just use regex, but it's not worth pulling in another boost lib for one function that is used once
std::string ret = str;
size_t start, end;
static const int NUM_TO_REPLACE = 2;
static const char toReplace[NUM_TO_REPLACE*2] = { '(', ')', '[', ']' };
bool done = false;
while(!done)
{
done = true;
for(int i = 0; i < NUM_TO_REPLACE; i++)
{
end = ret.find_first_of(toReplace[i*2+1]);
start = ret.find_last_of(toReplace[i*2], end);
if(start != std::string::npos && end != std::string::npos)
{
ret.erase(start, end - start + 1);
done = false;
}
}
}
// also strip whitespace
end = ret.find_last_not_of(' ');
if(end != std::string::npos)
end++;
ret = ret.substr(0, end);
return ret;
}
std::vector<std::string> commaStringToVector(std::string commaString)
{
// from a comma separated string, get a vector of strings
std::vector<std::string> strs;
size_t start = 0;
size_t comma = commaString.find(",");
strs.push_back(commaString.substr(start, comma));
if(comma != std::string::npos)
{
start = comma + 1;
while((comma = commaString.find(",", start)) != std::string::npos)
{
strs.push_back(commaString.substr(start, comma - start));
start = comma + 1;
}
strs.push_back(commaString.substr(start));
std::sort(strs.begin(), strs.end());
}
return strs;
}
std::string vectorToCommaString(std::vector<std::string> stringVector)
{
std::string out = "";
std::sort(stringVector.begin(), stringVector.end());
// from a vector of system names get comma separated string
for(std::vector<std::string>::const_iterator it = stringVector.cbegin() ; it != stringVector.cend() ; it++ )
{
out = out + (out == "" ? "" : ",") + (*it);
}
return out;
}

View file

@ -2,37 +2,12 @@
#ifndef ES_CORE_UTIL_H #ifndef ES_CORE_UTIL_H
#define ES_CORE_UTIL_H #define ES_CORE_UTIL_H
#include <boost/filesystem/path.hpp> #include <string>
std::string strToUpper(const char* from); std::string strToUpper(const char* from);
std::string& strToUpper(std::string& str); std::string& strToUpper(std::string& str);
std::string strToUpper(const std::string& str); std::string strToUpper(const std::string& str);
std::string getCanonicalPath(const std::string& str);
boost::filesystem::path removeCommonPathUsingStrings(const boost::filesystem::path& path, const boost::filesystem::path& relativeTo, bool& contains);
// example: removeCommonPath("/home/pi/roms/nes/foo/bar.nes", "/home/pi/roms/nes/") returns "foo/bar.nes"
boost::filesystem::path removeCommonPath(const boost::filesystem::path& path, const boost::filesystem::path& relativeTo, bool& contains);
// 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"
boost::filesystem::path makeRelativePath(const boost::filesystem::path& path, const boost::filesystem::path& relativeTo, bool allowHome);
// expands "./my/path.sfc" to "[relativeTo]/my/path.sfc"
// if allowHome is true, also expands "~/my/path.sfc" to "/home/pi/my/path.sfc"
boost::filesystem::path resolvePath(const boost::filesystem::path& path, const boost::filesystem::path& relativeTo, bool allowHome);
std::string escapePath(const boost::filesystem::path& path);
std::string strreplace(std::string str, const std::string& replace, const std::string& with); std::string strreplace(std::string str, const std::string& replace, const std::string& with);
// Remove (.*) and [.*] from str
std::string removeParenthesis(const std::string& str);
// split a comma-separated string into a vector
std::vector<std::string> commaStringToVector(std::string commaString);
// turn a vector of strings into a comma-separated string
std::string vectorToCommaString(std::vector<std::string> stringVector);
#endif // ES_CORE_UTIL_H #endif // ES_CORE_UTIL_H

View file

@ -102,7 +102,7 @@ void VideoComponent::onSizeChanged()
bool VideoComponent::setVideo(std::string path) bool VideoComponent::setVideo(std::string path)
{ {
// Convert the path into a generic format // Convert the path into a generic format
boost::filesystem::path fullPath = getCanonicalPath(path); boost::filesystem::path fullPath = Utils::FileSystem::getCanonicalPath(path);
fullPath.make_preferred().native(); fullPath.make_preferred().native();
// Check that it's changed // Check that it's changed

View file

@ -1,5 +1,6 @@
#include "resources/Font.h" #include "resources/Font.h"
#include "utils/FileSystemUtil.h"
#include "utils/StringUtil.h" #include "utils/StringUtil.h"
#include "Log.h" #include "Log.h"
#include "Renderer.h" #include "Renderer.h"
@ -101,7 +102,7 @@ void Font::unload(std::shared_ptr<ResourceManager>& /*rm*/)
std::shared_ptr<Font> Font::get(int size, const std::string& path) std::shared_ptr<Font> Font::get(int size, const std::string& path)
{ {
const std::string canonicalPath = getCanonicalPath(path); const std::string canonicalPath = Utils::FileSystem::getCanonicalPath(path);
std::pair<std::string, int> def(canonicalPath.empty() ? getDefaultPath() : canonicalPath, size); std::pair<std::string, int> def(canonicalPath.empty() ? getDefaultPath() : canonicalPath, size);
auto foundFont = sFontMap.find(def); auto foundFont = sFontMap.find(def);

View file

@ -1,5 +1,6 @@
#include "resources/TextureResource.h" #include "resources/TextureResource.h"
#include "utils/FileSystemUtil.h"
#include "resources/TextureData.h" #include "resources/TextureData.h"
#include "Util.h" #include "Util.h"
@ -104,7 +105,7 @@ std::shared_ptr<TextureResource> TextureResource::get(const std::string& path, b
{ {
std::shared_ptr<ResourceManager>& rm = ResourceManager::getInstance(); std::shared_ptr<ResourceManager>& rm = ResourceManager::getInstance();
const std::string canonicalPath = getCanonicalPath(path); const std::string canonicalPath = Utils::FileSystem::getCanonicalPath(path);
if(canonicalPath.empty()) if(canonicalPath.empty())
{ {
std::shared_ptr<TextureResource> tex(new TextureResource("", tile, false)); std::shared_ptr<TextureResource> tex(new TextureResource("", tile, false));

View file

@ -152,12 +152,21 @@ namespace Utils
// insert a backslash before most characters that would mess up a bash path // insert a backslash before most characters that would mess up a bash path
const char* invalidChars = "\\ '\"!$^&*(){}[]?;<>"; const char* invalidChars = "\\ '\"!$^&*(){}[]?;<>";
const char* invalidChar = invalidChars; const char* invalidChar = invalidChars;
size_t offset = std::string::npos; size_t start = 0;
size_t offset = 0;
while(*invalidChar) while(*invalidChar)
{ {
while((offset = path.find(*invalidChar)) != std::string::npos) while((offset = path.find(*invalidChar, start)) != std::string::npos)
path.insert(offset, 1, '\\'); {
start = offset + 1;
if((offset == 0) || (path[offset - 1] != '\\'))
{
path.insert(offset, 1, '\\');
++start;
}
}
++invalidChar; ++invalidChar;
} }
@ -170,6 +179,10 @@ namespace Utils
std::string getCanonicalPath(const std::string& _path) std::string getCanonicalPath(const std::string& _path)
{ {
// temporary hack for builtin resources
if((_path[0] == ':') && (_path[1] == '/'))
return _path;
std::string path = exists(_path) ? getAbsolutePath(_path) : getGenericPath(_path); std::string path = exists(_path) ? getAbsolutePath(_path) : getGenericPath(_path);
// cleanup path // cleanup path

View file

@ -1,5 +1,7 @@
#include "utils/StringUtil.h" #include "utils/StringUtil.h"
#include <algorithm>
namespace Utils namespace Utils
{ {
namespace String namespace String
@ -155,18 +157,92 @@ namespace Utils
} // trim } // trim
bool startsWith(const std::string& _string, const std::string& _test) std::string replace(const std::string& _string, const std::string& _replace, const std::string& _with)
{ {
return (_string.find(_test) == 0); std::string string = _string;
size_t pos;
while((pos = string.find(_replace)) != std::string::npos)
string = string.replace(pos, _replace.length(), _with.c_str(), _with.length());
return string;
} // replace
bool startsWith(const std::string& _string, const std::string& _start)
{
return (_string.find(_start) == 0);
} // startsWith } // startsWith
bool endsWith(const std::string& _string, const std::string& _test) bool endsWith(const std::string& _string, const std::string& _end)
{ {
return (_string.find(_test) == (_string.size() - _test.size())); return (_string.find(_end) == (_string.size() - _end.size()));
} // endsWith } // endsWith
std::string removeParenthesis(const std::string& _string)
{
static const char remove[4] = { '(', ')', '[', ']' };
std::string string = _string;
size_t start;
size_t end;
bool done = false;
while(!done)
{
done = true;
for(int i = 0; i < sizeof(remove); i += 2)
{
end = string.find_first_of(remove[i + 1]);
start = string.find_last_of( remove[i + 0], end);
if((start != std::string::npos) && (end != std::string::npos))
{
string.erase(start, end - start + 1);
done = false;
}
}
}
return trim(string);
} // removeParenthesis
stringVector commaStringToVector(const std::string& _string)
{
stringVector vector;
size_t start = 0;
size_t comma = _string.find(",");
while(comma != std::string::npos)
{
vector.push_back(_string.substr(start, comma - start));
start = comma + 1;
comma = _string.find(",", start);
}
vector.push_back(_string.substr(start));
std::sort(vector.begin(), vector.end());
return vector;
} // commaStringToVector
std::string vectorToCommaString(stringVector _vector)
{
std::string string;
std::sort(_vector.begin(), _vector.end());
for(stringVector::const_iterator it = _vector.cbegin(); it != _vector.cend(); ++it)
string += (string.length() ? "," : "") + (*it);
return string;
} // vectorToCommaString
} // String:: } // String::
} // Utils:: } // Utils::

View file

@ -3,20 +3,27 @@
#define ES_CORE_UTILS_STRING_UTIL_H #define ES_CORE_UTILS_STRING_UTIL_H
#include <string> #include <string>
#include <vector>
namespace Utils namespace Utils
{ {
namespace String namespace String
{ {
unsigned int chars2Unicode(const std::string& _string, size_t& _cursor); typedef std::vector<std::string> stringVector;
std::string unicode2Chars(const unsigned int _unicode);
size_t nextCursor (const std::string& _string, const size_t _cursor); unsigned int chars2Unicode (const std::string& _string, size_t& _cursor);
size_t prevCursor (const std::string& _string, const size_t _cursor); std::string unicode2Chars (const unsigned int _unicode);
size_t moveCursor (const std::string& _string, const size_t _cursor, const int _amount); size_t nextCursor (const std::string& _string, const size_t _cursor);
std::string toUpper (const std::string& _string); size_t prevCursor (const std::string& _string, const size_t _cursor);
std::string trim (const std::string& _string); size_t moveCursor (const std::string& _string, const size_t _cursor, const int _amount);
bool startsWith (const std::string& _string, const std::string& _test); std::string toUpper (const std::string& _string);
bool endsWith (const std::string& _string, const std::string& _test); std::string trim (const std::string& _string);
std::string replace (const std::string& _string, const std::string& _replace, const std::string& _with);
bool startsWith (const std::string& _string, const std::string& _start);
bool endsWith (const std::string& _string, const std::string& _end);
std::string removeParenthesis (const std::string& _string);
stringVector commaStringToVector(const std::string& _string);
std::string vectorToCommaString(stringVector _vector);
} // String:: } // String::