#pragma implementation #include #include #include #include #include "misc.h" PUBLIC SSTRING::SSTRING() { str = NULL; maxsiz = 200; } PUBLIC SSTRING::SSTRING (const char *_str) { str = NULL; if (_str != NULL) str = strdup(_str); maxsiz = 200; // Arbitrary maximum } PUBLIC SSTRING::SSTRING (const char *_str, int _maxsiz) { str = NULL; if (_str != NULL) str = strdup(_str); maxsiz = _maxsiz; } PUBLIC SSTRING::SSTRING(const SSTRING &_str) { str = strdup(_str.get()); maxsiz = _str.maxsiz; } PUBLIC SSTRING::SSTRING(const SSTRING *_str) { str = NULL; maxsiz = 200; // Arbitrary maximum if (_str != NULL){ str = strdup(_str->get()); maxsiz = _str->maxsiz; } } PUBLIC SSTRING &SSTRING::operator = (const SSTRING &_str) { setfrom (_str.get()); maxsiz = _str.maxsiz; return *this; } PUBLIC SSTRING &SSTRING::operator = (const char *_str) { setfrom (_str); return *this; } PUBLIC SSTRING &SSTRING::operator += (const SSTRING &_str) { append (_str.get()); return *this; } PUBLIC SSTRING &SSTRING::operator += (const char *_str) { append (_str); return *this; } PUBLIC SSTRING::~SSTRING() { free (str); } PUBLIC void SSTRING::copy (char *dst) const { *dst = '\0'; if (str != NULL) strcpy (dst,str); } PUBLIC void SSTRING::copy (SSTRING &dst) const { dst.setfrom (get()); } PUBLIC void SSTRING::setempty() { setfrom (""); } PUBLIC void SSTRING::clear() { setfrom (""); } /* Initialise the SSTRING from a value. This value may be a substring of the current value of this SSTRING */ PUBLIC VIRTUAL void SSTRING::setfrom (const char *src) { setmodified(); char *newstr = NULL; if (src != NULL && src[0] != '\0') newstr = strdup(src); free (str); str = newstr; } PUBLIC void SSTRING::setfrom (const SSTRING &src) { setfrom (src.get()); } PUBLIC void SSTRING::setfrom (const SSTRING *src) { setfrom (src->get()); } PUBLIC void SSTRING::setfrom (const char *src, int len) { char *newstr = NULL; if (src != NULL && src[0] != '\0'){ newstr = (char*) malloc (len+1); newstr[len] = '\0'; strncpy (newstr,src,len); } setmodified(); free (str); str = newstr; } /* Initialise a SSTRING from a integer (convert to ASCII decimal) */ PUBLIC void SSTRING::setfrom (int val) { char bufval[20]; ::sprintf (bufval,"%d",val); setfrom(bufval); } /* Append a string to the current content. */ PUBLIC void SSTRING::append (const char *app, int len2) { const char *pt1 = get(); int len1 = strlen(pt1); if (len2 == -1) len2 = strlen(app); char *newstr = (char*)malloc(len1+len2+1); if (newstr != NULL){ strcpy (newstr,pt1); strcpy_cut (newstr+len1,app,len2+1); free (str); str = newstr; setmodified(); } } /* Append a string to the current content. */ PUBLIC void SSTRING::append (const char *app) { append (app,-1); } /* Append one character to the current content. */ PUBLIC void SSTRING::append (const char car) { char tmp[]={car,'\0'}; append (tmp,-1); } /* Append a string to the current content. */ PUBLIC void SSTRING::append (const SSTRING &s) { append (s.get()); } /* Append a string to the current content. */ PUBLIC void SSTRING::append (const SSTRING *s) { if (s != NULL) append (s->get()); } /* Return the numerical (integer) value of the SSTRING */ PUBLIC int SSTRING::getval() const { return atoi(get()); } /* Return the numerical (double) value of the SSTRING */ PUBLIC double SSTRING::getvalf() const { return atof(get()); } /* Return the length of the string. */ PUBLIC int SSTRING::getlen() const { return strlen (get()); } /* Get the string value. Will never return NULL (only an empty string). */ PUBLIC const char *SSTRING::get() const { char *ret = str; if (str == NULL) ret = ""; return ret; } /* Get the string value. Will never return NULL (only an empty string). Same as SSTRING::get() for some STL compatiblity. */ PUBLIC const char *SSTRING::c_str() const { char *ret = str; if (str == NULL) ret = ""; return ret; } /* Perform a strcmp on the string and the other one. */ PUBLIC int SSTRING::cmp (const char *other) const { char *one = str; if (one == NULL) one = ""; return strcmp(one,other); } /* Perform a strncmp on the string and the other one. */ PUBLIC int SSTRING::ncmp (const char *other, int len) const { char *one = str; if (one == NULL) one = ""; return strncmp(one,other,len); } /* Perform a strncmp on the string and the other one. */ PUBLIC int SSTRING::ncmp (const SSTRING &other, int len) const { return ncmp(other.get(),len); } /* Perform a stricmp on the string and the other one. */ PUBLIC int SSTRING::icmp (const char *other) const { char *one = str; if (one == NULL) one = ""; return strcasecmp(one,other); } /* Perform a stricmp on the string and the other one. */ PUBLIC int SSTRING::icmp (const SSTRING &other) const { return icmp(other.get()); } /* Perform a strnicmp on the string and the other one. */ PUBLIC int SSTRING::nicmp (const char *other, int len) const { char *one = str; if (one == NULL) one = ""; return strncasecmp(one,other,len); } /* Perform a stricmp on the string and the other one. */ PUBLIC int SSTRING::nicmp (const SSTRING &other, int len) const { return nicmp(other.get(),len); } /* Find the occurence of a character in the string. */ PUBLIC const char *SSTRING::strchr(char carac) const { const char *ret = NULL; if (str != NULL) ret = ::strchr(str,carac); return ret; } /* Find the last occurence of a character in the string. */ PUBLIC const char *SSTRING::strrchr(char carac) const { const char *ret = NULL; if (str != NULL) ret = ::strrchr(str,carac); return ret; } /* Find the occurence of a string in the string. */ PUBLIC const char *SSTRING::strstr(const char *sub) const { const char *ret = NULL; if (str != NULL) ret = ::strstr(str,sub); return ret; } PUBLIC const char *SSTRING::stristr(const char *sub) const { const char *ret = NULL; if (str != NULL) ret = ::stristr(str,sub); return ret; } PUBLIC int SSTRING::cmp(const SSTRING &other) const { return cmp(other.get()); } PUBLIC bool SSTRING::operator == (const SSTRING &other) const { return cmp(other)==0; } PUBLIC bool SSTRING::operator == (const char *other) const { return cmp(other)==0; } PUBLIC bool SSTRING::operator != (const SSTRING &other) const { return cmp(other)!=0; } PUBLIC bool SSTRING::operator != (const char *other) const { return cmp(other)!=0; } PUBLIC void SSTRING::setmaxsiz(int size) { maxsiz = size; } PUBLIC int SSTRING::getmaxsiz() const { return maxsiz; } /* Return != 0 if the SSTRING is an empty string. */ PUBLIC bool SSTRING::is_empty() const { bool ret = true; if (str != NULL) ret = str[0] == '\0'; return ret; } /* Return true is the SSTRING is not empty */ PUBLIC bool SSTRING::is_filled() const { return !is_empty(); } /* Return true if the string contains only numbers */ PUBLIC bool SSTRING::is_num() const { bool ret = false; const char *pt = str; if (pt != NULL){ if (pt[0] == '-' || isdigit(pt[0])){ pt++; while (isdigit(pt[0])) pt++; ret = pt[0] == '\0'; } } return ret; } /* Cut the white space at the end of the string */ PUBLIC void SSTRING::strip_end() { if (str != NULL){ ::strip_end (str); setmodified(); } } /* Extract a word (non white space) from a string. Return a pointer to the end of the word in the line. */ PUBLIC char *SSTRING::copyword (const char *line) { char word[1000]; line = str_copyword(word,line,1000); setfrom (word); return (char*)line; } /* Cut the string if it exceed a given length. Return true if it was cut. */ PUBLIC bool SSTRING::truncate(int newlen) { bool ret = false; if (getlen() > newlen){ str[newlen] = '\0'; ret = true; setmodified(); } return ret; } /* Cut the string up to "pt" where pt points inside the string. Return true if it was cut. */ PUBLIC bool SSTRING::truncate(const char *pt) { bool ret = false; if (pt >= str && pt < str + getlen()){ *(char*)pt = '\0'; ret = true; } return ret; } /* Change one character in the string. The pointer must point inside the string. The string won't be enlarged. Return false if the operation was not performed. */ PUBLIC bool SSTRING::setchar(const char *pt, const char car) { bool ret = false; if (pt >= str && pt < str + getlen()){ *(char*)pt = car; ret = true; } return ret; } /* Change one character in the string. The position (starting at 0) must point inside the string. The string won't be enlarged. Return false if the operation was not performed. */ PUBLIC bool SSTRING::setchar(int pos, const char car) { return setchar (str+pos,car); } /* Record the comment part of the CSSTRING */ PUBLIC void CSSTRING::setcomment(const SSTRING &com) { comment.setfrom (com); } /* Record the value and the comment part of the CSSTRING */ PUBLIC void CSSTRING::setfrom_c (const SSTRING &val, const SSTRING &com) { setfrom (val); comment.setfrom (com); } /* Does an sprintf, but store the result in the SSTRING. Return the number of bytes stored */ PUBLIC int SSTRING::setfromf (const char *ctl, ...) { va_list list; va_start (list,ctl); char tmp[10000]; int ret = vsnprintf (tmp,sizeof(tmp)-1,ctl,list); if (ret == -1 || (unsigned)ret >= sizeof(tmp)-1){ // Too large, char *newbuf = NULL; ret = vasprintf (&newbuf,ctl,list); if (ret != -1){ free (str); str = newbuf; }else{ free (newbuf); } }else{ setfrom (tmp); } va_end (list); return ret; } /* Does an sprintf, but append the result in the SSTRING. Return the number of bytes stored */ PUBLIC int SSTRING::appendf (const char *ctl, ...) { va_list list; va_start (list,ctl); char tmp[10000]; int ret = vsnprintf (tmp,sizeof(tmp)-1,ctl,list); if (ret == -1 || (unsigned)ret >= sizeof(tmp)-1){ // Too large, char *newbuf = NULL; ret = vasprintf (&newbuf,ctl,list); if (ret != -1) append (newbuf); free (newbuf); }else{ append (tmp); } va_end (list); return ret; } /* Turn the string to lower case */ PUBLIC void SSTRING::to_lower() { if (str != NULL){ char *pt = str; bool modif = false; while (*pt != '\0'){ if (isupper(*pt)){ *pt = tolower(*pt); modif = true; } pt++; } if (modif) setmodified(); } } /* Turn the string to upper case */ PUBLIC void SSTRING::to_upper() { if (str != NULL){ char *pt = str; bool modif = false; while (*pt != '\0'){ if (islower(*pt)){ *pt = toupper(*pt); modif = true; } pt++; } if (modif) setmodified(); } } /* Get the sub string after start characters */ PUBLIC SSTRING SSTRING::substr (int start) const { SSTRING ret; if (str != NULL && start >= 0){ int len = strlen(str); if (len > start){ ret.setfrom (str+start); } } return ret; } /* Get the sub-string starting with start and ending with end (not included) */ PUBLIC SSTRING SSTRING::substr (int start, int end) const { SSTRING ret; if (str != NULL && start >= 0 && end > start){ int len = strlen(str); if (len > start){ if (end > len){ // Put the reminder of the string ret.setfrom (str+start); }else{ ret.setfrom (str+start,(int)(end-start)); } } } return ret; } /* Convert a multi-line string into a set of one line strings. Return the number of lines appended to tb. */ PUBLIC int SSTRING::cnv2lines (SSTRINGS &tb) { return str_cnv2lines(get(),tb); } /* Insert a string at the beginning. */ PUBLIC void SSTRING::insert (const char *s) { setfromf ("%s%s",s,get()); } PUBLIC void SSTRING::insert (const SSTRING &s) { insert (s.get()); } PUBLIC void SSTRING::insert (const SSTRING *s) { if (s != NULL) insert (s->get()); } #ifdef TEST static void test (const char *name, SSTRING &t, SSTRING c) { printf ("%s = :%s:[%p] == :%s:[%p]\n",name,t.get(),t.get(),c.get(),c.get()); } #define P(x) test (#x,x,x) int main (int, char *[]) { SSTRING t1; t1.setfrom ("allo"); P(t1); SSTRING t2 (t1); P(t2); SSTRING t3; t3 = t2; P(t3); for (int i=0; i