#include "util.h" #include #include unsigned int mrbesen::util::count(const std::string& str, char c) { size_t pos = 0; long count = -1; do { pos = str.find(c, pos); ++count; } while((pos++) != std::string::npos); return (unsigned int) count; } bool icompare_pred(unsigned char a, unsigned char b) { return std::tolower(a) == std::tolower(b); } bool mrbesen::util::equalsIgnoreCase(const std::string& a, const std::string& b, size_t max) { size_t al = a.size(), bl = b.size(); if((al == 0 && bl == 0) || max == 0) return true; if(al != bl && (al < max || bl < max)) { return false; } if(max == std::string::npos) { return std::equal(b.begin(), b.end(), a.begin(), icompare_pred); } else { if(max > al) max = al; if(max > bl) max = bl; return std::equal(b.begin(), b.begin()+max, a.begin(), icompare_pred); } } void mrbesen::util::toLower(const std::string& in, std::string& out) { if(&in == &out) { //wenn beide strings identisch sind, inplace funktion verwenden; toLower(out); return; } out = ""; out.reserve(in.size()); for(char c : in) { out += std::tolower(c); } } void mrbesen::util::toLower(std::string& in) { for(size_t p = 0; p < in.size(); p++) { in[p] = std::tolower(in[p]); } } bool mrbesen::util::endsWith(const std::string& str, const std::string& ending) { size_t es = ending.size(); size_t ss = str.size(); if(es > ss) return false; if(es == 0) return true; return str.rfind(ending) == (ss - es); } bool mrbesen::util::startsWith(const std::string& str, const std::string& start) { if(start.size() > str.size()) return false; if(start.size() == 0) return true; return str.find(start) == 0; } bool mrbesen::util::removeEnd(std::string& str, const std::string& ending) { if(ending.empty()) return false; if(endsWith(str, ending)) { str.resize(str.size() - ending.length()); return true; } return false; } bool mrbesen::util::removeStart(std::string& str, const std::string& start) { if(start.empty()) return false; if(startsWith(str, start)) { str = str.substr(start.length()); return true; } return false; } bool mrbesen::util::insertEnd(std::string& str, const std::string& ending) { if(ending.empty()) return false; if(endsWith(str, ending)) return false; str.append(ending); return true; } bool mrbesen::util::insertStart(std::string& str, const std::string& start) { if(start.empty()) return false; if(startsWith(str, start)) return false; str = start + str; return true; } unsigned int mrbesen::util::split(const std::string& str, const std::string& token, std::string* out, unsigned int count) { StringSpliterator spl(str, token); for(unsigned int i = 0; i < count; ++i) { out[i] = *spl; ++spl; if(!spl) return ++i; } return count; } bool mrbesen::util::trim(std::string& str, char c) { size_t first = str.find_first_not_of(c); if(first == std::string::npos) { bool changed = !str.empty(); str = ""; return changed; } size_t last = str.find_last_not_of(c)+1; bool changed = (last-first) < str.size(); if(changed) str = str.substr(first, last-first); return changed; } bool mrbesen::util::trimOnce(std::string& str, char c) { bool a = removeStart(str, std::string(1, c)); bool b = removeEnd(str, std::string(1, c)); return a || b; } std::string mrbesen::util::bytesToBase16(char* buffer, unsigned int len) { static const char hexmap[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; std::string s(len << 1, ' '); for (unsigned int i = 0; i < len; ++i) { s[ i<<1 ] = hexmap[(buffer[i] & 0xF0) >> 4]; s[(i<<1) + 1] = hexmap[buffer[i] & 0x0F]; } return s; } std::string mrbesen::util::bytesToBase64(char* buffer, unsigned int len) { //from: https://renenyffenegger.ch/notes/development/Base64/Encoding-and-decoding-base-64-with-cpp/index#cpp-base64-cpp if(len == 0) return ""; size_t len_encoded = (len+2) / 3 * 4; static const unsigned char trailing_char = '='; static const char* base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; std::string ret; ret.reserve(len_encoded); for(unsigned int pos = 0; pos < len; pos += 3) { ret.push_back(base64_chars[(buffer[pos] & 0xfc) >> 2]); if (pos+1 < len) { ret.push_back(base64_chars[((buffer[pos] & 0x03) << 4) + ((buffer[pos + 1] & 0xf0) >> 4)]); if (pos+2 < len) { ret.push_back(base64_chars[((buffer[pos + 1] & 0x0f) << 2) + ((buffer[pos + 2] & 0xc0) >> 6)]); ret.push_back(base64_chars[ buffer[pos + 2] & 0x3f]); } else { ret.push_back(base64_chars[(buffer[pos + 1] & 0x0f) << 2]); ret.push_back(trailing_char); } } else { ret.push_back(base64_chars[(buffer[pos] & 0x03) << 4]); ret.push_back(trailing_char); ret.push_back(trailing_char); } } return ret; } bool mrbesen::util::replace(std::string& modify, const std::string& search, char replace) { bool changed = false; for(size_t pos = modify.find_first_of(search); pos < std::string::npos; ) { modify[pos] = replace; changed = true; //search next pos = modify.find_first_of(search, pos+1); } return changed; } bool mrbesen::util::replace(std::string& modify, const std::string& search, const std::string& replacement) { if(search.empty()) return false; if(search.size() > modify.size()) return false; if(modify.find(search) == std::string::npos) return false; std::ostringstream out; size_t pos = 0; while(pos < modify.size()) { //search for next occurance of search size_t nextp = modify.find(search, pos); bool end = (nextp == std::string::npos); if(end) nextp = modify.size(); if(nextp > pos) { out << modify.substr(pos, (nextp)-pos); pos = nextp; } if(!end) out << replacement; pos += search.size(); } modify = out.str(); return true; } mrbesen::util::StringSpliterator::StringSpliterator(const std::string& d, const std::string& token) : data(d), token(token) { //trim while(mrbesen::util::removeStart(data, token)); while(mrbesen::util::removeEnd(data, token)); findNext(); } mrbesen::util::StringSpliterator::StringSpliterator(const std::string& d, char token) : StringSpliterator(d, std::string(1, token)) {} mrbesen::util::StringSpliterator::~StringSpliterator() {} std::string mrbesen::util::StringSpliterator::operator*() const { return data.substr(lasttok, (nexttok - lasttok)-token.size()); } mrbesen::util::StringSpliterator& mrbesen::util::StringSpliterator::operator++() { findNext(); return *this; } mrbesen::util::StringSpliterator mrbesen::util::StringSpliterator::operator++(int) { StringSpliterator ret = *this; findNext(); return ret; } void mrbesen::util::StringSpliterator::findNext() { if(!operator bool()) return; lasttok = nexttok; size_t test = 0; while((test = data.find(token, nexttok + token.size())) == (nexttok + token.size())) { lasttok = test; nexttok = test; } nexttok = test; if(nexttok != std::string::npos) nexttok += token.size(); } mrbesen::util::StringSpliterator::operator bool() const { return lasttok < data.length() && nexttok >= lasttok; }