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