1 // @(#)root/base:$Id$ 2 // Author: Fons Rademakers 04/08/95 3 4 /************************************************************************* 5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. * 6 * All rights reserved. * 7 * * 8 * For the licensing terms see $ROOTSYS/LICENSE. * 9 * For the list of contributors see $ROOTSYS/README/CREDITS. * 10 *************************************************************************/ 11 12 #ifndef ROOT_TString 13 #define ROOT_TString 14 15 16 ////////////////////////////////////////////////////////////////////////// 17 // // 18 // TString // 19 // // 20 // Basic string class. // 21 // // 22 // Cannot be stored in a TCollection... use TObjString instead. // 23 // // 24 ////////////////////////////////////////////////////////////////////////// 25 26 #ifndef __CINT__ 27 #include <string.h> 28 #include <stdio.h> 29 #endif 30 31 #ifndef ROOT_Riosfwd 32 #include "Riosfwd.h" 33 #endif 34 35 #ifndef ROOT_TMathBase 36 #include "TMathBase.h" 37 #endif 38 39 #include <stdarg.h> 40 #include <string> 41 42 #ifdef R__GLOBALSTL 43 namespace std { using ::string; } 44 #endif 45 46 class TRegexp; 47 class TPRegexp; 48 class TString; 49 class TSubString; 50 class TObjArray; 51 class TVirtualMutex; 52 class TBufferFile; 53 54 R__EXTERN TVirtualMutex *gStringMutex; 55 56 TString operator+(const TString &s1, const TString &s2); 57 TString operator+(const TString &s, const char *cs); 58 TString operator+(const char *cs, const TString &s); 59 TString operator+(const TString &s, char c); 60 TString operator+(const TString &s, Long_t i); 61 TString operator+(const TString &s, ULong_t i); 62 TString operator+(const TString &s, Long64_t i); 63 TString operator+(const TString &s, ULong64_t i); 64 TString operator+(char c, const TString &s); 65 TString operator+(Long_t i, const TString &s); 66 TString operator+(ULong_t i, const TString &s); 67 TString operator+(Long64_t i, const TString &s); 68 TString operator+(ULong64_t i, const TString &s); 69 Bool_t operator==(const TString &s1, const TString &s2); 70 Bool_t operator==(const TString &s1, const char *s2); 71 Bool_t operator==(const TSubString &s1, const TSubString &s2); 72 Bool_t operator==(const TSubString &s1, const TString &s2); 73 Bool_t operator==(const TSubString &s1, const char *s2); 74 75 76 ////////////////////////////////////////////////////////////////////////// 77 // // 78 // TSubString // 79 // // 80 // The TSubString class allows selected elements to be addressed. // 81 // There are no public constructors. // 82 // // 83 ////////////////////////////////////////////////////////////////////////// 84 class TSubString { 85 86 friend class TStringLong; 87 friend class TString; 88 89 friend Bool_t operator==(const TSubString &s1, const TSubString &s2); 90 friend Bool_t operator==(const TSubString &s1, const TString &s2); 91 friend Bool_t operator==(const TSubString &s1, const char *s2); 92 93 private: 94 TString &fStr; // Referenced string 95 Ssiz_t fBegin; // Index of starting character 96 Ssiz_t fExtent; // Length of TSubString 97 98 // NB: the only constructor is private 99 TSubString(const TString &s, Ssiz_t start, Ssiz_t len); 100 101 protected: 102 void SubStringError(Ssiz_t, Ssiz_t, Ssiz_t) const; 103 void AssertElement(Ssiz_t i) const; // Verifies i is valid index 104 105 public: 106 TSubString(const TSubString &s) 107 : fStr(s.fStr), fBegin(s.fBegin), fExtent(s.fExtent) { } 108 109 TSubString &operator=(const char *s); // Assignment from a char* 110 TSubString &operator=(const TString &s); // Assignment from a TString 111 TSubString &operator=(const TSubString &s); // Assignment from a TSubString 112 char &operator()(Ssiz_t i); // Index with optional bounds checking 113 char &operator[](Ssiz_t i); // Index with bounds checking 114 char operator()(Ssiz_t i) const; // Index with optional bounds checking 115 char operator[](Ssiz_t i) const; // Index with bounds checking 116 117 const char *Data() const; 118 Ssiz_t Length() const { return fExtent; } 119 Ssiz_t Start() const { return fBegin; } 120 TString& String() { return fStr; } 121 void ToLower(); // Convert self to lower-case 122 void ToUpper(); // Convert self to upper-case 123 124 // For detecting null substrings 125 Bool_t IsNull() const { return fBegin == kNPOS; } 126 int operator!() const { return fBegin == kNPOS; } 127 }; 128 129 130 ////////////////////////////////////////////////////////////////////////// 131 // // 132 // TString // 133 // // 134 ////////////////////////////////////////////////////////////////////////// 135 class TString { 136 137 friend class TStringLong; 138 friend class TSubString; 139 friend class TBufferFile; 140 141 friend TString operator+(const TString &s1, const TString &s2); 142 friend TString operator+(const TString &s, const char *cs); 143 friend TString operator+(const char *cs, const TString &s); 144 friend TString operator+(const TString &s, char c); 145 friend TString operator+(const TString &s, Long_t i); 146 friend TString operator+(const TString &s, ULong_t i); 147 friend TString operator+(const TString &s, Long64_t i); 148 friend TString operator+(const TString &s, ULong64_t i); 149 friend TString operator+(char c, const TString &s); 150 friend TString operator+(Long_t i, const TString &s); 151 friend TString operator+(ULong_t i, const TString &s); 152 friend TString operator+(Long64_t i, const TString &s); 153 friend TString operator+(ULong64_t i, const TString &s); 154 friend Bool_t operator==(const TString &s1, const TString &s2); 155 friend Bool_t operator==(const TString &s1, const char *s2); 156 157 private: 158 #ifdef R__BYTESWAP 159 enum { kShortMask = 0x01, kLongMask = 0x1 }; 160 #else 161 enum { kShortMask = 0x80, kLongMask = 0x80000000 }; 162 #endif 163 164 struct LongStr_t 165 { 166 Ssiz_t fCap; // Max string length (including null) 167 Ssiz_t fSize; // String length (excluding null) 168 char *fData; // Long string data 169 }; 170 171 enum { kMinCap = (sizeof(LongStr_t) - 1)/sizeof(char) > 2 ? 172 (sizeof(LongStr_t) - 1)/sizeof(char) : 2 }; 173 174 struct ShortStr_t 175 { 176 unsigned char fSize; // String length (excluding null) 177 char fData[kMinCap]; // Short string data 178 }; 179 180 union UStr_t { LongStr_t fL; ShortStr_t fS; }; 181 182 enum { kNwords = sizeof(UStr_t) / sizeof(Ssiz_t)}; 183 184 struct RawStr_t 185 { 186 Ssiz_t fWords[kNwords]; 187 }; 188 189 struct Rep_t 190 { 191 union 192 { 193 LongStr_t fLong; 194 ShortStr_t fShort; 195 RawStr_t fRaw; 196 }; 197 }; 198 199 protected: 200 #ifndef __CINT__ 201 Rep_t fRep; // String data 202 #endif 203 204 // Special concatenation constructor 205 TString(const char *a1, Ssiz_t n1, const char *a2, Ssiz_t n2); 206 void AssertElement(Ssiz_t nc) const; // Index in range 207 void Clobber(Ssiz_t nc); // Remove old contents 208 void InitChar(char c); // Initialize from char 209 210 enum { kAlignment = 16 }; 211 static Ssiz_t Align(Ssiz_t s) { return (s + (kAlignment-1)) & ~(kAlignment-1); } 212 static Ssiz_t Recommend(Ssiz_t s) { return (s < kMinCap ? kMinCap : Align(s+1)) - 1; } 213 static Ssiz_t AdjustCapacity(Ssiz_t oldCap, Ssiz_t newCap); 214 215 private: 216 Bool_t IsLong() const { return Bool_t(fRep.fShort.fSize & kShortMask); } 217 #ifdef R__BYTESWAP 218 void SetShortSize(Ssiz_t s) { fRep.fShort.fSize = (unsigned char)(s << 1); } 219 Ssiz_t GetShortSize() const { return fRep.fShort.fSize >> 1; } 220 #else 221 void SetShortSize(Ssiz_t s) { fRep.fShort.fSize = (unsigned char)s; } 222 Ssiz_t GetShortSize() const { return fRep.fShort.fSize; } 223 #endif 224 void SetLongSize(Ssiz_t s) { fRep.fLong.fSize = s; } 225 Ssiz_t GetLongSize() const { return fRep.fLong.fSize; } 226 void SetSize(Ssiz_t s) { IsLong() ? SetLongSize(s) : SetShortSize(s); } 227 void SetLongCap(Ssiz_t s) { fRep.fLong.fCap = kLongMask | s; } 228 Ssiz_t GetLongCap() const { return fRep.fLong.fCap & ~kLongMask; } 229 void SetLongPointer(char *p) { fRep.fLong.fData = p; } 230 char *GetLongPointer() { return fRep.fLong.fData; } 231 const char *GetLongPointer() const { return fRep.fLong.fData; } 232 char *GetShortPointer() { return fRep.fShort.fData; } 233 const char *GetShortPointer() const { return fRep.fShort.fData; } 234 char *GetPointer() { return IsLong() ? GetLongPointer() : GetShortPointer(); } 235 const char *GetPointer() const { return IsLong() ? GetLongPointer() : GetShortPointer(); } 236 #ifdef R__BYTESWAP 237 static Ssiz_t MaxSize() { return kMaxInt - 1; } 238 #else 239 static Ssiz_t MaxSize() { return (kMaxInt >> 1) - 1; } 240 #endif 241 void UnLink() const { if (IsLong()) delete [] fRep.fLong.fData; } 242 void Zero() { 243 Ssiz_t (&a)[kNwords] = fRep.fRaw.fWords; 244 for (UInt_t i = 0; i < kNwords; ++i) 245 a[i] = 0; 246 } 247 char *Init(Ssiz_t capacity, Ssiz_t nchar); 248 void Clone(Ssiz_t nc); // Make self a distinct copy w. capacity nc 249 void FormImp(const char *fmt, va_list ap); 250 UInt_t HashCase() const; 251 UInt_t HashFoldCase() const; 252 253 public: 254 enum EStripType { kLeading = 0x1, kTrailing = 0x2, kBoth = 0x3 }; 255 enum ECaseCompare { kExact, kIgnoreCase }; 256 257 TString(); // Null string 258 explicit TString(Ssiz_t ic); // Suggested capacity 259 TString(const TString &s); // Copy constructor 260 TString(const char *s); // Copy to embedded null 261 TString(const char *s, Ssiz_t n); // Copy past any embedded nulls 262 TString(const std::string &s); 263 TString(char c); 264 TString(char c, Ssiz_t s); 265 TString(const TSubString &sub); 266 267 virtual ~TString(); 268 269 // ROOT I/O interface 270 virtual void FillBuffer(char *&buffer) const; 271 virtual void ReadBuffer(char *&buffer); 272 virtual Int_t Sizeof() const; 273 274 static TString *ReadString(TBuffer &b, const TClass *clReq); 275 static void WriteString(TBuffer &b, const TString *a); 276 277 friend TBuffer &operator<<(TBuffer &b, const TString *obj); 278 279 // C I/O interface 280 Bool_t Gets(FILE *fp, Bool_t chop=kTRUE); 281 void Puts(FILE *fp); 282 283 // Type conversion 284 operator const char*() const { return GetPointer(); } 285 286 // Assignment 287 TString &operator=(char s); // Replace string 288 TString &operator=(const char *s); 289 TString &operator=(const TString &s); 290 TString &operator=(const std::string &s); 291 TString &operator=(const TSubString &s); 292 TString &operator+=(const char *s); // Append string 293 TString &operator+=(const TString &s); 294 TString &operator+=(char c); 295 TString &operator+=(Short_t i); 296 TString &operator+=(UShort_t i); 297 TString &operator+=(Int_t i); 298 TString &operator+=(UInt_t i); 299 TString &operator+=(Long_t i); 300 TString &operator+=(ULong_t i); 301 TString &operator+=(Float_t f); 302 TString &operator+=(Double_t f); 303 TString &operator+=(Long64_t i); 304 TString &operator+=(ULong64_t i); 305 306 // Indexing operators 307 char &operator[](Ssiz_t i); // Indexing with bounds checking 308 char &operator()(Ssiz_t i); // Indexing with optional bounds checking 309 char operator[](Ssiz_t i) const; 310 char operator()(Ssiz_t i) const; 311 TSubString operator()(Ssiz_t start, Ssiz_t len) const; // Sub-string operator 312 TSubString operator()(const TRegexp &re) const; // Match the RE 313 TSubString operator()(const TRegexp &re, Ssiz_t start) const; 314 TSubString operator()(TPRegexp &re) const; // Match the Perl compatible Regular Expression 315 TSubString operator()(TPRegexp &re, Ssiz_t start) const; 316 TSubString SubString(const char *pat, Ssiz_t start = 0, 317 ECaseCompare cmp = kExact) const; 318 319 // Non-static member functions 320 TString &Append(const char *cs); 321 TString &Append(const char *cs, Ssiz_t n); 322 TString &Append(const TString &s); 323 TString &Append(const TString &s, Ssiz_t n); 324 TString &Append(char c, Ssiz_t rep = 1); // Append c rep times 325 Int_t Atoi() const; 326 Long64_t Atoll() const; 327 Double_t Atof() const; 328 Bool_t BeginsWith(const char *s, ECaseCompare cmp = kExact) const; 329 Bool_t BeginsWith(const TString &pat, ECaseCompare cmp = kExact) const; 330 Ssiz_t Capacity() const { return (IsLong() ? GetLongCap() : kMinCap) - 1; } 331 Ssiz_t Capacity(Ssiz_t n); 332 TString &Chop(); 333 void Clear(); 334 int CompareTo(const char *cs, ECaseCompare cmp = kExact) const; 335 int CompareTo(const TString &st, ECaseCompare cmp = kExact) const; 336 Bool_t Contains(const char *pat, ECaseCompare cmp = kExact) const; 337 Bool_t Contains(const TString &pat, ECaseCompare cmp = kExact) const; 338 Bool_t Contains(const TRegexp &pat) const; 339 Bool_t Contains(TPRegexp &pat) const; 340 Int_t CountChar(Int_t c) const; 341 TString Copy() const; 342 const char *Data() const { return GetPointer(); } 343 Bool_t EndsWith(const char *pat, ECaseCompare cmp = kExact) const; 344 Bool_t EqualTo(const char *cs, ECaseCompare cmp = kExact) const; 345 Bool_t EqualTo(const TString &st, ECaseCompare cmp = kExact) const; 346 Ssiz_t First(char c) const; 347 Ssiz_t First(const char *cs) const; 348 void Form(const char *fmt, ...) 349 #if defined(__GNUC__) && !defined(__CINT__) 350 __attribute__((format(printf, 2, 3))) /* 1 is the this pointer */ 351 #endif 352 ; 353 UInt_t Hash(ECaseCompare cmp = kExact) const; 354 Ssiz_t Index(const char *pat, Ssiz_t i = 0, 355 ECaseCompare cmp = kExact) const; 356 Ssiz_t Index(const TString &s, Ssiz_t i = 0, 357 ECaseCompare cmp = kExact) const; 358 Ssiz_t Index(const char *pat, Ssiz_t patlen, Ssiz_t i, 359 ECaseCompare cmp) const; 360 Ssiz_t Index(const TString &s, Ssiz_t patlen, Ssiz_t i, 361 ECaseCompare cmp) const; 362 Ssiz_t Index(const TRegexp &pat, Ssiz_t i = 0) const; 363 Ssiz_t Index(const TRegexp &pat, Ssiz_t *ext, Ssiz_t i = 0) const; 364 Ssiz_t Index(TPRegexp &pat, Ssiz_t i = 0) const; 365 Ssiz_t Index(TPRegexp &pat, Ssiz_t *ext, Ssiz_t i = 0) const; 366 TString &Insert(Ssiz_t pos, const char *s); 367 TString &Insert(Ssiz_t pos, const char *s, Ssiz_t extent); 368 TString &Insert(Ssiz_t pos, const TString &s); 369 TString &Insert(Ssiz_t pos, const TString &s, Ssiz_t extent); 370 Bool_t IsAscii() const; 371 Bool_t IsAlpha() const; 372 Bool_t IsAlnum() const; 373 Bool_t IsDigit() const; 374 Bool_t IsFloat() const; 375 Bool_t IsHex() const; 376 Bool_t IsBin() const; 377 Bool_t IsOct() const; 378 Bool_t IsDec() const; 379 Bool_t IsInBaseN(Int_t base) const; 380 Bool_t IsNull() const { return Length() == 0; } 381 Bool_t IsWhitespace() const { return (Length() == CountChar(' ')); } 382 Ssiz_t Last(char c) const; 383 Ssiz_t Length() const { return IsLong() ? GetLongSize() : GetShortSize(); } 384 Bool_t MaybeRegexp() const; 385 Bool_t MaybeWildcard() const; 386 TString MD5() const; 387 TString &Prepend(const char *cs); // Prepend a character string 388 TString &Prepend(const char *cs, Ssiz_t n); 389 TString &Prepend(const TString &s); 390 TString &Prepend(const TString &s, Ssiz_t n); 391 TString &Prepend(char c, Ssiz_t rep = 1); // Prepend c rep times 392 istream &ReadFile(istream &str); // Read to EOF or null character 393 istream &ReadLine(istream &str, 394 Bool_t skipWhite = kTRUE); // Read to EOF or newline 395 istream &ReadString(istream &str); // Read to EOF or null character 396 istream &ReadToDelim(istream &str, char delim = '\n'); // Read to EOF or delimitor 397 istream &ReadToken(istream &str); // Read separated by white space 398 TString &Remove(Ssiz_t pos); // Remove pos to end of string 399 TString &Remove(Ssiz_t pos, Ssiz_t n); // Remove n chars starting at pos 400 TString &Remove(EStripType s, char c); // Like Strip() but changing string directly 401 TString &Replace(Ssiz_t pos, Ssiz_t n, const char *s); 402 TString &Replace(Ssiz_t pos, Ssiz_t n, const char *s, Ssiz_t ns); 403 TString &Replace(Ssiz_t pos, Ssiz_t n, const TString &s); 404 TString &Replace(Ssiz_t pos, Ssiz_t n1, const TString &s, Ssiz_t n2); 405 TString &ReplaceAll(const TString &s1, const TString &s2); // Find&Replace all s1 with s2 if any 406 TString &ReplaceAll(const TString &s1, const char *s2); // Find&Replace all s1 with s2 if any 407 TString &ReplaceAll(const char *s1, const TString &s2); // Find&Replace all s1 with s2 if any 408 TString &ReplaceAll(const char *s1, const char *s2); // Find&Replace all s1 with s2 if any 409 TString &ReplaceAll(const char *s1, Ssiz_t ls1, const char *s2, Ssiz_t ls2); // Find&Replace all s1 with s2 if any 410 void Resize(Ssiz_t n); // Truncate or add blanks as necessary 411 TSubString Strip(EStripType s = kTrailing, char c = ' ') const; 412 void ToLower(); // Change self to lower-case 413 void ToUpper(); // Change self to upper-case 414 TObjArray *Tokenize(const TString &delim) const; 415 Bool_t Tokenize(TString &tok, Ssiz_t &from, const char *delim = " ") const; 416 417 // Static member functions 418 static UInt_t Hash(const void *txt, Int_t ntxt); // Calculates hash index from any char string. 419 static Ssiz_t InitialCapacity(Ssiz_t ic = 15); // Initial allocation capacity 420 static Ssiz_t MaxWaste(Ssiz_t mw = 15); // Max empty space before reclaim 421 static Ssiz_t ResizeIncrement(Ssiz_t ri = 16); // Resizing increment 422 static Ssiz_t GetInitialCapacity(); 423 static Ssiz_t GetResizeIncrement(); 424 static Ssiz_t GetMaxWaste(); 425 static TString Itoa ( Int_t value, Int_t base); // Converts int to string with respect to the base specified (2-36) 426 static TString UItoa ( UInt_t value, Int_t base); 427 static TString LLtoa ( Long64_t value, Int_t base); 428 static TString ULLtoa (ULong64_t value, Int_t base); 429 static TString BaseConvert(const TString& s_in, Int_t base_in, Int_t base_out); // Converts string from base base_in to base base_out (supported bases 2-36) 430 static TString Format(const char *fmt, ...) 431 #if defined(__GNUC__) && !defined(__CINT__) 432 __attribute__((format(printf, 1, 2))) 433 #endif 434 ; 435 436 ClassDef(TString,2) //Basic string class 437 }; 438 439 // Related global functions 440 istream &operator>>(istream &str, TString &s); 441 ostream &operator<<(ostream &str, const TString &s); 442 #if defined(R__TEMPLATE_OVERLOAD_BUG) 443 template <> 444 #endif 445 TBuffer &operator>>(TBuffer &buf, TString *&sp); 446 447 TString ToLower(const TString &s); // Return lower-case version of argument 448 TString ToUpper(const TString &s); // Return upper-case version of argument 449 450 inline UInt_t Hash(const TString &s) { return s.Hash(); } 451 inline UInt_t Hash(const TString *s) { return s->Hash(); } 452 UInt_t Hash(const char *s); 453 454 extern char *Form(const char *fmt, ...) // format in circular buffer 455 #if defined(__GNUC__) && !defined(__CINT__) 456 __attribute__((format(printf, 1, 2))) 457 #endif 458 ; 459 extern void Printf(const char *fmt, ...) // format and print 460 #if defined(__GNUC__) && !defined(__CINT__) 461 __attribute__((format(printf, 1, 2))) 462 #endif 463 ; 464 extern char *Strip(const char *str, char c = ' '); // strip c off str, free with delete [] 465 extern char *StrDup(const char *str); // duplicate str, free with delete [] 466 extern char *Compress(const char *str); // remove blanks from string, free with delele [] 467 extern int EscChar(const char *src, char *dst, int dstlen, char *specchars, 468 char escchar); // copy from src to dst escaping specchars by escchar 469 extern int UnEscChar(const char *src, char *dst, int dstlen, char *specchars, 470 char escchar); // copy from src to dst removing escchar from specchars 471 472 #ifdef NEED_STRCASECMP 473 extern int strcasecmp(const char *str1, const char *str2); 474 extern int strncasecmp(const char *str1, const char *str2, Ssiz_t n); 475 #endif 476 477 ////////////////////////////////////////////////////////////////////////// 478 // // 479 // Inlines // 480 // // 481 ////////////////////////////////////////////////////////////////////////// 482 483 inline TString &TString::Append(const char *cs) 484 { return Replace(Length(), 0, cs, cs ? strlen(cs) : 0); } 485 486 inline TString &TString::Append(const char *cs, Ssiz_t n) 487 { return Replace(Length(), 0, cs, n); } 488 489 inline TString &TString::Append(const TString &s) 490 { return Replace(Length(), 0, s.Data(), s.Length()); } 491 492 inline TString &TString::Append(const TString &s, Ssiz_t n) 493 { return Replace(Length(), 0, s.Data(), TMath::Min(n, s.Length())); } 494 495 inline TString &TString::operator+=(const char *cs) 496 { return Append(cs, cs ? strlen(cs) : 0); } 497 498 inline TString &TString::operator+=(const TString &s) 499 { return Append(s.Data(), s.Length()); } 500 501 inline TString &TString::operator+=(char c) 502 { return Append(c); } 503 504 inline TString &TString::operator+=(Long_t i) 505 { char s[32]; sprintf(s, "%ld", i); return operator+=(s); } 506 507 inline TString &TString::operator+=(ULong_t i) 508 { char s[32]; sprintf(s, "%lu", i); return operator+=(s); } 509 510 inline TString &TString::operator+=(Short_t i) 511 { return operator+=((Long_t) i); } 512 513 inline TString &TString::operator+=(UShort_t i) 514 { return operator+=((ULong_t) i); } 515 516 inline TString &TString::operator+=(Int_t i) 517 { return operator+=((Long_t) i); } 518 519 inline TString &TString::operator+=(UInt_t i) 520 { return operator+=((ULong_t) i); } 521 522 inline TString &TString::operator+=(Double_t f) 523 { 524 char s[32]; 525 // coverity[secure_coding] Buffer is large enough: width specified in format 526 sprintf(s, "%.17g", f); 527 return operator+=(s); 528 } 529 530 inline TString &TString::operator+=(Float_t f) 531 { return operator+=((Double_t) f); } 532 533 inline TString &TString::operator+=(Long64_t l) 534 { 535 char s[32]; 536 // coverity[secure_coding] Buffer is large enough (2^64 = 20 digits). 537 sprintf(s, "%lld", l); 538 return operator+=(s); 539 } 540 541 inline TString &TString::operator+=(ULong64_t ul) 542 { 543 char s[32]; 544 // coverity[secure_coding] Buffer is large enough (2^64 = 20 digits). 545 sprintf(s, "%llu", ul); 546 return operator+=(s); 547 } 548 549 inline Bool_t TString::BeginsWith(const char *s, ECaseCompare cmp) const 550 { return Index(s, s ? strlen(s) : (Ssiz_t)0, (Ssiz_t)0, cmp) == 0; } 551 552 inline Bool_t TString::BeginsWith(const TString &pat, ECaseCompare cmp) const 553 { return Index(pat.Data(), pat.Length(), (Ssiz_t)0, cmp) == 0; } 554 555 inline Bool_t TString::Contains(const TString &pat, ECaseCompare cmp) const 556 { return Index(pat.Data(), pat.Length(), (Ssiz_t)0, cmp) != kNPOS; } 557 558 inline Bool_t TString::Contains(const char *s, ECaseCompare cmp) const 559 { return Index(s, s ? strlen(s) : 0, (Ssiz_t)0, cmp) != kNPOS; } 560 561 inline Bool_t TString::Contains(const TRegexp &pat) const 562 { return Index(pat, (Ssiz_t)0) != kNPOS; } 563 564 inline Bool_t TString::Contains(TPRegexp &pat) const 565 { return Index(pat, (Ssiz_t)0) != kNPOS; } 566 567 inline Bool_t TString::EqualTo(const char *cs, ECaseCompare cmp) const 568 { return (CompareTo(cs, cmp) == 0) ? kTRUE : kFALSE; } 569 570 inline Bool_t TString::EqualTo(const TString &st, ECaseCompare cmp) const 571 { return (CompareTo(st, cmp) == 0) ? kTRUE : kFALSE; } 572 573 inline Ssiz_t TString::Index(const char *s, Ssiz_t i, ECaseCompare cmp) const 574 { return Index(s, s ? strlen(s) : 0, i, cmp); } 575 576 inline Ssiz_t TString::Index(const TString &s, Ssiz_t i, ECaseCompare cmp) const 577 { return Index(s.Data(), s.Length(), i, cmp); } 578 579 inline Ssiz_t TString::Index(const TString &pat, Ssiz_t patlen, Ssiz_t i, 580 ECaseCompare cmp) const 581 { return Index(pat.Data(), patlen, i, cmp); } 582 583 inline TString &TString::Insert(Ssiz_t pos, const char *cs) 584 { return Replace(pos, 0, cs, cs ? strlen(cs) : 0); } 585 586 inline TString &TString::Insert(Ssiz_t pos, const char *cs, Ssiz_t n) 587 { return Replace(pos, 0, cs, n); } 588 589 inline TString &TString::Insert(Ssiz_t pos, const TString &s) 590 { return Replace(pos, 0, s.Data(), s.Length()); } 591 592 inline TString &TString::Insert(Ssiz_t pos, const TString &s, Ssiz_t n) 593 { return Replace(pos, 0, s.Data(), TMath::Min(n, s.Length())); } 594 595 inline TString &TString::Prepend(const char *cs) 596 { return Replace(0, 0, cs, cs ? strlen(cs) : 0); } 597 598 inline TString &TString::Prepend(const char *cs, Ssiz_t n) 599 { return Replace(0, 0, cs, n); } 600 601 inline TString &TString::Prepend(const TString &s) 602 { return Replace(0, 0, s.Data(), s.Length()); } 603 604 inline TString &TString::Prepend(const TString &s, Ssiz_t n) 605 { return Replace(0, 0, s.Data(), TMath::Min(n, s.Length())); } 606 607 inline TString &TString::Remove(Ssiz_t pos) 608 { return Replace(pos, TMath::Max(0, Length()-pos), 0, 0); } 609 610 inline TString &TString::Remove(Ssiz_t pos, Ssiz_t n) 611 { return Replace(pos, n, 0, 0); } 612 613 inline TString &TString::Chop() 614 { return Remove(TMath::Max(0, Length()-1)); } 615 616 inline TString &TString::Replace(Ssiz_t pos, Ssiz_t n, const char *cs) 617 { return Replace(pos, n, cs, cs ? strlen(cs) : 0); } 618 619 inline TString &TString::Replace(Ssiz_t pos, Ssiz_t n, const TString& s) 620 { return Replace(pos, n, s.Data(), s.Length()); } 621 622 inline TString &TString::Replace(Ssiz_t pos, Ssiz_t n1, const TString &s, 623 Ssiz_t n2) 624 { return Replace(pos, n1, s.Data(), TMath::Min(s.Length(), n2)); } 625 626 inline TString &TString::ReplaceAll(const TString &s1, const TString &s2) 627 { return ReplaceAll(s1.Data(), s1.Length(), s2.Data(), s2.Length()) ; } 628 629 inline TString &TString::ReplaceAll(const TString &s1, const char *s2) 630 { return ReplaceAll(s1.Data(), s1.Length(), s2, s2 ? strlen(s2) : 0); } 631 632 inline TString &TString::ReplaceAll(const char *s1, const TString &s2) 633 { return ReplaceAll(s1, s1 ? strlen(s1) : 0, s2.Data(), s2.Length()); } 634 635 inline TString &TString::ReplaceAll(const char *s1,const char *s2) 636 { return ReplaceAll(s1, s1 ? strlen(s1) : 0, s2, s2 ? strlen(s2) : 0); } 637 638 inline char &TString::operator()(Ssiz_t i) 639 { return GetPointer()[i]; } 640 641 inline char TString::operator()(Ssiz_t i) const 642 { return GetPointer()[i]; } 643 644 inline char &TString::operator[](Ssiz_t i) 645 { AssertElement(i); return GetPointer()[i]; } 646 647 inline char TString::operator[](Ssiz_t i) const 648 { AssertElement(i); return GetPointer()[i]; } 649 650 inline const char *TSubString::Data() const 651 { 652 // Return a pointer to the beginning of the substring. Note that the 653 // terminating null is in the same place as for the original 654 // TString, so this method is not appropriate for converting the 655 // TSubString to a string. To do that, construct a TString from the 656 // TSubString. For example: 657 // 658 // root [0] TString s("hello world") 659 // root [1] TSubString sub=s(0, 5) 660 // root [2] sub.Data() 661 // (const char* 0x857c8b8)"hello world" 662 // root [3] TString substr(sub) 663 // root [4] substr 664 // (class TString)"hello" 665 666 return fStr.Data() + fBegin; 667 } 668 669 // Access to elements of sub-string with bounds checking 670 inline char TSubString::operator[](Ssiz_t i) const 671 { AssertElement(i); return fStr.GetPointer()[fBegin+i]; } 672 673 inline char TSubString::operator()(Ssiz_t i) const 674 { return fStr.GetPointer()[fBegin+i]; } 675 676 inline TSubString &TSubString::operator=(const TSubString &s) 677 { fStr = s.fStr; fBegin = s.fBegin; fExtent = s.fExtent; return *this; } 678 679 680 // String Logical operators 681 inline Bool_t operator==(const TString &s1, const TString &s2) 682 { 683 return ((s1.Length() == s2.Length()) && 684 !memcmp(s1.Data(), s2.Data(), s1.Length())); 685 } 686 687 inline Bool_t operator!=(const TString &s1, const TString &s2) 688 { return !(s1 == s2); } 689 690 inline Bool_t operator<(const TString &s1, const TString &s2) 691 { return s1.CompareTo(s2) < 0; } 692 693 inline Bool_t operator>(const TString &s1, const TString &s2) 694 { return s1.CompareTo(s2) > 0; } 695 696 inline Bool_t operator<=(const TString &s1, const TString &s2) 697 { return s1.CompareTo(s2) <= 0; } 698 699 inline Bool_t operator>=(const TString &s1, const TString &s2) 700 { return s1.CompareTo(s2) >= 0; } 701 702 // Bool_t operator==(const TString &s1, const char *s2); 703 inline Bool_t operator!=(const TString &s1, const char *s2) 704 { return !(s1 == s2); } 705 706 inline Bool_t operator<(const TString &s1, const char *s2) 707 { return s1.CompareTo(s2) < 0; } 708 709 inline Bool_t operator>(const TString &s1, const char *s2) 710 { return s1.CompareTo(s2) > 0; } 711 712 inline Bool_t operator<=(const TString &s1, const char *s2) 713 { return s1.CompareTo(s2) <= 0; } 714 715 inline Bool_t operator>=(const TString &s1, const char *s2) 716 { return s1.CompareTo(s2) >= 0; } 717 718 inline Bool_t operator==(const char *s1, const TString &s2) 719 { return (s2 == s1); } 720 721 inline Bool_t operator!=(const char *s1, const TString &s2) 722 { return !(s2 == s1); } 723 724 inline Bool_t operator<(const char *s1, const TString &s2) 725 { return s2.CompareTo(s1) > 0; } 726 727 inline Bool_t operator>(const char *s1, const TString &s2) 728 { return s2.CompareTo(s1) < 0; } 729 730 inline Bool_t operator<=(const char *s1, const TString &s2) 731 { return s2.CompareTo(s1) >= 0; } 732 733 inline Bool_t operator>=(const char *s1, const TString &s2) 734 { return s2.CompareTo(s1) <= 0; } 735 736 // SubString Logical operators 737 // Bool_t operator==(const TSubString &s1, const TSubString &s2); 738 // Bool_t operator==(const TSubString &s1, const char *s2); 739 // Bool_t operator==(const TSubString &s1, const TString &s2); 740 inline Bool_t operator==(const TString &s1, const TSubString &s2) 741 { return (s2 == s1); } 742 743 inline Bool_t operator==(const char *s1, const TSubString &s2) 744 { return (s2 == s1); } 745 746 inline Bool_t operator!=(const TSubString &s1, const char *s2) 747 { return !(s1 == s2); } 748 749 inline Bool_t operator!=(const TSubString &s1, const TString &s2) 750 { return !(s1 == s2); } 751 752 inline Bool_t operator!=(const TSubString &s1, const TSubString &s2) 753 { return !(s1 == s2); } 754 755 inline Bool_t operator!=(const TString &s1, const TSubString &s2) 756 { return !(s2 == s1); } 757 758 inline Bool_t operator!=(const char *s1, const TSubString &s2) 759 { return !(s2 == s1); } 760 761 #endif 762