diff --git a/public/blah/containers/str.cpp b/public/blah/containers/str.cpp index b6c01d6..c5ad1e9 100644 --- a/public/blah/containers/str.cpp +++ b/public/blah/containers/str.cpp @@ -357,12 +357,32 @@ Vector Str::split(char ch) const return result; } -void Str::replace(char c, char r) +Str& Str::replace(const Str& os, const Str& ns) +{ + for (int i = 0; i < m_length - os.m_length + 1; i++) + { + if (strcmp(data() + i, os.data()) == 0) + { + if (ns.m_length > os.m_length) + reserve(ns.m_length - os.m_length); + + memcpy(data() + i + os.m_length, data() + i + ns.m_length, m_length - i - os.m_length); + memcpy(data() + i, ns.cstr(), ns.m_length); + set_length(m_length + ns.m_length - os.m_length); + i += os.m_length - 1; + } + } + + return *this; +} + +Str& Str::replace(char c, char r) { char* ptr = data(); for (int n = 0; n < m_length; n++) if (ptr[n] == c) ptr[n] = r; + return *this; } void Str::clear() diff --git a/public/blah/containers/str.h b/public/blah/containers/str.h index dc44599..d0beaa3 100644 --- a/public/blah/containers/str.h +++ b/public/blah/containers/str.h @@ -1,5 +1,6 @@ #pragma once #include +#include #include namespace Blah @@ -96,22 +97,25 @@ namespace Blah Str& trim(); // returns true if the string begins with the given string - bool starts_with(const Str& str, bool ignoreCase = false) const { return starts_with(str.cstr(), ignoreCase); } + bool starts_with(const Str& str, bool ignore_case = false) const { return starts_with(str.cstr(), ignore_case); } // returns true if the string begins with the given string - bool starts_with(const char* str, bool ignoreCase = false) const; + bool equals(const Str& str, bool ignore_case = false) const { return str.length() == length() && starts_with(str.cstr(), ignore_case); } + + // returns true if the string begins with the given string + bool starts_with(const char* str, bool ignore_case = false) const; // returns true if the string contains with the given string - bool contains(const Str& str, bool ignoreCase = false) const { return contains(str.cstr(), ignoreCase); } + bool contains(const Str& str, bool ignore_case = false) const { return contains(str.cstr(), ignore_case); } // returns true if the string contains with the given string - bool contains(const char* str, bool ignoreCase = false) const; + bool contains(const char* str, bool ignore_case = false) const; // returns true if the string ends with the given string - bool ends_with(const Str& str, bool ignoreCase = false) const { return ends_with(str.cstr(), ignoreCase); } + bool ends_with(const Str& str, bool ignore_case = false) const { return ends_with(str.cstr(), ignore_case); } // returns true if the string ends with the given string - bool ends_with(const char* str, bool ignoreCase = false) const; + bool ends_with(const char* str, bool ignore_case = false) const; // returns the first index of the given character, or -1 if it isn't found int first_index_of(char ch) const; @@ -127,8 +131,10 @@ namespace Blah Vector split(char ch) const; + Str& replace(const Str& old_str, const Str& new_str); + // replaces all occurances of the given character in the string - void replace(char c, char r); + Str& replace(char c, char r); // checks if the string has a length of 0 bool empty() const { return m_length <= 0; } @@ -169,6 +175,9 @@ namespace Blah int m_local_size; }; + // combine string + inline Str operator+(const Str& lhs, const Str& rhs) { Str str; str.append(lhs).append(rhs); return str; } + template class StrOf : public Str { @@ -184,6 +193,36 @@ namespace Blah // assignment operators StrOf& operator=(const char* rhs) { set(rhs); return *this; } StrOf& operator=(const Str& rhs) { set(rhs); return *this; } - StrOf& operator=(const StrOf& rhs) { set(rhs); return *this; } + StrOf& operator=(const StrOf& rhs) { set(rhs); return *this; } + + // creates a string from the format + static StrOf fmt(const char* str, ...); }; + + template + StrOf StrOf::fmt(const char* fmt, ...) + { + StrOf str; + + int add, diff; + + // determine arg length + va_list args; + va_start(args, fmt); + add = vsnprintf(NULL, 0, fmt, args); + va_end(args); + + // reserve + auto len = str.length(); + str.set_length(len + add); + diff = str.capacity() - len; + if (diff <= 0) diff = 0; + + // print out + va_start(args, fmt); + vsnprintf(str.cstr() + len, (size_t)diff, fmt, args); + va_end(args); + + return str; + } } \ No newline at end of file