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