| /* |
| Copyright 2019 Alain Dargelas |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| /* |
| * File: StringUtils.cpp |
| * Author: alain |
| * |
| * Created on March 14, 2017, 10:43 PM |
| */ |
| |
| #include "StringUtils.h" |
| #include <algorithm> |
| #include <locale> |
| #include <sstream> |
| |
| using namespace SURELOG; |
| |
| StringUtils::StringUtils() {} |
| |
| StringUtils::StringUtils(const StringUtils& orig) {} |
| |
| StringUtils::~StringUtils() {} |
| |
| std::string StringUtils::to_string(double a_value, const int n) { |
| std::ostringstream out; |
| out.precision(n); |
| out << std::fixed << a_value; |
| return out.str(); |
| } |
| |
| void StringUtils::tokenizeMulti(std::string str, std::string separator, |
| std::vector<std::string>& args) { |
| std::string tmp; |
| unsigned int sepSize = separator.size(); |
| unsigned int stringSize = str.size(); |
| for (unsigned int i = 0; i < stringSize; i++) { |
| bool isSeparator = true; |
| for (unsigned int j = 0; j < sepSize; j++) { |
| if (i + j >= stringSize) break; |
| if (str[i + j] != separator[j]) { |
| isSeparator = false; |
| break; |
| } |
| } |
| if (isSeparator) { |
| i = i + sepSize - 1; |
| args.push_back(tmp); |
| tmp = ""; |
| if (i == (str.size() - 1)) args.push_back(tmp); |
| } else if (i == (str.size() - 1)) { |
| tmp += str[i]; |
| args.push_back(tmp); |
| tmp = ""; |
| } else { |
| tmp += str[i]; |
| } |
| } |
| } |
| |
| void StringUtils::tokenize(std::string str, std::string separator, |
| std::vector<std::string>& args) { |
| std::string tmp; |
| unsigned int sepSize = separator.size(); |
| unsigned int stringSize = str.size(); |
| for (unsigned int i = 0; i < stringSize; i++) { |
| bool isSeparator = false; |
| for (unsigned int j = 0; j < sepSize; j++) { |
| if (str[i] == separator[j]) { |
| isSeparator = true; |
| break; |
| } |
| } |
| if (isSeparator) { |
| args.push_back(tmp); |
| tmp = ""; |
| if (i == (str.size() - 1)) args.push_back(tmp); |
| } else if (i == (str.size() - 1)) { |
| tmp += str[i]; |
| args.push_back(tmp); |
| tmp = ""; |
| } else { |
| tmp += str[i]; |
| } |
| } |
| } |
| |
| void StringUtils::tokenizeBalanced(std::string str, std::string separator, |
| std::vector<std::string>& args) { |
| std::string tmp; |
| unsigned int sepSize = separator.size(); |
| unsigned int stringSize = str.size(); |
| int level = 0; |
| bool inDoubleQuote = false; |
| for (unsigned int i = 0; i < stringSize; i++) { |
| if (str[i] == '"') { |
| if (inDoubleQuote == false) { |
| level++; |
| inDoubleQuote = true; |
| } else { |
| level--; |
| inDoubleQuote = false; |
| } |
| } |
| if (str[i] == '(' || str[i] == '[' || str[i] == '{') { |
| level++; |
| } |
| if (str[i] == ')' || str[i] == ']' || str[i] == '}') { |
| level--; |
| } |
| bool isSeparator = false; |
| for (unsigned int j = 0; j < sepSize; j++) { |
| if (str[i] == separator[j]) { |
| if (level == 0) isSeparator = true; |
| break; |
| } |
| } |
| if (isSeparator) { |
| args.push_back(tmp); |
| tmp = ""; |
| if (i == (str.size() - 1)) args.push_back(tmp); |
| } else if (i == (str.size() - 1)) { |
| tmp += str[i]; |
| args.push_back(tmp); |
| tmp = ""; |
| } else { |
| tmp += str[i]; |
| } |
| } |
| } |
| |
| void StringUtils::replaceInTokenVector(std::vector<std::string>& tokens, |
| std::vector<std::string> pattern, |
| std::string news) { |
| unsigned int patternIndex = 0; |
| std::vector<std::string>::iterator itr; |
| bool more = true; |
| while (more) { |
| more = false; |
| for (itr = tokens.begin(); itr != tokens.end(); itr++) { |
| if (*itr == pattern[patternIndex]) { |
| patternIndex++; |
| if (patternIndex == pattern.size()) { |
| *itr = news; |
| patternIndex = 0; |
| itr = tokens.erase(itr - (pattern.size() - 1), itr); |
| more = true; |
| } |
| } else { |
| patternIndex = 0; |
| } |
| } |
| } |
| } |
| |
| void StringUtils::replaceInTokenVector(std::vector<std::string>& tokens, |
| std::string pattern, std::string news) { |
| unsigned int tokensSize = tokens.size(); |
| for (unsigned int i = 0; i < tokensSize; i++) { |
| if (tokens[i] == pattern) tokens[i] = news; |
| } |
| } |
| |
| std::string StringUtils::getFirstNonEmptyToken( |
| std::vector<std::string>& tokens) { |
| unsigned int tokensSize = tokens.size(); |
| for (unsigned int i = 0; i < tokensSize; i++) { |
| if (tokens[i] != " ") return tokens[i]; |
| } |
| return ""; |
| } |
| |
| std::string& StringUtils::trim(std::string& str) { return ltrim(rtrim(str)); } |
| |
| std::string& StringUtils::ltrim(std::string& str) { |
| auto it2 = std::find_if(str.begin(), str.end(), [](char ch) { |
| return !std::isspace<char>(ch, std::locale::classic()); |
| }); |
| str.erase(str.begin(), it2); |
| return str; |
| } |
| |
| std::string& StringUtils::rtrim(std::string& str) { |
| auto it1 = std::find_if(str.rbegin(), str.rend(), [](char ch) { |
| return !std::isspace<char>(ch, std::locale::classic()); |
| }); |
| str.erase(it1.base(), str.end()); |
| return str; |
| } |
| |
| std::string& StringUtils::rtrimEqual(std::string& str) { |
| auto it1 = std::find_if(str.rbegin(), str.rend(), |
| [](char ch) { return (ch == '='); }); |
| if (it1 != str.rend()) str.erase(it1.base() - 1, str.end()); |
| return str; |
| } |
| |
| std::string& StringUtils::rtrim(std::string& str, char c) { |
| auto it1 = std::find_if(str.rbegin(), str.rend(), |
| [c](char ch) { return (ch == c); }); |
| if (it1 != str.rend()) str.erase(it1.base() - 1, str.end()); |
| return str; |
| } |
| |
| std::string& StringUtils::ltrim(std::string& str, char c) { |
| auto it1 = |
| std::find_if(str.begin(), str.end(), [c](char ch) { return (ch == c); }); |
| if (it1 != str.end()) str.erase(str.begin(), it1 + 1); |
| return str; |
| } |
| |
| bool StringUtils::ltrimStat(std::string& str, char c) { |
| auto it1 = |
| std::find_if(str.begin(), str.end(), [c](char ch) { return (ch == c); }); |
| if (it1 != str.end()) { |
| str.erase(str.begin(), it1 + 1); |
| return true; |
| } |
| return false; |
| } |
| |
| std::string StringUtils::leaf(std::string str) { |
| std::string result; |
| char c = '.'; |
| auto it1 = std::find_if(str.rbegin(), str.rend(), |
| [c](char ch) { return (ch == c); }); |
| if (it1 != str.rend()) str.erase(str.begin(), it1.base()); |
| return str; |
| return result; |
| } |
| |
| std::string& StringUtils::getRootFileName(std::string& str) { |
| bool found = true; |
| while (found) { |
| found = ltrimStat(str, '/'); |
| } |
| return str; |
| } |
| |
| std::string StringUtils::replaceAll(std::string str, const std::string& from, |
| const std::string& to) { |
| size_t start_pos = 0; |
| while ((start_pos = str.find(from, start_pos)) != std::string::npos) { |
| str.replace(start_pos, from.length(), to); |
| start_pos += |
| to.length(); // Handles case where 'to' is a substring of 'from' |
| } |
| return str; |
| } |
| |
| std::string StringUtils::eliminateRelativePath(std::string path) { |
| return replaceAll(path, "..", "__"); |
| } |
| |
| std::string StringUtils::getLineInString(std::string& bulk, unsigned int line) { |
| std::string lineText; |
| unsigned int size = bulk.size(); |
| const char* str = bulk.c_str(); |
| unsigned int count = 1; |
| for (unsigned int i = 0; i < size; i++) { |
| if (line == count) { |
| lineText += str[i]; |
| } |
| if (str[i] == '\n') count++; |
| if (count > line) break; |
| } |
| |
| return lineText; |
| } |