Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

/ray/src/lib/tl/tlstring.h

Go to the documentation of this file.
00001 /*
00002  * lib/tl/tlstring.h
00003  * 
00004  * Thread-save reference-counting string class. 
00005  * 
00006  * Copyright (c) 2004 by Wolfgang Wieser ] wwieser (a) gmx <*> de [ 
00007  * 
00008  * This file may be distributed and/or modified under the terms of the 
00009  * GNU General Public License version 2 as published by the Free Software 
00010  * Foundation. (See COPYING.GPL for details.)
00011  * 
00012  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00013  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00014  * 
00015  */
00016 
00017 #ifndef _TemplateLibrary_TLString_H_
00018 #define _TemplateLibrary_TLString_H_ 1
00019 
00026 #include <lib/sconfig.h>    /* MUST be first */
00027 
00028 #include <lib/salloc.h>
00029 #include <lib/threads/atomic.h>
00030 
00031 #if HAVE_STDARG_H
00032 #  include <stdarg.h>
00033 #endif
00034 
00036 
00037 // See lib/serror.h. 
00038 class SError;
00039 
00040 
00053 class TLString
00054 {
00055     public:
00056         // Our own inline version of strcpy
00057         //static inline void strcpy(char *d,const char *s)
00058         //  {  while(*d++=*s++);  }
00059         //  {  __builtin_strcpy(d,s);  }
00060         
00062         struct SData
00063         {
00064             AtomicInt refcnt;  
00065             char *str;         
00066             size_t len;        
00067             size_t asize;      
00068             
00070             static inline size_t RoundUp(size_t s)
00071                 {  return((s&7) ? (s|7)+1 : s);  }
00072             
00076             // I will allocate 50% more but limited to 16k bytes. 
00077             // (Hint: 32k*50% = 16k :)
00078             static inline size_t GrowRoundUp(size_t s)
00079                 {  return(RoundUp(s + (s>=32768 ? 16384 : (s>>1))));  }
00080             
00083             void DownSizeIfNeeded(size_t s);
00084             
00086             void _EnsureSize(size_t s);
00088             void _DoTightenSize();
00089             
00092             inline void EnsureSize(size_t s)
00093                 {  if(asize<s)  _EnsureSize(s);  }
00094             
00097             inline void TightenSize()
00098                 {  if(asize>len+1)  _DoTightenSize();  }
00099             
00102             SData(const char *str);
00103             SData(const char *str,size_t len);
00106             SData(const SData &s);
00108             SData(size_t ensure_size);
00110             inline ~SData()   {  FREE(str);  }
00111         };
00112         
00113     private:
00115         SData *d;
00116         
00117         inline void _aqref() const  {  if(d) d->refcnt.inc();  }
00118         inline void _deref() const  {  if(d && d->refcnt.DecAndTest())  delete d;  }
00119         inline void _aqrefN() const  {  d->refcnt.inc();  }
00120         inline void _derefN() const  {  if(d->refcnt.DecAndTest())  delete d;  }
00121         
00128         inline void _detachN()
00129         {
00130             // I hope this does not make trouble with threads. 
00131             if(d->refcnt.val()==1)  return;  // We're the only user. 
00132             SData *d2=new SData(*d);  _derefN();  d=d2;  // NO _aqrefN()!
00133         }
00140         inline void _detach()  {  if(d)  _detachN();  }
00141         
00143         inline void _storeN(const char *str)
00144             {  d = new SData(str);  /* no _aqref()! */  }
00145         inline void _storeN(const char *str,size_t len)
00146             {  d = new SData(str,len);  /* no _aqref()! */  }
00147         inline void _storeN(const TLString &str)
00148             {  d = new SData(str);  /* no _aqref()! */  }
00149         
00151         inline void _referenceN(const TLString &str)
00152             {  str._aqref();  d=str.d;  }
00153         
00154     public:
00156         inline TLString() : d(NULL) {}
00158         inline TLString(const char *str)
00159             {  d = str ? new SData(str) : NULL; /* NO _aqref();*/  }
00161         inline TLString(const TLString &s)  {  s._aqref();  d=s.d;  }
00163         TLString(const char *strA,const char *strB);
00165         TLString(const char *strA,const TLString &strB);
00167         TLString(const TLString &strA,const char *strB);
00169         TLString(const TLString &strA,const TLString &strB);
00171         inline ~TLString()  {  _deref();  /*d=NULL;*/  }
00172         
00174         inline TLString &operator=(const TLString &s)
00175             {  _deref();  s._aqref();  d=s.d;  return(*this);  }
00176         
00178         inline TLString &operator=(const char *str)   //  vv-- no _aqref()!
00179             {  _deref();  d = str ? new SData(str) : NULL;  return(*this);  }
00181         inline void assign(const char *str,size_t len)
00182             {  _deref();  d = str ? new SData(str,len) : NULL;  }
00183         
00185         inline void deref()  {  _deref();  d=NULL;  }
00186         
00188         inline bool operator!() const  {  return(!d);  }
00190         inline operator bool() const  {  return((bool)d);  }
00191         
00193         inline size_t length() const
00194             {  return(d ? d->len : 0);  }
00195         
00203         inline const char *str() const
00204             {  return(d ? d->str : NULL);  }
00205         
00207         inline char operator[](size_t idx) const  // FIXME: check me ("race")
00208             {  return(d && idx<d->len ? d->str[idx] : '\0');  }
00209         
00211         void append(const char *str);
00213         void append(const char *str,size_t len);
00215         inline TLString &operator+=(const char *str)
00216             {  append(str);  return(*this);  }
00217         
00219         void append(const TLString &str);
00221         inline TLString &operator+=(const TLString &str)
00222             {  append(str);  return(*this);  }
00223         
00225         void prepend(const char *str);
00227         void prepend(const TLString &str);
00228         
00241         void sprintf(const char *fmt,...) _fnformat_(__printf__,2,3);
00243         void vsprintf(const char *fmt,va_list ap);
00244         
00310         static TLString ParseString(const char *instr,ssize_t inlen,
00311             SError &error);
00312         
00322         void trunc(size_t len,bool do_not_shrink=0);
00323         
00325         void skip(size_t n);
00326         
00336         int zero();
00337         
00344         ssize_t index(char c) const;
00351         ssize_t rindex(char c) const;
00352         
00355         ssize_t find(const char *str) const;
00356         ssize_t find(const TLString &str) const;
00357         
00359         ssize_t rfind(const char *str) const;
00360         ssize_t rfind(const TLString &str) const;
00361         
00373         size_t TightenSize();
00374         
00375         friend bool operator==(const TLString &strA,const TLString &strB);
00376         friend bool operator==(const TLString &strA,const char *strB);
00377         
00378         friend bool operator<(const TLString &strA,const TLString &strB);
00379         friend bool operator<(const TLString &strA,const char *strB);
00380         friend bool operator>(const TLString &strA,const char *strB);
00381         friend bool operator<=(const TLString &strA,const TLString &strB);
00382         friend bool operator<=(const TLString &strA,const char *strB);
00383         friend bool operator>=(const TLString &strA,const char *strB);
00384         
00393         int compare(const TLString &strB);
00394 };
00395 
00397 inline TLString operator+(const TLString &strA,const TLString &strB)
00398     {  return(TLString(strA,strB));  }
00400 inline TLString operator+(const TLString &strA,const char *strB)
00401     {  return(TLString(strA,strB));  }
00403 inline TLString operator+(const char *strA,const TLString &strB)
00404     {  return(TLString(strA,strB));  }
00405 //inline TLString operator+(const char *strA,const char *strB)
00406 //  {  return(TLString(strA,strB));  }
00407 
00414 
00415 bool operator==(const TLString &strA,const TLString &strB);
00416 bool operator==(const TLString &strA,const char *strB);
00417 inline bool operator==(const char *strA,const TLString &strB)
00418     {  return(operator==(strB,strA));  }
00420 
00427 
00428 inline bool operator!=(const TLString &strA,const TLString &strB)
00429     {  return(!operator==(strA,strB));  }
00430 inline bool operator!=(const TLString &strA,const char *strB)
00431     {  return(!operator==(strA,strB));  }
00432 inline bool operator!=(const char *strA,const TLString &strB)
00433     {  return(operator!=(strB,strA));  }
00435 
00439 
00440 bool operator<(const TLString &strA,const TLString &strB);
00441 inline bool operator>(const TLString &strA,const TLString &strB)
00442     {  return(operator<(strB,strA));  }
00443 
00444 bool operator<(const TLString &strA,const char *strB);
00445 bool operator>(const TLString &strA,const char *strB);
00446 inline bool operator<(const char *strA,const TLString &strB)
00447     {  return(operator>(strB,strA));  }
00448 inline bool operator>(const char *strA,const TLString &strB)
00449     {  return(operator<(strB,strA));  }
00450 
00451 bool operator<=(const TLString &strA,const TLString &strB);
00452 inline bool operator>=(const TLString &strA,const TLString &strB)
00453     {  return(operator<=(strB,strA));  }
00454 
00455 bool operator<=(const TLString &strA,const char *strB);
00456 bool operator>=(const TLString &strA,const char *strB);
00457 inline bool operator<=(const char *strA,const TLString &strB)
00458     {  return(operator>=(strB,strA));  }
00459 inline bool operator>=(const char *strA,const TLString &strB)
00460     {  return(operator<=(strB,strA));  }
00462 
00463 #endif  /* _TemplateLibrary_TLString_H_ */

Generated on Sat Feb 19 22:33:46 2005 for Ray by doxygen 1.3.5