28 TBranchSTL::TBranchSTL():
38 fIndArrayCl = TClass::GetClass(
"TIndArray" );
39 fBranchVector.reserve( 25 );
41 fReadLeaves = (ReadLeaves_t)&TBranchSTL::ReadLeavesImpl;
42 fFillLeaves = (FillLeaves_t)&TBranchSTL::FillLeavesImpl;
48 TBranchSTL::TBranchSTL( TTree *tree,
const char *name,
49 TVirtualCollectionProxy *collProxy,
50 Int_t buffsize, Int_t splitlevel )
53 fCollProxy = collProxy;
54 fBasketSize = buffsize;
55 fSplitLevel = splitlevel;
56 fContName = collProxy->GetCollectionClass()->GetName();
63 fDirectory = fTree->GetDirectory();
66 fIndArrayCl = TClass::GetClass(
"TIndArray" );
67 fBranchVector.reserve( 25 );
69 fReadLeaves = (ReadLeaves_t)&TBranchSTL::ReadLeavesImpl;
70 fFillLeaves = (FillLeaves_t)&TBranchSTL::FillLeavesImpl;
75 fBasketBytes =
new Int_t[fMaxBaskets];
76 fBasketEntry =
new Long64_t[fMaxBaskets];
77 fBasketSeek =
new Long64_t[fMaxBaskets];
79 for (Int_t i = 0; i < fMaxBaskets; ++i) {
90 TBranchSTL::TBranchSTL( TBranch* parent,
const char* name,
91 TVirtualCollectionProxy* collProxy,
92 Int_t buffsize, Int_t splitlevel,
93 TStreamerInfo* info, Int_t
id )
95 fTree = parent->GetTree();
96 fCollProxy = collProxy;
97 fBasketSize = buffsize;
98 fSplitLevel = splitlevel;
99 fContName = collProxy->GetCollectionClass()->GetName();
100 fClassName = info->GetClass()->GetName();
101 fClassVersion = info->GetClassVersion();
102 fClCheckSum = info->GetClass()->GetCheckSum();
105 fMother = parent->GetMother();
107 fDirectory = fTree->GetDirectory();
110 fReadLeaves = (ReadLeaves_t)&TBranchSTL::ReadLeavesImpl;
111 fFillLeaves = (ReadLeaves_t)&TBranchSTL::FillLeavesImpl;
114 fIndArrayCl = TClass::GetClass(
"TIndArray" );
115 fBranchVector.reserve( 25 );
120 fBasketBytes =
new Int_t[fMaxBaskets];
121 fBasketEntry =
new Long64_t[fMaxBaskets];
122 fBasketSeek =
new Long64_t[fMaxBaskets];
124 for (Int_t i = 0; i < fMaxBaskets; ++i) {
135 TBranchSTL::~TBranchSTL()
137 BranchMap_t::iterator brIter;
138 for( brIter = fBranchMap.begin(); brIter != fBranchMap.end(); ++brIter ) {
139 (*brIter).second.fPointers->clear();
140 delete (*brIter).second.fPointers;
147 void TBranchSTL::Browse( TBrowser *b )
149 Int_t nbranches = fBranches.GetEntriesFast();
151 TList persistentBranches;
153 TIter iB(&fBranches);
154 while( (branch = (TBranch*)iB()) )
155 persistentBranches.Add(branch);
156 persistentBranches.Browse( b );
163 Int_t TBranchSTL::FillImpl(ROOT::Internal::TBranchIMTHelper *imtHelper)
168 BranchMap_t::iterator brIter;
169 for( brIter = fBranchMap.begin(); brIter != fBranchMap.end(); ++brIter )
170 (*brIter).second.fPointers->clear();
175 if( fAddress != fObject ) {
181 Int_t totalBytes = 0;
186 fInd.SetNumItems( 0 );
187 bytes = TBranch::FillImpl(imtHelper);
190 Error(
"Fill",
"The IO error while writing the indices!");
198 for( Int_t i = 0; i < fBranches.GetEntriesFast(); ++i ) {
199 TBranch *br = (TBranch *)fBranches.UncheckedAt(i);
200 bytes = br->FillImpl(imtHelper);
202 Error(
"Fill",
"The IO error while writing the branch %s!", br->GetName() );
214 TVirtualCollectionProxy::TPushPop helper( fCollProxy, fObject );
215 UInt_t size = fCollProxy->Size();
220 if( fInd.GetCapacity() < size )
221 fInd.ClearAndResize( size );
223 fInd.SetNumItems( size );
228 TClass* cl = fCollProxy->GetValueClass();
229 TClass* actClass = 0;
230 TClass* vectClass = 0;
232 std::vector<void*>* elPointers = 0;
233 TBranchElement* elBranch = 0;
235 UChar_t maxID = fBranches.GetEntriesFast()+1;
237 ElementBranchHelper_t bHelper;
238 Int_t totalBytes = 0;
242 for( UInt_t i = 0; i < size; ++i ) {
246 element = *(
char**)fCollProxy->At( i );
253 actClass = cl->GetActualClass( element );
254 brIter = fBranchMap.find( actClass );
259 if( brIter == fBranchMap.end() ) {
263 std::string vectClName(
"vector<");
264 vectClName += actClass->GetName() + std::string(
"*>");
265 vectClass = TClass::GetClass( vectClName.c_str() );
267 Warning(
"Fill",
"Unable to find dictionary for class %s", vectClName.c_str() );
275 elPointers =
new std::vector<void*>();
276 if (fName.Length() && fName[fName.Length()-1]==
'.') {
278 brName.Form(
"%s%s", GetName(), actClass->GetName() );
280 brName.Form(
"%s.%s", GetName(), actClass->GetName() );
282 elBranch =
new TBranchElement(
this, brName,
283 vectClass->GetCollectionProxy(),
284 fBasketSize, fSplitLevel-1 );
286 elBranch->SetFirstEntry( fEntryNumber );
288 fBranches.Add( elBranch );
291 bHelper.fBranch = elBranch;
292 bHelper.fPointers = elPointers;
293 bHelper.fBaseOffset = actClass->GetBaseClassOffset( cl );
297 brIter = fBranchMap.insert(std::make_pair(actClass, bHelper ) ).first;
298 elBranch->SetAddress( &((*brIter).second.fPointers) );
304 elPointers = (*brIter).second.fPointers;
305 elBranch = (*brIter).second.fBranch;
306 elID = (*brIter).second.fId;
307 elOffset = (*brIter).second.fBaseOffset;
313 elPointers->push_back( element + elOffset );
320 bytes = TBranch::FillImpl(
nullptr);
322 Error(
"Fill",
"The IO error while writing the indices!");
330 for( Int_t i = 0; i < fBranches.GetEntriesFast(); ++i ) {
331 TBranch *br = (TBranch *)fBranches.UncheckedAt(i);
334 Error(
"Fill",
"The IO error while writing the branch %s!", br->GetName() );
346 Int_t TBranchSTL::GetEntry( Long64_t entry, Int_t getall )
351 if( TestBit( kDoNotProcess ) && !getall )
354 if ( (entry < fFirstEntry) || (entry >= fEntryNumber) )
364 TClass *cl = TClass::GetClass( fContName );
367 Error(
"GetEntry",
"Dictionary class not found for: %s", fContName.Data() );
371 fCollProxy = cl->GetCollectionProxy();
373 Error(
"GetEntry",
"No collection proxy!" );
381 Int_t totalBytes = 0;
382 Int_t bytes = TBranch::GetEntry( entry, getall );
389 Error(
"GetEntry",
"IO error! Unable to get the indices!" );
393 Int_t size = fInd.GetNumItems();
398 UInt_t nBranches = fBranches.GetEntriesFast();
399 TClass* elClass = fCollProxy->GetValueClass();
400 TClass* tmpClass = 0;
402 if( fBranchVector.size() < nBranches )
403 fBranchVector.resize( nBranches );
408 if( fAddress != fObject ) {
409 *((
void **)fAddress) = fCollProxy->New();
410 fObject = *(
char**)fAddress;
412 TVirtualCollectionProxy::TPushPop helper( fCollProxy, fObject );
413 void* env = fCollProxy->Allocate( size, kTRUE );
420 std::vector<void*>* elemVect = 0;
421 TBranchElement* elemBranch = 0;
423 for( Int_t i = 0; i < size; ++i ) {
424 element = (
void**)fCollProxy->At(i);
438 if( index > nBranches ) {
439 Error(
"GetEntry",
"Index %d out of range, unable to find the branch, setting pointer to 0",
449 elemVect = fBranchVector[index].fPointers;
451 elemBranch = (TBranchElement *)fBranches.UncheckedAt(index);
452 elemBranch->SetAddress( &(fBranchVector[index].fPointers) );
454 bytes = elemBranch->GetEntry( entry, getall );
457 Error(
"GetEntry",
"No entry for index %d, setting pointer to 0", index );
459 fBranchVector[index].fPosition++;
464 Error(
"GetEntry",
"I/O error while getting entry for index %d, setting pointer to 0", index );
466 fBranchVector[index].fPosition++;
470 elemVect = fBranchVector[index].fPointers;
475 TVirtualCollectionProxy *proxy = elemBranch->GetCollectionProxy();
477 proxy = TClass::GetClass(elemBranch->GetClassName())->GetCollectionProxy();
480 tmpClass = proxy->GetValueClass();
481 if (tmpClass && elClass) {
482 fBranchVector[index].fBaseOffset = tmpClass->GetBaseClassOffset( elClass );
483 fBranchVector[index].fPosition = 0;
485 Error(
"GetEntry",
"Missing TClass for %s (%s)",elemBranch->GetName(),elemBranch->GetClassName());
488 Error(
"GetEntry",
"Missing CollectionProxy for %s (%s)",elemBranch->GetName(),elemBranch->GetClassName());
495 *element = ((
char*)(*elemVect)[fBranchVector[index].fPosition++])
496 - fBranchVector[index].fBaseOffset;
500 fCollProxy->Commit(env);
505 for( UInt_t i = 0; i < fBranchVector.size(); ++i ) {
506 delete fBranchVector[i].fPointers;
507 fBranchVector[i].fPointers = 0;
519 Int_t TBranchSTL::GetExpectedType(TClass *&expectedClass,EDataType &expectedType)
522 expectedType = kOther_t;
525 expectedClass = TClass::GetClass( fContName );
530 TStreamerElement* element = GetInfo()->GetElement(fID);
532 expectedClass = element->GetClassPointer();
533 if (!expectedClass) {
534 Error(
"GetExpectedType",
"TBranchSTL did not find the TClass for %s", element->GetTypeNameBasic());
538 Error(
"GetExpectedType",
"Did not find the type for %s",GetName());
548 TStreamerInfo* TBranchSTL::GetInfo()
const
557 TClass *cl = TClass::GetClass( fClassName );
562 fInfo = (TStreamerInfo*)cl->GetStreamerInfo( fClassVersion );
567 if( fClCheckSum && !cl->IsVersioned() ) {
571 Int_t ninfos = cl->GetStreamerInfos()->GetEntriesFast() - 1;
572 for( Int_t i = -1; i < ninfos; ++i ) {
573 TVirtualStreamerInfo* info = (TVirtualStreamerInfo*) cl->GetStreamerInfos()->UncheckedAt(i);
580 if( info->GetCheckSum() == fClCheckSum ) {
582 fInfo = (TStreamerInfo*)cl->GetStreamerInfo( fClassVersion );
593 Bool_t TBranchSTL::IsFolder()
const
595 if( fBranches.GetEntriesFast() >= 1 )
603 void TBranchSTL::Print(
const char *option)
const
605 if (strncmp(option,
"debugAddress",strlen(
"debugAddress"))==0) {
606 if (strlen(GetName())>24) Printf(
"%-24s\n%-24s ", GetName(),
"");
607 else Printf(
"%-24s ", GetName());
609 TBranchElement *parent =
dynamic_cast<TBranchElement*
>(GetMother()->GetSubBranch(
this));
610 Int_t ind = parent ? parent->GetListOfBranches()->IndexOf(
this) : -1;
611 TVirtualStreamerInfo *info = GetInfo();
612 Int_t *branchOffset = parent ? parent->GetBranchOffset() : 0;
614 Printf(
"%-16s %2d SplitCollPtr %-16s %-16s %8x %-16s n/a\n",
615 info ? info->GetName() :
"StreamerInfo unvailable", fID,
616 GetClassName(), fParent ? fParent->GetName() :
"n/a",
617 (branchOffset && parent && ind>=0) ? branchOffset[ind] : 0,
619 for( Int_t i = 0; i < fBranches.GetEntriesFast(); ++i ) {
620 TBranch *br = (TBranch *)fBranches.UncheckedAt(i);
621 br->Print(
"debugAddressSub");
623 }
else if (strncmp(option,
"debugInfo",strlen(
"debugInfo"))==0) {
624 Printf(
"Branch %s uses:\n",GetName());
626 GetInfo()->GetElement(fID)->ls();
628 for (Int_t i = 0; i < fBranches.GetEntriesFast(); ++i) {
629 TBranchElement* subbranch = (TBranchElement*)fBranches.At(i);
630 subbranch->Print(
"debugInfoSub");
634 TBranch::Print(option);
635 for( Int_t i = 0; i < fBranches.GetEntriesFast(); ++i ) {
636 TBranch *br = (TBranch *)fBranches.UncheckedAt(i);
645 void TBranchSTL::ReadLeavesImpl( TBuffer& b )
647 b.ReadClassBuffer( fIndArrayCl, &fInd );
653 void TBranchSTL::FillLeavesImpl( TBuffer& b )
655 b.WriteClassBuffer( fIndArrayCl, &fInd );
661 void TBranchSTL::SetAddress(
void* addr )
667 fAddress = (
char*)addr;
668 fObject = *(
char**)addr;
678 TStreamerElement *el = (TStreamerElement*)fInfo->GetElements()->At( fID );
683 if( el->IsaPointer() ) {
684 fAddress = (
char*)addr+el->GetOffset();
685 fObject = *(
char**)fAddress;
687 fAddress = (
char*)addr+el->GetOffset();
688 fObject = (
char*)addr+el->GetOffset();