Logo ROOT   6.14/05
Reference Guide
TString.cxx
Go to the documentation of this file.
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 /** \class TString
13 \ingroup Base
14 
15 Basic string class.
16 
17 Cannot be stored in a TCollection... use TObjString instead.
18 
19 The underlying string is stored as a char* that can be accessed via
20 TString::Data().
21 TString provides Short String Optimization (SSO) so that short
22 strings (<15 on 64-bit and <11 on 32-bit) are contained in the
23 TString internal data structure without the need for mallocing the
24 required space.
25 
26 Substring operations are provided by the TSubString class, which
27 holds a reference to the original string and its data, along with
28 the offset and length of the substring. To retrieve the substring
29 as a TString, construct a TString from it, eg:
30 ~~~ {.cpp}
31  root [0] TString s("hello world")
32  root [1] TString s2( s(0,5) )
33  root [2] s2
34  (class TString)"hello"
35 ~~~
36 */
37 
38 #include <ROOT/RConfig.h>
39 #include <stdlib.h>
40 #include <ctype.h>
41 #include <list>
42 #include <algorithm>
43 
44 #include "Varargs.h"
45 #include "TString.h"
46 #include "TBuffer.h"
47 #include "TError.h"
48 #include "Bytes.h"
49 #include "TClass.h"
50 #include "TMD5.h"
51 #include "TObjArray.h"
52 #include "TObjString.h"
53 #include "TVirtualMutex.h"
54 #include "ThreadLocalStorage.h"
55 
56 
57 #if defined(R__WIN32)
58 #define strtoull _strtoui64
59 #endif
60 
61 #ifdef R__GLOBALSTL
62 namespace std { using ::list; }
63 #endif
64 
66 
67 // Amount to shift hash values to avoid clustering
68 const UInt_t kHashShift = 5;
69 
70 ////////////////////////////////////////////////////////////////////////////////
71 //
72 // In what follows, fCap is the length of the underlying representation
73 // vector. Hence, the capacity for a null terminated string held in this
74 // vector is fCap-1. The variable fSize is the length of the held
75 // string, excluding the terminating null.
76 //
77 // The algorithms make no assumptions about whether internal strings
78 // hold embedded nulls. However, they do assume that any string
79 // passed in as an argument that does not have a length count is null
80 // terminated and therefore has no embedded nulls.
81 //
82 // The internal string is always null terminated.
83 
84 ////////////////////////////////////////////////////////////////////////////////
85 /// TString default ctor.
86 
88 {
89  Zero();
90 }
91 
92 ////////////////////////////////////////////////////////////////////////////////
93 /// Create TString able to contain ic characters.
94 
96 {
97  Init(ic, 0);
98 }
99 
100 ////////////////////////////////////////////////////////////////////////////////
101 /// Create TString and initialize it with string cs.
102 
103 TString::TString(const char *cs)
104 {
105  if (cs) {
106  Ssiz_t n = strlen(cs);
107  char *data = Init(n, n);
108  memcpy(data, cs, n);
109  } else
110  Init(0, 0);
111 }
112 
113 ////////////////////////////////////////////////////////////////////////////////
114 /// Create TString and initialize it with string cs.
115 
116 TString::TString(const std::string &s)
117 {
118  Ssiz_t n = s.length();
119  char *data = Init(n, n);
120  memcpy(data, s.c_str(), n);
121 }
122 
123 ////////////////////////////////////////////////////////////////////////////////
124 /// Create TString and initialize it with the first n characters of cs.
125 
126 TString::TString(const char *cs, Ssiz_t n)
127 {
128  char *data = Init(n, n);
129  memcpy(data, cs, n);
130 }
131 
132 ////////////////////////////////////////////////////////////////////////////////
133 /// Initialize a string with a single character.
134 
136 {
137  char *data = Init(1, 1);
138  data[0] = c;
139 }
140 
141 ////////////////////////////////////////////////////////////////////////////////
142 /// Initialize a string with a single character.
143 
145 {
146  InitChar(c);
147 }
148 
149 ////////////////////////////////////////////////////////////////////////////////
150 /// Initialize the first n locations of a TString with character c.
151 
153 {
154  char *data = Init(n, n);
155  while (n--) data[n] = c;
156 }
157 
158 ////////////////////////////////////////////////////////////////////////////////
159 /// Copy constructor.
160 
162 {
163  if (!s.IsLong())
164  fRep.fRaw = s.fRep.fRaw;
165  else {
166  Ssiz_t n = s.GetLongSize();
167  char *data = Init(n, n);
168  memcpy(data, s.GetLongPointer(), n);
169  }
170 }
171 
172 ////////////////////////////////////////////////////////////////////////////////
173 /// Move constructor.
174 
176 {
177  // Short or long, all data is in fRaw.
178  fRep.fRaw = s.fRep.fRaw;
179  s.Init(0,0);
180 }
181 
182 ////////////////////////////////////////////////////////////////////////////////
183 /// Copy a std::string_view in a TString.
184 
186 {
187  Ssiz_t len = substr.length();
188  char *data = Init(len, len);
189  memcpy(data, substr.data(), len);
190 }
191 
192 ////////////////////////////////////////////////////////////////////////////////
193 /// Copy a TSubString in a TString.
194 
196 {
197  Ssiz_t len = substr.IsNull() ? 0 : substr.Length();
198  char *data = Init(len, len);
199  memcpy(data, substr.Data(), len);
200 }
201 
202 ////////////////////////////////////////////////////////////////////////////////
203 /// Special constructor to initialize with the concatenation of a1 and a2.
204 
205 TString::TString(const char *a1, Ssiz_t n1, const char *a2, Ssiz_t n2)
206 {
207  if (!a1) n1=0;
208  if (!a2) n2=0;
209  Ssiz_t tot = n1+n2;
210  char *data = Init(tot, tot);
211  memcpy(data, a1, n1);
212  memcpy(data+n1, a2, n2);
213 }
214 
215 ////////////////////////////////////////////////////////////////////////////////
216 /// Delete a TString.
217 
219 {
220  UnLink();
221 }
222 
223 ////////////////////////////////////////////////////////////////////////////////
224 /// Private member function returning an empty string representation of
225 /// size capacity and containing nchar characters.
226 
227 char *TString::Init(Ssiz_t capacity, Ssiz_t nchar)
228 {
229  if (capacity > MaxSize()) {
230  Error("TString::Init", "capacity too large (%d, max = %d)", capacity, MaxSize());
231  capacity = MaxSize();
232  if (nchar > capacity)
233  nchar = capacity;
234  }
235 
236  char *data;
237  if (capacity < kMinCap) {
238  SetShortSize(nchar);
239  data = GetShortPointer();
240  } else {
241  Ssiz_t cap = Recommend(capacity);
242  data = new char[cap+1];
243  SetLongCap(cap+1);
244  SetLongSize(nchar);
245  SetLongPointer(data);
246  }
247  data[nchar] = 0; // terminating null
248 
249  return data;
250 }
251 
252 ////////////////////////////////////////////////////////////////////////////////
253 /// Assign character c to TString.
254 
256 {
257  if (!c) {
258  UnLink();
259  Zero();
260  return *this;
261  }
262  return Replace(0, Length(), &c, 1);
263 }
264 
265 ////////////////////////////////////////////////////////////////////////////////
266 /// Assign string cs to TString.
267 
268 TString& TString::operator=(const char *cs)
269 {
270  if (!cs || !*cs) {
271  UnLink();
272  Zero();
273  return *this;
274  }
275  return Replace(0, Length(), cs, strlen(cs));
276 }
277 
278 ////////////////////////////////////////////////////////////////////////////////
279 /// Assign std::string s to TString.
280 
281 TString& TString::operator=(const std::string &s)
282 {
283  if (s.length()==0) {
284  UnLink();
285  Zero();
286  return *this;
287  }
288  return Replace(0, Length(), s.c_str(), s.length());
289 }
290 
291 ////////////////////////////////////////////////////////////////////////////////
292 /// Assign std::string s to TString.
293 
295 {
296  if (s.length()==0) {
297  UnLink();
298  Zero();
299  return *this;
300  }
301  return Replace(0, Length(), s.data(), s.length());
302 }
303 
304 ////////////////////////////////////////////////////////////////////////////////
305 /// Assignment operator.
306 
308 {
309  if (this != &rhs) {
310  UnLink();
311  if (!rhs.IsLong())
312  fRep.fRaw = rhs.fRep.fRaw;
313  else {
314  Ssiz_t n = rhs.GetLongSize();
315  char *data = Init(n, n);
316  memcpy(data, rhs.GetLongPointer(), n);
317  }
318  }
319  return *this;
320 }
321 
322 ////////////////////////////////////////////////////////////////////////////////
323 /// Move-Assignment operator.
324 
326 {
327  UnLink();
328  fRep.fRaw = rhs.fRep.fRaw;
329  rhs.Zero();
330  return *this;
331 }
332 
333 ////////////////////////////////////////////////////////////////////////////////
334 /// Assign a TSubString substr to TString.
335 
337 {
338  Ssiz_t len = substr.IsNull() ? 0 : substr.Length();
339  if (!len) {
340  UnLink();
341  Zero();
342  return *this;
343  }
344  return Replace(0, Length(), substr.Data(), len);
345 }
346 
347 ////////////////////////////////////////////////////////////////////////////////
348 /// Append character c rep times to string.
349 
351 {
352  if (!rep) return *this;
353 
354  Ssiz_t len = Length();
355  Ssiz_t tot = len + rep; // Final string length
356 
357  if (tot > MaxSize()) {
358  Error("TString::Append", "rep too large (%d, max = %d)", rep, MaxSize()-len);
359  tot = MaxSize();
360  rep = tot - len;
361  }
362 
363  Ssiz_t capac = Capacity();
364  char *data, *p = GetPointer();
365 
366  if (capac - tot >= 0) {
367  SetSize(tot);
368  data = p;
369  } else {
370  Ssiz_t cap = AdjustCapacity(capac, tot);
371  data = new char[cap+1];
372  memcpy(data, p, len);
373  UnLink();
374  SetLongCap(cap+1);
375  SetLongSize(tot);
376  SetLongPointer(data);
377  }
378  data[tot] = 0;
379 
380  data += len;
381  while (rep--)
382  *data++ = c;
383 
384  return *this;
385 }
386 
387 ////////////////////////////////////////////////////////////////////////////////
388 /// Return string capacity. If nc != current capacity Clone() the string
389 /// in a string with the desired capacity.
390 
392 {
393  if (nc > Length())
394  Clone(nc);
395 
396  return Capacity();
397 }
398 
399 ////////////////////////////////////////////////////////////////////////////////
400 /// Compare a string to char *cs2. Returns returns zero if the two
401 /// strings are identical, otherwise returns the difference between
402 /// the first two differing bytes (treated as unsigned char values,
403 /// so that `\200' is greater than `\0', for example). Zero-length
404 /// strings are always identical.
405 
406 int TString::CompareTo(const char *cs2, ECaseCompare cmp) const
407 {
408  if (!cs2) return 1;
409 
410  const char *cs1 = Data();
411  Ssiz_t len = Length();
412  Ssiz_t i = 0;
413  if (cmp == kExact) {
414  for (; cs2[i]; ++i) {
415  if (i == len) return -1;
416  if (cs1[i] != cs2[i]) return ((cs1[i] > cs2[i]) ? 1 : -1);
417  }
418  } else { // ignore case
419  for (; cs2[i]; ++i) {
420  if (i == len) return -1;
421  char c1 = tolower((unsigned char)cs1[i]);
422  char c2 = tolower((unsigned char)cs2[i]);
423  if (c1 != c2) return ((c1 > c2) ? 1 : -1);
424  }
425  }
426  return (i < len) ? 1 : 0;
427 }
428 
429 ////////////////////////////////////////////////////////////////////////////////
430 /// Compare a string to another string. Returns returns zero if the two
431 /// strings are identical, otherwise returns the difference between
432 /// the first two differing bytes (treated as unsigned char values,
433 /// so that `\200' is greater than `\0', for example). Zero-length
434 /// strings are always identical.
435 
436 int TString::CompareTo(const TString &str, ECaseCompare cmp) const
437 {
438  const char *s1 = Data();
439  const char *s2 = str.Data();
440  Ssiz_t len = Length();
441  Ssiz_t slen, sleno = str.Length();
442  slen = sleno;
443  if (len < slen) slen = len;
444  if (cmp == kExact) {
445  int result = memcmp(s1, s2, slen);
446  if (result != 0) return result;
447  } else {
448  Ssiz_t i = 0;
449  for (; i < slen; ++i) {
450  char c1 = tolower((unsigned char)s1[i]);
451  char c2 = tolower((unsigned char)s2[i]);
452  if (c1 != c2) return ((c1 > c2) ? 1 : -1);
453  }
454  }
455  // strings are equal up to the length of the shorter one.
456  slen = sleno;
457  if (len == slen) return 0;
458  return (len > slen) ? 1 : -1;
459 }
460 
461 ////////////////////////////////////////////////////////////////////////////////
462 /// Return number of times character c occurs in the string.
463 
465 {
466  Int_t count = 0;
467  Int_t len = Length();
468  const char *data = Data();
469  for (Int_t n = 0; n < len; n++)
470  if (data[n] == c) count++;
471 
472  return count;
473 }
474 
475 ////////////////////////////////////////////////////////////////////////////////
476 /// Copy a string.
477 
479 {
480  TString temp(*this);
481  return temp;
482 }
483 
484 ////////////////////////////////////////////////////////////////////////////////
485 /// Find first occurrence of a character c.
486 
488 {
489  const char *f = strchr(Data(), c);
490  return f ? f - Data() : kNPOS;
491 }
492 
493 ////////////////////////////////////////////////////////////////////////////////
494 /// Find first occurrence of a character in cs.
495 
496 Ssiz_t TString::First(const char *cs) const
497 {
498  const char *f = strpbrk(Data(), cs);
499  return f ? f - Data() : kNPOS;
500 }
501 
502 #ifndef R__BYTESWAP
503 ////////////////////////////////////////////////////////////////////////////////
504 
505 inline static UInt_t SwapInt(UInt_t x)
506 {
507  return (((x & 0x000000ffU) << 24) | ((x & 0x0000ff00U) << 8) |
508  ((x & 0x00ff0000U) >> 8) | ((x & 0xff000000U) >> 24));
509 }
510 #endif
511 
512 ////////////////////////////////////////////////////////////////////////////////
513 /// Utility used by Hash().
514 
515 inline static void Mash(UInt_t& hash, UInt_t chars)
516 {
517  hash = (chars ^
518  ((hash << kHashShift) |
519  (hash >> (kBitsPerByte*sizeof(UInt_t) - kHashShift))));
520 }
521 
522 ////////////////////////////////////////////////////////////////////////////////
523 /// Return a case-sensitive hash value (endian independent).
524 
525 UInt_t Hash(const char *str)
526 {
527  UInt_t len = str ? strlen(str) : 0;
528  UInt_t hv = len; // Mix in the string length.
529  UInt_t i = hv*sizeof(char)/sizeof(UInt_t);
530 
531  if (((ULong_t)str)%sizeof(UInt_t) == 0) {
532  // str is word aligned
533  const UInt_t *p = (const UInt_t*)str;
534 
535  while (i--) {
536 #ifndef R__BYTESWAP
537  UInt_t h = *p++;
538  Mash(hv, SwapInt(h));
539 #else
540  Mash(hv, *p++); // XOR in the characters.
541 #endif
542  }
543 
544  // XOR in any remaining characters:
545  if ((i = len*sizeof(char)%sizeof(UInt_t)) != 0) {
546  UInt_t h = 0;
547  const char* c = (const char*)p;
548  while (i--)
549  h = ((h << kBitsPerByte*sizeof(char)) | *c++);
550  Mash(hv, h);
551  }
552  } else {
553  // str is not word aligned
554  UInt_t h;
555  const unsigned char *p = (const unsigned char*)str;
556 
557  while (i--) {
558  memcpy(&h, p, sizeof(UInt_t));
559 #ifndef R__BYTESWAP
560  Mash(hv, SwapInt(h));
561 #else
562  Mash(hv, h);
563 #endif
564  p += sizeof(UInt_t);
565  }
566 
567  // XOR in any remaining characters:
568  if ((i = len*sizeof(char)%sizeof(UInt_t)) != 0) {
569  h = 0;
570  const char* c = (const char*)p;
571  while (i--)
572  h = ((h << kBitsPerByte*sizeof(char)) | *c++);
573  Mash(hv, h);
574  }
575  }
576  return hv;
577 }
578 
579 ////////////////////////////////////////////////////////////////////////////////
580 /// Return a case-sensitive hash value (endian independent).
581 
583 {
584  UInt_t hv = (UInt_t)Length(); // Mix in the string length.
585  UInt_t i = hv*sizeof(char)/sizeof(UInt_t);
586  const UInt_t *p = (const UInt_t*)Data();
587  {
588  while (i--) {
589 #ifndef R__BYTESWAP
590  UInt_t h = *p++;
591  Mash(hv, SwapInt(h)); // XOR in the characters.
592 #else
593  Mash(hv, *p++); // XOR in the characters.
594 #endif
595  }
596  }
597  // XOR in any remaining characters:
598  if ((i = Length()*sizeof(char)%sizeof(UInt_t)) != 0) {
599  UInt_t h = 0;
600  const char* c = (const char*)p;
601  while (i--)
602  h = ((h << kBitsPerByte*sizeof(char)) | *c++);
603  Mash(hv, h);
604  }
605  return hv;
606 }
607 
608 ////////////////////////////////////////////////////////////////////////////////
609 /// Return a case-insensitive hash value (endian independent).
610 
612 {
613  UInt_t hv = (UInt_t)Length(); // Mix in the string length.
614  UInt_t i = hv;
615  const unsigned char *p = (const unsigned char*)Data();
616  while (i--) {
617  Mash(hv, toupper(*p));
618  ++p;
619  }
620  return hv;
621 }
622 
623 ////////////////////////////////////////////////////////////////////////////////
624 /// Return hash value.
625 
627 {
628  return (cmp == kExact) ? HashCase() : HashFoldCase();
629 }
630 
631  // MurmurHash3 - a blazingly fast public domain hash!
632  // See http://code.google.com/p/smhasher/
633  // There are two versions, one optimized for 32 bit and one for 64 bit.
634  // They give different hash results!
635  // We use only the 64 bit version which also works on 32 bit.
636 
637  //-----------------------------------------------------------------------------
638  // MurmurHash3 was written by Austin Appleby, and is placed in the public
639  // domain. The author hereby disclaims copyright to this source code.
640 
641  // Note - The x86 and x64 versions do _not_ produce the same results, as the
642  // algorithms are optimized for their respective platforms. You can still
643  // compile and run any of them on any platform, but your performance with the
644  // non-native version will be less than optimal.
645 
646  //-----------------------------------------------------------------------------
647  // Platform-specific functions and macros
648 
649  // From MurmurHash.h:
650 
651 #if defined(_MSC_VER) && (_MSC_VER < 1800)
652  // Microsoft Visual Studio
653  typedef unsigned char uint8_t;
654  typedef unsigned long uint32_t;
655  typedef unsigned __int64 uint64_t;
656 #else // defined(_MSC_VER)
657  // Other compilers
658 #include <stdint.h>
659 #endif // !defined(_MSC_VER)
660 
661  // From MurmurHash.cpp:
662 #if defined(_MSC_VER)
663  // Microsoft Visual Studio
664 #include <stdlib.h>
665 #define ROTL64(x,y) _rotl64(x,y)
666 #define BIG_CONSTANT(x) (x)
667 #else // defined(_MSC_VER)
668  // Other compilers
669  inline uint64_t rotl64 ( uint64_t x, int8_t r )
670  {
671  return (x << r) | (x >> (64 - r));
672  }
673 
674 #define ROTL64(x,y) rotl64(x,y)
675 #define BIG_CONSTANT(x) (x##LLU)
676 #endif // !defined(_MSC_VER)
677 
678 namespace {
679 
680  /////////////////////////////////////////////////////////////////////////////
681  /// Block read - if your platform needs to do endian-swapping or can only
682  /// handle aligned reads, do the conversion here
683 
684  R__ALWAYS_INLINE uint64_t getblock(const uint64_t* p, int i)
685  {
686  return p[i];
687  }
688 
689  /////////////////////////////////////////////////////////////////////////////
690  /// Finalization mix - force all bits of a hash block to avalanche
691 
692  R__ALWAYS_INLINE uint64_t fmix(uint64_t k)
693  {
694  k ^= k >> 33;
695  k *= BIG_CONSTANT(0xff51afd7ed558ccd);
696  k ^= k >> 33;
697  k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53);
698  k ^= k >> 33;
699 
700  return k;
701  }
702 
703  /////////////////////////////////////////////////////////////////////////////
704  /// "key" is input to be hashed.
705  /// "len" is the number of bytes to hash starting at "key".
706  /// "seed" is a hash seed, "out" is a buffer (128 bytes) that will receive
707  /// the results.
708 
709  static void MurmurHash3_x64_128(const void * key, const int len,
710  const uint32_t seed, uint64_t out[2] )
711  {
712  const uint8_t * data = (const uint8_t*)key;
713  const int nblocks = len / 16;
714 
715  uint64_t h1 = seed;
716  uint64_t h2 = seed;
717 
718  uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5);
719  uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f);
720 
721  //----------
722  // body
723 
724  const uint64_t * blocks = (const uint64_t *)(data);
725 
726  for(int i = 0; i < nblocks; i++)
727  {
728  uint64_t k1 = getblock(blocks,i*2+0);
729  uint64_t k2 = getblock(blocks,i*2+1);
730 
731  k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1;
732 
733  h1 = ROTL64(h1,27); h1 += h2; h1 = h1*5+0x52dce729;
734 
735  k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2;
736 
737  h2 = ROTL64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5;
738  }
739 
740  //----------
741  // tail
742 
743  const uint8_t * tail = (const uint8_t*)(data + nblocks*16);
744 
745  uint64_t k1 = 0;
746  uint64_t k2 = 0;
747 
748  switch(len & 15) {
749  case 15: k2 ^= uint64_t(tail[14]) << 48; // fall through
750  case 14: k2 ^= uint64_t(tail[13]) << 40; // fall through
751  case 13: k2 ^= uint64_t(tail[12]) << 32; // fall through
752  case 12: k2 ^= uint64_t(tail[11]) << 24; // fall through
753  case 11: k2 ^= uint64_t(tail[10]) << 16; // fall through
754  case 10: k2 ^= uint64_t(tail[ 9]) << 8; // fall through
755  case 9: k2 ^= uint64_t(tail[ 8]) << 0;
756  k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2;
757  // fall through
758  case 8: k1 ^= uint64_t(tail[ 7]) << 56; // fall through
759  case 7: k1 ^= uint64_t(tail[ 6]) << 48; // fall through
760  case 6: k1 ^= uint64_t(tail[ 5]) << 40; // fall through
761  case 5: k1 ^= uint64_t(tail[ 4]) << 32; // fall through
762  case 4: k1 ^= uint64_t(tail[ 3]) << 24; // fall through
763  case 3: k1 ^= uint64_t(tail[ 2]) << 16; // fall through
764  case 2: k1 ^= uint64_t(tail[ 1]) << 8; // fall through
765  case 1: k1 ^= uint64_t(tail[ 0]) << 0;
766  k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1;
767  };
768 
769  //----------
770  // finalization
771 
772  h1 ^= len; h2 ^= len;
773 
774  h1 += h2;
775  h2 += h1;
776 
777  h1 = fmix(h1);
778  h2 = fmix(h2);
779 
780  h1 += h2;
781  h2 += h1;
782 
783  ((uint64_t*)out)[0] = h1;
784  ((uint64_t*)out)[1] = h2;
785  }
786 
787 }
788 
789 ////////////////////////////////////////////////////////////////////////////////
790 /// Calculates hash index from any char string. (static function)
791 /// - For string: i = TString::Hash(string,nstring);
792 /// - For int: i = TString::Hash(&intword,sizeof(int));
793 /// - For pointer: i = TString::Hash(&pointer,sizeof(void*));
794 ///
795 /// This employs two different hash functions, depending on ntxt:
796 /// - ntxt == sizeof(void*): a simple bitwise xor to get fast pointer hashes
797 /// - else: MurmurHash3_x64_128 http://code.google.com/p/smhasher/
798 
799 UInt_t TString::Hash(const void *txt, Int_t ntxt)
800 {
801  if (ntxt != sizeof(void*)) {
802  uint64_t buf[2] = {0};
803  MurmurHash3_x64_128(txt, ntxt, 0x6384BA69, buf);
804  return (UInt_t) buf[0];
805  } else {
806  // simple, superfast hash for pointers and alike
807  UInt_t ret = (UInt_t)0x6384BA69;
808  // aligned?
809  if (((size_t)txt) % sizeof(void*)) {
810  UInt_t* itxt = (UInt_t*)txt;
811  ret ^= itxt[0];
812  if (sizeof(void*) > sizeof(UInt_t)) {
813  ret ^= itxt[1];
814  }
815  } else {
816  const unsigned char* ctxt = (const unsigned char*) txt;
817  for (unsigned int i = 0; i < 4; ++i) {
818  ret ^= ctxt[i] << (i * 8);
819  }
820  if (sizeof(void*) > sizeof(UInt_t)) {
821  ctxt += 4;
822  for (unsigned int i = 0; i < 4; ++i) {
823  ret ^= ctxt[i] << (i * 8);
824  }
825  }
826  }
827  return ret;
828  }
829 }
830 
831 ////////////////////////////////////////////////////////////////////////////////
832 /// Returns false if strings are not equal.
833 
834 static int MemIsEqual(const char *p, const char *q, Ssiz_t n)
835 {
836  while (n--)
837  {
838  if (tolower((unsigned char)*p) != tolower((unsigned char)*q))
839  return kFALSE;
840  p++; q++;
841  }
842  return kTRUE;
843 }
844 
845 ////////////////////////////////////////////////////////////////////////////////
846 /// Search for a string in the TString. Plen is the length of pattern,
847 /// startIndex is the index from which to start and cmp selects the type
848 /// of case-comparison.
849 
850 Ssiz_t TString::Index(const char *pattern, Ssiz_t plen, Ssiz_t startIndex,
851  ECaseCompare cmp) const
852 {
853  Ssiz_t slen = Length();
854  if (slen < startIndex + plen) return kNPOS;
855  if (plen == 0) return startIndex;
856  slen -= startIndex + plen;
857  const char *sp = Data() + startIndex;
858  if (cmp == kExact) {
859  char first = *pattern;
860  for (Ssiz_t i = 0; i <= slen; ++i)
861  if (sp[i] == first && memcmp(sp+i+1, pattern+1, plen-1) == 0)
862  return i + startIndex;
863  } else {
864  int first = tolower((unsigned char) *pattern);
865  for (Ssiz_t i = 0; i <= slen; ++i)
866  if (tolower((unsigned char) sp[i]) == first &&
867  MemIsEqual(sp+i+1, pattern+1, plen-1))
868  return i + startIndex;
869  }
870  return kNPOS;
871 }
872 
873 ////////////////////////////////////////////////////////////////////////////////
874 /// Find last occurrence of a character c.
875 
876 Ssiz_t TString::Last(char c) const
877 {
878  const char *f = strrchr(Data(), (unsigned char) c);
879  return f ? f - Data() : kNPOS;
880 }
881 
882 ////////////////////////////////////////////////////////////////////////////////
883 /// Return the MD5 digest for this string, in a string representation.
884 
886 {
887  TMD5 md5;
888  md5.Update((const UChar_t*)Data(), Length());
889  UChar_t digest[16];
890  md5.Final(digest);
891  return md5.AsString();
892 }
893 
894 ////////////////////////////////////////////////////////////////////////////////
895 /// Returns true if string contains one of the regexp characters "^$.[]*+?".
896 
898 {
899  const char *specials = "^$.[]*+?";
900 
901  if (First(specials) == kNPOS)
902  return kFALSE;
903  return kTRUE;
904 }
905 
906 ////////////////////////////////////////////////////////////////////////////////
907 /// Returns true if string contains one of the wildcard characters "[]*?".
908 
910 {
911  const char *specials = "[]*?";
912 
913  if (First(specials) == kNPOS)
914  return kFALSE;
915  return kTRUE;
916 }
917 
918 ////////////////////////////////////////////////////////////////////////////////
919 /// Prepend character c rep times to string.
920 
922 {
923  if (!rep) return *this;
924 
925  Ssiz_t len = Length();
926  Ssiz_t tot = len + rep; // Final string length
927 
928  if (tot > MaxSize()) {
929  Error("TString::Prepend", "rep too large (%d, max = %d)", rep, MaxSize()-len);
930  tot = MaxSize();
931  rep = tot - len;
932  }
933 
934  Ssiz_t capac = Capacity();
935  char *data, *p = GetPointer();
936 
937  if (capac - tot >= 0) {
938  memmove(p + rep, p, len);
939  SetSize(tot);
940  data = p;
941  } else {
942  Ssiz_t cap = AdjustCapacity(capac, tot);
943  data = new char[cap+1];
944  memcpy(data+rep, p, len);
945  UnLink();
946  SetLongCap(cap+1);
947  SetLongSize(tot);
948  SetLongPointer(data);
949  }
950  data[tot] = 0;
951 
952  while (rep--)
953  *data++ = c;
954 
955  return *this;
956 }
957 
958 ////////////////////////////////////////////////////////////////////////////////
959 /// Remove at most n1 characters from self beginning at pos,
960 /// and replace them with the first n2 characters of cs.
961 
962 TString &TString::Replace(Ssiz_t pos, Ssiz_t n1, const char *cs, Ssiz_t n2)
963 {
964  Ssiz_t len = Length();
965  if (pos <= kNPOS || pos > len) {
966  Error("TString::Replace",
967  "first argument out of bounds: pos = %d, Length = %d", pos, len);
968  return *this;
969  }
970 
971  n1 = TMath::Min(n1, len - pos);
972  if (!cs) n2 = 0;
973 
974  Ssiz_t tot = len - n1 + n2; // Final string length
975  Ssiz_t rem = len - n1 - pos; // Length of remnant at end of string
976 
977  Ssiz_t capac = Capacity();
978  char *p = GetPointer();
979 
980  if (capac - len + n1 >= n2) {
981  if (n1 != n2) {
982  if (rem) {
983  if (n1 > n2) {
984  if (n2) memmove(p + pos, cs, n2);
985  memmove(p + pos + n2, p + pos + n1, rem);
986  goto finish;
987  }
988  if (p + pos < cs && cs < p + len) {
989  if (p + pos + n1 <= cs)
990  cs += n2 - n1;
991  else { // p + pos < cs < p + pos + n1
992  memmove(p + pos, cs, n1);
993  pos += n1;
994  cs += n2;
995  n2 -= n1;
996  n1 = 0;
997  }
998  }
999  memmove(p + pos + n2, p + pos + n1, rem);
1000  }
1001  }
1002  if (n2) memmove(p + pos, cs, n2);
1003 finish:
1004  SetSize(tot);
1005  p[tot] = 0;
1006  } else {
1007  Ssiz_t cap = AdjustCapacity(capac, tot);
1008  char *data = new char[cap+1];
1009  if (pos) memcpy(data, p, pos);
1010  if (n2 ) memcpy(data + pos, cs, n2);
1011  if (rem) memcpy(data + pos + n2, p + pos + n1, rem);
1012  UnLink();
1013  SetLongCap(cap+1);
1014  SetLongSize(tot);
1015  SetLongPointer(data);
1016  data[tot] = 0;
1017  }
1018 
1019  return *this;
1020 }
1021 
1022 ////////////////////////////////////////////////////////////////////////////////
1023 /// Find & Replace ls1 symbols of s1 with ls2 symbols of s2 if any.
1024 
1025 TString& TString::ReplaceAll(const char *s1, Ssiz_t ls1, const char *s2,
1026  Ssiz_t ls2)
1027 {
1028  if (s1 && ls1 > 0) {
1029  Ssiz_t index = 0;
1030  while ((index = Index(s1, ls1, index, kExact)) != kNPOS) {
1031  Replace(index, ls1, s2, ls2);
1032  index += ls2;
1033  }
1034  }
1035  return *this;
1036 }
1037 
1038 ////////////////////////////////////////////////////////////////////////////////
1039 /// Remove char c at begin and/or end of string (like Strip()) but
1040 /// modifies directly the string.
1041 
1043 {
1044  Ssiz_t start = 0; // Index of first character
1045  Ssiz_t end = Length(); // One beyond last character
1046  const char *direct = Data(); // Avoid a dereference w dumb compiler
1047  Ssiz_t send = end;
1048 
1049  if (st & kLeading)
1050  while (start < end && direct[start] == c)
1051  ++start;
1052  if (st & kTrailing)
1053  while (start < end && direct[end-1] == c)
1054  --end;
1055  if (end == start) {
1056  UnLink();
1057  Zero();
1058  return *this;
1059  }
1060  if (start)
1061  Remove(0, start);
1062  if (send != end)
1063  Remove(send - start - (send - end), send - end);
1064  return *this;
1065 }
1066 
1067 ////////////////////////////////////////////////////////////////////////////////
1068 /// Resize the string. Truncate or add blanks as necessary.
1069 
1071 {
1072  if (n < Length())
1073  Remove(n); // Shrank; truncate the string
1074  else
1075  Append(' ', n-Length()); // Grew or staid the same
1076 }
1077 
1078 ////////////////////////////////////////////////////////////////////////////////
1079 /// Return a substring of self stripped at beginning and/or end.
1080 
1082 {
1083  Ssiz_t start = 0; // Index of first character
1084  Ssiz_t end = Length(); // One beyond last character
1085  const char *direct = Data(); // Avoid a dereference w dumb compiler
1086 
1087  if (st & kLeading)
1088  while (start < end && direct[start] == c)
1089  ++start;
1090  if (st & kTrailing)
1091  while (start < end && direct[end-1] == c)
1092  --end;
1093  if (end == start) start = end = kNPOS; // make the null substring
1094  return TSubString(*this, start, end-start);
1095 }
1096 
1097 ////////////////////////////////////////////////////////////////////////////////
1098 /// Change string to lower-case.
1099 
1101 {
1102  Ssiz_t n = Length();
1103  char *p = GetPointer();
1104  while (n--) {
1105  *p = tolower((unsigned char)*p);
1106  p++;
1107  }
1108 }
1109 
1110 ////////////////////////////////////////////////////////////////////////////////
1111 /// Change string to upper case.
1112 
1114 {
1115  Ssiz_t n = Length();
1116  char *p = GetPointer();
1117  while (n--) {
1118  *p = toupper((unsigned char)*p);
1119  p++;
1120  }
1121 }
1122 
1123 ////////////////////////////////////////////////////////////////////////////////
1124 /// Check to make sure a string index is in range.
1125 
1127 {
1128  if (i == kNPOS || i > Length())
1129  Error("TString::AssertElement",
1130  "out of bounds: i = %d, Length = %d", i, Length());
1131 }
1132 
1133 ////////////////////////////////////////////////////////////////////////////////
1134 /// Calculate a nice capacity greater than or equal to newCap.
1135 
1137 {
1138  Ssiz_t ms = MaxSize();
1139  if (newCap > ms - 1) {
1140  Error("TString::AdjustCapacity", "capacity too large (%d, max = %d)",
1141  newCap, ms);
1142  }
1143  Ssiz_t cap = oldCap < ms / 2 - kAlignment ?
1144  Recommend(TMath::Max(newCap, 2 * oldCap)) : ms - 1;
1145  return cap;
1146 }
1147 
1148 ////////////////////////////////////////////////////////////////////////////////
1149 /// Clear string without changing its capacity.
1150 
1152 {
1153  Clobber(Capacity());
1154 }
1155 
1156 ////////////////////////////////////////////////////////////////////////////////
1157 /// Clear string and make sure it has a capacity of nc.
1158 
1160 {
1161  if (nc > MaxSize()) {
1162  Error("TString::Clobber", "capacity too large (%d, max = %d)", nc, MaxSize());
1163  nc = MaxSize();
1164  }
1165 
1166  if (nc < kMinCap) {
1167  UnLink();
1168  Zero();
1169  } else {
1170  char *data = GetLongPointer();
1171  Ssiz_t cap = Recommend(nc);
1172  if (cap != Capacity()) {
1173  data = new char[cap+1];
1174  UnLink();
1175  SetLongCap(cap+1);
1176  SetLongPointer(data);
1177  }
1178  SetLongSize(0);
1179  data[0] = 0;
1180  }
1181 }
1182 
1183 ////////////////////////////////////////////////////////////////////////////////
1184 /// Make self a distinct copy with capacity of at least tot, where tot cannot
1185 /// be smaller than the current length. Preserve previous contents.
1186 
1188 {
1189  Ssiz_t len = Length();
1190  if (len >= tot) return;
1191 
1192  if (tot > MaxSize()) {
1193  Error("TString::Clone", "tot too large (%d, max = %d)", tot, MaxSize());
1194  tot = MaxSize();
1195  }
1196 
1197  Ssiz_t capac = Capacity();
1198  char *data, *p = GetPointer();
1199 
1200  if (capac - tot < 0) {
1201  Ssiz_t cap = Recommend(tot);
1202  data = new char[cap+1];
1203  memcpy(data, p, len);
1204  UnLink();
1205  SetLongCap(cap+1);
1206  SetLongSize(len);
1207  SetLongPointer(data);
1208  data[len] = 0;
1209  }
1210 }
1211 
1212 ////////////////////////////////////////////////////////////////////////////////
1213 // ROOT I/O
1214 
1215 ////////////////////////////////////////////////////////////////////////////////
1216 /// Copy string into I/O buffer.
1217 
1218 void TString::FillBuffer(char *&buffer) const
1219 {
1220  UChar_t nwh;
1221  Int_t nchars = Length();
1222 
1223  if (nchars > 254) {
1224  nwh = 255;
1225  tobuf(buffer, nwh);
1226  tobuf(buffer, nchars);
1227  } else {
1228  nwh = UChar_t(nchars);
1229  tobuf(buffer, nwh);
1230  }
1231  const char *data = GetPointer();
1232  for (int i = 0; i < nchars; i++) buffer[i] = data[i];
1233  buffer += nchars;
1234 }
1235 
1236 ////////////////////////////////////////////////////////////////////////////////
1237 /// Read string from I/O buffer.
1238 
1239 void TString::ReadBuffer(char *&buffer)
1240 {
1241  UnLink();
1242  Zero();
1243 
1244  UChar_t nwh;
1245  Int_t nchars;
1246 
1247  frombuf(buffer, &nwh);
1248  if (nwh == 255)
1249  frombuf(buffer, &nchars);
1250  else
1251  nchars = nwh;
1252 
1253  if (nchars < 0) {
1254  Error("TString::ReadBuffer", "found case with nwh=%d and nchars=%d", nwh, nchars);
1255  return;
1256  }
1257 
1258  char *data = Init(nchars, nchars);
1259 
1260  for (int i = 0; i < nchars; i++) frombuf(buffer, &data[i]);
1261 }
1262 
1263 ////////////////////////////////////////////////////////////////////////////////
1264 /// Read TString object from buffer. Simplified version of
1265 /// TBuffer::ReadObject (does not keep track of multiple
1266 /// references to same string). We need to have it here
1267 /// because TBuffer::ReadObject can only handle descendant
1268 /// of TObject.
1269 
1271 {
1272  R__ASSERT(b.IsReading());
1273 
1274  // Make sure ReadArray is initialized
1275  b.InitMap();
1276 
1277  // Before reading object save start position
1278  UInt_t startpos = UInt_t(b.Length());
1279 
1280  UInt_t tag;
1281  TClass *clRef = b.ReadClass(clReq, &tag);
1282 
1283  TString *a;
1284  if (!clRef) {
1285 
1286  a = 0;
1287 
1288  } else {
1289 
1290  a = (TString *) clRef->New();
1291  if (!a) {
1292  ::Error("TString::ReadObject", "could not create object of class %s",
1293  clRef->GetName());
1294  // Exception
1295  return a;
1296  }
1297 
1298  a->Streamer(b);
1299 
1300  b.CheckByteCount(startpos, tag, clRef);
1301  }
1302 
1303  return a;
1304 }
1305 
1306 ////////////////////////////////////////////////////////////////////////////////
1307 /// Returns size string will occupy on I/O buffer.
1308 
1310 {
1311  if (Length() > 254)
1312  return Length()+sizeof(UChar_t)+sizeof(Int_t);
1313  else
1314  return Length()+sizeof(UChar_t);
1315 }
1316 
1317 ////////////////////////////////////////////////////////////////////////////////
1318 /// Stream a string object.
1319 
1320 void TString::Streamer(TBuffer &b)
1321 {
1322  if (b.IsReading()) {
1323  b.ReadTString(*this);
1324  } else {
1325  b.WriteTString(*this);
1326  }
1327 }
1328 
1329 ////////////////////////////////////////////////////////////////////////////////
1330 /// Write TString object to buffer. Simplified version of
1331 /// TBuffer::WriteObject (does not keep track of multiple
1332 /// references to the same string). We need to have it here
1333 /// because TBuffer::ReadObject can only handle descendant
1334 /// of TObject
1335 
1337 {
1338  R__ASSERT(b.IsWriting());
1339 
1340  // Make sure WriteMap is initialized
1341  b.InitMap();
1342 
1343  if (!a) {
1344 
1345  b << (UInt_t) 0;
1346 
1347  } else {
1348 
1349  // Reserve space for leading byte count
1350  UInt_t cntpos = UInt_t(b.Length());
1351  b.SetBufferOffset(Int_t(cntpos+sizeof(UInt_t)));
1352 
1353  TClass *cl = a->IsA();
1354  b.WriteClass(cl);
1355 
1356  ((TString *)a)->Streamer(b);
1357 
1358  // Write byte count
1359  b.SetByteCount(cntpos);
1360  }
1361 }
1362 
1363 ////////////////////////////////////////////////////////////////////////////////
1364 /// Read string from TBuffer. Function declared in ClassDef.
1365 
1366 #if defined(R__TEMPLATE_OVERLOAD_BUG)
1367 template <>
1368 #endif
1370 {
1371  s = (TString *) TString::ReadString(buf, TString::Class());
1372  return buf;
1373 }
1374 
1375 ////////////////////////////////////////////////////////////////////////////////
1376 /// Write TString or derived to TBuffer.
1377 
1379 {
1380  TString::WriteString(buf, s);
1381  return buf;
1382 }
1383 
1384 ////////////////////////////////////////////////////////////////////////////////
1385 // Related global functions
1386 
1387 ////////////////////////////////////////////////////////////////////////////////
1388 /// Compare TString with a char *.
1389 
1390 Bool_t operator==(const TString& s1, const char *s2)
1391 {
1392  if (!s2) return kFALSE;
1393 
1394  const char *data = s1.Data();
1395  Ssiz_t len = s1.Length();
1396  Ssiz_t i;
1397  for (i = 0; s2[i]; ++i)
1398  if (data[i] != s2[i] || i == len) return kFALSE;
1399  return (i == len);
1400 }
1401 
1402 ////////////////////////////////////////////////////////////////////////////////
1403 /// Return a lower-case version of str.
1404 
1406 {
1407  Ssiz_t n = str.Length();
1408  TString temp((char)0, n);
1409  const char *uc = str.Data();
1410  char *lc = (char*)temp.Data();
1411  // Guard against tolower() being a macro
1412  while (n--) { *lc++ = tolower((unsigned char)*uc); uc++; }
1413  return temp;
1414 }
1415 
1416 ////////////////////////////////////////////////////////////////////////////////
1417 /// Return an upper-case version of str.
1418 
1420 {
1421  Ssiz_t n = str.Length();
1422  TString temp((char)0, n);
1423  const char* uc = str.Data();
1424  char* lc = (char*)temp.Data();
1425  // Guard against toupper() being a macro
1426  while (n--) { *lc++ = toupper((unsigned char)*uc); uc++; }
1427  return temp;
1428 }
1429 
1430 ////////////////////////////////////////////////////////////////////////////////
1431 /// Use the special concatenation constructor.
1432 
1433 TString operator+(const TString &s, const char *cs)
1434 {
1435  return TString(s.Data(), s.Length(), cs, cs ? strlen(cs) : 0);
1436 }
1437 
1438 ////////////////////////////////////////////////////////////////////////////////
1439 /// Use the special concatenation constructor.
1440 
1441 TString operator+(const char *cs, const TString &s)
1442 {
1443  return TString(cs, cs ? strlen(cs) : 0, s.Data(), s.Length());
1444 }
1445 
1446 ////////////////////////////////////////////////////////////////////////////////
1447 /// Use the special concatenation constructor.
1448 
1449 TString operator+(const TString &s1, const TString &s2)
1450 {
1451  return TString(s1.Data(), s1.Length(), s2.Data(), s2.Length());
1452 }
1453 
1454 ////////////////////////////////////////////////////////////////////////////////
1455 /// Add char to string.
1456 
1457 TString operator+(const TString &s, char c)
1458 {
1459  return TString(s.Data(), s.Length(), &c, 1);
1460 }
1461 
1462 ////////////////////////////////////////////////////////////////////////////////
1463 /// Add string to char.
1464 
1465 TString operator+(char c, const TString &s)
1466 {
1467  return TString(&c, 1, s.Data(), s.Length());
1468 }
1469 
1470 ////////////////////////////////////////////////////////////////////////////////
1471 // Static Member Functions
1472 // The static data members access
1473 
1474 ////////////////////////////////////////////////////////////////////////////////
1475 
1477 {
1478  ::Obsolete("TString::GetInitialCapacity", "v5-30-00", "v5-32-00");
1479  return 15;
1480 }
1481 
1482 ////////////////////////////////////////////////////////////////////////////////
1483 
1485 {
1486  ::Obsolete("TString::GetResizeIncrement", "v5-30-00", "v5-32-00");
1487  return 16;
1488 }
1489 
1490 ////////////////////////////////////////////////////////////////////////////////
1491 
1493 {
1494  ::Obsolete("TString::GetMaxWaste", "v5-30-00", "v5-32-00");
1495  return 15;
1496 }
1497 
1498 ////////////////////////////////////////////////////////////////////////////////
1499 /// Set default initial capacity for all TStrings. Default is 15.
1500 
1502 {
1503  ::Obsolete("TString::InitialCapacity", "v5-30-00", "v5-32-00");
1504  return 15;
1505 }
1506 
1507 ////////////////////////////////////////////////////////////////////////////////
1508 /// Set default resize increment for all TStrings. Default is 16.
1509 
1511 {
1512  ::Obsolete("TString::ResizeIncrement", "v5-30-00", "v5-32-00");
1513  return 16;
1514 }
1515 
1516 ////////////////////////////////////////////////////////////////////////////////
1517 /// Set maximum space that may be wasted in a string before doing a resize.
1518 /// Default is 15.
1519 
1521 {
1522  ::Obsolete("TString::MaxWaste", "v5-30-00", "v5-32-00");
1523  return 15;
1524 }
1525 
1526 /** \class TSubString
1527 A zero length substring is legal. It can start
1528 at any character. It is considered to be "pointing"
1529 to just before the character.
1530 
1531 A "null" substring is a zero length substring that
1532 starts with the nonsense index kNPOS. It can
1533 be detected with the member function IsNull().
1534 */
1535 
1536 ////////////////////////////////////////////////////////////////////////////////
1537 /// Private constructor.
1538 
1539 TSubString::TSubString(const TString &str, Ssiz_t start, Ssiz_t nextent)
1540  : fStr((TString&)str), fBegin(start), fExtent(nextent)
1541 {
1542 }
1543 
1544 ////////////////////////////////////////////////////////////////////////////////
1545 /// Return sub-string of string starting at start with length len.
1546 
1548 {
1549  if (start < Length() && len > 0) {
1550  if (start+len > Length())
1551  len = Length() - start;
1552  } else {
1553  start = kNPOS;
1554  len = 0;
1555  }
1556  return TSubString(*this, start, len);
1557 }
1558 
1559 ////////////////////////////////////////////////////////////////////////////////
1560 /// Returns a substring matching "pattern", or the null substring
1561 /// if there is no such match. It would be nice if this could be yet another
1562 /// overloaded version of operator(), but this would result in a type
1563 /// conversion ambiguity with operator(Ssiz_t, Ssiz_t).
1564 
1565 TSubString TString::SubString(const char *pattern, Ssiz_t startIndex,
1566  ECaseCompare cmp) const
1567 {
1568  Ssiz_t len = pattern ? strlen(pattern) : 0;
1569  Ssiz_t i = Index(pattern, len, startIndex, cmp);
1570  return TSubString(*this, i, i == kNPOS ? 0 : len);
1571 }
1572 
1573 ////////////////////////////////////////////////////////////////////////////////
1574 /// Return character at pos i from sub-string. Check validity of i.
1575 
1577 {
1578  AssertElement(i);
1579  return fStr(fBegin+i);
1580 }
1581 
1582 ////////////////////////////////////////////////////////////////////////////////
1583 /// Return character at pos i from sub-string. No check on i.
1584 
1586 {
1587  return fStr(fBegin+i);
1588 }
1589 
1590 ////////////////////////////////////////////////////////////////////////////////
1591 /// Assign string to sub-string.
1592 
1594 {
1595  if (!IsNull())
1596  fStr.Replace(fBegin, fExtent, str.Data(), str.Length());
1597 
1598  return *this;
1599 }
1600 
1601 ////////////////////////////////////////////////////////////////////////////////
1602 /// Assign char* to sub-string.
1603 
1605 {
1606  if (!IsNull())
1607  fStr.Replace(fBegin, fExtent, cs, cs ? strlen(cs) : 0);
1608 
1609  return *this;
1610 }
1611 
1612 ////////////////////////////////////////////////////////////////////////////////
1613 /// Compare sub-string to char *.
1614 
1615 Bool_t operator==(const TSubString& ss, const char *cs)
1616 {
1617  if (ss.IsNull()) return *cs =='\0'; // Two null strings compare equal
1618 
1619  const char* data = ss.fStr.Data() + ss.fBegin;
1620  Ssiz_t i;
1621  for (i = 0; cs[i]; ++i)
1622  if (cs[i] != data[i] || i == ss.fExtent) return kFALSE;
1623  return (i == ss.fExtent);
1624 }
1625 
1626 ////////////////////////////////////////////////////////////////////////////////
1627 /// Compare sub-string to string.
1628 
1630 {
1631  if (ss.IsNull()) return s.IsNull(); // Two null strings compare equal.
1632  if (ss.fExtent != s.Length()) return kFALSE;
1633  return !memcmp(ss.fStr.Data() + ss.fBegin, s.Data(), ss.fExtent);
1634 }
1635 
1636 ////////////////////////////////////////////////////////////////////////////////
1637 /// Compare two sub-strings.
1638 
1640 {
1641  if (s1.IsNull()) return s2.IsNull();
1642  if (s1.fExtent != s2.fExtent) return kFALSE;
1643  return !memcmp(s1.fStr.Data()+s1.fBegin, s2.fStr.Data()+s2.fBegin,
1644  s1.fExtent);
1645 }
1646 
1647 ////////////////////////////////////////////////////////////////////////////////
1648 /// Convert sub-string to lower-case.
1649 
1651 {
1652  if (!IsNull()) { // Ignore null substrings
1653  char *p = fStr.GetPointer() + fBegin;
1654  Ssiz_t n = fExtent;
1655  while (n--) { *p = tolower((unsigned char)*p); p++;}
1656  }
1657 }
1658 
1659 ////////////////////////////////////////////////////////////////////////////////
1660 /// Convert sub-string to upper-case.
1661 
1663 {
1664  if (!IsNull()) { // Ignore null substrings
1665  char *p = fStr.GetPointer() + fBegin;
1666  Ssiz_t n = fExtent;
1667  while (n--) { *p = toupper((unsigned char)*p); p++;}
1668  }
1669 }
1670 
1671 ////////////////////////////////////////////////////////////////////////////////
1672 /// Output error message.
1673 
1675 {
1676  Error("TSubString::SubStringError",
1677  "out of bounds: start = %d, n = %d, sr = %d", start, n, sr);
1678 }
1679 
1680 ////////////////////////////////////////////////////////////////////////////////
1681 /// Check to make sure a sub-string index is in range.
1682 
1684 {
1685  if (i == kNPOS || i >= Length())
1686  Error("TSubString::AssertElement",
1687  "out of bounds: i = %d, Length = %d", i, Length());
1688 }
1689 
1690 ////////////////////////////////////////////////////////////////////////////////
1691 /// Returns true if all characters in string are ascii.
1692 
1694 {
1695  const char *cp = Data();
1696  for (Ssiz_t i = 0; i < Length(); ++i)
1697  if (cp[i] & ~0x7F)
1698  return kFALSE;
1699  return kTRUE;
1700 }
1701 
1702 ////////////////////////////////////////////////////////////////////////////////
1703 /// Returns true if all characters in string are alphabetic.
1704 /// Returns false in case string length is 0.
1705 
1707 {
1708  const char *cp = Data();
1709  Ssiz_t len = Length();
1710  if (len == 0) return kFALSE;
1711  for (Ssiz_t i = 0; i < len; ++i)
1712  if (!isalpha(cp[i]))
1713  return kFALSE;
1714  return kTRUE;
1715 }
1716 
1717 ////////////////////////////////////////////////////////////////////////////////
1718 /// Returns true if all characters in string are alphanumeric.
1719 /// Returns false in case string length is 0.
1720 
1722 {
1723  const char *cp = Data();
1724  Ssiz_t len = Length();
1725  if (len == 0) return kFALSE;
1726  for (Ssiz_t i = 0; i < len; ++i)
1727  if (!isalnum(cp[i]))
1728  return kFALSE;
1729  return kTRUE;
1730 }
1731 
1732 ////////////////////////////////////////////////////////////////////////////////
1733 /// Returns true if all characters in string are digits (0-9) or white spaces,
1734 /// i.e. "123456" and "123 456" are both valid integer strings.
1735 /// Returns false in case string length is 0 or string contains other
1736 /// characters or only whitespace.
1737 
1739 {
1740  const char *cp = Data();
1741  Ssiz_t len = Length();
1742  if (len == 0) return kFALSE;
1743  Int_t b = 0, d = 0;
1744  for (Ssiz_t i = 0; i < len; ++i) {
1745  if (cp[i] != ' ' && !isdigit(cp[i])) return kFALSE;
1746  if (cp[i] == ' ') b++;
1747  if (isdigit(cp[i])) d++;
1748  }
1749  if (b && !d)
1750  return kFALSE;
1751  return kTRUE;
1752 }
1753 
1754 ////////////////////////////////////////////////////////////////////////////////
1755 /// Returns kTRUE if string contains a floating point or integer number.
1756 /// Examples of valid formats are:
1757 /// ~~~ {.cpp}
1758 /// 64320
1759 /// 64 320
1760 /// 6 4 3 2 0
1761 /// 6.4320 6,4320
1762 /// 6.43e20 6.43E20 6,43e20
1763 /// 6.43e-20 6.43E-20 6,43e-20, -6.43e+20
1764 /// ~~~
1765 
1767 {
1768  //we first check if we have an integer, in this case, IsDigit() will be true straight away
1769  if (IsDigit()) return kTRUE;
1770 
1771  TString tmp = *this;
1772  //now we look for occurrences of '.', ',', e', 'E', '+', '-' and replace each
1773  //with ' ', if it is a floating point, IsDigit() will then return kTRUE
1774 
1775  tmp.ToLower();
1776  Ssiz_t pos = tmp.First('.');
1777  if (pos != kNPOS) tmp.Replace(pos, 1, " ", 1);
1778  pos = tmp.First(',');
1779  if (pos != kNPOS) tmp.Replace(pos, 1, " ", 1);
1780  pos = tmp.Index("e-");
1781  if (pos >= 1) tmp.Replace(pos, 2, " ", 1);
1782  pos = tmp.Index("e+");
1783  if (pos >= 1) tmp.Replace(pos, 2, " ", 1);
1784  pos = tmp.Index("e");
1785  if (pos >= 1) tmp.Replace(pos, 1, " ", 1);
1786  pos = tmp.First('-');
1787  if (pos == 0) tmp.Replace(pos, 1, " ", 1);
1788  pos = tmp.First('+');
1789  if (pos == 0) tmp.Replace(pos, 1, " ", 1);
1790 
1791  //test if it is now uniquely composed of numbers
1792  return tmp.IsDigit();
1793 }
1794 
1795 ////////////////////////////////////////////////////////////////////////////////
1796 /// Returns true if all characters in string are hexadecimal digits
1797 /// (0-9,a-f,A-F). Returns false in case string length is 0 or string
1798 /// contains other characters.
1799 
1801 {
1802  const char *cp = Data();
1803  Ssiz_t len = Length();
1804  if (len == 0) return kFALSE;
1805  for (Ssiz_t i = 0; i < len; ++i)
1806  if (!isxdigit(cp[i]))
1807  return kFALSE;
1808  return kTRUE;
1809 }
1810 
1811 ////////////////////////////////////////////////////////////////////////////////
1812 /// Returns true if all characters in string are binary digits (0,1).
1813 /// Returns false in case string length is 0 or string contains other
1814 /// characters.
1815 
1817 {
1818  const char *cp = Data();
1819  Ssiz_t len = Length();
1820  if (len == 0) return kFALSE;
1821  for (Ssiz_t i = 0; i < len; ++i)
1822  if (cp[i] != '0' && cp[i] != '1')
1823  return kFALSE;
1824  return kTRUE;
1825 }
1826 
1827 ////////////////////////////////////////////////////////////////////////////////
1828 /// Returns true if all characters in string are octal digits (0-7).
1829 /// Returns false in case string length is 0 or string contains other
1830 /// characters.
1831 
1833 {
1834  const char *cp = Data();
1835  Ssiz_t len = Length();
1836  if (len == 0) return kFALSE;
1837  for (Ssiz_t i = 0; i < len; ++i)
1838  if (!isdigit(cp[i]) || cp[i]=='8' || cp[i]=='9')
1839  return kFALSE;
1840  return kTRUE;
1841 }
1842 
1843 ////////////////////////////////////////////////////////////////////////////////
1844 /// Returns true if all characters in string are decimal digits (0-9).
1845 /// Returns false in case string length is 0 or string contains other
1846 /// characters.
1847 
1849 {
1850  const char *cp = Data();
1851  Ssiz_t len = Length();
1852  if (len == 0) return kFALSE;
1853  for (Ssiz_t i = 0; i < len; ++i)
1854  if (!isdigit(cp[i]))
1855  return kFALSE;
1856  return kTRUE;
1857 }
1858 
1859 ////////////////////////////////////////////////////////////////////////////////
1860 /// Returns true if all characters in string are expressed in the base
1861 /// specified (range=2-36), i.e. {0,1} for base 2, {0-9,a-f,A-F} for base 16,
1862 /// {0-9,a-z,A-Z} for base 36. Returns false in case string length is 0 or
1863 /// string contains other characters.
1864 
1866 {
1867  if (base < 2 || base > 36) {
1868  Error("TString::IsInBaseN", "base %d is not supported. Supported bases are {2,3,...,36}.", base);
1869  return kFALSE;
1870  }
1871  if (Length() == 0) {
1872  Error("TString::IsInBaseN", "input string is empty.") ;
1873  return kFALSE;
1874  }
1875  TString str = TString(Data()) ;
1876  str.ToUpper() ;
1877  TString str_ref0 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
1878  TString str_ref = str_ref0 ;
1879  str_ref.Remove(base) ;
1880  Bool_t isInBase = kTRUE ;
1881  for (Int_t k = 0; k < str.Length(); k++) {
1882  if (! str_ref.Contains(str[k])) {
1883  isInBase = kFALSE ;
1884  break ;
1885  }
1886  }
1887  return (isInBase);
1888 }
1889 
1890 ////////////////////////////////////////////////////////////////////////////////
1891 /// Return integer value of string.
1892 /// Valid strings include only digits and whitespace (see IsDigit()),
1893 /// i.e. "123456", "123 456" and "1 2 3 4 56" are all valid
1894 /// integer strings whose Atoi() value is 123456.
1895 
1897 {
1898  //any whitespace ?
1899  Int_t end = Index(" ");
1900  //if no white spaces in string, just use atoi()
1901  if (end == -1) return atoi(Data());
1902  //make temporary string, removing whitespace
1903  Int_t start = 0;
1904  TString tmp;
1905  //loop over all whitespace
1906  while (end > -1) {
1907  tmp += (*this)(start, end-start);
1908  start = end+1; end = Index(" ", start);
1909  }
1910  //finally add part from last whitespace to end of string
1911  end = Length();
1912  tmp += (*this)(start, end-start);
1913  return atoi(tmp.Data());
1914 }
1915 
1916 ////////////////////////////////////////////////////////////////////////////////
1917 /// Return long long value of string.
1918 /// Valid strings include only digits and whitespace (see IsDigit()),
1919 /// i.e. "123456", "123 456" and "1 2 3 4 56" are all valid
1920 /// integer strings whose Atoll() value is 123456.
1921 
1923 {
1924  //any whitespace ?
1925  Int_t end = Index(" ");
1926  //if no white spaces in string, just use atoi()
1927 #ifndef R__WIN32
1928  if (end == -1) return atoll(Data());
1929 #else
1930  if (end == -1) return _atoi64(Data());
1931 #endif
1932  //make temporary string, removing whitespace
1933  Int_t start = 0;
1934  TString tmp;
1935  //loop over all whitespace
1936  while (end > -1) {
1937  tmp += (*this)(start, end-start);
1938  start = end+1; end = Index(" ", start);
1939  }
1940  //finally add part from last whitespace to end of string
1941  end = Length();
1942  tmp += (*this)(start, end-start);
1943 #ifndef R__WIN32
1944  return atoll(tmp.Data());
1945 #else
1946  return _atoi64(tmp.Data());
1947 #endif
1948 }
1949 
1950 ////////////////////////////////////////////////////////////////////////////////
1951 /// Return floating-point value contained in string.
1952 /// Examples of valid strings are:
1953 /// ~~~ {.cpp}
1954 /// 64320
1955 /// 64 320
1956 /// 6 4 3 2 0
1957 /// 6.4320 6,4320
1958 /// 6.43e20 6.43E20 6,43e20
1959 /// 6.43e-20 6.43E-20 6,43e-20
1960 /// ~~~
1961 
1963 {
1964  //look for a comma and some whitespace
1965  Int_t comma = Index(",");
1966  Int_t end = Index(" ");
1967  //if no commas & no whitespace in string, just use atof()
1968  if (comma == -1 && end == -1) return atof(Data());
1969  TString tmp = *this;
1970  if (comma > -1) {
1971  //replace comma with decimal point
1972  tmp.Replace(comma, 1, ".");
1973  }
1974  //no whitespace ?
1975  if (end == -1) return atof(tmp.Data());
1976  //remove whitespace
1977  Int_t start = 0;
1978  TString tmp2;
1979  while (end > -1) {
1980  tmp2 += tmp(start, end-start);
1981  start = end+1; end = tmp.Index(" ", start);
1982  }
1983  end = tmp.Length();
1984  tmp2 += tmp(start, end-start);
1985  return atof(tmp2.Data());
1986 }
1987 
1988 ////////////////////////////////////////////////////////////////////////////////
1989 /// Converts an Int_t to a TString with respect to the base specified (2-36).
1990 /// Thus it is an enhanced version of sprintf (adapted from versions 0.4 of
1991 /// http://www.jb.man.ac.uk/~slowe/cpp/itoa.html).
1992 /// Usage: the following statement produce the same output, namely "1111"
1993 /// ~~~ {.cpp}
1994 /// std::cout << TString::Itoa(15,2) ;
1995 /// std::cout << TString::Itoa(0xF,2) ; /// 0x prefix to handle hex
1996 /// std::cout << TString::Itoa(017,2) ; /// 0 prefix to handle oct
1997 /// ~~~
1998 /// In case of error returns the "!" string.
1999 
2001 {
2002  std::string buf;
2003  // check that the base if valid
2004  if (base < 2 || base > 36) {
2005  Error("TString::Itoa", "base %d is not supported. Supported bases are {2,3,...,36}.",base) ;
2006  return (TString("!"));
2007  }
2008  buf.reserve(35); // Pre-allocate enough space (35=kMaxDigits)
2009  Int_t quotient = value;
2010  // Translating number to string with base:
2011  do {
2012  buf += "0123456789abcdefghijklmnopqrstuvwxyz"[ TMath::Abs(quotient % base) ];
2013  quotient /= base;
2014  } while (quotient);
2015  // Append the negative sign
2016  if (value < 0) buf += '-';
2017  std::reverse(buf.begin(), buf.end());
2018  return (TString(buf.data()));
2019 }
2020 
2021 ////////////////////////////////////////////////////////////////////////////////
2022 /// Converts a UInt_t (twice the range of an Int_t) to a TString with respect
2023 /// to the base specified (2-36). Thus it is an enhanced version of sprintf
2024 /// (adapted from versions 0.4 of http://www.jb.man.ac.uk/~slowe/cpp/itoa.html).
2025 /// In case of error returns the "!" string.
2026 
2028 {
2029  std::string buf;
2030  // check that the base if valid
2031  if (base < 2 || base > 36) {
2032  Error("TString::UItoa", "base %d is not supported. Supported bases are {2,3,...,36}.",base);
2033  return (TString("!"));
2034  }
2035  buf.reserve(35); // Pre-allocate enough space (35=kMaxDigits)
2036  UInt_t quotient = value;
2037  // Translating number to string with base:
2038  do {
2039  buf += "0123456789abcdefghijklmnopqrstuvwxyz"[ quotient % base ];
2040  quotient /= base;
2041  } while (quotient);
2042  std::reverse(buf.begin(), buf.end());
2043  return (TString(buf.data()));
2044 }
2045 
2046 ////////////////////////////////////////////////////////////////////////////////
2047 /// Converts a Long64_t to a TString with respect to the base specified (2-36).
2048 /// Thus it is an enhanced version of sprintf (adapted from versions 0.4 of
2049 /// http://www.jb.man.ac.uk/~slowe/cpp/itoa.html).
2050 /// In case of error returns the "!" string.
2051 
2053 {
2054  std::string buf;
2055  // check that the base if valid
2056  if (base < 2 || base > 36) {
2057  Error("TString::LLtoa", "base %d is not supported. Supported bases are {2,3,...,36}.",base);
2058  return (TString("!"));
2059  }
2060  buf.reserve(35); // Pre-allocate enough space (35=kMaxDigits)
2061  Long64_t quotient = value;
2062  // Translating number to string with base:
2063  do {
2064  buf += "0123456789abcdefghijklmnopqrstuvwxyz"[ TMath::Abs(quotient % base) ];
2065  quotient /= base;
2066  } while (quotient);
2067  // Append the negative sign
2068  if (value < 0) buf += '-';
2069  std::reverse(buf.begin(), buf.end());
2070  return (TString(buf.data()));
2071 }
2072 
2073 ////////////////////////////////////////////////////////////////////////////////
2074 /// Converts a ULong64_t (twice the range of an Long64_t) to a TString with
2075 /// respect to the base specified (2-36). Thus it is an enhanced version of
2076 /// sprintf (adapted from versions 0.4 of http://www.jb.man.ac.uk/~slowe/cpp/itoa.html).
2077 /// In case of error returns the "!" string.
2078 
2080 {
2081  std::string buf;
2082  // check that the base if valid
2083  if (base < 2 || base > 36) {
2084  Error("TString::ULLtoa", "base %d is not supported. Supported bases are {2,3,...,36}.",base);
2085  return (TString("!"));
2086  }
2087  buf.reserve(35); // Pre-allocate enough space (35=kMaxDigits)
2088  ULong64_t quotient = value;
2089  // Translating number to string with base:
2090  do {
2091  buf += "0123456789abcdefghijklmnopqrstuvwxyz"[ quotient % base ];
2092  quotient /= base;
2093  } while (quotient);
2094  std::reverse(buf.begin(), buf.end());
2095  return (TString(buf.data()));
2096 }
2097 
2098 ////////////////////////////////////////////////////////////////////////////////
2099 /// Converts string from base base_in to base base_out. Supported bases
2100 /// are 2-36. At most 64 bit data can be converted.
2101 
2102 TString TString::BaseConvert(const TString& s_in, Int_t base_in, Int_t base_out)
2103 {
2104  TString s_out = "!" ; // return value in case of issue
2105  // checking base range
2106  if (base_in < 2 || base_in > 36 || base_out < 2 || base_out > 36) {
2107  Error("TString::BaseConvert", "only bases 2-36 are supported (base_in=%d, base_out=%d).", base_in, base_out);
2108  return (s_out);
2109  }
2110  // cleaning s_in
2111  TString s_in_ = s_in;
2112  Bool_t isSigned = kFALSE;
2113  if (s_in_[0] == '-') {
2114  isSigned = kTRUE;
2115  s_in_.Remove(0, 1);
2116  }
2117  if (!isSigned && s_in_[0] == '+') s_in_.Remove(0, 1); // !isSigned to avoid strings beginning with "-+"
2118  if (base_in == 16 && s_in_.BeginsWith("0x")) s_in_.Remove(0, 2); // removing hex prefix if any
2119  s_in_ = TString(s_in_.Strip(TString::kLeading, '0')); // removing leading zeros (necessary for length comparison below)
2120  if (!s_in_.Length()) s_in_ += '0';
2121  // checking s_in_ is expressed in the mentioned base
2122  if (!s_in_.IsInBaseN(base_in)) {
2123  Error("TString::BaseConvert", "s_in=\"%s\" is not in base %d", s_in.Data(), base_in);
2124  return (s_out);
2125  }
2126  // checking s_in <= 64 bits
2127  TString s_max = TString::ULLtoa(18446744073709551615ULL, base_in);
2128  if (s_in_.Length() > s_max.Length()) {
2129  // string comparison (s_in_>s_max) does not take care of length
2130  Error("TString::BaseConvert", "s_in=\"%s\" > %s = 2^64-1 in base %d.", s_in.Data(), s_max.Data(), base_in);
2131  return (s_out);
2132  } else if (s_in_.Length() == s_max.Length()) {
2133  // if ( s_in_.Length() < s_max.Length() ) everything's fine
2134  s_in_.ToLower(); // s_max is lower case
2135  if (s_in_ > s_max) {
2136  // string comparison
2137  Error("TString::BaseConvert", "s_in=\"%s\" > %s = 2^64-1 in base %d.", s_in.Data(), s_max.Data(), base_in);
2138  return (s_out);
2139  }
2140  }
2141 
2142  // computing s_out
2143  ULong64_t i = ULong64_t(strtoull(s_in.Data(), 0, base_in));
2144  s_out = TString::ULLtoa(i, base_out);
2145  if (isSigned) s_out.Prepend("-");
2146  return (s_out);
2147 }
2148 
2149 ////////////////////////////////////////////////////////////////////////////////
2150 /// Return true if string ends with the specified string.
2151 
2152 Bool_t TString::EndsWith(const char *s, ECaseCompare cmp) const
2153 {
2154  if (!s) return kTRUE;
2155 
2156  Ssiz_t l = strlen(s);
2157  if (l > Length()) return kFALSE;
2158  const char *s2 = Data() + Length() - l;
2159 
2160  if (cmp == kExact)
2161  return strcmp(s, s2) == 0;
2162  return strcasecmp(s, s2) == 0;
2163 }
2164 
2165 ////////////////////////////////////////////////////////////////////////////////
2166 /// This function is used to isolate sequential tokens in a TString.
2167 /// These tokens are separated in the string by at least one of the
2168 /// characters in delim. The returned array contains the tokens
2169 /// as TObjString's. The returned array is the owner of the objects,
2170 /// and must be deleted by the user.
2171 
2173 {
2174  std::list<Int_t> splitIndex;
2175 
2176  Int_t i, start, nrDiff = 0;
2177  for (i = 0; i < delim.Length(); i++) {
2178  start = 0;
2179  while (start < Length()) {
2180  Int_t pos = Index(delim(i), start);
2181  if (pos == kNPOS) break;
2182  splitIndex.push_back(pos);
2183  start = pos + 1;
2184  }
2185  if (start > 0) nrDiff++;
2186  }
2187  splitIndex.push_back(Length());
2188 
2189  if (nrDiff > 1)
2190  splitIndex.sort();
2191 
2192  TObjArray *arr = new TObjArray();
2193  arr->SetOwner();
2194 
2195  start = -1;
2196  std::list<Int_t>::const_iterator it;
2197 #ifndef R__HPUX
2198  for (it = splitIndex.begin(); it != splitIndex.end(); ++it) {
2199 #else
2200  for (it = splitIndex.begin(); it != (std::list<Int_t>::const_iterator) splitIndex.end(); ++it) {
2201 #endif
2202  Int_t stop = *it;
2203  if (stop - 1 >= start + 1) {
2204  TString tok = (*this)(start+1, stop-start-1);
2205  TObjString *objstr = new TObjString(tok);
2206  arr->Add(objstr);
2207  }
2208  start = stop;
2209  }
2210 
2211  return arr;
2212 }
2213 
2214 ////////////////////////////////////////////////////////////////////////////////
2215 /// Formats a string using a printf style format descriptor.
2216 /// Existing string contents will be overwritten.
2217 
2218 void TString::FormImp(const char *fmt, va_list ap)
2219 {
2220  Ssiz_t buflen = 20 + 20 * strlen(fmt); // pick a number, any strictly positive number
2221  Clobber(buflen);
2222 
2223  va_list sap;
2224  R__VA_COPY(sap, ap);
2225 
2226  int n, vc = 0;
2227 again:
2228  n = vsnprintf(GetPointer(), buflen, fmt, ap);
2229  // old vsnprintf's return -1 if string is truncated new ones return
2230  // total number of characters that would have been written
2231  if (n == -1 || n >= buflen) {
2232  if (n == -1)
2233  buflen *= 2;
2234  else
2235  buflen = n+1;
2236  Clobber(buflen);
2237  va_end(ap);
2238  R__VA_COPY(ap, sap);
2239  vc = 1;
2240  goto again;
2241  }
2242  va_end(sap);
2243  if (vc)
2244  va_end(ap);
2245 
2246  SetSize(strlen(Data()));
2247 }
2248 
2249 ////////////////////////////////////////////////////////////////////////////////
2250 /// Formats a string using a printf style format descriptor.
2251 /// Existing string contents will be overwritten.
2252 /// See also the static version TString::Format
2253 /// ~~~ {.cpp}
2254 /// TString formatted;
2255 /// formatted.Form("%s in <%s>: %s", type, location, msg);
2256 ///
2257 /// lines.emplace_back(TString::Format("Welcome to ROOT %s%%shttp://root.cern.ch",
2258 /// gROOT->GetVersion()));
2259 /// ~~~
2260 ///
2261 /// Note: this is not to be confused with ::Format and ::Form (in the global namespace)
2262 /// which returns a const char* and relies on a thread-local static character buffer.
2263 
2264 void TString::Form(const char *va_(fmt), ...)
2265 {
2266  va_list ap;
2267  va_start(ap, va_(fmt));
2268  FormImp(va_(fmt), ap);
2269  va_end(ap);
2270 }
2271 
2272 ////////////////////////////////////////////////////////////////////////////////
2273 /// Static method which formats a string using a printf style format
2274 /// descriptor and return a TString. Similar to TString::Form() but it is
2275 /// not needed to first create a TString.
2276 /// ~~~ {.cpp}
2277 /// lines.emplace_back(TString::Format("Welcome to ROOT %s%%shttp://root.cern.ch",
2278 /// gROOT->GetVersion()));
2279 /// TString formatted;
2280 /// formatted.Form("%s in <%s>: %s", type, location, msg);
2281 /// ~~~
2282 ///
2283 /// Note: this is not to be confused with ::Format and ::Form (in the global namespace)
2284 /// which returns a const char* and relies on a thread-local static character buffer.
2285 
2286 TString TString::Format(const char *va_(fmt), ...)
2287 {
2288  va_list ap;
2289  va_start(ap, va_(fmt));
2290  TString str;
2291  str.FormImp(va_(fmt), ap);
2292  va_end(ap);
2293  return str;
2294 }
2295 
2296 //---- Global String Handling Functions ----------------------------------------
2297 
2298 ////////////////////////////////////////////////////////////////////////////////
2299 /// Format a string in a formatting buffer (using a printf style
2300 /// format descriptor).
2301 
2302 static char *SlowFormat(const char *format, va_list ap, int hint)
2303 {
2304  static const int fld_size = 2048;
2305  TTHREAD_TLS(char*) slowBuffer(0);
2306  TTHREAD_TLS(int) slowBufferSize(0);
2307 
2308  if (hint == -1) hint = fld_size;
2309  if (hint > slowBufferSize) {
2310  delete [] slowBuffer;
2311  slowBufferSize = 2 * hint;
2312  if (hint < 0 || slowBufferSize < 0) {
2313  slowBufferSize = 0;
2314  slowBuffer = 0;
2315  return 0;
2316  }
2317  slowBuffer = new char[slowBufferSize];
2318  }
2319 
2320  va_list sap;
2321  R__VA_COPY(sap, ap);
2322 
2323  int n = vsnprintf(slowBuffer, slowBufferSize, format, ap);
2324  // old vsnprintf's return -1 if string is truncated new ones return
2325  // total number of characters that would have been written
2326  if (n == -1 || n >= slowBufferSize) {
2327  if (n == -1) n = 2 * slowBufferSize;
2328  if (n == slowBufferSize) n++;
2329  if (n <= 0) {
2330  va_end(sap);
2331  return 0; // int overflow!
2332  }
2333  va_end(ap);
2334  R__VA_COPY(ap, sap);
2335  char *buf = SlowFormat(format, ap, n);
2336  va_end(sap);
2337  va_end(ap);
2338  return buf;
2339  }
2340 
2341  va_end(sap);
2342 
2343  return slowBuffer;
2344 }
2345 
2346 ////////////////////////////////////////////////////////////////////////////////
2347 /// Format a string in a circular formatting buffer (using a printf style
2348 /// format descriptor).
2349 
2350 static char *Format(const char *format, va_list ap)
2351 {
2352  static const int cb_size = 4096;
2353  static const int fld_size = 2048;
2354 
2355  // a circular formating buffer
2356  TTHREAD_TLS_ARRAY(char,cb_size,gFormbuf); // gFormbuf[cb_size]; // some slob for form overflow
2357  TTHREAD_TLS(char*) gBfree(0);
2358  TTHREAD_TLS(char*) gEndbuf(0);
2359 
2360  if (gBfree == 0) {
2361  gBfree = gFormbuf;
2362  gEndbuf = &gFormbuf[cb_size-1];
2363  }
2364  char *buf = gBfree;
2365 
2366  if (buf+fld_size > gEndbuf)
2367  buf = gFormbuf;
2368 
2369  va_list sap;
2370  R__VA_COPY(sap, ap);
2371 
2372  int n = vsnprintf(buf, fld_size, format, ap);
2373  // old vsnprintf's return -1 if string is truncated new ones return
2374  // total number of characters that would have been written
2375  if (n == -1 || n >= fld_size) {
2376  va_end(ap);
2377  R__VA_COPY(ap, sap);
2378  buf = SlowFormat(format, ap, n);
2379  va_end(sap);
2380  va_end(ap);
2381  return buf;
2382  }
2383 
2384  va_end(sap);
2385 
2386  gBfree = buf+n+1;
2387  return buf;
2388 }
2389 
2390 ////////////////////////////////////////////////////////////////////////////////
2391 /// Formats a string in a circular formatting buffer. Removes the need to
2392 /// create and delete short lived strings. Don't pass Form() pointers
2393 /// from user code down to ROOT functions as the circular buffer may
2394 /// be overwritten downstream. Use Form() results immediately or use
2395 /// TString::Format() instead.
2396 
2397 char *Form(const char *va_(fmt), ...)
2398 {
2399  va_list ap;
2400  va_start(ap,va_(fmt));
2401  char *b = Format(va_(fmt), ap);
2402  va_end(ap);
2403  return b;
2404 }
2405 
2406 ////////////////////////////////////////////////////////////////////////////////
2407 /// Formats a string in a circular formatting buffer and prints the string.
2408 /// Appends a newline. If gPrintViaErrorHandler is true it will print via the
2409 /// currently active ROOT error handler.
2410 
2411 void Printf(const char *va_(fmt), ...)
2412 {
2413  va_list ap;
2414  va_start(ap,va_(fmt));
2416  ErrorHandler(kPrint, 0, va_(fmt), ap);
2417  else {
2418  char *b = Format(va_(fmt), ap);
2419  printf("%s\n", b);
2420  fflush(stdout);
2421  }
2422  va_end(ap);
2423 }
2424 
2425 ////////////////////////////////////////////////////////////////////////////////
2426 /// Strip leading and trailing c (blanks by default) from a string.
2427 /// The returned string has to be deleted by the user.
2428 
2429 char *Strip(const char *s, char c)
2430 {
2431  if (!s) return 0;
2432 
2433  int l = strlen(s);
2434  char *buf = new char[l+1];
2435 
2436  if (l == 0) {
2437  *buf = '\0';
2438  return buf;
2439  }
2440 
2441  // get rid of leading c's
2442  const char *t1 = s;
2443  while (*t1 == c)
2444  t1++;
2445 
2446  // get rid of trailing c's
2447  const char *t2 = s + l - 1;
2448  while (*t2 == c && t2 > s)
2449  t2--;
2450 
2451  if (t1 > t2) {
2452  *buf = '\0';
2453  return buf;
2454  }
2455  strncpy(buf, t1, (Ssiz_t) (t2-t1+1));
2456  *(buf+(t2-t1+1)) = '\0';
2457 
2458  return buf;
2459 }
2460 
2461 ////////////////////////////////////////////////////////////////////////////////
2462 /// Duplicate the string str. The returned string has to be deleted by
2463 /// the user.
2464 
2465 char *StrDup(const char *str)
2466 {
2467  if (!str) return 0;
2468 
2469  char *s = new char[strlen(str)+1];
2470  if (s) strcpy(s, str);
2471 
2472  return s;
2473 }
2474 
2475 ////////////////////////////////////////////////////////////////////////////////
2476 /// Remove all blanks from the string str. The returned string has to be
2477 /// deleted by the user.
2478 
2479 char *Compress(const char *str)
2480 {
2481  if (!str) return 0;
2482 
2483  const char *p = str;
2484  char *s, *s1 = new char[strlen(str)+1];
2485  s = s1;
2486 
2487  while (*p) {
2488  if (*p != ' ')
2489  *s++ = *p;
2490  p++;
2491  }
2492  *s = '\0';
2493 
2494  return s1;
2495 }
2496 
2497 ////////////////////////////////////////////////////////////////////////////////
2498 /// Escape specchars in src with escchar and copy to dst.
2499 
2500 int EscChar(const char *src, char *dst, int dstlen, char *specchars,
2501  char escchar)
2502 {
2503  const char *p;
2504  char *q, *end = dst+dstlen-1;
2505 
2506  for (p = src, q = dst; *p && q < end; ) {
2507  if (strchr(specchars, *p)) {
2508  *q++ = escchar;
2509  if (q < end)
2510  *q++ = *p++;
2511  } else
2512  *q++ = *p++;
2513  }
2514  *q = '\0';
2515 
2516  if (*p != 0)
2517  return -1;
2518  return q-dst;
2519 }
2520 
2521 ////////////////////////////////////////////////////////////////////////////////
2522 /// Un-escape specchars in src from escchar and copy to dst.
2523 
2524 int UnEscChar(const char *src, char *dst, int dstlen, char *specchars, char)
2525 {
2526  const char *p;
2527  char *q, *end = dst+dstlen-1;
2528 
2529  for (p = src, q = dst; *p && q < end; ) {
2530  if (strchr(specchars, *p))
2531  p++;
2532  else
2533  *q++ = *p++;
2534  }
2535  *q = '\0';
2536 
2537  if (*p != 0)
2538  return -1;
2539  return q-dst;
2540 }
2541 
2542 #ifdef NEED_STRCASECMP
2543 ////////////////////////////////////////////////////////////////////////////////
2544 /// Case insensitive string compare.
2545 
2546 int strcasecmp(const char *str1, const char *str2)
2547 {
2548  return strncasecmp(str1, str2, str2 ? strlen(str2)+1 : 0);
2549 }
2550 
2551 ////////////////////////////////////////////////////////////////////////////////
2552 /// Case insensitive string compare of n characters.
2553 
2554 int strncasecmp(const char *str1, const char *str2, Ssiz_t n)
2555 {
2556  while (n > 0) {
2557  int c1 = *str1;
2558  int c2 = *str2;
2559 
2560  if (isupper(c1))
2561  c1 = tolower(c1);
2562 
2563  if (isupper(c2))
2564  c2 = tolower(c2);
2565 
2566  if (c1 != c2)
2567  return c1 - c2;
2568 
2569  str1++;
2570  str2++;
2571  n--;
2572  }
2573  return 0;
2574 }
2575 #endif
2576 
2577 ////////////////////////////////////////////////////////////////////////////////
2578 /// Print a TString in the cling interpreter:
2579 
2580 std::string cling::printValue(const TString* val) {
2581  TString s = TString::Format("\"%s\"[%d]", val->Data(), (int)val->Length());
2582  return s.Data();
2583 }
2584 
2585 ////////////////////////////////////////////////////////////////////////////////
2586 /// Print a TString in the cling interpreter:
2587 
2588 std::string cling::printValue(const TSubString* val) {
2589  TString s = TString::Format("\"%.*s\"[%d]", (int)val->Length(), val->Data(), (int)val->Length());
2590  return s.Data();
2591 }
2592 
2593 ////////////////////////////////////////////////////////////////////////////////
2594 /// Print a TString in the cling interpreter:
2595 
2596 std::string cling::printValue(const std::string_view* val) {
2597  std::string str(*val);
2598  TString s = TString::Format("\"%s\"[%d]", str.c_str(), (int)val->length());
2599  return s.Data();
2600 }
A zero length substring is legal.
Definition: TString.h:77
static Ssiz_t GetMaxWaste()
Definition: TString.cxx:1492
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
void SetBufferOffset(Int_t offset=0)
Definition: TBuffer.h:90
Bool_t IsReading() const
Definition: TBuffer.h:83
void frombuf(char *&buf, Bool_t *x)
Definition: Bytes.h:280
Ssiz_t Capacity() const
Definition: TString.h:352
Bool_t IsWriting() const
Definition: TBuffer.h:84
void ToLower()
Convert sub-string to lower-case.
Definition: TString.cxx:1650
An array of TObjects.
Definition: TObjArray.h:37
TSubString & operator=(const char *s)
Assign char* to sub-string.
Definition: TString.cxx:1604
static TString Itoa(Int_t value, Int_t base)
Converts an Int_t to a TString with respect to the base specified (2-36).
Definition: TString.cxx:2000
long long Long64_t
Definition: RtypesCore.h:69
TString operator+(const TString &s, const char *cs)
Use the special concatenation constructor.
Definition: TString.cxx:1433
static Ssiz_t MaxWaste(Ssiz_t mw=15)
Set maximum space that may be wasted in a string before doing a resize.
Definition: TString.cxx:1520
char * Compress(const char *str)
Remove all blanks from the string str.
Definition: TString.cxx:2479
void Final()
MD5 finalization, ends an MD5 message-digest operation, writing the the message digest and zeroizing ...
Definition: TMD5.cxx:167
#define R__ALWAYS_INLINE
Definition: RConfig.h:556
void ToUpper()
Convert sub-string to upper-case.
Definition: TString.cxx:1662
Collectable string class.
Definition: TObjString.h:28
return c1
Definition: legend1.C:41
char * Form(const char *va_(fmt),...)
Formats a string in a circular formatting buffer.
Definition: TString.cxx:2397
friend Bool_t operator==(const TSubString &s1, const TSubString &s2)
Compare two sub-strings.
Definition: TString.cxx:1639
const Ssiz_t kNPOS
Definition: RtypesCore.h:111
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:687
char * StrDup(const char *str)
Duplicate the string str.
Definition: TString.cxx:2465
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
unsigned int Replace(std::string &s, const std::string what, const std::string withWhat)
TString & fStr
Definition: TString.h:87
Bool_t IsFloat() const
Returns kTRUE if string contains a floating point or integer number.
Definition: TString.cxx:1766
void Clone(Ssiz_t nc)
Make self a distinct copy with capacity of at least tot, where tot cannot be smaller than the current...
Definition: TString.cxx:1187
static TString UItoa(UInt_t value, Int_t base)
Converts a UInt_t (twice the range of an Int_t) to a TString with respect to the base specified (2-36...
Definition: TString.cxx:2027
void ToUpper()
Change string to upper case.
Definition: TString.cxx:1113
Buffer base class used for serializing objects.
Definition: TBuffer.h:40
#define R__ASSERT(e)
Definition: TError.h:96
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:634
Bool_t operator==(const TString &s1, const char *s2)
Compare TString with a char *.
Definition: TString.cxx:1390
const char * AsString() const
Return message digest as string.
Definition: TMD5.cxx:220
TString ToUpper(const TString &str)
Return an upper-case version of str.
Definition: TString.cxx:1419
Basic string class.
Definition: TString.h:131
#define f(i)
Definition: RSha256.hxx:104
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:168
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1100
int Int_t
Definition: RtypesCore.h:41
TString & operator=(char s)
Assign character c to TString.
Definition: TString.cxx:255
bool Bool_t
Definition: RtypesCore.h:59
Ssiz_t Length() const
Definition: TString.h:114
virtual void WriteClass(const TClass *cl)=0
static Ssiz_t ResizeIncrement(Ssiz_t ri=16)
Set default resize increment for all TStrings. Default is 16.
Definition: TString.cxx:1510
TString Copy() const
Copy a string.
Definition: TString.cxx:478
char * GetPointer()
Definition: TString.h:242
virtual void WriteTString(const TString &s)=0
RawStr_t fRaw
Definition: TString.h:203
TString ToLower(const TString &str)
Return a lower-case version of str.
Definition: TString.cxx:1405
STL namespace.
Rep_t fRep
Definition: TString.h:209
TString & Prepend(const char *cs)
Definition: TString.h:656
TBuffer & operator<<(TBuffer &buf, const TString *s)
Write TString or derived to TBuffer.
Definition: TString.cxx:1378
const char * Data() const
Definition: TString.h:721
static void WriteString(TBuffer &b, const TString *a)
Write TString object to buffer.
Definition: TString.cxx:1336
void Obsolete(const char *function, const char *asOfVers, const char *removedFromVers)
Use this function to declare a function obsolete.
Definition: TError.cxx:278
Bool_t MaybeWildcard() const
Returns true if string contains one of the wildcard characters "[]*?".
Definition: TString.cxx:909
Short_t Abs(Short_t d)
Definition: TMathBase.h:108
char * Init(Ssiz_t capacity, Ssiz_t nchar)
Private member function returning an empty string representation of size capacity and containing ncha...
Definition: TString.cxx:227
UInt_t Hash(ECaseCompare cmp=kExact) const
Return hash value.
Definition: TString.cxx:626
static int MemIsEqual(const char *p, const char *q, Ssiz_t n)
Returns false if strings are not equal.
Definition: TString.cxx:834
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
Definition: TString.h:677
Int_t Length() const
Definition: TBuffer.h:96
Double_t x[n]
Definition: legend1.C:17
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
Definition: TString.cxx:2286
virtual void ReadBuffer(char *&buffer)
Read string from I/O buffer.
Definition: TString.cxx:1239
void Class()
Definition: Class.C:29
This code implements the MD5 message-digest algorithm.
Definition: TMD5.h:44
UInt_t HashFoldCase() const
Return a case-insensitive hash value (endian independent).
Definition: TString.cxx:611
Bool_t IsAlnum() const
Returns true if all characters in string are alphanumeric.
Definition: TString.cxx:1721
void Init(TClassEdit::TInterpreterLookupHelper *helper)
Definition: TClassEdit.cxx:121
static TString * ReadString(TBuffer &b, const TClass *clReq)
Read TString object from buffer.
Definition: TString.cxx:1270
void Clear()
Clear string without changing its capacity.
Definition: TString.cxx:1151
virtual void InitMap()=0
friend class TString
Definition: TString.h:80
ECaseCompare
Definition: TString.h:263
TString & Append(const char *cs)
Definition: TString.h:559
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2152
static Ssiz_t GetInitialCapacity()
Definition: TString.cxx:1476
Bool_t IsNull() const
Definition: TString.h:121
char * Strip(const char *s, char c)
Strip leading and trailing c (blanks by default) from a string.
Definition: TString.cxx:2429
#define va_(arg)
Definition: Varargs.h:41
void AssertElement(Ssiz_t nc) const
Check to make sure a string index is in range.
Definition: TString.cxx:1126
Ssiz_t First(char c) const
Find first occurrence of a character c.
Definition: TString.cxx:487
void tobuf(char *&buf, Bool_t x)
Definition: Bytes.h:57
TH1F * h1
Definition: legend1.C:5
Long64_t Atoll() const
Return long long value of string.
Definition: TString.cxx:1922
void Error(const char *location, const char *msgfmt,...)
Bool_t IsAlpha() const
Returns true if all characters in string are alphabetic.
Definition: TString.cxx:1706
char & operator()(Ssiz_t i)
Definition: TString.h:709
static UInt_t SwapInt(UInt_t x)
Definition: TString.cxx:505
Bool_t IsOct() const
Returns true if all characters in string are octal digits (0-7).
Definition: TString.cxx:1832
#define ROTL64(x, y)
Definition: TString.cxx:674
std::string printValue(const TDatime *val)
Print a TDatime at the prompt.
Definition: TDatime.cxx:514
char & operator[](Ssiz_t i)
Return character at pos i from sub-string. Check validity of i.
Definition: TString.cxx:1576
R__EXTERN Bool_t gPrintViaErrorHandler
Definition: TError.h:107
const Int_t kPrint
Definition: TError.h:36
ROOT::R::TRInterface & r
Definition: Object.C:4
#define R__VA_COPY(to, from)
Definition: Varargs.h:58
void Update(const UChar_t *buf, UInt_t len)
Update TMD5 object to reflect the concatenation of another buffer full of bytes.
Definition: TMD5.cxx:108
char & operator()(Ssiz_t i)
Return character at pos i from sub-string. No check on i.
Definition: TString.cxx:1585
UInt_t HashCase() const
Return a case-sensitive hash value (endian independent).
Definition: TString.cxx:582
auto * a
Definition: textangle.C:12
#define BIG_CONSTANT(x)
Definition: TString.cxx:675
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:610
Ssiz_t fExtent
Definition: TString.h:89
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2264
unsigned int UInt_t
Definition: RtypesCore.h:42
TBuffer & operator>>(TBuffer &buf, TString *&s)
Read string from TBuffer. Function declared in ClassDef.
Definition: TString.cxx:1369
Ssiz_t Length() const
Definition: TString.h:405
TString MD5() const
Return the MD5 digest for this string, in a string representation.
Definition: TString.cxx:885
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
Definition: TString.cxx:1081
#define s1(x)
Definition: RSha256.hxx:91
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:75
virtual void SetByteCount(UInt_t cntpos, Bool_t packInVersion=kFALSE)=0
static Ssiz_t GetResizeIncrement()
Definition: TString.cxx:1484
int UnEscChar(const char *src, char *dst, int dstlen, char *specchars, char)
Un-escape specchars in src from escchar and copy to dst.
Definition: TString.cxx:2524
static constexpr double ms
#define h(i)
Definition: RSha256.hxx:106
static Ssiz_t InitialCapacity(Ssiz_t ic=15)
Set default initial capacity for all TStrings. Default is 15.
Definition: TString.cxx:1501
void FormImp(const char *fmt, va_list ap)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2218
const Bool_t kFALSE
Definition: RtypesCore.h:88
void Clobber(Ssiz_t nc)
Clear string and make sure it has a capacity of nc.
Definition: TString.cxx:1159
TString & Remove(Ssiz_t pos)
Definition: TString.h:668
int Ssiz_t
Definition: RtypesCore.h:63
RooCmdArg Index(RooCategory &icat)
#define d(i)
Definition: RSha256.hxx:102
Bool_t IsInBaseN(Int_t base) const
Returns true if all characters in string are expressed in the base specified (range=2-36), i.e.
Definition: TString.cxx:1865
Bool_t IsDec() const
Returns true if all characters in string are decimal digits (0-9).
Definition: TString.cxx:1848
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition: TString.cxx:2172
char * GetLongPointer()
Definition: TString.h:238
return c2
Definition: legend2.C:14
int EscChar(const char *src, char *dst, int dstlen, char *specchars, char escchar)
Escape specchars in src with escchar and copy to dst.
Definition: TString.cxx:2500
auto * t1
Definition: textangle.C:20
#define ClassImp(name)
Definition: Rtypes.h:359
static char * SlowFormat(const char *format, va_list ap, int hint)
Format a string in a formatting buffer (using a printf style format descriptor).
Definition: TString.cxx:2302
double Double_t
Definition: RtypesCore.h:55
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition: TString.cxx:876
Ssiz_t GetLongSize() const
Definition: TString.h:233
const UInt_t kHashShift
Definition: TString.cxx:68
unsigned long long ULong64_t
Definition: RtypesCore.h:70
Ssiz_t fBegin
Definition: TString.h:88
unsigned long ULong_t
Definition: RtypesCore.h:51
virtual Int_t Sizeof() const
Returns size string will occupy on I/O buffer.
Definition: TString.cxx:1309
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.
Definition: TString.cxx:2102
basic_string_view< char > string_view
Definition: RStringView.hxx:35
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
static TString ULLtoa(ULong64_t value, Int_t base)
Converts a ULong64_t (twice the range of an Long64_t) to a TString with respect to the base specified...
Definition: TString.cxx:2079
static constexpr double s
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition: TString.cxx:406
virtual void ReadTString(TString &s)=0
Bool_t IsNull() const
Definition: TString.h:402
Bool_t IsAscii() const
Returns true if all characters in string are ascii.
Definition: TString.cxx:1693
void SubStringError(Ssiz_t, Ssiz_t, Ssiz_t) const
Output error message.
Definition: TString.cxx:1674
void ErrorHandler(int level, const char *location, const char *fmt, va_list va)
General error handler function. It calls the user set error handler.
Definition: TError.cxx:202
auto * l
Definition: textangle.C:4
TSubString(const TString &s, Ssiz_t start, Ssiz_t len)
Private constructor.
Definition: TString.cxx:1539
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:200
Bool_t IsHex() const
Returns true if all characters in string are hexadecimal digits (0-9,a-f,A-F).
Definition: TString.cxx:1800
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
uint64_t rotl64(uint64_t x, int8_t r)
Definition: TString.cxx:669
Bool_t IsBin() const
Returns true if all characters in string are binary digits (0,1).
Definition: TString.cxx:1816
virtual TClass * ReadClass(const TClass *cl=0, UInt_t *objTag=0)=0
const size_t kBitsPerByte
Definition: RtypesCore.h:110
Int_t CountChar(Int_t c) const
Return number of times character c occurs in the string.
Definition: TString.cxx:464
#define c(i)
Definition: RSha256.hxx:101
Int_t Atoi() const
Return integer value of string.
Definition: TString.cxx:1896
static TString LLtoa(Long64_t value, Int_t base)
Converts a Long64_t to a TString with respect to the base specified (2-36).
Definition: TString.cxx:2052
TString()
TString default ctor.
Definition: TString.cxx:87
void Add(TObject *obj)
Definition: TObjArray.h:73
Double_t Atof() const
Return floating-point value contained in string.
Definition: TString.cxx:1962
Bool_t IsDigit() const
Returns true if all characters in string are digits (0-9) or white spaces, i.e.
Definition: TString.cxx:1738
unsigned char UChar_t
Definition: RtypesCore.h:34
static void Mash(UInt_t &hash, UInt_t chars)
Utility used by Hash().
Definition: TString.cxx:515
virtual void FillBuffer(char *&buffer) const
Copy string into I/O buffer.
Definition: TString.cxx:1218
Definition: first.py:1
UInt_t Hash(const char *str)
Return a case-sensitive hash value (endian independent).
Definition: TString.cxx:525
Bool_t IsLong() const
Definition: TString.h:224
float * q
Definition: THbookFile.cxx:87
static constexpr double sr
TSubString SubString(const char *pat, Ssiz_t start=0, ECaseCompare cmp=kExact) const
Returns a substring matching "pattern", or the null substring if there is no such match...
Definition: TString.cxx:1565
const Bool_t kTRUE
Definition: RtypesCore.h:87
void AssertElement(Ssiz_t i) const
Check to make sure a sub-string index is in range.
Definition: TString.cxx:1683
void Printf(const char *va_(fmt),...)
Formats a string in a circular formatting buffer and prints the string.
Definition: TString.cxx:2411
const Int_t n
Definition: legend1.C:16
static Ssiz_t AdjustCapacity(Ssiz_t oldCap, Ssiz_t newCap)
Calculate a nice capacity greater than or equal to newCap.
Definition: TString.cxx:1136
Bool_t MaybeRegexp() const
Returns true if string contains one of the regexp characters "^$.[]*+?".
Definition: TString.cxx:897
EStripType
Definition: TString.h:262
void InitChar(char c)
Initialize a string with a single character.
Definition: TString.cxx:135
void Resize(Ssiz_t n)
Resize the string. Truncate or add blanks as necessary.
Definition: TString.cxx:1070
virtual ~TString()
Delete a TString.
Definition: TString.cxx:218
static char * Format(const char *format, va_list ap)
Format a string in a circular formatting buffer (using a printf style format descriptor).
Definition: TString.cxx:2350
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition: TClass.cxx:4792
const char * Data() const
Definition: TString.h:364