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