diff --git a/es-app/src/CollectionSystemManager.cpp b/es-app/src/CollectionSystemManager.cpp index 4b439546b..0b79e6b88 100644 --- a/es-app/src/CollectionSystemManager.cpp +++ b/es-app/src/CollectionSystemManager.cpp @@ -144,7 +144,7 @@ void CollectionSystemManager::loadCollectionSystems() void CollectionSystemManager::loadEnabledListFromSettings() { // we parse the auto collection settings list - std::vector autoSelected = commaStringToVector(Settings::getInstance()->getString("CollectionSystemsAuto")); + std::vector autoSelected = Utils::String::commaStringToVector(Settings::getInstance()->getString("CollectionSystemsAuto")); // iterate the map for(std::map::iterator it = mAutoCollectionSystemsData.begin() ; it != mAutoCollectionSystemsData.end() ; it++ ) @@ -153,7 +153,7 @@ void CollectionSystemManager::loadEnabledListFromSettings() } // we parse the custom collection settings list - std::vector customSelected = commaStringToVector(Settings::getInstance()->getString("CollectionSystemsCustom")); + std::vector customSelected = Utils::String::commaStringToVector(Settings::getInstance()->getString("CollectionSystemsCustom")); // iterate the map for(std::map::iterator it = mCustomCollectionSystemsData.begin() ; it != mCustomCollectionSystemsData.end() ; it++ ) @@ -509,11 +509,11 @@ bool CollectionSystemManager::toggleGameInCollection(FileData* file) } 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 { - 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); return true; diff --git a/es-app/src/FileData.cpp b/es-app/src/FileData.cpp index 4e2177df2..399df7e81 100644 --- a/es-app/src/FileData.cpp +++ b/es-app/src/FileData.cpp @@ -45,7 +45,7 @@ std::string FileData::getDisplayName() const std::string FileData::getCleanName() const { - return removeParenthesis(this->getDisplayName()); + return Utils::String::removeParenthesis(this->getDisplayName()); } const std::string FileData::getThumbnailPath() const @@ -255,7 +255,7 @@ void FileData::launchGame(Window* window) 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 rom_raw = boost::filesystem::path(getPath()).make_preferred().string(); @@ -324,8 +324,7 @@ void CollectionFileData::refreshMetadata() const std::string& CollectionFileData::getName() { if (mDirty) { - mCollectionFileName = removeParenthesis(mSourceFileData->metadata.get("name")); - Utils::String::trim(mCollectionFileName); + mCollectionFileName = Utils::String::removeParenthesis(mSourceFileData->metadata.get("name")); mCollectionFileName += " [" + strToUpper(mSourceFileData->getSystem()->getName()) + "]"; mDirty = false; } diff --git a/es-app/src/FileFilterIndex.cpp b/es-app/src/FileFilterIndex.cpp index 1be1ca3f1..f10c1c659 100644 --- a/es-app/src/FileFilterIndex.cpp +++ b/es-app/src/FileFilterIndex.cpp @@ -94,7 +94,7 @@ std::string FileFilterIndex::getIndexableKey(FileData* game, FilterIndexType typ case GENRE_FILTER: { key = strToUpper(game->metadata.get("genre")); - Utils::String::trim(key); + key = Utils::String::trim(key); if (getSecondary && !key.empty()) { std::istringstream f(key); std::string newKey; @@ -121,7 +121,7 @@ std::string FileFilterIndex::getIndexableKey(FileData* game, FilterIndexType typ case PUBDEV_FILTER: { key = strToUpper(game->metadata.get("publisher")); - Utils::String::trim(key); + key = Utils::String::trim(key); if ((getSecondary && !key.empty()) || (!getSecondary && key.empty())) key = strToUpper(game->metadata.get("developer")); @@ -173,7 +173,7 @@ std::string FileFilterIndex::getIndexableKey(FileData* game, FilterIndexType typ break; } } - Utils::String::trim(key); + key = Utils::String::trim(key); if (key.empty() || (type == RATINGS_FILTER && key == "0 STARS")) { key = UNKNOWN_LABEL; } diff --git a/es-app/src/Gamelist.cpp b/es-app/src/Gamelist.cpp index 2a3e92661..9a4bb7b08 100644 --- a/es-app/src/Gamelist.cpp +++ b/es-app/src/Gamelist.cpp @@ -10,21 +10,13 @@ #include #include -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 FileData* root = system->getRootFolder(); - - boost::filesystem::path relative; bool contains = false; - if (trustGamelist) - { - relative = removeCommonPathUsingStrings(path, root->getPath(), contains); - } - else - { - relative = removeCommonPath(path, root->getPath(), contains); - } + boost::filesystem::path relative = Utils::FileSystem::removeCommonPath(path.generic_string(), root->getPath().generic_string(), contains); + if(!contains) { 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) { - bool trustGamelist = Settings::getInstance()->getBool("ParseGamelistOnly"); std::string xmlpath = system->getGamelistPath(false); if(!Utils::FileSystem::exists(xmlpath)) @@ -119,15 +110,15 @@ void parseGamelist(SystemData* system) FileType type = typeList[i]; 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."; continue; } - FileData* file = findOrCreateFile(system, path, type, trustGamelist); + FileData* file = findOrCreateFile(system, path, type); if(!file) { 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 // 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; } - 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()); if(nodePath == gamePath || (Utils::FileSystem::exists(nodePath.generic_string()) && Utils::FileSystem::exists(gamePath.generic_string()) && boost::filesystem::equivalent(nodePath, gamePath))) { diff --git a/es-app/src/MetaData.cpp b/es-app/src/MetaData.cpp index cf93013bd..5b9aceac1 100644 --- a/es-app/src/MetaData.cpp +++ b/es-app/src/MetaData.cpp @@ -1,5 +1,6 @@ #include "MetaData.h" +#include "utils/FileSystemUtil.h" #include "Log.h" #include "Util.h" #include @@ -82,7 +83,7 @@ MetaDataList MetaDataList::createFromXML(MetaDataListType type, pugi::xml_node& std::string value = md.text().get(); 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); }else{ @@ -110,7 +111,7 @@ void MetaDataList::appendToXML(pugi::xml_node& parent, bool ignoreDefaults, cons // try and make paths relative if we can std::string value = mapIter->second; 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()); } diff --git a/es-app/src/SystemScreenSaver.cpp b/es-app/src/SystemScreenSaver.cpp index c82b7a445..929decf7c 100644 --- a/es-app/src/SystemScreenSaver.cpp +++ b/es-app/src/SystemScreenSaver.cpp @@ -339,7 +339,7 @@ void SystemScreenSaver::pickGameListNode(unsigned long index, const char *nodeNa if (index-- == 0) { // 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(); 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 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; shortPath = shortPath.replace(0, (*it)->getStartPath().length()+1, ""); diff --git a/es-app/src/guis/GuiCollectionSystemsOptions.cpp b/es-app/src/guis/GuiCollectionSystemsOptions.cpp index 410578f63..fcb0c4c26 100644 --- a/es-app/src/guis/GuiCollectionSystemsOptions.cpp +++ b/es-app/src/guis/GuiCollectionSystemsOptions.cpp @@ -4,6 +4,7 @@ #include "components/SwitchComponent.h" #include "guis/GuiSettings.h" #include "guis/GuiTextEditPopup.h" +#include "utils/StringUtil.h" #include "views/ViewController.h" #include "CollectionSystemManager.h" #include "Window.h" @@ -110,8 +111,8 @@ void GuiCollectionSystemsOptions::createCollection(std::string inName) { std::string name = CollectionSystemManager::get()->getValidNewCollectionName(inName); SystemData* newSys = CollectionSystemManager::get()->addNewCustomCollection(name); customOptionList->add(name, name, true); - std::string outAuto = vectorToCommaString(autoOptionList->getSelectedObjects()); - std::string outCustom = vectorToCommaString(customOptionList->getSelectedObjects()); + std::string outAuto = Utils::String::vectorToCommaString(autoOptionList->getSelectedObjects()); + std::string outCustom = Utils::String::vectorToCommaString(customOptionList->getSelectedObjects()); updateSettings(outAuto, outCustom); ViewController::get()->goToSystemView(newSys); @@ -161,9 +162,9 @@ void GuiCollectionSystemsOptions::addSystemsToMenu() 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 outCustom = vectorToCommaString(customOptionList->getSelectedObjects()); + std::string outCustom = Utils::String::vectorToCommaString(customOptionList->getSelectedObjects()); std::string prevCustom = Settings::getInstance()->getString("CollectionSystemsCustom"); bool outSort = sortAllSystemsSwitch->getState(); bool prevSort = Settings::getInstance()->getBool("SortAllSystems"); diff --git a/es-core/src/Util.cpp b/es-core/src/Util.cpp index 04cc6f170..246af37f0 100644 --- a/es-core/src/Util.cpp +++ b/es-core/src/Util.cpp @@ -1,9 +1,5 @@ #include "Util.h" -#include "utils/FileSystemUtil.h" -#include "platform.h" -#include - std::string strToUpper(const char* from) { std::string str(from); @@ -25,141 +21,6 @@ std::string strToUpper(const std::string& 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) { size_t pos; @@ -168,108 +29,3 @@ std::string strreplace(std::string str, const std::string& replace, const std::s 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 commaStringToVector(std::string commaString) -{ - // from a comma separated string, get a vector of strings - std::vector 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 stringVector) -{ - std::string out = ""; - std::sort(stringVector.begin(), stringVector.end()); - // from a vector of system names get comma separated string - for(std::vector::const_iterator it = stringVector.cbegin() ; it != stringVector.cend() ; it++ ) - { - out = out + (out == "" ? "" : ",") + (*it); - } - return out; -} \ No newline at end of file diff --git a/es-core/src/Util.h b/es-core/src/Util.h index 526cee99b..19e84d98e 100644 --- a/es-core/src/Util.h +++ b/es-core/src/Util.h @@ -2,37 +2,12 @@ #ifndef ES_CORE_UTIL_H #define ES_CORE_UTIL_H -#include +#include std::string strToUpper(const char* from); std::string& strToUpper(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); -// Remove (.*) and [.*] from str -std::string removeParenthesis(const std::string& str); - -// split a comma-separated string into a vector -std::vector commaStringToVector(std::string commaString); - -// turn a vector of strings into a comma-separated string -std::string vectorToCommaString(std::vector stringVector); - #endif // ES_CORE_UTIL_H diff --git a/es-core/src/components/VideoComponent.cpp b/es-core/src/components/VideoComponent.cpp index cbbc535a6..0968fcc6a 100644 --- a/es-core/src/components/VideoComponent.cpp +++ b/es-core/src/components/VideoComponent.cpp @@ -102,7 +102,7 @@ void VideoComponent::onSizeChanged() bool VideoComponent::setVideo(std::string path) { // 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(); // Check that it's changed diff --git a/es-core/src/resources/Font.cpp b/es-core/src/resources/Font.cpp index 918e7e388..dfded5c8e 100644 --- a/es-core/src/resources/Font.cpp +++ b/es-core/src/resources/Font.cpp @@ -1,5 +1,6 @@ #include "resources/Font.h" +#include "utils/FileSystemUtil.h" #include "utils/StringUtil.h" #include "Log.h" #include "Renderer.h" @@ -101,7 +102,7 @@ void Font::unload(std::shared_ptr& /*rm*/) std::shared_ptr Font::get(int size, const std::string& path) { - const std::string canonicalPath = getCanonicalPath(path); + const std::string canonicalPath = Utils::FileSystem::getCanonicalPath(path); std::pair def(canonicalPath.empty() ? getDefaultPath() : canonicalPath, size); auto foundFont = sFontMap.find(def); diff --git a/es-core/src/resources/TextureResource.cpp b/es-core/src/resources/TextureResource.cpp index 7768111fc..76fa1239a 100644 --- a/es-core/src/resources/TextureResource.cpp +++ b/es-core/src/resources/TextureResource.cpp @@ -1,5 +1,6 @@ #include "resources/TextureResource.h" +#include "utils/FileSystemUtil.h" #include "resources/TextureData.h" #include "Util.h" @@ -104,7 +105,7 @@ std::shared_ptr TextureResource::get(const std::string& path, b { std::shared_ptr& rm = ResourceManager::getInstance(); - const std::string canonicalPath = getCanonicalPath(path); + const std::string canonicalPath = Utils::FileSystem::getCanonicalPath(path); if(canonicalPath.empty()) { std::shared_ptr tex(new TextureResource("", tile, false)); diff --git a/es-core/src/utils/FileSystemUtil.cpp b/es-core/src/utils/FileSystemUtil.cpp index 04c9a821b..b19fbf699 100644 --- a/es-core/src/utils/FileSystemUtil.cpp +++ b/es-core/src/utils/FileSystemUtil.cpp @@ -152,12 +152,21 @@ namespace Utils // insert a backslash before most characters that would mess up a bash path const char* invalidChars = "\\ '\"!$^&*(){}[]?;<>"; const char* invalidChar = invalidChars; - size_t offset = std::string::npos; + size_t start = 0; + size_t offset = 0; while(*invalidChar) { - while((offset = path.find(*invalidChar)) != std::string::npos) - path.insert(offset, 1, '\\'); + while((offset = path.find(*invalidChar, start)) != std::string::npos) + { + start = offset + 1; + + if((offset == 0) || (path[offset - 1] != '\\')) + { + path.insert(offset, 1, '\\'); + ++start; + } + } ++invalidChar; } @@ -170,6 +179,10 @@ namespace Utils 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); // cleanup path diff --git a/es-core/src/utils/StringUtil.cpp b/es-core/src/utils/StringUtil.cpp index 26a7c7c0b..54e2b18f2 100644 --- a/es-core/src/utils/StringUtil.cpp +++ b/es-core/src/utils/StringUtil.cpp @@ -1,5 +1,7 @@ #include "utils/StringUtil.h" +#include + namespace Utils { namespace String @@ -155,18 +157,92 @@ namespace Utils } // 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 - 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 + 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:: } // Utils:: diff --git a/es-core/src/utils/StringUtil.h b/es-core/src/utils/StringUtil.h index fcbd84e79..47fb7d1fe 100644 --- a/es-core/src/utils/StringUtil.h +++ b/es-core/src/utils/StringUtil.h @@ -3,20 +3,27 @@ #define ES_CORE_UTILS_STRING_UTIL_H #include +#include namespace Utils { namespace String { - unsigned int chars2Unicode(const std::string& _string, size_t& _cursor); - std::string unicode2Chars(const unsigned int _unicode); - 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 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); + typedef std::vector stringVector; + + unsigned int chars2Unicode (const std::string& _string, size_t& _cursor); + std::string unicode2Chars (const unsigned int _unicode); + 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 toUpper (const std::string& _string); + std::string trim (const std::string& _string); + std::string replace (const std::string& _string, const std::string& _replace, const std::string& _with); + 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::