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