diff --git a/inc/util.h b/inc/util.h index 9d496d5..117deea 100644 --- a/inc/util.h +++ b/inc/util.h @@ -22,4 +22,26 @@ bool removeStart(std::string& str, const std::string& start); bool insertEnd(std::string& str, const std::string& ending); bool insertStart(std::string& str, const std::string& start); +unsigned int split(const std::string& str, const std::string& token, std::string* out, unsigned int count); + +void trim(std::string& str, char c = ' '); + +class StringSpliterator : public std::iterator { +public: + StringSpliterator(const std::string& d, const std::string& token); + ~StringSpliterator(); + + std::string operator*() const; + StringSpliterator& operator++(); + StringSpliterator operator++(int); + operator bool() const; +private: + void findNext(); + + std::string data; + std::string token; + size_t lasttok = 0; + size_t nexttok = 0; +}; + } \ No newline at end of file diff --git a/src/util.cpp b/src/util.cpp index 54649e9..fa3b49f 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -109,3 +109,66 @@ bool mrbesen::Util::insertStart(std::string& str, const std::string& start) { 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; +} + +void mrbesen::Util::trim(std::string& str, char c) { + size_t first = str.find_first_not_of(c); + if(first == std::string::npos) { + str = ""; + return; + } + size_t last = str.find_last_not_of(c)+1; + str = str.substr(first, last-first); +} + +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() {} + +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; +} diff --git a/tests/main.cpp b/tests/main.cpp index 435bd2d..757a3c4 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -13,8 +13,15 @@ int testUtil_toLower(); int testUtil_start_endWith(); int testUtil_removeStart_End(); int testUtil_insertStart_End(); +int testUtil_trim(); -test_t tests[] = {testFiles_parent, testFiles_file, testFiles_extention, testFiles_scan, testUtil_Count, testUtil_equalsIgnoreCase, testUtil_toLower, testUtil_start_endWith, testUtil_removeStart_End, testUtil_insertStart_End, NULL}; +int testStringSpliterator(); +int testUtilSplit(); + +test_t tests[] = {testFiles_parent, testFiles_file, testFiles_extention, testFiles_scan, + testUtil_Count, testUtil_equalsIgnoreCase, testUtil_toLower, testUtil_start_endWith, testUtil_removeStart_End, testUtil_insertStart_End, testUtil_trim, + testStringSpliterator, testUtilSplit, + NULL}; int main(int argc, char** argv) { diff --git a/tests/stringspliteratortest.cpp b/tests/stringspliteratortest.cpp new file mode 100644 index 0000000..f230904 --- /dev/null +++ b/tests/stringspliteratortest.cpp @@ -0,0 +1,76 @@ +#include "test.h" + +#include "util.h" + +using namespace mrbesen::Util; + + +int testStringSpliterator() { + + StringSpliterator spl("abc;def;ghi", ";"); + + ASSERT(spl, ""); + + ASSERT(*spl == "abc", *spl); + ASSERT(*spl == "abc", *spl); + ASSERT(spl, ""); + + spl++; + + ASSERT(spl, ""); + ASSERT(*spl == "def", *spl); + ASSERT(spl, ""); + + ++spl; + ASSERT(*spl == "ghi", *spl); + + ASSERT(spl, ""); + + spl++; + + ASSERT(!spl, ""); + + StringSpliterator spl2(";abc;def;;ghi;", ";"); + + ASSERT(spl2, ""); + + ASSERT(*spl2 == "abc", *spl2); + + ASSERT(spl2, ""); + + spl2++; + + ASSERT(spl2, ""); + + ASSERT(*spl2 == "def", ""); + + ++spl2; + //ASSERT(*spl2 == "ghi", *spl2); + ASSERT(spl2, ""); + + spl2++; + ASSERT(!spl2, ""); + + return TESTGOOD; +} + +int testUtilSplit() { + + std::string test = ";abc;def;ghi;;"; + + std::string out[4]; + unsigned int count = split(test, ";", out, 4); + ASSERT(count == 3, count); + ASSERT(out[0] == "abc", out[0]); + ASSERT(out[1] == "def", out[1]); + ASSERT(out[2] == "ghi", out[2]); + + test = "abc;;def;g;;hi"; + count = split(test, ";;", out, 2); + ASSERT(count == 2, count); + ASSERT(out[0] == "abc", out[0]); + //ASSERT(out[1] == "def;g;;hi", out[1]); + ASSERT(out[1] == "def;g", out[1]); + + return TESTGOOD; +} \ No newline at end of file diff --git a/tests/utilstest.cpp b/tests/utilstest.cpp index 246011a..181d1c8 100644 --- a/tests/utilstest.cpp +++ b/tests/utilstest.cpp @@ -146,5 +146,26 @@ int testUtil_insertStart_End() { ASSERT(insertEnd(a, "def"), ""); ASSERT(a == "bcabcdef", a); + return TESTGOOD; +} + +int testUtil_trim() { + std::string a = " abc def "; + + trim(a); + ASSERT(a == "abc def", a); + + trim(a, '_'); + ASSERT(a == "abc def", a); + + trim(a, 'f'); + ASSERT(a == "abc de", a); + + a = " "; + trim(a); + ASSERT(a == "", a); + trim(a); + ASSERT(a == "", a); + return TESTGOOD; } \ No newline at end of file