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 for (int i = 0; i < nchars; i++) frombuf(buffer, &data[i]);
1359}
1360
1361////////////////////////////////////////////////////////////////////////////////
1362/// Read TString object from buffer. Simplified version of
1363/// TBuffer::ReadObject (does not keep track of multiple
1364/// references to same string). We need to have it here
1365/// because TBuffer::ReadObject can only handle descendant
1366/// of TObject.
1367
1369{
1370 R__ASSERT(b.IsReading());
1371
1372 // Make sure ReadArray is initialized
1373 b.InitMap();
1374
1375 // Before reading object save start position
1376 UInt_t startpos = UInt_t(b.Length());
1377
1378 UInt_t tag;
1379 TClass *clRef = b.ReadClass(clReq, &tag);
1380
1381 TString *a;
1382 if (!clRef) {
1383
1384 a = nullptr;
1385
1386 } else {
1387
1388 a = (TString *) clRef->New();
1389 if (!a) {
1390 ::Error("TString::ReadObject", "could not create object of class %s",
1391 clRef->GetName());
1392 // Exception
1393 return a;
1394 }
1395
1396 a->Streamer(b);
1397
1398 b.CheckByteCount(startpos, tag, clRef);
1399 }
1400
1401 return a;
1402}
1403
1404////////////////////////////////////////////////////////////////////////////////
1405/// Returns size string will occupy on I/O buffer.
1406
1408{
1409 if (Length() > 254)
1410 return Length()+sizeof(UChar_t)+sizeof(Int_t);
1411 else
1412 return Length()+sizeof(UChar_t);
1413}
1414
1415////////////////////////////////////////////////////////////////////////////////
1416/// Stream a string object.
1417
1419{
1420 if (b.IsReading()) {
1421 b.ReadTString(*this);
1422 } else {
1423 b.WriteTString(*this);
1424 }
1425}
1426
1427////////////////////////////////////////////////////////////////////////////////
1428/// Write TString object to buffer. Simplified version of
1429/// TBuffer::WriteObject (does not keep track of multiple
1430/// references to the same string). We need to have it here
1431/// because TBuffer::ReadObject can only handle descendant
1432/// of TObject
1433
1435{
1436 R__ASSERT(b.IsWriting());
1437
1438 // Make sure WriteMap is initialized
1439 b.InitMap();
1440
1441 if (!a) {
1442
1443 b << (UInt_t) 0;
1444
1445 } else {
1446
1447 // Reserve space for leading byte count
1448 UInt_t cntpos = UInt_t(b.Length());
1449 b.SetBufferOffset(Int_t(cntpos+sizeof(UInt_t)));
1450
1451 TClass *cl = a->IsA();
1452 b.WriteClass(cl);
1453
1454 ((TString *)a)->Streamer(b);
1455
1456 // Write byte count
1457 b.SetByteCount(cntpos);
1458 }
1459}
1460
1461////////////////////////////////////////////////////////////////////////////////
1462/// Read string from TBuffer. Function declared in ClassDef.
1463
1464#if defined(R__TEMPLATE_OVERLOAD_BUG)
1465template <>
1466#endif
1468{
1470 return buf;
1471}
1472
1473////////////////////////////////////////////////////////////////////////////////
1474/// Write TString or derived to TBuffer.
1475
1477{
1478 TString::WriteString(buf, s);
1479 return buf;
1480}
1481
1482////////////////////////////////////////////////////////////////////////////////
1483// Related global functions
1484
1485////////////////////////////////////////////////////////////////////////////////
1486/// Compare TString with a char *.
1487
1488Bool_t operator==(const TString& s1, const char *s2)
1489{
1490 if (!s2) return kFALSE;
1491
1492 const char *data = s1.Data();
1493 Ssiz_t len = s1.Length();
1494 Ssiz_t i;
1495 for (i = 0; s2[i]; ++i)
1496 if (data[i] != s2[i] || i == len) return kFALSE;
1497 return (i == len);
1498}
1499
1500////////////////////////////////////////////////////////////////////////////////
1501/// Return a lower-case version of str.
1502
1504{
1505 Ssiz_t n = str.Length();
1506 TString temp((char)0, n);
1507 const char *uc = str.Data();
1508 char *lc = (char*)temp.Data();
1509 // Guard against tolower() being a macro
1510 while (n--) { *lc++ = tolower((unsigned char)*uc); uc++; }
1511 return temp;
1512}
1513
1514////////////////////////////////////////////////////////////////////////////////
1515/// Return an upper-case version of str.
1516
1518{
1519 Ssiz_t n = str.Length();
1520 TString temp((char)0, n);
1521 const char* uc = str.Data();
1522 char* lc = (char*)temp.Data();
1523 // Guard against toupper() being a macro
1524 while (n--) { *lc++ = toupper((unsigned char)*uc); uc++; }
1525 return temp;
1526}
1527
1528////////////////////////////////////////////////////////////////////////////////
1529/// Use the special concatenation constructor.
1530
1531TString operator+(const TString &s, const char *cs)
1532{
1533 return TString(s.Data(), s.Length(), cs, cs ? strlen(cs) : 0);
1534}
1535
1536////////////////////////////////////////////////////////////////////////////////
1537/// Use the special concatenation constructor.
1538
1539TString operator+(const char *cs, const TString &s)
1540{
1541 return TString(cs, cs ? strlen(cs) : 0, s.Data(), s.Length());
1542}
1543
1544////////////////////////////////////////////////////////////////////////////////
1545/// Use the special concatenation constructor.
1546
1548{
1549 return TString(s1.Data(), s1.Length(), s2.Data(), s2.Length());
1550}
1551
1552////////////////////////////////////////////////////////////////////////////////
1553/// Add char to string.
1554
1556{
1557 return TString(s.Data(), s.Length(), &c, 1);
1558}
1559
1560////////////////////////////////////////////////////////////////////////////////
1561/// Add string to char.
1562
1564{
1565 return TString(&c, 1, s.Data(), s.Length());
1566}
1567
1568////////////////////////////////////////////////////////////////////////////////
1569// Static Member Functions
1570// The static data members access
1571
1572////////////////////////////////////////////////////////////////////////////////
1573
1575{
1576 ::Obsolete("TString::GetInitialCapacity", "v5-30-00", "v5-32-00");
1577 return 15;
1578}
1579
1580////////////////////////////////////////////////////////////////////////////////
1581
1583{
1584 ::Obsolete("TString::GetResizeIncrement", "v5-30-00", "v5-32-00");
1585 return 16;
1586}
1587
1588////////////////////////////////////////////////////////////////////////////////
1589
1591{
1592 ::Obsolete("TString::GetMaxWaste", "v5-30-00", "v5-32-00");
1593 return 15;
1594}
1595
1596////////////////////////////////////////////////////////////////////////////////
1597/// Set default initial capacity for all TStrings. Default is 15.
1598
1600{
1601 ::Obsolete("TString::InitialCapacity", "v5-30-00", "v5-32-00");
1602 return 15;
1603}
1604
1605////////////////////////////////////////////////////////////////////////////////
1606/// Set default resize increment for all TStrings. Default is 16.
1607
1609{
1610 ::Obsolete("TString::ResizeIncrement", "v5-30-00", "v5-32-00");
1611 return 16;
1612}
1613
1614////////////////////////////////////////////////////////////////////////////////
1615/// Set maximum space that may be wasted in a string before doing a resize.
1616/// Default is 15.
1617
1619{
1620 ::Obsolete("TString::MaxWaste", "v5-30-00", "v5-32-00");
1621 return 15;
1622}
1623
1624/** \class TSubString
1625A zero length substring is legal. It can start
1626at any character. It is considered to be "pointing"
1627to just before the character.
1628
1629A "null" substring is a zero length substring that
1630starts with the nonsense index kNPOS. It can
1631be detected with the member function IsNull().
1632*/
1633
1634////////////////////////////////////////////////////////////////////////////////
1635/// Private constructor.
1636
1638 : fStr((TString&)str), fBegin(start), fExtent(nextent)
1639{
1640}
1641
1642////////////////////////////////////////////////////////////////////////////////
1643/// Return sub-string of string starting at start with length len.
1644
1646{
1647 if (start < Length() && len > 0) {
1648 if (start+len > Length())
1649 len = Length() - start;
1650 } else {
1651 start = kNPOS;
1652 len = 0;
1653 }
1654 return TSubString(*this, start, len);
1655}
1656
1657////////////////////////////////////////////////////////////////////////////////
1658/// Returns a substring matching "pattern", or the null substring
1659/// if there is no such match. It would be nice if this could be yet another
1660/// overloaded version of operator(), but this would result in a type
1661/// conversion ambiguity with operator(Ssiz_t, Ssiz_t).
1662
1664 ECaseCompare cmp) const
1665{
1666 Ssiz_t len = pattern ? strlen(pattern) : 0;
1667 Ssiz_t i = Index(pattern, len, startIndex, cmp);
1668 return TSubString(*this, i, i == kNPOS ? 0 : len);
1669}
1670
1671////////////////////////////////////////////////////////////////////////////////
1672/// Return character at pos i from sub-string. Check validity of i.
1673
1675{
1676 AssertElement(i);
1677 return fStr(fBegin+i);
1678}
1679
1680////////////////////////////////////////////////////////////////////////////////
1681/// Return character at pos i from sub-string. No check on i.
1682
1684{
1685 return fStr(fBegin+i);
1686}
1687
1688////////////////////////////////////////////////////////////////////////////////
1689/// Assign string to sub-string.
1690
1692{
1693 if (!IsNull())
1694 fStr.Replace(fBegin, fExtent, str.Data(), str.Length());
1695
1696 return *this;
1697}
1698
1699////////////////////////////////////////////////////////////////////////////////
1700/// Assign char* to sub-string.
1701
1703{
1704 if (!IsNull())
1705 fStr.Replace(fBegin, fExtent, cs, cs ? strlen(cs) : 0);
1706
1707 return *this;
1708}
1709
1710////////////////////////////////////////////////////////////////////////////////
1711/// Compare sub-string to char *.
1712
1713Bool_t operator==(const TSubString& ss, const char *cs)
1714{
1715 if (ss.IsNull()) return *cs =='\0'; // Two null strings compare equal
1716
1717 const char* data = ss.fStr.Data() + ss.fBegin;
1718 Ssiz_t i;
1719 for (i = 0; cs[i]; ++i)
1720 if (cs[i] != data[i] || i == ss.fExtent) return kFALSE;
1721 return (i == ss.fExtent);
1722}
1723
1724////////////////////////////////////////////////////////////////////////////////
1725/// Compare sub-string to string.
1726
1728{
1729 if (ss.IsNull()) return s.IsNull(); // Two null strings compare equal.
1730 if (ss.fExtent != s.Length()) return kFALSE;
1731 return !memcmp(ss.fStr.Data() + ss.fBegin, s.Data(), ss.fExtent);
1732}
1733
1734////////////////////////////////////////////////////////////////////////////////
1735/// Compare two sub-strings.
1736
1738{
1739 if (s1.IsNull()) return s2.IsNull();
1740 if (s1.fExtent != s2.fExtent) return kFALSE;
1741 return !memcmp(s1.fStr.Data()+s1.fBegin, s2.fStr.Data()+s2.fBegin,
1742 s1.fExtent);
1743}
1744
1745////////////////////////////////////////////////////////////////////////////////
1746/// Convert sub-string to lower-case.
1747
1749{
1750 if (!IsNull()) { // Ignore null substrings
1751 char *p = fStr.GetPointer() + fBegin;
1752 Ssiz_t n = fExtent;
1753 while (n--) { *p = tolower((unsigned char)*p); p++;}
1754 }
1755}
1756
1757////////////////////////////////////////////////////////////////////////////////
1758/// Convert sub-string to upper-case.
1759
1761{
1762 if (!IsNull()) { // Ignore null substrings
1763 char *p = fStr.GetPointer() + fBegin;
1764 Ssiz_t n = fExtent;
1765 while (n--) { *p = toupper((unsigned char)*p); p++;}
1766 }
1767}
1768
1769////////////////////////////////////////////////////////////////////////////////
1770/// Output error message.
1771
1773{
1774 Error("TSubString::SubStringError",
1775 "out of bounds: start = %d, n = %d, sr = %d", start, n, sr);
1776}
1777
1778////////////////////////////////////////////////////////////////////////////////
1779/// Check to make sure a sub-string index is in range.
1780
1782{
1783 if (i == kNPOS || i >= Length())
1784 Error("TSubString::AssertElement",
1785 "out of bounds: i = %d, Length = %d", i, Length());
1786}
1787
1788////////////////////////////////////////////////////////////////////////////////
1789/// Returns true if all characters in string are ascii.
1790
1792{
1793 const char *cp = Data();
1794 for (Ssiz_t i = 0; i < Length(); ++i)
1795 if (cp[i] & ~0x7F)
1796 return kFALSE;
1797 return kTRUE;
1798}
1799
1800////////////////////////////////////////////////////////////////////////////////
1801/// Returns true if all characters in string are alphabetic.
1802/// Returns false in case string length is 0.
1803
1805{
1806 const char *cp = Data();
1807 Ssiz_t len = Length();
1808 if (len == 0) return kFALSE;
1809 for (Ssiz_t i = 0; i < len; ++i)
1810 if (!isalpha(cp[i]))
1811 return kFALSE;
1812 return kTRUE;
1813}
1814
1815////////////////////////////////////////////////////////////////////////////////
1816/// Returns true if all characters in string are alphanumeric.
1817/// Returns false in case string length is 0.
1818
1820{
1821 const char *cp = Data();
1822 Ssiz_t len = Length();
1823 if (len == 0) return kFALSE;
1824 for (Ssiz_t i = 0; i < len; ++i)
1825 if (!isalnum(cp[i]))
1826 return kFALSE;
1827 return kTRUE;
1828}
1829
1830////////////////////////////////////////////////////////////////////////////////
1831/// Returns true if all characters in string are digits (0-9) or white spaces,
1832/// i.e. "123456" and "123 456" are both valid integer strings.
1833/// Returns false in case string length is 0 or string contains other
1834/// characters or only whitespace.
1835
1837{
1838 const char *cp = Data();
1839 Ssiz_t len = Length();
1840 if (len == 0) return kFALSE;
1841 Int_t b = 0, d = 0;
1842 for (Ssiz_t i = 0; i < len; ++i) {
1843 if (cp[i] != ' ' && !isdigit(cp[i])) return kFALSE;
1844 if (cp[i] == ' ') b++;
1845 if (isdigit(cp[i])) d++;
1846 }
1847 if (b && !d)
1848 return kFALSE;
1849 return kTRUE;
1850}
1851
1852////////////////////////////////////////////////////////////////////////////////
1853/// Returns kTRUE if string contains a floating point or integer number.
1854/// Examples of valid formats are:
1855/// ~~~ {.cpp}
1856/// 64320
1857/// 64 320
1858/// 6 4 3 2 0
1859/// 6.4320 6,4320
1860/// 6.43e20 6.43E20 6,43e20
1861/// 6.43e-20 6.43E-20 6,43e-20, -6.43e+20
1862/// ~~~
1863
1865{
1866 //we first check if we have an integer, in this case, IsDigit() will be true straight away
1867 if (IsDigit()) return kTRUE;
1868
1869 TString tmp = *this;
1870 //now we look for occurrences of '.', ',', e', 'E', '+', '-' and replace each
1871 //with ' ', if it is a floating point, IsDigit() will then return kTRUE
1872
1873 tmp.ToLower();
1874 Ssiz_t pos = tmp.First('.');
1875 if (pos != kNPOS) tmp.Replace(pos, 1, " ", 1);
1876 pos = tmp.First(',');
1877 if (pos != kNPOS) tmp.Replace(pos, 1, " ", 1);
1878 pos = tmp.Index("e-");
1879 if (pos >= 1) tmp.Replace(pos, 2, " ", 1);
1880 pos = tmp.Index("e+");
1881 if (pos >= 1) tmp.Replace(pos, 2, " ", 1);
1882 pos = tmp.Index("e");
1883 if (pos >= 1) tmp.Replace(pos, 1, " ", 1);
1884 pos = tmp.First('-');
1885 if (pos == 0) tmp.Replace(pos, 1, " ", 1);
1886 pos = tmp.First('+');
1887 if (pos == 0) tmp.Replace(pos, 1, " ", 1);
1888
1889 //test if it is now uniquely composed of numbers
1890 return tmp.IsDigit();
1891}
1892
1893////////////////////////////////////////////////////////////////////////////////
1894/// Returns true if all characters in string are hexadecimal digits
1895/// (0-9,a-f,A-F). Returns false in case string length is 0 or string
1896/// contains other characters.
1897
1899{
1900 const char *cp = Data();
1901 Ssiz_t len = Length();
1902 if (len == 0) return kFALSE;
1903 for (Ssiz_t i = 0; i < len; ++i)
1904 if (!isxdigit(cp[i]))
1905 return kFALSE;
1906 return kTRUE;
1907}
1908
1909////////////////////////////////////////////////////////////////////////////////
1910/// Returns true if all characters in string are binary digits (0,1).
1911/// Returns false in case string length is 0 or string contains other
1912/// characters.
1913
1915{
1916 const char *cp = Data();
1917 Ssiz_t len = Length();
1918 if (len == 0) return kFALSE;
1919 for (Ssiz_t i = 0; i < len; ++i)
1920 if (cp[i] != '0' && cp[i] != '1')
1921 return kFALSE;
1922 return kTRUE;
1923}
1924
1925////////////////////////////////////////////////////////////////////////////////
1926/// Returns true if all characters in string are octal digits (0-7).
1927/// Returns false in case string length is 0 or string contains other
1928/// characters.
1929
1931{
1932 const char *cp = Data();
1933 Ssiz_t len = Length();
1934 if (len == 0) return kFALSE;
1935 for (Ssiz_t i = 0; i < len; ++i)
1936 if (!isdigit(cp[i]) || cp[i]=='8' || cp[i]=='9')
1937 return kFALSE;
1938 return kTRUE;
1939}
1940
1941////////////////////////////////////////////////////////////////////////////////
1942/// Returns true if all characters in string are decimal digits (0-9).
1943/// Returns false in case string length is 0 or string contains other
1944/// characters.
1945
1947{
1948 const char *cp = Data();
1949 Ssiz_t len = Length();
1950 if (len == 0) return kFALSE;
1951 for (Ssiz_t i = 0; i < len; ++i)
1952 if (!isdigit(cp[i]))
1953 return kFALSE;
1954 return kTRUE;
1955}
1956
1957////////////////////////////////////////////////////////////////////////////////
1958/// Returns true if all characters in string are expressed in the base
1959/// specified (range=2-36), i.e. {0,1} for base 2, {0-9,a-f,A-F} for base 16,
1960/// {0-9,a-z,A-Z} for base 36. Returns false in case string length is 0 or
1961/// string contains other characters.
1962
1964{
1965 if (base < 2 || base > 36) {
1966 Error("TString::IsInBaseN", "base %d is not supported. Supported bases are {2,3,...,36}.", base);
1967 return kFALSE;
1968 }
1969 if (Length() == 0) {
1970 Error("TString::IsInBaseN", "input string is empty.") ;
1971 return kFALSE;
1972 }
1973 TString str = TString(Data()) ;
1974 str.ToUpper() ;
1975 TString str_ref0 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
1977 str_ref.Remove(base) ;
1979 for (Int_t k = 0; k < str.Length(); k++) {
1980 if (! str_ref.Contains(str[k])) {
1981 isInBase = kFALSE ;
1982 break ;
1983 }
1984 }
1985 return (isInBase);
1986}
1987
1988////////////////////////////////////////////////////////////////////////////////
1989/// Return integer value of string.
1990/// Valid strings include only digits and whitespace (see IsDigit()),
1991/// i.e. "123456", "123 456" and "1 2 3 4 56" are all valid
1992/// integer strings whose Atoi() value is 123456.
1993
1995{
1996 //any whitespace ?
1997 Int_t end = Index(" ");
1998 //if no white spaces in string, just use atoi()
1999 if (end == -1) return atoi(Data());
2000 //make temporary string, removing whitespace
2001 Int_t start = 0;
2002 TString tmp;
2003 //loop over all whitespace
2004 while (end > -1) {
2005 tmp += (*this)(start, end-start);
2006 start = end+1; end = Index(" ", start);
2007 }
2008 //finally add part from last whitespace to end of string
2009 end = Length();
2010 tmp += (*this)(start, end-start);
2011 return atoi(tmp.Data());
2012}
2013
2014////////////////////////////////////////////////////////////////////////////////
2015/// Return long long value of string.
2016/// Valid strings include only digits and whitespace (see IsDigit()),
2017/// i.e. "123456", "123 456" and "1 2 3 4 56" are all valid
2018/// integer strings whose Atoll() value is 123456.
2019
2021{
2022 //any whitespace ?
2023 Int_t end = Index(" ");
2024 //if no white spaces in string, just use atoi()
2025#ifndef R__WIN32
2026 if (end == -1) return atoll(Data());
2027#else
2028 if (end == -1) return _atoi64(Data());
2029#endif
2030 //make temporary string, removing whitespace
2031 Int_t start = 0;
2032 TString tmp;
2033 //loop over all whitespace
2034 while (end > -1) {
2035 tmp += (*this)(start, end-start);
2036 start = end+1; end = Index(" ", start);
2037 }
2038 //finally add part from last whitespace to end of string
2039 end = Length();
2040 tmp += (*this)(start, end-start);
2041#ifndef R__WIN32
2042 return atoll(tmp.Data());
2043#else
2044 return _atoi64(tmp.Data());
2045#endif
2046}
2047
2048////////////////////////////////////////////////////////////////////////////////
2049/// Return floating-point value contained in string.
2050/// Examples of valid strings are:
2051/// ~~~ {.cpp}
2052/// 64320
2053/// 64 320
2054/// 6 4 3 2 0
2055/// 6.4320 6,4320
2056/// 6.43e20 6.43E20 6,43e20
2057/// 6.43e-20 6.43E-20 6,43e-20
2058/// ~~~
2059
2061{
2062 //look for a comma and some whitespace
2063 Int_t comma = Index(",");
2064 Int_t end = Index(" ");
2065 //if no commas & no whitespace in string, just use atof()
2066 if (comma == -1 && end == -1) return atof(Data());
2067 TString tmp = *this;
2068 if (comma > -1) {
2069 //replace comma with decimal point
2070 tmp.Replace(comma, 1, ".");
2071 }
2072 //no whitespace ?
2073 if (end == -1) return atof(tmp.Data());
2074 //remove whitespace
2075 Int_t start = 0;
2076 TString tmp2;
2077 while (end > -1) {
2078 tmp2 += tmp(start, end-start);
2079 start = end+1; end = tmp.Index(" ", start);
2080 }
2081 end = tmp.Length();
2082 tmp2 += tmp(start, end-start);
2083 return atof(tmp2.Data());
2084}
2085
2086////////////////////////////////////////////////////////////////////////////////
2087/// Converts an Int_t to a TString with respect to the base specified (2-36).
2088/// Thus it is an enhanced version of sprintf (adapted from versions 0.4 of
2089/// http://www.jb.man.ac.uk/~slowe/cpp/itoa.html).
2090/// Usage: the following statement produce the same output, namely "1111"
2091/// ~~~ {.cpp}
2092/// std::cout << TString::Itoa(15,2) ;
2093/// std::cout << TString::Itoa(0xF,2) ; /// 0x prefix to handle hex
2094/// std::cout << TString::Itoa(017,2) ; /// 0 prefix to handle oct
2095/// ~~~
2096/// In case of error returns the "!" string.
2097
2099{
2100 std::string buf;
2101 // check that the base if valid
2102 if (base < 2 || base > 36) {
2103 Error("TString::Itoa", "base %d is not supported. Supported bases are {2,3,...,36}.",base) ;
2104 return (TString("!"));
2105 }
2106 buf.reserve(35); // Pre-allocate enough space (35=kMaxDigits)
2108 // Translating number to string with base:
2109 do {
2110 buf += "0123456789abcdefghijklmnopqrstuvwxyz"[ std::abs(quotient % base) ];
2111 quotient /= base;
2112 } while (quotient);
2113 // Append the negative sign
2114 if (value < 0) buf += '-';
2115 std::reverse(buf.begin(), buf.end());
2116 return (TString(buf.data()));
2117}
2118
2119////////////////////////////////////////////////////////////////////////////////
2120/// Converts a UInt_t (twice the range of an Int_t) to a TString with respect
2121/// to the base specified (2-36). Thus it is an enhanced version of sprintf
2122/// (adapted from versions 0.4 of http://www.jb.man.ac.uk/~slowe/cpp/itoa.html).
2123/// In case of error returns the "!" string.
2124
2126{
2127 std::string buf;
2128 // check that the base if valid
2129 if (base < 2 || base > 36) {
2130 Error("TString::UItoa", "base %d is not supported. Supported bases are {2,3,...,36}.",base);
2131 return (TString("!"));
2132 }
2133 buf.reserve(35); // Pre-allocate enough space (35=kMaxDigits)
2135 // Translating number to string with base:
2136 do {
2137 buf += "0123456789abcdefghijklmnopqrstuvwxyz"[ quotient % base ];
2138 quotient /= base;
2139 } while (quotient);
2140 std::reverse(buf.begin(), buf.end());
2141 return (TString(buf.data()));
2142}
2143
2144////////////////////////////////////////////////////////////////////////////////
2145/// Converts a Long64_t to a TString with respect to the base specified (2-36).
2146/// Thus it is an enhanced version of sprintf (adapted from versions 0.4 of
2147/// http://www.jb.man.ac.uk/~slowe/cpp/itoa.html).
2148/// In case of error returns the "!" string.
2149
2151{
2152 std::string buf;
2153 // check that the base if valid
2154 if (base < 2 || base > 36) {
2155 Error("TString::LLtoa", "base %d is not supported. Supported bases are {2,3,...,36}.",base);
2156 return (TString("!"));
2157 }
2158 buf.reserve(35); // Pre-allocate enough space (35=kMaxDigits)
2160 // Translating number to string with base:
2161 do {
2162 buf += "0123456789abcdefghijklmnopqrstuvwxyz"[ std::abs(quotient % base) ];
2163 quotient /= base;
2164 } while (quotient);
2165 // Append the negative sign
2166 if (value < 0) buf += '-';
2167 std::reverse(buf.begin(), buf.end());
2168 return (TString(buf.data()));
2169}
2170
2171////////////////////////////////////////////////////////////////////////////////
2172/// Converts a ULong64_t (twice the range of an Long64_t) to a TString with
2173/// respect to the base specified (2-36). Thus it is an enhanced version of
2174/// sprintf (adapted from versions 0.4 of http://www.jb.man.ac.uk/~slowe/cpp/itoa.html).
2175/// In case of error returns the "!" string.
2176
2178{
2179 std::string buf;
2180 // check that the base if valid
2181 if (base < 2 || base > 36) {
2182 Error("TString::ULLtoa", "base %d is not supported. Supported bases are {2,3,...,36}.",base);
2183 return (TString("!"));
2184 }
2185 buf.reserve(35); // Pre-allocate enough space (35=kMaxDigits)
2187 // Translating number to string with base:
2188 do {
2189 buf += "0123456789abcdefghijklmnopqrstuvwxyz"[ quotient % base ];
2190 quotient /= base;
2191 } while (quotient);
2192 std::reverse(buf.begin(), buf.end());
2193 return (TString(buf.data()));
2194}
2195
2196////////////////////////////////////////////////////////////////////////////////
2197/// Converts string from base base_in to base base_out. Supported bases
2198/// are 2-36. At most 64 bit data can be converted.
2199
2201{
2202 TString s_out = "!" ; // return value in case of issue
2203 // checking base range
2205 Error("TString::BaseConvert", "only bases 2-36 are supported (base_in=%d, base_out=%d).", base_in, base_out);
2206 return (s_out);
2207 }
2208 // cleaning s_in
2209 TString s_in_ = s_in;
2211 if (s_in_[0] == '-') {
2212 isSigned = kTRUE;
2213 s_in_.Remove(0, 1);
2214 }
2215 if (!isSigned && s_in_[0] == '+') s_in_.Remove(0, 1); // !isSigned to avoid strings beginning with "-+"
2216 if (base_in == 16 && s_in_.BeginsWith("0x")) s_in_.Remove(0, 2); // removing hex prefix if any
2217 s_in_ = TString(s_in_.Strip(TString::kLeading, '0')); // removing leading zeros (necessary for length comparison below)
2218 if (!s_in_.Length()) s_in_ += '0';
2219 // checking s_in_ is expressed in the mentioned base
2220 if (!s_in_.IsInBaseN(base_in)) {
2221 Error("TString::BaseConvert", "s_in=\"%s\" is not in base %d", s_in.Data(), base_in);
2222 return (s_out);
2223 }
2224 // checking s_in <= 64 bits
2225 TString s_max = TString::ULLtoa(18446744073709551615ULL, base_in);
2226 if (s_in_.Length() > s_max.Length()) {
2227 // string comparison (s_in_>s_max) does not take care of length
2228 Error("TString::BaseConvert", "s_in=\"%s\" > %s = 2^64-1 in base %d.", s_in.Data(), s_max.Data(), base_in);
2229 return (s_out);
2230 } else if (s_in_.Length() == s_max.Length()) {
2231 // if ( s_in_.Length() < s_max.Length() ) everything's fine
2232 s_in_.ToLower(); // s_max is lower case
2233 if (s_in_ > s_max) {
2234 // string comparison
2235 Error("TString::BaseConvert", "s_in=\"%s\" > %s = 2^64-1 in base %d.", s_in.Data(), s_max.Data(), base_in);
2236 return (s_out);
2237 }
2238 }
2239
2240 // computing s_out
2241 ULong64_t i = ULong64_t(strtoull(s_in.Data(), nullptr, base_in));
2243 if (isSigned) s_out.Prepend("-");
2244 return (s_out);
2245}
2246
2247////////////////////////////////////////////////////////////////////////////////
2248/// Return true if string ends with the specified string.
2249
2250Bool_t TString::EndsWith(const char *s, ECaseCompare cmp) const
2251{
2252 if (!s) return kTRUE;
2253
2254 Ssiz_t l = strlen(s);
2255 if (l > Length()) return kFALSE;
2256 const char *s2 = Data() + Length() - l;
2257
2258 if (cmp == kExact)
2259 return strcmp(s, s2) == 0;
2260 return strcasecmp(s, s2) == 0;
2261}
2262
2263////////////////////////////////////////////////////////////////////////////////
2264/// This function is used to isolate sequential tokens in a TString.
2265/// These tokens are separated in the string by at least one of the
2266/// characters in delim. The returned array contains the tokens
2267/// as TObjString's. The returned array is the owner of the objects,
2268/// and must be deleted by the user.
2269
2271{
2272 std::list<Int_t> splitIndex;
2273
2274 Int_t i, start, nrDiff = 0;
2275 for (i = 0; i < delim.Length(); i++) {
2276 start = 0;
2277 while (start < Length()) {
2278 Int_t pos = Index(delim(i), start);
2279 if (pos == kNPOS) break;
2280 splitIndex.push_back(pos);
2281 start = pos + 1;
2282 }
2283 if (start > 0) nrDiff++;
2284 }
2285 splitIndex.push_back(Length());
2286
2287 if (nrDiff > 1)
2288 splitIndex.sort();
2289
2290 TObjArray *arr = new TObjArray();
2291 arr->SetOwner();
2292
2293 start = -1;
2294 std::list<Int_t>::const_iterator it;
2295#ifndef R__HPUX
2296 for (it = splitIndex.begin(); it != splitIndex.end(); ++it) {
2297#else
2298 for (it = splitIndex.begin(); it != (std::list<Int_t>::const_iterator) splitIndex.end(); ++it) {
2299#endif
2300 Int_t stop = *it;
2301 if (stop - 1 >= start + 1) {
2302 TString tok = (*this)(start+1, stop-start-1);
2304 arr->Add(objstr);
2305 }
2306 start = stop;
2307 }
2308
2309 return arr;
2310}
2311
2312////////////////////////////////////////////////////////////////////////////////
2313/// Formats a string using a printf style format descriptor.
2314/// Existing string contents will be overwritten.
2315
2316void TString::FormImp(const char *fmt, va_list ap)
2317{
2318 Ssiz_t buflen = 20 + 20 * strlen(fmt); // pick a number, any strictly positive number
2319 buflen = Clobber(buflen); // Update buflen, as Clobber clamps length to MaxSize (if Fatal does not abort)
2320
2321 va_list sap;
2322 R__VA_COPY(sap, ap);
2323
2324 int n, vc = 0;
2325again:
2326 n = vsnprintf(GetPointer(), buflen, fmt, ap);
2327 // old vsnprintf's return -1 if string is truncated new ones return
2328 // total number of characters that would have been written
2329 if (n == -1 || n >= buflen) {
2330 if (n == -1)
2331 buflen *= 2;
2332 else
2333 buflen = n+1;
2334 buflen = Clobber(buflen);
2335 va_end(ap);
2336 R__VA_COPY(ap, sap);
2337 vc = 1;
2338 goto again;
2339 }
2340 va_end(sap);
2341 if (vc)
2342 va_end(ap);
2343
2344 SetSize(strlen(Data()));
2345}
2346
2347////////////////////////////////////////////////////////////////////////////////
2348/// Formats a string using a printf style format descriptor.
2349/// Existing string contents will be overwritten.
2350/// See also the static version TString::Format
2351/// ~~~ {.cpp}
2352/// TString formatted;
2353/// formatted.Form("%s in <%s>: %s", type, location, msg);
2354///
2355/// lines.emplace_back(TString::Format("Welcome to ROOT %s%%shttp://root.cern",
2356/// gROOT->GetVersion()));
2357/// ~~~
2358///
2359/// Note: this is not to be confused with ::Format and ::Form (in the global namespace)
2360/// which returns a const char* and relies on a thread-local static character buffer.
2361
2362void TString::Form(const char *va_(fmt), ...)
2363{
2364 va_list ap;
2365 va_start(ap, va_(fmt));
2366 FormImp(va_(fmt), ap);
2367 va_end(ap);
2368}
2369
2370////////////////////////////////////////////////////////////////////////////////
2371/// Static method which formats a string using a printf style format
2372/// descriptor and return a TString. Similar to TString::Form() but it is
2373/// not needed to first create a TString.
2374/// ~~~ {.cpp}
2375/// lines.emplace_back(TString::Format("Welcome to ROOT %s%%shttp://root.cern",
2376/// gROOT->GetVersion()));
2377/// TString formatted;
2378/// formatted.Form("%s in <%s>: %s", type, location, msg);
2379/// ~~~
2380///
2381/// Note: this is not to be confused with ::Format and ::Form (in the global namespace)
2382/// which returns a const char* and relies on a thread-local static character buffer.
2383
2384TString TString::Format(const char *va_(fmt), ...)
2385{
2386 va_list ap;
2387 va_start(ap, va_(fmt));
2388 TString str;
2389 str.FormImp(va_(fmt), ap);
2390 va_end(ap);
2391 return str;
2392}
2393
2394//---- Global String Handling Functions ----------------------------------------
2395
2396////////////////////////////////////////////////////////////////////////////////
2397/// Format a string in a formatting buffer (using a printf style
2398/// format descriptor).
2399
2400static char *SlowFormat(const char *format, va_list ap, int hint)
2401{
2402 static const int fld_size = 2048;
2403 TTHREAD_TLS(char*) slowBuffer(nullptr);
2405
2406 if (hint == -1) hint = fld_size;
2407 if (hint > slowBufferSize) {
2408 delete [] slowBuffer;
2409 slowBufferSize = 2 * hint;
2410 if (hint < 0 || slowBufferSize < 0) {
2411 slowBufferSize = 0;
2412 slowBuffer = nullptr;
2413 return nullptr;
2414 }
2415 slowBuffer = new char[slowBufferSize];
2416 }
2417
2418 va_list sap;
2419 R__VA_COPY(sap, ap);
2420
2422 // old vsnprintf's return -1 if string is truncated new ones return
2423 // total number of characters that would have been written
2424 if (n == -1 || n >= slowBufferSize) {
2425 if (n == -1) n = 2 * slowBufferSize;
2426 if (n == slowBufferSize) n++;
2427 if (n <= 0) {
2428 va_end(sap);
2429 return nullptr; // int overflow!
2430 }
2431 va_end(ap);
2432 R__VA_COPY(ap, sap);
2433 char *buf = SlowFormat(format, ap, n);
2434 va_end(sap);
2435 va_end(ap);
2436 return buf;
2437 }
2438
2439 va_end(sap);
2440
2441 return slowBuffer;
2442}
2443
2444////////////////////////////////////////////////////////////////////////////////
2445/// Format a string in a circular formatting buffer (using a printf style
2446/// format descriptor).
2447
2448static char *Format(const char *format, va_list ap)
2449{
2450 static const int cb_size = 4096;
2451 static const int fld_size = 2048;
2452
2453 // a circular formating buffer
2454 TTHREAD_TLS_ARRAY(char,cb_size,gFormbuf); // gFormbuf[cb_size]; // some slob for form overflow
2455 TTHREAD_TLS(char*) gBfree(nullptr);
2456 TTHREAD_TLS(char*) gEndbuf(nullptr);
2457
2458 if (gBfree == nullptr) {
2459 gBfree = gFormbuf;
2460 gEndbuf = &gFormbuf[cb_size-1];
2461 }
2462 char *buf = gBfree;
2463
2464 if (buf+fld_size > gEndbuf)
2465 buf = gFormbuf;
2466
2467 va_list sap;
2468 R__VA_COPY(sap, ap);
2469
2470 int n = vsnprintf(buf, fld_size, format, ap);
2471 // old vsnprintf's return -1 if string is truncated new ones return
2472 // total number of characters that would have been written
2473 if (n == -1 || n >= fld_size) {
2474 va_end(ap);
2475 R__VA_COPY(ap, sap);
2476 buf = SlowFormat(format, ap, n);
2477 va_end(sap);
2478 va_end(ap);
2479 return buf;
2480 }
2481
2482 va_end(sap);
2483
2484 gBfree = buf+n+1;
2485 return buf;
2486}
2487
2488////////////////////////////////////////////////////////////////////////////////
2489/// Formats a string in a circular formatting buffer. Removes the need to
2490/// create and delete short lived strings. Don't pass Form() pointers
2491/// from user code down to ROOT functions as the circular buffer may
2492/// be overwritten downstream. Use Form() results immediately or use
2493/// TString::Format() instead.
2494
2495char *Form(const char *va_(fmt), ...)
2496{
2497 va_list ap;
2498 va_start(ap,va_(fmt));
2499 char *b = Format(va_(fmt), ap);
2500 va_end(ap);
2501 return b;
2502}
2503
2504////////////////////////////////////////////////////////////////////////////////
2505/// Formats a string in a circular formatting buffer and prints the string.
2506/// Appends a newline. If gPrintViaErrorHandler is true it will print via the
2507/// currently active ROOT error handler.
2508
2509void Printf(const char *va_(fmt), ...)
2510{
2511 va_list ap;
2512 va_start(ap,va_(fmt));
2514 ErrorHandler(kPrint, nullptr, va_(fmt), ap);
2515 else {
2516 char *b = Format(va_(fmt), ap);
2517 printf("%s\n", b);
2518 fflush(stdout);
2519 }
2520 va_end(ap);
2521}
2522
2523////////////////////////////////////////////////////////////////////////////////
2524/// Strip leading and trailing c (blanks by default) from a string.
2525/// The returned string has to be deleted by the user.
2526
2527char *Strip(const char *s, char c)
2528{
2529 if (!s) return nullptr;
2530
2531 int l = strlen(s);
2532 char *buf = new char[l+1];
2533
2534 if (l == 0) {
2535 *buf = '\0';
2536 return buf;
2537 }
2538
2539 // get rid of leading c's
2540 const char *t1 = s;
2541 while (*t1 == c)
2542 t1++;
2543
2544 // get rid of trailing c's
2545 const char *t2 = s + l - 1;
2546 while (*t2 == c && t2 > s)
2547 t2--;
2548
2549 if (t1 > t2) {
2550 *buf = '\0';
2551 return buf;
2552 }
2553 strncpy(buf, t1, (Ssiz_t) (t2-t1+1));
2554 *(buf+(t2-t1+1)) = '\0';
2555
2556 return buf;
2557}
2558
2559////////////////////////////////////////////////////////////////////////////////
2560/// Duplicate the string str. The returned string has to be deleted by
2561/// the user.
2562
2563char *StrDup(const char *str)
2564{
2565 if (!str) return nullptr;
2566
2567 auto len = strlen(str)+1;
2568 char *s = new char[len];
2569 if (s) strlcpy(s, str, len);
2570
2571 return s;
2572}
2573
2574////////////////////////////////////////////////////////////////////////////////
2575/// Remove all blanks from the string str. The returned string has to be
2576/// deleted by the user.
2577
2578char *Compress(const char *str)
2579{
2580 if (!str) return nullptr;
2581
2582 const char *p = str;
2583 char *s, *s1 = new char[strlen(str)+1];
2584 s = s1;
2585
2586 while (*p) {
2587 if (*p != ' ')
2588 *s++ = *p;
2589 p++;
2590 }
2591 *s = '\0';
2592
2593 return s1;
2594}
2595
2596////////////////////////////////////////////////////////////////////////////////
2597/// Escape specchars in src with escchar and copy to dst.
2598
2599int EscChar(const char *src, char *dst, int dstlen, char *specchars,
2600 char escchar)
2601{
2602 const char *p;
2603 char *q, *end = dst+dstlen-1;
2604
2605 for (p = src, q = dst; *p && q < end; ) {
2606 if (strchr(specchars, *p)) {
2607 *q++ = escchar;
2608 if (q < end)
2609 *q++ = *p++;
2610 } else
2611 *q++ = *p++;
2612 }
2613 *q = '\0';
2614
2615 if (*p != 0)
2616 return -1;
2617 return q-dst;
2618}
2619
2620////////////////////////////////////////////////////////////////////////////////
2621/// Un-escape specchars in src from escchar and copy to dst.
2622
2623int UnEscChar(const char *src, char *dst, int dstlen, char *specchars, char)
2624{
2625 const char *p;
2626 char *q, *end = dst+dstlen-1;
2627
2628 for (p = src, q = dst; *p && q < end; ) {
2629 if (strchr(specchars, *p))
2630 p++;
2631 else
2632 *q++ = *p++;
2633 }
2634 *q = '\0';
2635
2636 if (*p != 0)
2637 return -1;
2638 return q-dst;
2639}
2640
2641#ifdef NEED_STRCASECMP
2642////////////////////////////////////////////////////////////////////////////////
2643/// Case insensitive string compare.
2644
2645int strcasecmp(const char *str1, const char *str2)
2646{
2647 return strncasecmp(str1, str2, str2 ? strlen(str2)+1 : 0);
2648}
2649
2650////////////////////////////////////////////////////////////////////////////////
2651/// Case insensitive string compare of n characters.
2652
2653int strncasecmp(const char *str1, const char *str2, Ssiz_t n)
2654{
2655 while (n > 0) {
2656 int c1 = *str1;
2657 int c2 = *str2;
2658
2659 if (isupper(c1))
2660 c1 = tolower(c1);
2661
2662 if (isupper(c2))
2663 c2 = tolower(c2);
2664
2665 if (c1 != c2)
2666 return c1 - c2;
2667
2668 str1++;
2669 str2++;
2670 n--;
2671 }
2672 return 0;
2673}
2674#endif
2675
2676////////////////////////////////////////////////////////////////////////////////
2677/// Print a TString in the cling interpreter:
2678
2679std::string cling::printValue(const TString* val) {
2680 TString s = TString::Format("\"%s\"[%d]", val->Data(), (int)val->Length());
2681 return s.Data();
2682}
2683
2684////////////////////////////////////////////////////////////////////////////////
2685/// Print a TString in the cling interpreter:
2686
2687std::string cling::printValue(const TSubString* val) {
2688 TString s = TString::Format("\"%.*s\"[%d]", (int)val->Length(), val->Data(), (int)val->Length());
2689 return s.Data();
2690}
2691
2692////////////////////////////////////////////////////////////////////////////////
2693/// Print a TString in the cling interpreter:
2694
2695std::string cling::printValue(const std::string_view* val) {
2696 std::string str(*val);
2697 TString s = TString::Format("\"%s\"[%d]", str.c_str(), (int)val->length());
2698 return s.Data();
2699}
void frombuf(char *&buf, Bool_t *x)
Definition Bytes.h:278
void tobuf(char *&buf, Bool_t x)
Definition Bytes.h:55
#define R__ALWAYS_INLINE
Definition RConfig.hxx:560
#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:59
unsigned char UChar_t
Unsigned Character 1 byte (unsigned char)
Definition RtypesCore.h:52
int Ssiz_t
String size (currently int)
Definition RtypesCore.h:81
constexpr ULong_t kBitsPerByte
Definition RtypesCore.h:130
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int)
Definition RtypesCore.h:60
unsigned long ULongptr_t
Unsigned integer large enough to hold a pointer (platform-dependent)
Definition RtypesCore.h:90
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
constexpr Ssiz_t kNPOS
The equivalent of std::string::npos for the ROOT class TString.
Definition RtypesCore.h:131
long long Long64_t
Portable signed long integer 8 bytes.
Definition RtypesCore.h:83
unsigned long long ULong64_t
Portable unsigned long integer 8 bytes.
Definition RtypesCore.h:84
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
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:1476
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:1503
TString operator+(const TString &s, const char *cs)
Use the special concatenation constructor.
Definition TString.cxx:1531
#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:1467
#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:1488
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:2400
TString ToUpper(const TString &str)
Return an upper-case version of str.
Definition TString.cxx:1517
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:2578
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:2623
void Printf(const char *fmt,...)
Formats a string in a circular formatting buffer and prints the string.
Definition TString.cxx:2509
char * StrDup(const char *str)
Duplicate the string str.
Definition TString.cxx:2563
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:2599
#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:623
TClass * IsA() const override
Definition TClass.h:634
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:2125
Ssiz_t Length() const
Definition TString.h:425
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:2150
Rep_t fRep
Definition TString.h:223
void SetShortSize(Ssiz_t s)
Definition TString.h:251
char & operator()(Ssiz_t i)
Definition TString.h:732
Bool_t IsDec() const
Returns true if all characters in string are decimal digits (0-9).
Definition TString.cxx:1946
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:1618
Int_t Atoi() const
Return integer value of string.
Definition TString.cxx:1994
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:2250
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:1898
Double_t Atof() const
Return floating-point value contained in string.
Definition TString.cxx:2060
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:1864
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:1663
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
Definition TString.h:702
Ssiz_t First(char c) const
Find first occurrence of a character c.
Definition TString.cxx:545
const char * Data() const
Definition TString.h:384
static TString * ReadString(TBuffer &b, const TClass *clReq)
Read TString object from buffer.
Definition TString.cxx:1368
Bool_t IsDigit() const
Returns true if all characters in string are digits (0-9) or white spaces, i.e.
Definition TString.cxx:1836
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:1608
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:1930
virtual ~TString()
Delete a TString.
Definition TString.cxx:258
Ssiz_t Capacity() const
Definition TString.h:372
static Ssiz_t GetMaxWaste()
Definition TString.cxx:1590
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:712
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:1804
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:1791
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition TString.cxx:2270
static Ssiz_t GetResizeIncrement()
Definition TString.cxx:1582
void SetLongCap(Ssiz_t s)
Definition TString.h:257
TString & Prepend(const char *cs)
Definition TString.h:681
Bool_t IsBin() const
Returns true if all characters in string are binary digits (0,1).
Definition TString.cxx:1914
void UnLink() const
Definition TString.h:271
Bool_t IsNull() const
Definition TString.h:422
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:2200
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:2177
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:1434
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:693
static Ssiz_t InitialCapacity(Ssiz_t ic=15)
Set default initial capacity for all TStrings. Default is 15.
Definition TString.cxx:1599
virtual void Streamer(TBuffer &)
Stream a string object.
Definition TString.cxx:1418
char * GetShortPointer()
Definition TString.h:262
TString & Append(const char *cs)
Definition TString.h:580
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:1963
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:2384
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:2098
virtual Int_t Sizeof() const
Returns size string will occupy on I/O buffer.
Definition TString.cxx:1407
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:2362
static TClass * Class()
static Ssiz_t GetInitialCapacity()
Definition TString.cxx:1574
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:1819
void FormImp(const char *fmt, va_list ap)
Formats a string using a printf style format descriptor.
Definition TString.cxx:2316
char * GetPointer()
Definition TString.h:264
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:659
static Ssiz_t Recommend(Ssiz_t s)
Definition TString.h:234
Long64_t Atoll() const
Return long long value of string.
Definition TString.cxx:2020
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:1637
TSubString & operator=(const char *s)
Assign char* to sub-string.
Definition TString.cxx:1702
Bool_t IsNull() const
Definition TString.h:128
void ToUpper()
Convert sub-string to upper-case.
Definition TString.cxx:1760
TString & fStr
Definition TString.h:94
void SubStringError(Ssiz_t, Ssiz_t, Ssiz_t) const
Output error message.
Definition TString.cxx:1772
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:1674
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:1781
void ToLower()
Convert sub-string to lower-case.
Definition TString.cxx:1748
const char * Data() const
Definition TString.h:744
char & operator()(Ssiz_t i)
Return character at pos i from sub-string. No check on i.
Definition TString.cxx:1683
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
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