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