00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef _TemplateLibrary_TLString_H_
00018 #define _TemplateLibrary_TLString_H_ 1
00019
00026 #include <lib/sconfig.h>
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
00038 class SError;
00039
00040
00053 class TLString
00054 {
00055 public:
00056
00057
00058
00059
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
00077
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
00131 if(d->refcnt.val()==1) return;
00132 SData *d2=new SData(*d); _derefN(); d=d2;
00133 }
00140 inline void _detach() { if(d) _detachN(); }
00141
00143 inline void _storeN(const char *str)
00144 { d = new SData(str); }
00145 inline void _storeN(const char *str,size_t len)
00146 { d = new SData(str,len); }
00147 inline void _storeN(const TLString &str)
00148 { d = new SData(str); }
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; }
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(); }
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)
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
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
00406
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