Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TBufferText.cxx
Go to the documentation of this file.
1// $Id$
2// Author: Sergey Linev 21.12.2017
3
4/*************************************************************************
5 * Copyright (C) 1995-2017, 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/**
13\class TBufferText
14\ingroup IO
15
16Base class for text-based streamers like TBufferJSON or TBufferXML
17Special actions list will use methods, introduced in this class.
18
19Idea to have equivalent methods names in TBufferFile and TBufferText, that
20actions list for both are the same.
21*/
22
23#include "TBufferText.h"
24
25#include "TStreamerInfo.h"
26#include "TStreamerElement.h"
28#include "TFile.h"
29#include "TVirtualMutex.h"
30#include "TInterpreter.h"
31#include "TExMap.h"
32#include "TError.h"
33#include "snprintf.h"
34
36
37const char *TBufferText::fgFloatFmt = "%e";
38const char *TBufferText::fgDoubleFmt = "%.14e";
39
40////////////////////////////////////////////////////////////////////////////////
41/// Default constructor
42
44{
45}
46
47////////////////////////////////////////////////////////////////////////////////
48/// Normal constructor
49
51{
52 fBufSize = 1000000000;
53
54 SetParent(parent);
56}
57
58////////////////////////////////////////////////////////////////////////////////
59/// destructor
60
62{
63}
64
65////////////////////////////////////////////////////////////////////////////////
66/// Read one collection of objects from the buffer using the StreamerInfoLoopAction.
67/// The collection needs to be a split TClonesArray or a split vector of pointers.
68
70{
71 TVirtualStreamerInfo *info = sequence.fStreamerInfo;
72 IncrementLevel(info);
73
74 if (gDebug) {
75 // loop on all active members
76 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
77 for (TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin(); iter != end;
78 ++iter) {
79 // Idea: Try to remove this function call as it is really needed only for JSON streaming.
80 SetStreamerElementNumber((*iter).fConfiguration->fCompInfo->fElem, (*iter).fConfiguration->fCompInfo->fType);
81 (*iter).PrintDebug(*this, obj);
82 (*iter)(*this, obj);
83 }
84 } else {
85 // loop on all active members
86 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
87 for (TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin(); iter != end;
88 ++iter) {
89 // Idea: Try to remove this function call as it is really needed only for JSON streaming.
90 SetStreamerElementNumber((*iter).fConfiguration->fCompInfo->fElem, (*iter).fConfiguration->fCompInfo->fType);
91 (*iter)(*this, obj);
92 }
93 }
94 DecrementLevel(info);
95 return 0;
96}
97
98////////////////////////////////////////////////////////////////////////////////
99/// Read one collection of objects from the buffer using the StreamerInfoLoopAction.
100/// The collection needs to be a split TClonesArray or a split vector of pointers.
101
103 void *end_collection)
104{
105 TVirtualStreamerInfo *info = sequence.fStreamerInfo;
106 IncrementLevel(info);
107
108 if (gDebug) {
109 // loop on all active members
110 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
111 for (TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin(); iter != end;
112 ++iter) {
113 // Idea: Try to remove this function call as it is really needed only for JSON streaming.
114 SetStreamerElementNumber((*iter).fConfiguration->fCompInfo->fElem, (*iter).fConfiguration->fCompInfo->fType);
115 (*iter).PrintDebug(
116 *this, *(char **)start_collection); // Warning: This limits us to TClonesArray and vector of pointers.
117 (*iter)(*this, start_collection, end_collection);
118 }
119 } else {
120 // loop on all active members
121 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
122 for (TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin(); iter != end;
123 ++iter) {
124 // Idea: Try to remove this function call as it is really needed only for JSON streaming.
125 SetStreamerElementNumber((*iter).fConfiguration->fCompInfo->fElem, (*iter).fConfiguration->fCompInfo->fType);
126 (*iter)(*this, start_collection, end_collection);
127 }
128 }
129 DecrementLevel(info);
130 return 0;
131}
132
133////////////////////////////////////////////////////////////////////////////////
134/// Read one collection of objects from the buffer using the StreamerInfoLoopAction.
135
137 void *end_collection)
138{
139 TVirtualStreamerInfo *info = sequence.fStreamerInfo;
140 IncrementLevel(info);
141
143 if (gDebug) {
144
145 // Get the address of the first item for the PrintDebug.
146 // (Performance is not essential here since we are going to print to
147 // the screen anyway).
148 void *arr0 = loopconfig->GetFirstAddress(start_collection, end_collection);
149 // loop on all active members
150 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
151 for (TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin(); iter != end;
152 ++iter) {
153 // Idea: Try to remove this function call as it is really needed only for JSON streaming.
154 SetStreamerElementNumber((*iter).fConfiguration->fCompInfo->fElem, (*iter).fConfiguration->fCompInfo->fType);
155 (*iter).PrintDebug(*this, arr0);
156 (*iter)(*this, start_collection, end_collection, loopconfig);
157 }
158 } else {
159 // loop on all active members
160 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
161 for (TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin(); iter != end;
162 ++iter) {
163 // Idea: Try to remove this function call as it is really needed only for JSON streaming.
164 SetStreamerElementNumber((*iter).fConfiguration->fCompInfo->fElem, (*iter).fConfiguration->fCompInfo->fType);
165 (*iter)(*this, start_collection, end_collection, loopconfig);
166 }
167 }
168 DecrementLevel(info);
169 return 0;
170}
171
172////////////////////////////////////////////////////////////////////////////////
173/// Function called by the Streamer functions to serialize object at p
174/// to buffer b. The optional argument info may be specified to give an
175/// alternative StreamerInfo instead of using the default StreamerInfo
176/// automatically built from the class definition.
177/// For more information, see class TStreamerInfo.
178
180{
181 // build the StreamerInfo if first time for the class
182 TStreamerInfo *sinfo = (TStreamerInfo *)const_cast<TClass *>(cl)->GetCurrentStreamerInfo();
183 if (!sinfo) {
184 // Have to be sure between the check and the taking of the lock if the current streamer has changed
186 sinfo = (TStreamerInfo *)const_cast<TClass *>(cl)->GetCurrentStreamerInfo();
187 if (!sinfo) {
188 const_cast<TClass *>(cl)->BuildRealData(pointer);
189 sinfo = new TStreamerInfo(const_cast<TClass *>(cl));
190 const_cast<TClass *>(cl)->SetCurrentStreamerInfo(sinfo);
191 const_cast<TClass *>(cl)->RegisterStreamerInfo(sinfo);
192 if (gDebug > 0)
193 Info("WriteClassBuffer", "Creating StreamerInfo for class: %s, version: %d", cl->GetName(),
194 cl->GetClassVersion());
195 sinfo->Build();
196 }
197 } else if (!sinfo->IsCompiled()) {
199 // Redo the test in case we have been victim of a data race on fIsCompiled.
200 if (!sinfo->IsCompiled()) {
201 const_cast<TClass *>(cl)->BuildRealData(pointer);
202 sinfo->BuildOld();
203 }
204 }
205
206 // write the class version number and reserve space for the byte count
207 UInt_t R__c = WriteVersion(cl, kTRUE);
208
209 // NOTE: In the future Philippe wants this to happen via a custom action
210 TagStreamerInfo(sinfo);
211 ApplySequence(*(sinfo->GetWriteTextActions()), (char *)pointer);
212
213 // write the byte count at the start of the buffer
214 SetByteCount(R__c, kTRUE);
215
216 if (gDebug > 2)
217 Info("WriteClassBuffer", "class: %s version %d has written %d bytes", cl->GetName(), cl->GetClassVersion(),
218 UInt_t(fBufCur - fBuffer) - R__c - (UInt_t)sizeof(UInt_t));
219 return 0;
220}
221
222////////////////////////////////////////////////////////////////////////////////
223/// Deserialize information from a buffer into an object.
224///
225/// Note: This function is called by the xxx::Streamer() functions in
226/// rootcint-generated dictionaries.
227/// This function assumes that the class version and the byte count
228/// information have been read.
229///
230/// \param[in] cl pointer to the local TClass
231/// \param[out] pointer void pointer to object
232/// \param[in] version The version number of the class
233/// \param[in] start The starting position in the buffer b
234/// \param[in] count The number of bytes for this object in the buffer
235/// \param[in] onFileClass pointer to TClass object on file
236///
237
238Int_t TBufferText::ReadClassBuffer(const TClass *cl, void *pointer, Int_t version, UInt_t start, UInt_t count,
239 const TClass *onFileClass)
240{
241
242 //---------------------------------------------------------------------------
243 // The ondisk class has been specified so get foreign streamer info
244 /////////////////////////////////////////////////////////////////////////////
245
246 TStreamerInfo *sinfo = nullptr;
247 if (onFileClass) {
248 sinfo = (TStreamerInfo *)cl->GetConversionStreamerInfo(onFileClass, version);
249 if (!sinfo) {
250 Error("ReadClassBuffer",
251 "Could not find the right streamer info to convert %s version %d into a %s, object skipped at offset %d",
252 onFileClass->GetName(), version, cl->GetName(), Length());
253 CheckByteCount(start, count, onFileClass);
254 return 0;
255 }
256 }
257 //---------------------------------------------------------------------------
258 // Get local streamer info
259 /////////////////////////////////////////////////////////////////////////////
260 /// The StreamerInfo should exist at this point.
261
262 else {
264 auto infos = cl->GetStreamerInfos();
265 auto ninfos = infos->GetSize();
266 if (version < -1 || version >= ninfos) {
267 Error("ReadBuffer1", "class: %s, attempting to access a wrong version: %d, object skipped at offset %d",
268 cl->GetName(), version, Length());
269 CheckByteCount(start, count, cl);
270 return 0;
271 }
272 sinfo = (TStreamerInfo *)infos->At(version);
273 if (!sinfo) {
274 // Unless the data is coming via a socket connection from with schema evolution
275 // (tracking) was not enabled. So let's create the StreamerInfo if it is the
276 // one for the current version, otherwise let's complain ...
277 // We could also get here if there old class version was '1' and the new class version is higher than 1
278 // AND the checksum is the same.
279 if (version == cl->GetClassVersion() || version == 1) {
280 const_cast<TClass *>(cl)->BuildRealData(pointer);
281 // This creation is alright since we just checked within the
282 // current 'locked' section.
283 sinfo = new TStreamerInfo(const_cast<TClass *>(cl));
284 const_cast<TClass *>(cl)->RegisterStreamerInfo(sinfo);
285 if (gDebug > 0)
286 Info("ReadClassBuffer", "Creating StreamerInfo for class: %s, version: %d", cl->GetName(), version);
287 sinfo->Build();
288 } else if (version == 0) {
289 // When the object was written the class was version zero, so
290 // there is no StreamerInfo to be found.
291 // Check that the buffer position corresponds to the byte count.
292 CheckByteCount(start, count, cl);
293 return 0;
294 } else {
295 Error("ReadClassBuffer",
296 "Could not find the StreamerInfo for version %d of the class %s, object skipped at offset %d",
297 version, cl->GetName(), Length());
298 CheckByteCount(start, count, cl);
299 return 0;
300 }
301 } else if (!sinfo->IsCompiled()) { // Note this read is protected by the above lock.
302 // Streamer info has not been compiled, but exists.
303 // Therefore it was read in from a file and we have to do schema evolution.
304 const_cast<TClass *>(cl)->BuildRealData(pointer);
305 sinfo->BuildOld();
306 }
307 }
308
309 // Deserialize the object.
310 ApplySequence(*(sinfo->GetReadTextActions()), (char *)pointer);
311 if (sinfo->IsRecovered())
312 count = 0;
313
314 // Check that the buffer position corresponds to the byte count.
315 CheckByteCount(start, count, cl);
316 return 0;
317}
318
319////////////////////////////////////////////////////////////////////////////////
320/// Deserialize information from a buffer into an object.
321///
322/// Note: This function is called by the xxx::Streamer()
323/// functions in rootcint-generated dictionaries.
324///
325
326Int_t TBufferText::ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onFileClass)
327{
328 // Read the class version from the buffer.
329 UInt_t R__s = 0; // Start of object.
330 UInt_t R__c = 0; // Count of bytes.
331 Version_t version;
332
333 if (onFileClass)
334 version = ReadVersion(&R__s, &R__c, onFileClass);
335 else
336 version = ReadVersion(&R__s, &R__c, cl);
337
338 Bool_t v2file = kFALSE;
339 TFile *file = (TFile *)GetParent();
340 if (file && file->GetVersion() < 30000) {
341 version = -1; // This is old file
342 v2file = kTRUE;
343 }
344
345 //---------------------------------------------------------------------------
346 // The ondisk class has been specified so get foreign streamer info
347 /////////////////////////////////////////////////////////////////////////////
348
349 TStreamerInfo *sinfo = nullptr;
350 if (onFileClass) {
351 sinfo = (TStreamerInfo *)cl->GetConversionStreamerInfo(onFileClass, version);
352 if (!sinfo) {
353 Error("ReadClassBuffer",
354 "Could not find the right streamer info to convert %s version %d into a %s, object skipped at offset %d",
355 onFileClass->GetName(), version, cl->GetName(), Length());
356 CheckByteCount(R__s, R__c, onFileClass);
357 return 0;
358 }
359 }
360 //---------------------------------------------------------------------------
361 // Get local streamer info
362 /////////////////////////////////////////////////////////////////////////////
363 /// The StreamerInfo should exist at this point.
364
365 else {
367 if (guess && guess->GetClassVersion() == version) {
368 sinfo = guess;
369 } else {
370 // The last one is not the one we are looking for.
371 {
373
374 const TObjArray *infos = cl->GetStreamerInfos();
375 Int_t infocapacity = infos->Capacity();
376 if (infocapacity) {
377 if (version < -1 || version >= infocapacity) {
378 Error("ReadClassBuffer",
379 "class: %s, attempting to access a wrong version: %d, object skipped at offset %d",
380 cl->GetName(), version, Length());
381 CheckByteCount(R__s, R__c, cl);
382 return 0;
383 }
384 sinfo = (TStreamerInfo *)infos->UncheckedAt(version);
385 if (sinfo) {
386 if (!sinfo->IsCompiled()) {
387 // Streamer info has not been compiled, but exists.
388 // Therefore it was read in from a file and we have to do schema evolution?
390 const_cast<TClass *>(cl)->BuildRealData(pointer);
391 sinfo->BuildOld();
392 }
393 // If the compilation succeeded, remember this StreamerInfo.
394 // const_cast okay because of the lock on gInterpreterMutex.
395 if (sinfo->IsCompiled())
396 const_cast<TClass *>(cl)->SetLastReadInfo(sinfo);
397 }
398 }
399 }
400
401 if (!sinfo) {
402 // Unless the data is coming via a socket connection from with schema evolution
403 // (tracking) was not enabled. So let's create the StreamerInfo if it is the
404 // one for the current version, otherwise let's complain ...
405 // We could also get here when reading a file prior to the introduction of StreamerInfo.
406 // We could also get here if there old class version was '1' and the new class version is higher than 1
407 // AND the checksum is the same.
408 if (v2file || version == cl->GetClassVersion() || version == 1) {
410
411 // We need to check if another thread did not get here first
412 // and did the StreamerInfo creation already.
413 auto infos = cl->GetStreamerInfos();
414 auto ninfos = infos->GetSize();
415 if (!(version < -1 || version >= ninfos)) {
416 sinfo = (TStreamerInfo *)infos->At(version);
417 }
418 if (!sinfo) {
419 const_cast<TClass *>(cl)->BuildRealData(pointer);
420 sinfo = new TStreamerInfo(const_cast<TClass *>(cl));
421 sinfo->SetClassVersion(version);
422 const_cast<TClass *>(cl)->RegisterStreamerInfo(sinfo);
423 if (gDebug > 0)
424 Info("ReadClassBuffer", "Creating StreamerInfo for class: %s, version: %d", cl->GetName(),
425 version);
426 if (v2file) {
427 sinfo->Build(); // Get the elements.
428 sinfo->Clear("build"); // Undo compilation.
429 sinfo->BuildEmulated(file); // Fix the types and redo compilation.
430 } else {
431 sinfo->Build();
432 }
433 }
434 } else if (version == 0) {
435 // When the object was written the class was version zero, so
436 // there is no StreamerInfo to be found.
437 // Check that the buffer position corresponds to the byte count.
438 CheckByteCount(R__s, R__c, cl);
439 return 0;
440 } else {
441 Error("ReadClassBuffer",
442 "Could not find the StreamerInfo for version %d of the class %s, object skipped at offset %d",
443 version, cl->GetName(), Length());
444 CheckByteCount(R__s, R__c, cl);
445 return 0;
446 }
447 }
448 }
449 }
450
451 // deserialize the object
452 ApplySequence(*(sinfo->GetReadTextActions()), (char *)pointer);
453 if (sinfo->TStreamerInfo::IsRecovered())
454 R__c = 0; // 'TStreamerInfo::' avoids going via a virtual function.
455
456 // Check that the buffer position corresponds to the byte count.
457 CheckByteCount(R__s, R__c, cl);
458
459 if (gDebug > 2)
460 Info("ReadClassBuffer", "for class: %s has read %d bytes", cl->GetName(), R__c);
461
462 return 0;
463}
464
465////////////////////////////////////////////////////////////////////////////////
466/// stream object to/from buffer
467
468void TBufferText::StreamObject(void *obj, const std::type_info &typeinfo, const TClass * /* onFileClass */)
469{
470 StreamObject(obj, TClass::GetClass(typeinfo));
471}
472
473////////////////////////////////////////////////////////////////////////////////
474/// stream object to/from buffer
475
476void TBufferText::StreamObject(void *obj, const char *className, const TClass * /* onFileClass */)
477{
478 StreamObject(obj, TClass::GetClass(className));
479}
480
482{
483 // stream object to/from buffer
484
485 StreamObject(obj, obj ? obj->IsA() : TObject::Class());
486}
487
488////////////////////////////////////////////////////////////////////////////////
489/// read a Float16_t from the buffer
490
492{
493 ReadFloat(*f);
494}
495
496////////////////////////////////////////////////////////////////////////////////
497/// read a Double32_t from the buffer
498
500{
501 ReadDouble(*d);
502}
503
504////////////////////////////////////////////////////////////////////////////////
505/// Read a Double32_t from the buffer when the factor and minimun value have
506/// been specified
507/// see comments about Double32_t encoding at TBufferFile::WriteDouble32().
508/// Currently TBufferText does not optimize space in this case.
509
510void TBufferText::ReadWithFactor(Float_t *f, Double_t /* factor */, Double_t /* minvalue */)
511{
512 ReadFloat(*f);
513}
514
515////////////////////////////////////////////////////////////////////////////////
516/// Read a Float16_t from the buffer when the number of bits is specified
517/// (explicitly or not)
518/// see comments about Float16_t encoding at TBufferFile::WriteFloat16().
519/// Currently TBufferText does not optimize space in this case.
520
522{
523 ReadFloat(*f);
524}
525
526////////////////////////////////////////////////////////////////////////////////
527/// Read a Double32_t from the buffer when the factor and minimun value have
528/// been specified
529/// see comments about Double32_t encoding at TBufferFile::WriteDouble32().
530/// Currently TBufferText does not optimize space in this case.
531
532void TBufferText::ReadWithFactor(Double_t *d, Double_t /* factor */, Double_t /* minvalue */)
533{
534 ReadDouble(*d);
535}
536
537////////////////////////////////////////////////////////////////////////////////
538/// Read a Double32_t from the buffer when the number of bits is specified
539/// (explicitly or not)
540/// see comments about Double32_t encoding at TBufferFile::WriteDouble32().
541/// Currently TBufferText does not optimize space in this case.
542
544{
545 ReadDouble(*d);
546}
547
548////////////////////////////////////////////////////////////////////////////////
549/// write a Float16_t to the buffer
550
552{
553 WriteFloat(*f);
554}
555
556////////////////////////////////////////////////////////////////////////////////
557/// write a Double32_t to the buffer
558
560{
561 WriteDouble(*d);
562}
563
564////////////////////////////////////////////////////////////////////////////////
565/// Read array of Float16_t from buffer
566
568{
569 return ReadArray(f);
570}
571
572////////////////////////////////////////////////////////////////////////////////
573/// Read array of Double32_t from buffer
574
576{
577 return ReadArray(d);
578}
579
580////////////////////////////////////////////////////////////////////////////////
581/// Read array of Float16_t from buffer
582
584{
585 return ReadStaticArray(f);
586}
587
588////////////////////////////////////////////////////////////////////////////////
589/// Read array of Double32_t from buffer
590
592{
593 return ReadStaticArray(d);
594}
595
596////////////////////////////////////////////////////////////////////////////////
597/// read array of Float16_t from buffer
598
600{
601 ReadFastArray(f, n);
602}
603
604////////////////////////////////////////////////////////////////////////////////
605/// read array of Float16_t from buffer
606
608{
609 ReadFastArray(f, n);
610}
611
612////////////////////////////////////////////////////////////////////////////////
613/// read array of Float16_t from buffer
614
616{
617 ReadFastArray(f, n);
618}
619
620////////////////////////////////////////////////////////////////////////////////
621/// read array of Double32_t from buffer
622
624{
625 ReadFastArray(d, n);
626}
627
628////////////////////////////////////////////////////////////////////////////////
629/// read array of Double32_t from buffer
630
632{
633 ReadFastArray(d, n);
634}
635
636////////////////////////////////////////////////////////////////////////////////
637/// read array of Double32_t from buffer
638
640{
641 ReadFastArray(d, n);
642}
643////////////////////////////////////////////////////////////////////////////////
644/// Write array of Float16_t to buffer
645
647{
648 WriteArray(f, n);
649}
650
651////////////////////////////////////////////////////////////////////////////////
652/// Write array of Double32_t to buffer
653
655{
656 WriteArray(d, n);
657}
658
659////////////////////////////////////////////////////////////////////////////////
660/// Write array of Float16_t to buffer
661
663{
665}
666
667////////////////////////////////////////////////////////////////////////////////
668/// Write array of Double32_t to buffer
669
671{
673}
674
675////////////////////////////////////////////////////////////////////////////////
676/// Skip class version from I/O buffer.
677
679{
680 ReadVersion(nullptr, nullptr, cl);
681}
682
683////////////////////////////////////////////////////////////////////////////////
684/// Write data of base class.
685
687{
688 elem->WriteBuffer(*this, (char *)start);
689}
690
691////////////////////////////////////////////////////////////////////////////////
692/// Read data of base class.
693
695{
696 elem->ReadBuffer(*this, (char *)start);
697}
698
699////////////////////////////////////////////////////////////////////////////////
700/// method compress float string, excluding exp and/or move float point
701/// - 1.000000e-01 -> 0.1
702/// - 3.750000e+00 -> 3.75
703/// - 3.750000e-03 -> 0.00375
704/// - 3.750000e-04 -> 3.75e-4
705/// - 1.100000e-10 -> 1.1e-10
706
707void TBufferText::CompactFloatString(char *sbuf, unsigned len)
708{
709 char *pnt = nullptr, *exp = nullptr, *lastdecimal = nullptr, *s = sbuf;
710 bool negative_exp = false;
711 int power = 0;
712 while (*s && --len) {
713 switch (*s) {
714 case '.': pnt = s; break;
715 case 'E':
716 case 'e': exp = s; break;
717 case '-':
718 if (exp)
719 negative_exp = true;
720 break;
721 case '+': break;
722 default: // should be digits from '0' to '9'
723 if ((*s < '0') || (*s > '9'))
724 return;
725 if (exp)
726 power = power * 10 + (*s - '0');
727 else if (pnt && *s != '0')
728 lastdecimal = s;
729 break;
730 }
731 ++s;
732 }
733 if (*s)
734 return; // if end-of-string was not found
735
736 if (!exp) {
737 // value without exponent like 123.4569000
738 if (pnt) {
739 if (lastdecimal)
740 *(lastdecimal + 1) = 0;
741 else
742 *pnt = 0;
743 }
744 } else if (power == 0) {
745 if (lastdecimal)
746 *(lastdecimal + 1) = 0;
747 else if (pnt)
748 *pnt = 0;
749 } else if (!negative_exp && pnt && exp && (exp - pnt > power)) {
750 // this is case of value 1.23000e+02
751 // we can move point and exclude exponent easily
752 for (int cnt = 0; cnt < power; ++cnt) {
753 char tmp = *pnt;
754 *pnt = *(pnt + 1);
755 *(++pnt) = tmp;
756 }
757 if (lastdecimal && (pnt < lastdecimal))
758 *(lastdecimal + 1) = 0;
759 else
760 *pnt = 0;
761 } else if (negative_exp && pnt && exp && (power < (s - exp))) {
762 // this is small negative exponent like 1.2300e-02
763 if (!lastdecimal)
764 lastdecimal = pnt;
765 *(lastdecimal + 1) = 0;
766 // copy most significant digit on the point place
767 *pnt = *(pnt - 1);
768
769 for (char *pos = lastdecimal + 1; pos >= pnt; --pos)
770 *(pos + power) = *pos;
771 *(pnt - 1) = '0';
772 *pnt = '.';
773 for (int cnt = 1; cnt < power; ++cnt)
774 *(pnt + cnt) = '0';
775 } else if (pnt && exp) {
776 // keep exponent, but non-significant zeros
777 if (lastdecimal)
778 pnt = lastdecimal + 1;
779 // copy exponent sign
780 *pnt++ = *exp++;
781 if (*exp == '+')
782 ++exp;
783 else if (*exp == '-')
784 *pnt++ = *exp++;
785 // exclude zeros in the begin of exponent
786 while (*exp == '0')
787 ++exp;
788 while (*exp)
789 *pnt++ = *exp++;
790 *pnt = 0;
791 }
792}
793
794////////////////////////////////////////////////////////////////////////////////
795/// set printf format for float/double members, default "%e"
796/// to change format only for doubles, use SetDoubleFormat
797
798void TBufferText::SetFloatFormat(const char *fmt)
799{
800 if (!fmt)
801 fmt = "%e";
802 fgFloatFmt = fmt;
803 fgDoubleFmt = fmt;
804}
805
806////////////////////////////////////////////////////////////////////////////////
807/// return current printf format for float members, default "%e"
808
810{
811 return fgFloatFmt;
812}
813
814////////////////////////////////////////////////////////////////////////////////
815/// set printf format for double members, default "%.14e"
816/// use it after SetFloatFormat, which also overwrites format for doubles
817
818void TBufferText::SetDoubleFormat(const char *fmt)
819{
820 if (!fmt)
821 fmt = "%.14e";
822 fgDoubleFmt = fmt;
823}
824
825////////////////////////////////////////////////////////////////////////////////
826/// return current printf format for double members, default "%.14e"
827
829{
830 return fgDoubleFmt;
831}
832
833////////////////////////////////////////////////////////////////////////////////
834/// convert float to string with configured format
835
836const char *TBufferText::ConvertFloat(Float_t value, char *buf, unsigned len, Bool_t not_optimize)
837{
838 if (not_optimize) {
840 } else if ((value == std::nearbyint(value)) && (std::abs(value) < 1e15)) {
841 snprintf(buf, len, "%1.0f", value);
842 } else {
845 }
846 return buf;
847}
848
849////////////////////////////////////////////////////////////////////////////////
850/// convert float to string with configured format
851
852const char *TBufferText::ConvertDouble(Double_t value, char *buf, unsigned len, Bool_t not_optimize)
853{
854 if (not_optimize) {
856 } else if ((value == std::nearbyint(value)) && (std::abs(value) < 1e25)) {
857 snprintf(buf, len, "%1.0f", value);
858 } else {
861 }
862 return buf;
863}
#define d(i)
Definition RSha256.hxx:102
#define f(i)
Definition RSha256.hxx:104
short Version_t
Definition RtypesCore.h:65
float Float_t
Definition RtypesCore.h:57
constexpr Bool_t kFALSE
Definition RtypesCore.h:101
long long Long64_t
Definition RtypesCore.h:80
constexpr Bool_t kTRUE
Definition RtypesCore.h:100
#define ClassImp(name)
Definition Rtypes.h:377
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char mode
R__EXTERN TVirtualMutex * gInterpreterMutex
Int_t gDebug
Definition TROOT.cxx:595
#define R__LOCKGUARD(mutex)
#define snprintf
Definition civetweb.c:1540
Direct subclass of TBuffer, implements common methods for TBufferFile and TBufferText classes.
Definition TBufferIO.h:30
void TagStreamerInfo(TVirtualStreamerInfo *info) override
Mark the classindex of the current file as using this TStreamerInfo.
Base class for text-based streamers like TBufferJSON or TBufferXML Special actions list will use meth...
Definition TBufferText.h:20
Int_t CheckByteCount(UInt_t, UInt_t, const TClass *) final
Definition TBufferText.h:78
static const char * ConvertFloat(Float_t v, char *buf, unsigned len, Bool_t not_optimize=kFALSE)
convert float to string with configured format
void WriteFastArrayDouble32(const Double_t *d, Long64_t n, TStreamerElement *ele=nullptr) final
Write array of Double32_t to buffer.
static const char * GetFloatFormat()
return current printf format for float members, default "%e"
Int_t ReadArrayDouble32(Double_t *&d, TStreamerElement *ele=nullptr) override
Read array of Double32_t from buffer.
void ReadFastArrayFloat16(Float_t *f, Int_t n, TStreamerElement *ele=nullptr) final
read array of Float16_t from buffer
void ReadFastArrayDouble32(Double_t *d, Int_t n, TStreamerElement *ele=nullptr) final
read array of Double32_t from buffer
Int_t ReadArrayFloat16(Float_t *&f, TStreamerElement *ele=nullptr) override
Read array of Float16_t from buffer.
void ReadWithNbits(Float_t *ptr, Int_t nbits) final
Read a Float16_t from the buffer when the number of bits is specified (explicitly or not) see comment...
TBufferText()
Default constructor.
void WriteArrayDouble32(const Double_t *d, Int_t n, TStreamerElement *ele=nullptr) final
Write array of Double32_t to buffer.
Int_t WriteClassBuffer(const TClass *cl, void *pointer) override
Function called by the Streamer functions to serialize object at p to buffer b.
static void CompactFloatString(char *buf, unsigned len)
method compress float string, excluding exp and/or move float point
void ReadFastArrayWithFactor(Float_t *ptr, Int_t n, Double_t factor, Double_t minvalue) final
read array of Float16_t from buffer
static const char * ConvertDouble(Double_t v, char *buf, unsigned len, Bool_t not_optimize=kFALSE)
convert float to string with configured format
void StreamObject(void *obj, const std::type_info &typeinfo, const TClass *onFileClass=nullptr) override
stream object to/from buffer
Int_t ApplySequenceVecPtr(const TStreamerInfoActions::TActionSequence &sequence, void *start_collection, void *end_collection) final
Read one collection of objects from the buffer using the StreamerInfoLoopAction.
void WriteArrayFloat16(const Float_t *f, Int_t n, TStreamerElement *ele=nullptr) final
Write array of Float16_t to buffer.
void ReadFastArrayWithNbits(Float_t *ptr, Int_t n, Int_t nbits) final
read array of Float16_t from buffer
void ReadFloat16(Float_t *f, TStreamerElement *ele=nullptr) final
read a Float16_t from the buffer
Int_t ApplySequence(const TStreamerInfoActions::TActionSequence &sequence, void *object) final
Read one collection of objects from the buffer using the StreamerInfoLoopAction.
void SkipVersion(const TClass *cl=nullptr) final
Skip class version from I/O buffer.
virtual void WriteBaseClass(void *start, TStreamerBase *elem)
Write data of base class.
~TBufferText() override
destructor
void SetByteCount(UInt_t, Bool_t=kFALSE) final
Definition TBufferText.h:80
Int_t ReadStaticArrayFloat16(Float_t *f, TStreamerElement *ele=nullptr) final
Read array of Float16_t from buffer.
Int_t ReadStaticArrayDouble32(Double_t *d, TStreamerElement *ele=nullptr) final
Read array of Double32_t from buffer.
static const char * fgDoubleFmt
! printf argument for doubles, either "%f" or "%e" or "%10f" and so on
virtual void ReadBaseClass(void *start, TStreamerBase *elem)
Read data of base class.
static void SetFloatFormat(const char *fmt="%e")
set printf format for float/double members, default "%e" to change format only for doubles,...
Int_t ReadClassBuffer(const TClass *, void *, const TClass *=nullptr) override
Deserialize information from a buffer into an object.
void WriteFloat16(Float_t *f, TStreamerElement *ele=nullptr) final
write a Float16_t to the buffer
static const char * GetDoubleFormat()
return current printf format for double members, default "%.14e"
void ReadDouble32(Double_t *d, TStreamerElement *ele=nullptr) final
read a Double32_t from the buffer
void WriteFastArrayFloat16(const Float_t *d, Long64_t n, TStreamerElement *ele=nullptr) final
Write array of Float16_t to buffer.
void ReadWithFactor(Float_t *ptr, Double_t factor, Double_t minvalue) final
Read a Double32_t from the buffer when the factor and minimun value have been specified see comments ...
void WriteDouble32(Double_t *d, TStreamerElement *ele=nullptr) final
write a Double32_t to the buffer
static const char * fgFloatFmt
! printf argument for floats, either "%f" or "%e" or "%10f" and so on
static void SetDoubleFormat(const char *fmt="%.14e")
set printf format for double members, default "%.14e" use it after SetFloatFormat,...
virtual Version_t ReadVersion(UInt_t *start=nullptr, UInt_t *bcnt=nullptr, const TClass *cl=nullptr)=0
virtual void ReadDouble(Double_t &d)=0
Int_t fBufSize
Definition TBuffer.h:50
virtual void WriteDouble(Double_t d)=0
void SetParent(TObject *parent)
Set parent owning this buffer.
Definition TBuffer.cxx:270
TObject * GetParent() const
Return pointer to parent of this buffer.
Definition TBuffer.cxx:262
virtual void ReadFloat(Float_t &f)=0
@ kCannotHandleMemberWiseStreaming
Definition TBuffer.h:76
virtual void SetStreamerElementNumber(TStreamerElement *elem, Int_t comp_type)=0
virtual void WriteArray(const Bool_t *b, Int_t n)=0
virtual Int_t ReadArray(Bool_t *&b)=0
char * fBufCur
Definition TBuffer.h:52
virtual void ReadFastArray(Bool_t *b, Int_t n)=0
virtual void IncrementLevel(TVirtualStreamerInfo *info)=0
virtual void DecrementLevel(TVirtualStreamerInfo *)=0
char * fBuffer
Definition TBuffer.h:51
virtual Int_t ReadStaticArray(Bool_t *b)=0
virtual void WriteFastArray(const Bool_t *b, Long64_t n)=0
virtual UInt_t WriteVersion(const TClass *cl, Bool_t useBcnt=kFALSE)=0
virtual void WriteFloat(Float_t f)=0
Int_t Length() const
Definition TBuffer.h:100
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:81
TVirtualStreamerInfo * GetCurrentStreamerInfo()
Definition TClass.h:437
void SetLastReadInfo(TVirtualStreamerInfo *info)
Definition TClass.h:443
TVirtualStreamerInfo * GetLastReadInfo() const
Definition TClass.h:442
const TObjArray * GetStreamerInfos() const
Definition TClass.h:490
TVirtualStreamerInfo * GetConversionStreamerInfo(const char *onfile_classname, Int_t version) const
Return a Conversion StreamerInfo from the class 'classname' for version number 'version' to this clas...
Definition TClass.cxx:7086
Version_t GetClassVersion() const
Definition TClass.h:418
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition TClass.cxx:2968
Int_t Capacity() const
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
A ROOT file is composed of a header, followed by consecutive data records (TKey instances) with a wel...
Definition TFile.h:53
Int_t GetVersion() const
Definition TFile.h:238
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
An array of TObjects.
Definition TObjArray.h:31
TObject * UncheckedAt(Int_t i) const
Definition TObjArray.h:84
Mother of all ROOT objects.
Definition TObject.h:41
static TClass * Class()
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:780
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:976
virtual TClass * IsA() const
Definition TObject.h:245
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:950
Int_t WriteBuffer(TBuffer &b, char *pointer)
Write the base class into the buffer.
Int_t ReadBuffer(TBuffer &b, char *pointer)
Read the content of the buffer.
TLoopConfiguration * fLoopConfig
If this is a bundle of memberwise streaming action, this configures the looping.
TVirtualStreamerInfo * fStreamerInfo
StreamerInfo used to derive these actions.
Base class of the Configurations for the member wise looping routines.
virtual void * GetFirstAddress(void *start, const void *end) const =0
Describes a persistent version of a class.
Int_t GetClassVersion() const override
void BuildEmulated(TFile *file) override
Create an Emulation TStreamerInfo object.
void Build(Bool_t isTransient=kFALSE) override
Build the I/O data structure for the current class version.
void BuildOld() override
rebuild the TStreamerInfo structure
void SetClassVersion(Int_t vers) override
TStreamerInfoActions::TActionSequence * GetReadTextActions()
TStreamerInfoActions::TActionSequence * GetWriteTextActions()
void Clear(Option_t *="") override
If opt contains 'built', reset this StreamerInfo as if Build or BuildOld was never called on it (usef...
Abstract Interface class describing Streamer information for one class.
const Int_t n
Definition legend1.C:16