/* * The Mana Client * Copyright (C) 2007-2009 The Mana World Development Team * Copyright (C) 2009-2012 The Mana Developers * * This file is part of The Mana Client. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "utils/stringutils.h" #include #include #include #include std::string &trim(std::string &str) { std::string::size_type pos = str.find_last_not_of(' '); if (pos != std::string::npos) { str.erase(pos + 1); pos = str.find_first_not_of(' '); if (pos != std::string::npos) str.erase(0, pos); } else { // There is nothing else but whitespace in the string str.clear(); } return str; } std::string &toLower(std::string &str) { std::transform(str.begin(), str.end(), str.begin(), tolower); return str; } std::string &toUpper(std::string &str) { std::transform(str.begin(), str.end(), str.begin(), toupper); return str; } unsigned int atox(const std::string &str) { unsigned int value; sscanf(str.c_str(), "0x%06x", &value); return value; } const char *ipToString(int address) { static char asciiIP[16]; snprintf(asciiIP, 16, "%i.%i.%i.%i", (unsigned char)(address), (unsigned char)(address >> 8), (unsigned char)(address >> 16), (unsigned char)(address >> 24)); return asciiIP; } std::string strprintf(char const *format, ...) { char buf[256]; va_list args; va_start(args, format); int nb = vsnprintf(buf, 256, format, args); va_end(args); if (nb < 256) { return buf; } // The static size was not big enough, try again with a dynamic allocation. ++nb; // Add 1 for the null terminator. std::string res(nb, char()); va_start(args, format); vsnprintf(res.data(), nb, format, args); va_end(args); return res; } std::string &replaceCharacters(std::string &str, std::string_view chars, char replacement) { for (auto &c : str) { if (chars.find(c) != std::string::npos) c = replacement; } return str; } std::string &removeColors(std::string &msg) { auto pos = msg.find("##"); while (pos != std::string::npos && msg.length() - pos >= 3) { msg.erase(pos, 3); pos = msg.find("##", pos); } return msg; } bool isWordSeparator(char chr) { return (chr == ' ' || chr == ',' || chr == '.' || chr == '"'); } std::string findSameSubstring(const std::string &str1, const std::string &str2) { int minLength = str1.length() > str2.length() ? str2.length() : str1.length(); for (int f = 0; f < minLength; f ++) { if (str1.at(f) != str2.at(f)) { return str1.substr(0, f); } } return str1.substr(0, minLength); } bool getBoolFromString(std::string text, bool def) { toLower(trim(text)); if (text == "true" || text == "1" || text == "on" || text == "yes" || text == "y") return true; if (text == "false" || text == "0" || text == "off" || text == "no" || text == "n") return false; return def; } std::string autocomplete(const std::vector &candidates, std::string base) { auto i = candidates.begin(); toLower(base); std::string newName; while (i != candidates.end()) { if (!i->empty()) { std::string name = *i; toLower(name); std::string::size_type pos = name.find(base, 0); if (pos == 0) { if (!newName.empty()) { toLower(newName); newName = findSameSubstring(name, newName); } else { newName = *i; } } } ++i; } return newName; } std::string normalize(const std::string &name) { std::string normalized = name; return toLower(trim(normalized)); } std::string getDirectoryFromURL(const std::string &url) { std::string directory = url; // Parse out any "http://", "ftp://", etc... size_t pos = directory.find("://"); if (pos != std::string::npos) directory.erase(0, pos + 3); // Replace characters which are not valid or difficult in file system paths replaceCharacters(directory, ":*?\"<>| ", '_'); // Replace ".." (double dots) with "_" to avoid directory traversal. pos = directory.find(".."); while (pos != std::string::npos) { directory.replace(pos, 2, "_"); pos = directory.find(".."); } return directory; } std::string join(const std::vector &strings, const char *separator) { std::string result; if (auto i = strings.begin(), e = strings.end(); i != e) { result += *i++; for (; i != e; ++i) result.append(separator).append(*i); } return result; }