#include "../include/StringUtils.hpp" #include namespace QuickMedia { template static void string_split_t(const std::string &str, const T &delimiter, StringSplitCallback callback_func) { size_t index = 0; while(index < str.size()) { size_t new_index = str.find(delimiter, index); if(new_index == std::string::npos) new_index = str.size(); if(!callback_func(str.data() + index, new_index - index)) break; if constexpr(std::is_same::value) index = new_index + 1; else index = new_index + delimiter.size(); } } void string_split(const std::string &str, const std::string &delimiter, StringSplitCallback callback_func) { string_split_t(str, delimiter, callback_func); } void string_split(const std::string &str, char delimiter, StringSplitCallback callback_func) { string_split_t(str, delimiter, callback_func); } size_t string_replace_all(std::string &str, char old_char, char new_char) { size_t num_replaced_substrings = 0; for(char &c : str) { if(c == old_char) { c = new_char; ++num_replaced_substrings; } } return num_replaced_substrings; } size_t string_replace_all(std::string &str, char old_char, const std::string &new_str) { size_t num_replaced_substrings = 0; size_t index = 0; while(index < str.size()) { index = str.find(old_char, index); if(index == std::string::npos) break; str.replace(index, 1, new_str); index += new_str.size(); ++num_replaced_substrings; } return num_replaced_substrings; } size_t string_replace_all(std::string &str, const std::string &old_str, const std::string &new_str) { size_t num_replaced_substrings = 0; size_t index = 0; while(index < str.size()) { index = str.find(old_str, index); if(index == std::string::npos) break; str.replace(index, old_str.size(), new_str); index += new_str.size(); ++num_replaced_substrings; } return num_replaced_substrings; } static bool is_whitespace(char c) { return c == ' ' || c == '\n' || c == '\t' || c == '\v'; } std::string strip(const std::string &str) { if(str.empty()) return str; int start = 0; for(; start < (int)str.size(); ++start) { if(!is_whitespace(str[start])) break; } int end = str.size() - 1; for(; end >= start; --end) { if(!is_whitespace(str[end])) break; } return str.substr(start, end - start + 1); } bool string_starts_with(const std::string &str, const char *sub) { size_t sub_len = strlen(sub); return sub_len == 0 || (str.size() >= sub_len && memcmp(str.c_str(), sub, sub_len) == 0); } bool string_ends_with(const std::string &str, const std::string &ends_with_str) { size_t ends_len = ends_with_str.size(); return ends_len == 0 || (str.size() >= ends_len && memcmp(&str[str.size() - ends_len], ends_with_str.data(), ends_len) == 0); } size_t str_find_case_insensitive(const std::string &str, size_t start_index, const char *substr, size_t substr_len) { auto it = std::search(str.begin() + start_index, str.end(), substr, substr + substr_len, [](char c1, char c2) { return to_upper(c1) == to_upper(c2); }); if(it == str.end()) return std::string::npos; return it - str.begin(); } char to_upper(char c) { if(c >= 'a' && c <= 'z') return c - 32; else return c; } bool strcase_equals(const char *str1, const char *str2) { for(;;) { const char c1 = *str1; const char c2 = *str2; if(to_upper(c1) != to_upper(c2)) return false; else if(c1 == '\0') return true; ++str1; ++str2; } } }