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