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