#include "sstring.h" #include #include "extvalue.h" #include void SString::initEmpty() { txt=NULL; used=0; size=0; } SString::SString() { initEmpty(); } SString::~SString() { resize(0); } SString::SString(int x) { initEmpty(); if (x) ensureSize(x+1); } SString::SString(const char *t,int t_len) { initEmpty(); if (!t) return; copyFrom(t,t_len); } SString::SString(const SString &from) { initEmpty(); operator=(from); } SString::SString(SString&& from) { txt=from.txt; size=from.size; used=from.used; from.txt=NULL; from.size=0; from.used=0; } void SString::resize(int newsize) { if (newsize==size) return; txt=(char*)realloc(txt,newsize); size=newsize; } void SString::ensureSize(int needed) { if (size>needed) return; resize( (size>0) ? (needed+needed/2+1) : (needed+1)); } char *SString::directWrite(int ensuresize) { ensureSize(ensuresize); appending=used; return txt; } char *SString::directAppend(int maxappend) { ensureSize(used+maxappend); appending=used; return txt+appending; } void SString::endWrite(int newlength) { if (newlength<0) newlength=strlen(txt); else txt[newlength]=0; used=newlength; assert(used=(len()-begin)) length=len()-begin; if (length<=0) return SString(); if (length==len()) return *this; return SString((*this)(begin),length); } /////////////////////////////////////// bool SString::equals(const SString& s) const { if (this==&s) return true; if (len()!=s.len()) return false; return strcmp(getPtr(),s.getPtr())==0; } /////////////////////////////////////// int SString::indexOf(int character,int start) const { const char *found=strchr(getPtr()+start,character); return found?found-getPtr():-1; } int SString::indexOf(const char *substring,int start) const { const char *found=strstr(getPtr()+start,substring); return found?found-getPtr():-1; } int SString::indexOf(const SString & substring,int start) const { const char *found=strstr(getPtr()+start,substring.c_str()); return found?found-getPtr():-1; } bool SString::getNextToken (int& pos,SString &token,char separator) const { if (pos>=len()) {token=0;return false;} int p1=pos,p2; const char *t1=getPtr()+pos; const char *t2=strchr(t1,separator); if (t2) pos=(p2=(t2-getPtr()))+1; else p2=pos=len(); strncpy(token.directWrite(p2-p1),t1,p2-p1); token.endWrite(p2-p1); return true; } bool SString::startsWith(const char *pattern) const { const char *t=this->c_str(); for (;*pattern;pattern++,t++) if (*t != *pattern) return false; return true; } SString SString::valueOf(int i) { return SString::sprintf("%d",i); } SString SString::valueOf(long i) { return SString::sprintf("%d",i); } SString SString::valueOf(double d) { SString tmp=SString::sprintf("%.15g",d); if ((!strchr(tmp.c_str(),'.'))&&(!strchr(tmp.c_str(),'e'))) tmp+=".0"; return tmp; } SString SString::valueOf(const SString& s) { return s; } SString SString::sprintf(const char* format, ...) { int n, size = 30; va_list ap; SString ret; #ifdef USE_VSCPRINTF va_start(ap, format); size=_vscprintf(format, ap); va_end(ap); #endif while (1) { char* p=ret.directWrite(size); assert(p!=NULL); size=ret.directMaxLen()+1; /* Try to print in the allocated space. */ va_start(ap, format); n = vsnprintf(p, size, format, ap); va_end(ap); /* If that worked, return the string. */ if (n > -1 && n < size) { ret.endWrite(n); return ret; } /* Else try again with more space. */ #ifdef VSNPRINTF_RETURNS_REQUIRED_SIZE if (n > -1) /* glibc 2.1 */ size = n; /* precisely what is needed */ else /* glibc 2.0 */ #endif size *= 2; /* twice the old size */ } } SString &SString::empty() { static SString empty; return empty; }