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