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