35 ClassImp(TBufferText);
37 const char *TBufferText::fgFloatFmt =
"%e";
38 const char *TBufferText::fgDoubleFmt =
"%.14e";
43 TBufferText::TBufferText() : TBufferIO()
50 TBufferText::TBufferText(TBuffer::EMode mode, TObject *parent) : TBufferIO(mode)
52 fBufSize = 1000000000;
55 SetBit(kCannotHandleMemberWiseStreaming);
61 TBufferText::~TBufferText()
69 Int_t TBufferText::ApplySequence(
const TStreamerInfoActions::TActionSequence &sequence,
void *obj)
71 TVirtualStreamerInfo *info = sequence.fStreamerInfo;
76 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
77 for (TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin(); iter != end;
80 SetStreamerElementNumber((*iter).fConfiguration->fCompInfo->fElem, (*iter).fConfiguration->fCompInfo->fType);
81 (*iter).PrintDebug(*
this, obj);
86 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
87 for (TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin(); iter != end;
90 SetStreamerElementNumber((*iter).fConfiguration->fCompInfo->fElem, (*iter).fConfiguration->fCompInfo->fType);
102 Int_t TBufferText::ApplySequenceVecPtr(
const TStreamerInfoActions::TActionSequence &sequence,
void *start_collection,
103 void *end_collection)
105 TVirtualStreamerInfo *info = sequence.fStreamerInfo;
106 IncrementLevel(info);
110 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
111 for (TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin(); iter != end;
114 SetStreamerElementNumber((*iter).fConfiguration->fCompInfo->fElem, (*iter).fConfiguration->fCompInfo->fType);
116 *
this, *(
char **)start_collection);
117 (*iter)(*
this, start_collection, end_collection);
121 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
122 for (TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin(); iter != end;
125 SetStreamerElementNumber((*iter).fConfiguration->fCompInfo->fElem, (*iter).fConfiguration->fCompInfo->fType);
126 (*iter)(*
this, start_collection, end_collection);
129 DecrementLevel(info);
136 Int_t TBufferText::ApplySequence(
const TStreamerInfoActions::TActionSequence &sequence,
void *start_collection,
137 void *end_collection)
139 TVirtualStreamerInfo *info = sequence.fStreamerInfo;
140 IncrementLevel(info);
142 TStreamerInfoActions::TLoopConfiguration *loopconfig = sequence.fLoopConfig;
148 void *arr0 = loopconfig->GetFirstAddress(start_collection, end_collection);
150 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
151 for (TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin(); iter != end;
154 SetStreamerElementNumber((*iter).fConfiguration->fCompInfo->fElem, (*iter).fConfiguration->fCompInfo->fType);
155 (*iter).PrintDebug(*
this, arr0);
156 (*iter)(*
this, start_collection, end_collection, loopconfig);
160 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
161 for (TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin(); iter != end;
164 SetStreamerElementNumber((*iter).fConfiguration->fCompInfo->fElem, (*iter).fConfiguration->fCompInfo->fType);
165 (*iter)(*
this, start_collection, end_collection, loopconfig);
168 DecrementLevel(info);
179 Int_t TBufferText::WriteClassBuffer(
const TClass *cl,
void *pointer)
182 TStreamerInfo *sinfo = (TStreamerInfo *)const_cast<TClass *>(cl)->GetCurrentStreamerInfo();
185 R__LOCKGUARD(gInterpreterMutex);
186 sinfo = (TStreamerInfo *)const_cast<TClass *>(cl)->GetCurrentStreamerInfo();
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);
193 Info(
"WriteClassBuffer",
"Creating StreamerInfo for class: %s, version: %d", cl->GetName(),
194 cl->GetClassVersion());
197 }
else if (!sinfo->IsCompiled()) {
198 R__LOCKGUARD(gInterpreterMutex);
200 if (!sinfo->IsCompiled()) {
201 const_cast<TClass *
>(cl)->BuildRealData(pointer);
207 UInt_t R__c = WriteVersion(cl, kTRUE);
210 TagStreamerInfo(sinfo);
211 ApplySequence(*(sinfo->GetWriteTextActions()), (
char *)pointer);
214 SetByteCount(R__c, kTRUE);
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));
235 Int_t TBufferText::ReadClassBuffer(const TClass *cl,
void *pointer, Int_t version, UInt_t start, UInt_t count,
236 const TClass *onFileClass)
243 TStreamerInfo *sinfo =
nullptr;
245 sinfo = (TStreamerInfo *)cl->GetConversionStreamerInfo(onFileClass, version);
247 Error(
"ReadClassBuffer",
248 "Could not find the right streamer info to convert %s version %d into a %s, object skipped at offset %d",
249 onFileClass->GetName(), version, cl->GetName(), Length());
250 CheckByteCount(start, count, onFileClass);
260 R__LOCKGUARD(gInterpreterMutex);
261 auto infos = cl->GetStreamerInfos();
262 auto ninfos = infos->GetSize();
263 if (version < -1 || version >= ninfos) {
264 Error(
"ReadBuffer1",
"class: %s, attempting to access a wrong version: %d, object skipped at offset %d",
265 cl->GetName(), version, Length());
266 CheckByteCount(start, count, cl);
269 sinfo = (TStreamerInfo *)infos->At(version);
276 if (version == cl->GetClassVersion() || version == 1) {
277 const_cast<TClass *
>(cl)->BuildRealData(pointer);
280 sinfo =
new TStreamerInfo(const_cast<TClass *>(cl));
281 const_cast<TClass *
>(cl)->RegisterStreamerInfo(sinfo);
283 Info(
"ReadClassBuffer",
"Creating StreamerInfo for class: %s, version: %d", cl->GetName(), version);
285 }
else if (version == 0) {
289 CheckByteCount(start, count, cl);
292 Error(
"ReadClassBuffer",
293 "Could not find the StreamerInfo for version %d of the class %s, object skipped at offset %d",
294 version, cl->GetName(), Length());
295 CheckByteCount(start, count, cl);
298 }
else if (!sinfo->IsCompiled()) {
301 const_cast<TClass *
>(cl)->BuildRealData(pointer);
307 ApplySequence(*(sinfo->GetReadTextActions()), (
char *)pointer);
308 if (sinfo->IsRecovered())
312 CheckByteCount(start, count, cl);
323 Int_t TBufferText::ReadClassBuffer(const TClass *cl,
void *pointer, const TClass *onFileClass)
331 version = ReadVersion(&R__s, &R__c, onFileClass);
333 version = ReadVersion(&R__s, &R__c, cl);
335 Bool_t v2file = kFALSE;
336 TFile *file = (TFile *)GetParent();
337 if (file && file->GetVersion() < 30000) {
346 TStreamerInfo *sinfo =
nullptr;
348 sinfo = (TStreamerInfo *)cl->GetConversionStreamerInfo(onFileClass, version);
350 Error(
"ReadClassBuffer",
351 "Could not find the right streamer info to convert %s version %d into a %s, object skipped at offset %d",
352 onFileClass->GetName(), version, cl->GetName(), Length());
353 CheckByteCount(R__s, R__c, onFileClass);
363 TStreamerInfo *guess = (TStreamerInfo *)cl->GetLastReadInfo();
364 if (guess && guess->GetClassVersion() == version) {
369 R__LOCKGUARD(gInterpreterMutex);
371 const TObjArray *infos = cl->GetStreamerInfos();
372 Int_t infocapacity = infos->Capacity();
374 if (version < -1 || version >= infocapacity) {
375 Error(
"ReadClassBuffer",
376 "class: %s, attempting to access a wrong version: %d, object skipped at offset %d",
377 cl->GetName(), version, Length());
378 CheckByteCount(R__s, R__c, cl);
381 sinfo = (TStreamerInfo *)infos->UncheckedAt(version);
383 if (!sinfo->IsCompiled()) {
386 R__LOCKGUARD(gInterpreterMutex);
387 const_cast<TClass *
>(cl)->BuildRealData(pointer);
392 if (sinfo->IsCompiled())
393 const_cast<TClass *>(cl)->SetLastReadInfo(sinfo);
405 if (v2file || version == cl->GetClassVersion() || version == 1) {
406 R__LOCKGUARD(gInterpreterMutex);
410 auto infos = cl->GetStreamerInfos();
411 auto ninfos = infos->GetSize();
412 if (!(version < -1 || version >= ninfos)) {
413 sinfo = (TStreamerInfo *)infos->At(version);
416 const_cast<TClass *
>(cl)->BuildRealData(pointer);
417 sinfo =
new TStreamerInfo(const_cast<TClass *>(cl));
418 sinfo->SetClassVersion(version);
419 const_cast<TClass *
>(cl)->RegisterStreamerInfo(sinfo);
421 Info(
"ReadClassBuffer",
"Creating StreamerInfo for class: %s, version: %d", cl->GetName(),
425 sinfo->Clear(
"build");
426 sinfo->BuildEmulated(file);
431 }
else if (version == 0) {
435 CheckByteCount(R__s, R__c, cl);
438 Error(
"ReadClassBuffer",
439 "Could not find the StreamerInfo for version %d of the class %s, object skipped at offset %d",
440 version, cl->GetName(), Length());
441 CheckByteCount(R__s, R__c, cl);
449 ApplySequence(*(sinfo->GetReadTextActions()), (
char *)pointer);
450 if (sinfo->TStreamerInfo::IsRecovered())
454 CheckByteCount(R__s, R__c, cl);
457 Info("ReadClassBuffer", "for class: %s has read %d bytes", cl->GetName(), R__c);
465 void TBufferText::StreamObject(
void *obj, const std::type_info &typeinfo, const TClass * )
467 StreamObject(obj, TClass::GetClass(typeinfo));
473 void TBufferText::StreamObject(
void *obj,
const char *className,
const TClass * )
475 StreamObject(obj, TClass::GetClass(className));
478 void TBufferText::StreamObject(TObject *obj)
482 StreamObject(obj, obj ? obj->IsA() : TObject::Class());
488 void TBufferText::ReadFloat16(Float_t *f, TStreamerElement * )
496 void TBufferText::ReadDouble32(Double_t *d, TStreamerElement * )
507 void TBufferText::ReadWithFactor(Float_t *f, Double_t , Double_t )
518 void TBufferText::ReadWithNbits(Float_t *f, Int_t )
529 void TBufferText::ReadWithFactor(Double_t *d, Double_t , Double_t )
540 void TBufferText::ReadWithNbits(Double_t *d, Int_t )
548 void TBufferText::WriteFloat16(Float_t *f, TStreamerElement * )
556 void TBufferText::WriteDouble32(Double_t *d, TStreamerElement * )
564 Int_t TBufferText::ReadArrayFloat16(Float_t *&f, TStreamerElement * )
572 Int_t TBufferText::ReadArrayDouble32(Double_t *&d, TStreamerElement * )
580 Int_t TBufferText::ReadStaticArrayFloat16(Float_t *f, TStreamerElement * )
582 return ReadStaticArray(f);
588 Int_t TBufferText::ReadStaticArrayDouble32(Double_t *d, TStreamerElement * )
590 return ReadStaticArray(d);
596 void TBufferText::ReadFastArrayFloat16(Float_t *f, Int_t n, TStreamerElement * )
604 void TBufferText::ReadFastArrayWithFactor(Float_t *f, Int_t n, Double_t , Double_t )
612 void TBufferText::ReadFastArrayWithNbits(Float_t *f, Int_t n, Int_t )
620 void TBufferText::ReadFastArrayDouble32(Double_t *d, Int_t n, TStreamerElement * )
628 void TBufferText::ReadFastArrayWithFactor(Double_t *d, Int_t n, Double_t , Double_t )
636 void TBufferText::ReadFastArrayWithNbits(Double_t *d, Int_t n, Int_t )
643 void TBufferText::WriteArrayFloat16(
const Float_t *f, Int_t n, TStreamerElement * )
651 void TBufferText::WriteArrayDouble32(
const Double_t *d, Int_t n, TStreamerElement * )
659 void TBufferText::WriteFastArrayFloat16(
const Float_t *f, Int_t n, TStreamerElement * )
661 WriteFastArray(f, n);
667 void TBufferText::WriteFastArrayDouble32(
const Double_t *d, Int_t n, TStreamerElement * )
669 WriteFastArray(d, n);
675 void TBufferText::SkipVersion(
const TClass *cl)
677 ReadVersion(
nullptr,
nullptr, cl);
683 void TBufferText::WriteBaseClass(
void *start, TStreamerBase *elem)
685 elem->WriteBuffer(*
this, (
char *)start);
691 void TBufferText::ReadBaseClass(
void *start, TStreamerBase *elem)
693 elem->ReadBuffer(*
this, (
char *)start);
704 void TBufferText::CompactFloatString(
char *sbuf,
unsigned len)
706 char *pnt =
nullptr, *exp =
nullptr, *lastdecimal =
nullptr, *s = sbuf;
707 bool negative_exp =
false;
709 while (*s && --len) {
711 case '.': pnt = s;
break;
713 case 'e': exp = s;
break;
720 if ((*s <
'0') || (*s >
'9'))
723 power = power * 10 + (*s -
'0');
724 else if (pnt && *s !=
'0')
737 *(lastdecimal + 1) = 0;
741 }
else if (power == 0) {
743 *(lastdecimal + 1) = 0;
746 }
else if (!negative_exp && pnt && exp && (exp - pnt > power)) {
749 for (
int cnt = 0; cnt < power; ++cnt) {
754 if (lastdecimal && (pnt < lastdecimal))
755 *(lastdecimal + 1) = 0;
758 }
else if (negative_exp && pnt && exp && (power < (s - exp))) {
762 *(lastdecimal + 1) = 0;
766 for (
char *pos = lastdecimal + 1; pos >= pnt; --pos)
767 *(pos + power) = *pos;
770 for (
int cnt = 1; cnt < power; ++cnt)
772 }
else if (pnt && exp) {
775 pnt = lastdecimal + 1;
780 else if (*exp ==
'-')
795 void TBufferText::SetFloatFormat(
const char *fmt)
806 const char *TBufferText::GetFloatFormat()
815 void TBufferText::SetDoubleFormat(
const char *fmt)
825 const char *TBufferText::GetDoubleFormat()
833 const char *TBufferText::ConvertFloat(Float_t value,
char *buf,
unsigned len, Bool_t not_optimize)
836 snprintf(buf, len, fgFloatFmt, value);
837 }
else if ((value == std::nearbyint(value)) && (std::abs(value) < 1e15)) {
838 snprintf(buf, len,
"%1.0f", value);
840 snprintf(buf, len, fgFloatFmt, value);
841 CompactFloatString(buf, len);
849 const char *TBufferText::ConvertDouble(Double_t value,
char *buf,
unsigned len, Bool_t not_optimize)
852 snprintf(buf, len, fgFloatFmt, value);
853 }
else if ((value == std::nearbyint(value)) && (std::abs(value) < 1e25)) {
854 snprintf(buf, len,
"%1.0f", value);
856 snprintf(buf, len, fgDoubleFmt, value);
857 CompactFloatString(buf, len);