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