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