424 lines
7.4 KiB
C++
424 lines
7.4 KiB
C++
#include "cString.hpp"
|
|
|
|
/*** ANSI C Header Files ***/
|
|
#include <stdlib.h> /* 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> cString::split( const char match ) const
|
|
{
|
|
const char match_s[2] = { match, 0 };
|
|
return split(match_s, -1);
|
|
}
|
|
|
|
const std::vector<cString> cString::split( const char* match ) const
|
|
{
|
|
return split(match, -1);
|
|
}
|
|
|
|
const std::vector<cString> cString::split( const char* match, int max_split ) const
|
|
{
|
|
std::vector<cString> 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;
|
|
}
|
|
|