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