#include "cString.hpp" /*** ANSI C Header Files ***/ #include /* strtol */ #ifdef _MSC_VER /// disable _s warnings # define _CRT_SECURE_NO_WARNINGS /// disable pragma warnings # pragma warning( disable : 4068 ) # pragma warning( disable : 4996 ) # include "MSUNIX/msunix.hpp" #endif using UtilityEngine::cString; cString::cString() { clear(); } cString::cString(const char* s) { copy_str(s); } cString::cString(const cString& copy) { copy_str(copy); } cString::~cString() { clear(); } const char* cString::alloc_str(size_t sz) { if (mp_str) clear(); m_len = (sz > __cString__MAX_LEN) ? __cString__MAX_LEN : sz; mp_str = (char *)calloc(1, m_len + 1); return mp_str; } void cString::clear() { if (mp_str) free((void *)mp_str); mp_str = nullptr; m_len = 0; } const char* cString::c_str() const { return mp_str; } const char* cString::copy_str(const char* copy) { if (copy) { size_t len = strnlen(copy, __cString__MAX_LEN); alloc_str(len); strncpy((char *)mp_str, copy, len); m_len = len; } return mp_str; } bool cString::have_value() const { if (mp_str) return true; else return false; } size_t cString::length() const { return m_len; } size_t cString::size() const { return m_len; } /// string format cString& cString::format(const char* format, ...) { char * buffer; va_list args; va_start(args, format); vasprintf(&buffer, format, args); copy_str(buffer); free(buffer); return *this; } /// trim leading and trailing spaces cString& cString::trim() { const static char * whitespace = "\x20\x1b\t\r\n\v\b\f\a"; if (!have_value()) return *this; // make sure we have a string size_t begin = 0; size_t end = length() - 1; for (begin = 0; begin <= end; ++begin) { if (strchr(whitespace, mp_str[begin]) == nullptr) { break; } } for (; end > begin; --end) { if (strchr(whitespace, mp_str[end]) == nullptr) { break; } else { mp_str[end] = '\0'; } } if (begin) { for (size_t i = 0; mp_str[i]; ++i) { mp_str[i] = mp_str[begin++]; } } m_len = strlen(mp_str); return *this; } cString cString::lower() const { cString rs = *this; for (size_t i = 0; rs.mp_str[i]; ++i) { rs.mp_str[i] = (char)tolower(rs.mp_str[i]); } return rs; } cString cString::upper() const { cString rs = *this; for (size_t i = 0; rs.mp_str[i]; ++i) { rs.mp_str[i] = (char)toupper(rs.mp_str[i]); } return rs; } const char& cString::first_char() const { return mp_str[0]; } const char& cString::last_char() const { return mp_str[length() - 1]; } /// non-destructive split const std::vector cString::split(const char match) const { const char match_s[2] = { match, 0 }; return split(match_s, -1); } const std::vector cString::split(const char* match) const { return split(match, -1); } const std::vector cString::split(const char* match, int max_split) const { std::vector rtn; if (length() < 1) return rtn; size_t match_len = strnlen(match, __cString__MAX_LEN); if (match_len >= __cString__MAX_LEN) return rtn; char* mi; /// match index char* pstr = mp_str; /// string pointer while ((mi = strstr(pstr, match)) && (max_split < 0 || --max_split)) { if (mi != pstr) { size_t lhsz = mi - pstr; char* cslhs = (char *)malloc(lhsz + 1); cslhs[lhsz] = '\0'; /// strncpy doesn't terminate it rtn.emplace_back(strncpy(cslhs, pstr, lhsz)); /// calls cString copy ctor pstr += lhsz; free(cslhs); } pstr += match_len; } if (*pstr != '\0') { rtn.emplace_back(pstr); } return rtn; } const cString& cString::char_repl(const char& match, const char& repl) { for (size_t i = 0; mp_str[i]; ++i) { if (mp_str[i] == match) mp_str[i] = repl; } return *this; } long int cString::char_find(const char& match) const { for (size_t i = 0; mp_str[i]; ++i) { if (mp_str[i] == match) return i; } return -1; } cString cString::substr(size_t start, size_t length) const { cString rs; char * buf; if ((length + 1) > __cString__MAX_LEN) return rs; if ((start + length) > __cString__MAX_LEN) return rs; if (length > m_len - start) return rs; if (!mp_str) return rs; buf = (char *)calloc(sizeof(char), length + 1); memcpy(buf, mp_str + start, length); rs = buf; return rs; } long int cString::find(const cString& match) { char * pos = strstr(mp_str, match.c_str()); if (pos) return (long)(pos - mp_str); else return -1; } const cString cString::replace(const cString& match, const cString& repl) { cString rs; long f1 = find(match); if (f1 >= 0) { size_t pos1 = (size_t)f1; size_t pos2 = pos1 + match.length(); cString s1 = pos1 > 0 ? substr(0, pos1) : ""; cString s2 = substr(pos2, length() - pos2); rs = s1 + repl + s2; } return rs; } const bool cString::IsInt() const { bool rtn = false; cString tmp = c_str(); tmp.trim(); switch (tmp.first_char()) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': rtn = true; break; default: rtn = false; break; } return rtn; } const long int cString::ToInt() const { return strtol(mp_str, NULL, 10); } cString& cString::operator = (const char* rhs) { copy_str(rhs); return *this; } cString& cString::operator = (const cString& rhs) { copy_str(rhs.c_str()); return *this; } cString& cString::operator += (const char rhs) { operator+=(&rhs); return *this; } cString& cString::operator += (const char* rhs) { if (rhs) { size_t newlen = m_len + strnlen(rhs, __cString__MAX_LEN); if (newlen > __cString__MAX_LEN) newlen = __cString__MAX_LEN; char * buf = (char *)calloc(1, newlen + 1); if (!buf) return *this; if (mp_str && m_len) strncpy(buf, mp_str, m_len); strncpy(buf + m_len, rhs, newlen - m_len); buf[newlen] = '\0'; copy_str(buf); free(buf); } return *this; } cString& cString::operator += (const cString& rhs) { operator+=(rhs.c_str()); return *this; } bool cString::operator == (const char* rhs) const { if (std::strncmp(this->c_str(), rhs, __cString__MAX_LEN) == 0) return true; else return false; } bool cString::operator == (const cString& rhs) const { if (std::strncmp(this->c_str(), rhs.c_str(), __cString__MAX_LEN) == 0) return true; else return false; } bool cString::operator != (const char* rhs) const { if (std::strncmp(this->c_str(), rhs, __cString__MAX_LEN) != 0) return true; else return false; } bool cString::operator != (const cString& rhs) const { if (std::strncmp(this->c_str(), rhs.c_str(), __cString__MAX_LEN) != 0) return true; else return false; } bool cString::operator > (const cString& rhs) const { if (std::strncmp(this->c_str(), rhs.c_str(), __cString__MAX_LEN) > 0) return true; else return false; } bool cString::operator < (const cString& rhs) const { if (std::strncmp(this->c_str(), rhs.c_str(), __cString__MAX_LEN) < 0) return true; else return false; } bool cString::operator >= (const cString& rhs) const { if (std::strncmp(this->c_str(), rhs.c_str(), __cString__MAX_LEN) >= 0) return true; else return false; } bool cString::operator <= (const cString& rhs) const { if (std::strncmp(this->c_str(), rhs.c_str(), __cString__MAX_LEN) <= 0) return true; else return false; } cString::operator const char* () const { return c_str(); } cString::operator std::string () const { return std::string(c_str()); } cString operator + (const cString& lhs, const cString& rhs) { cString rs = lhs; rs += rhs; return rs; }