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