00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "TBranchElement.h"
00021
00022 #include "TBasket.h"
00023 #include "TBranchObject.h"
00024 #include "TBranchRef.h"
00025 #include "TBrowser.h"
00026 #include "TClass.h"
00027 #include "TClassEdit.h"
00028 #include "TClonesArray.h"
00029 #include "TDataMember.h"
00030 #include "TDataType.h"
00031 #include "TError.h"
00032 #include "TMath.h"
00033 #include "TFile.h"
00034 #include "TFolder.h"
00035 #include "TLeafElement.h"
00036 #include "TRealData.h"
00037 #include "TStreamerElement.h"
00038 #include "TStreamerInfo.h"
00039 #include "TTree.h"
00040 #include "TVirtualCollectionProxy.h"
00041 #include "TVirtualCollectionIterators.h"
00042 #include "TVirtualPad.h"
00043 #include "TBranchSTL.h"
00044 #include "TVirtualArray.h"
00045 #include "TBufferFile.h"
00046 #include "TInterpreter.h"
00047 #include "TROOT.h"
00048
00049 #include "TStreamerInfoActions.h"
00050
00051 ClassImp(TBranchElement)
00052
00053
00054 namespace {
00055 void RemovePrefix(TString& str, const char* prefix) {
00056
00057 if (str.Length() && prefix && strlen(prefix)) {
00058 if (!str.Index(prefix)) {
00059 str.Remove(0, strlen(prefix));
00060 }
00061 }
00062 }
00063 struct R__PushCache {
00064 TBufferFile &fBuffer;
00065 TVirtualArray *fOnfileObject;
00066
00067 R__PushCache(TBufferFile &b, TVirtualArray *in) : fBuffer(b), fOnfileObject(in) {
00068 if (fOnfileObject) fBuffer.PushDataCache( fOnfileObject );
00069 }
00070 ~R__PushCache() {
00071 if (fOnfileObject) fBuffer.PopDataCache();
00072 }
00073 };
00074 }
00075
00076
00077 void TBranchElement::SwitchContainer(TObjArray* branches) {
00078
00079
00080 const Int_t nbranches = branches->GetEntriesFast();
00081 for (Int_t i = 0; i < nbranches; ++i) {
00082 TBranchElement* br = (TBranchElement*) branches->At(i);
00083 switch (br->GetType()) {
00084 case 31: br->SetType(41); break;
00085 case 41: {
00086 br->SetType(31);
00087 br->fCollProxy = 0;
00088 break;
00089 }
00090 }
00091 br->SetReadLeavesPtr();
00092
00093 SwitchContainer(br->GetListOfBranches());
00094 }
00095 }
00096
00097
00098 namespace {
00099 Bool_t CanSelfReference(TClass *cl) {
00100 if (cl) {
00101 if (cl->GetCollectionProxy()) {
00102 TClass *inside = cl->GetCollectionProxy()->GetValueClass();
00103 if (inside) {
00104 return CanSelfReference(inside);
00105 } else {
00106 return kFALSE;
00107 }
00108 }
00109 static TClassRef stringClass("std::string");
00110 if (cl == stringClass || cl == TString::Class()) {
00111 return kFALSE;
00112 }
00113
00114
00115
00116 return kTRUE;
00117 }
00118 return kFALSE;
00119 }
00120 }
00121
00122
00123 TBranchElement::TBranchElement()
00124 : TBranch()
00125 , fClassName()
00126 , fParentName()
00127 , fClonesName()
00128 , fCollProxy(0)
00129 , fCheckSum(0)
00130 , fClassVersion(0)
00131 , fID(0)
00132 , fType(0)
00133 , fStreamerType(-1)
00134 , fMaximum(0)
00135 , fSTLtype(TClassEdit::kNotSTL)
00136 , fNdata(1)
00137 , fBranchCount(0)
00138 , fBranchCount2(0)
00139 , fInfo(0)
00140 , fObject(0)
00141 , fOnfileObject(0)
00142 , fInit(kFALSE)
00143 , fInitOffsets(kFALSE)
00144 , fTargetClass()
00145 , fCurrentClass()
00146 , fParentClass()
00147 , fBranchClass()
00148 , fBranchOffset(0)
00149 , fBranchID(-1)
00150 , fReadActionSequence(0)
00151 , fIterators(0)
00152 , fPtrIterators(0)
00153 {
00154
00155 fNleaves = 0;
00156 fReadLeaves = (ReadLeaves_t)&TBranchElement::ReadLeavesImpl;
00157 }
00158
00159
00160 TBranchElement::TBranchElement(TTree *tree, const char* bname, TStreamerInfo* sinfo, Int_t id, char* pointer, Int_t basketsize, Int_t splitlevel, Int_t btype)
00161 : TBranch()
00162 , fClassName(sinfo->GetName())
00163 , fParentName()
00164 , fClonesName()
00165 , fCollProxy(0)
00166 , fCheckSum(sinfo->GetCheckSum())
00167 , fClassVersion(sinfo->GetClass()->GetClassVersion())
00168 , fID(id)
00169 , fType(0)
00170 , fStreamerType(-1)
00171 , fMaximum(0)
00172 , fSTLtype(TClassEdit::kNotSTL)
00173 , fNdata(1)
00174 , fBranchCount(0)
00175 , fBranchCount2(0)
00176 , fInfo(sinfo)
00177 , fObject(0)
00178 , fOnfileObject(0)
00179 , fInit(kTRUE)
00180 , fInitOffsets(kFALSE)
00181 , fTargetClass(fClassName)
00182 , fCurrentClass()
00183 , fParentClass()
00184 , fBranchClass(sinfo->GetClass())
00185 , fBranchOffset(0)
00186 , fBranchID(-1)
00187 , fReadActionSequence(0)
00188 , fIterators(0)
00189 , fPtrIterators(0)
00190 {
00191
00192
00193
00194
00195 Init(tree, 0, bname,sinfo,id,pointer,basketsize,splitlevel,btype);
00196 }
00197
00198
00199 TBranchElement::TBranchElement(TBranch *parent, const char* bname, TStreamerInfo* sinfo, Int_t id, char* pointer, Int_t basketsize, Int_t splitlevel, Int_t btype)
00200 : TBranch()
00201 , fClassName(sinfo->GetName())
00202 , fParentName()
00203 , fClonesName()
00204 , fCollProxy(0)
00205 , fCheckSum(sinfo->GetCheckSum())
00206 , fClassVersion(sinfo->GetClass()->GetClassVersion())
00207 , fID(id)
00208 , fType(0)
00209 , fStreamerType(-1)
00210 , fMaximum(0)
00211 , fSTLtype(TClassEdit::kNotSTL)
00212 , fNdata(1)
00213 , fBranchCount(0)
00214 , fBranchCount2(0)
00215 , fInfo(sinfo)
00216 , fObject(0)
00217 , fOnfileObject(0)
00218 , fInit(kTRUE)
00219 , fInitOffsets(kFALSE)
00220 , fTargetClass( fClassName )
00221 , fCurrentClass()
00222 , fParentClass()
00223 , fBranchClass(sinfo->GetClass())
00224 , fBranchOffset(0)
00225 , fBranchID(-1)
00226 , fReadActionSequence(0)
00227 , fIterators(0)
00228 , fPtrIterators(0)
00229 {
00230
00231
00232
00233
00234 Init(parent ? parent->GetTree() : 0, parent, bname,sinfo,id,pointer,basketsize,splitlevel,btype);
00235 }
00236
00237
00238 void TBranchElement::Init(TTree *tree, TBranch *parent,const char* bname, TStreamerInfo* sinfo, Int_t id, char* pointer, Int_t basketsize, Int_t splitlevel, Int_t btype)
00239 {
00240
00241
00242
00243
00244 TString name(bname);
00245
00246
00247 SetName(name);
00248 SetTitle(name);
00249
00250
00251 fSplitLevel = splitlevel;
00252 fTree = tree;
00253 if (fTree == 0) return;
00254 fMother = parent ? parent->GetMother() : this;
00255 fParent = parent;
00256 fDirectory = fTree->GetDirectory();
00257 fFileName = "";
00258
00259
00260
00261
00262 SetAutoDelete(kFALSE);
00263
00264 fReadLeaves = (ReadLeaves_t)&TBranchElement::ReadLeavesImpl;
00265
00266
00267
00268
00269 Int_t splitSTLP = splitlevel - (splitlevel%TTree::kSplitCollectionOfPointers);
00270 splitlevel %= TTree::kSplitCollectionOfPointers;
00271
00272 fCompress = -1;
00273 if (fTree->GetDirectory()) {
00274 TFile* bfile = fTree->GetDirectory()->GetFile();
00275 if (bfile) {
00276 fCompress = bfile->GetCompressionLevel();
00277 }
00278 }
00279
00280
00281
00282
00283
00284 if (id > -1) {
00285
00286 ULong_t* elems = sinfo->GetElems();
00287 TStreamerElement* element = (TStreamerElement*) elems[id];
00288 fStreamerType = element->GetType();
00289 }
00290
00291
00292
00293
00294
00295
00296
00297
00298 fEntryOffsetLen = 0;
00299 if (btype || (fStreamerType <= TVirtualStreamerInfo::kBase) || (fStreamerType == TVirtualStreamerInfo::kCharStar) || (fStreamerType == TVirtualStreamerInfo::kBits) || (fStreamerType > TVirtualStreamerInfo::kFloat16)) {
00300 fEntryOffsetLen = fTree->GetDefaultEntryOffsetLen();
00301 }
00302
00303
00304
00305
00306
00307
00308 if (basketsize < (100 + fEntryOffsetLen)) {
00309 basketsize = 100 + fEntryOffsetLen;
00310 }
00311 fBasketSize = basketsize;
00312
00313
00314
00315
00316
00317
00318 fBasketBytes = new Int_t[fMaxBaskets];
00319 fBasketEntry = new Long64_t[fMaxBaskets];
00320 fBasketSeek = new Long64_t[fMaxBaskets];
00321
00322 for (Int_t i = 0; i < fMaxBaskets; ++i) {
00323 fBasketBytes[i] = 0;
00324 fBasketEntry[i] = 0;
00325 fBasketSeek[i] = 0;
00326 }
00327
00328
00329
00330
00331 TBranchElement* brOfCounter = 0;
00332
00333 if (id < 0) {
00334
00335 if (fBranchClass.GetClass()) {
00336 Bool_t hasCustomStreamer = kFALSE;
00337 Bool_t canSelfReference = CanSelfReference(fBranchClass);
00338 if (fBranchClass.GetClass()->InheritsFrom(TObject::Class())) {
00339 if (canSelfReference) SetBit(kBranchObject);
00340 hasCustomStreamer = (!fBranchClass.GetClass()->GetCollectionProxy() && (gCint->ClassInfo_RootFlag(fBranchClass.GetClass()->GetClassInfo()) & 1));
00341 } else {
00342 if (canSelfReference) SetBit(kBranchAny);
00343 hasCustomStreamer = !fBranchClass.GetClass()->GetCollectionProxy() && (fBranchClass.GetClass()->GetStreamer() != 0 || (gCint->ClassInfo_RootFlag(fBranchClass.GetClass()->GetClassInfo()) & 1));
00344 }
00345 if (hasCustomStreamer) {
00346 fType = -1;
00347 }
00348 }
00349 } else {
00350
00351 ULong_t* elems = sinfo->GetElems();
00352 TStreamerElement* element = (TStreamerElement*) elems[id];
00353 if ((fStreamerType == TVirtualStreamerInfo::kObject) || (fStreamerType == TVirtualStreamerInfo::kBase) || (fStreamerType == TVirtualStreamerInfo::kTNamed) || (fStreamerType == TVirtualStreamerInfo::kTObject) || (fStreamerType == TVirtualStreamerInfo::kObjectp) || (fStreamerType == TVirtualStreamerInfo::kObjectP)) {
00354
00355
00356
00357 if (CanSelfReference(fBranchClass)) {
00358 if (fBranchClass.GetClass()->InheritsFrom(TObject::Class())) {
00359 SetBit(kBranchObject);
00360 } else {
00361 SetBit(kBranchAny);
00362 }
00363 }
00364 }
00365 if (element->IsA() == TStreamerBasicPointer::Class()) {
00366
00367 TStreamerBasicPointer *bp = (TStreamerBasicPointer *)element;
00368 TString countname;
00369 countname = bname;
00370 Ssiz_t dot = countname.Last('.');
00371 if (dot>=0) {
00372 countname.Remove(dot+1);
00373 } else {
00374 countname = "";
00375 }
00376 countname += bp->GetCountName();
00377 brOfCounter = (TBranchElement *)fTree->GetBranch(countname);
00378 countname.Form("%s[%s]",name.Data(),bp->GetCountName());
00379 SetTitle(countname);
00380
00381 } else if (element->IsA() == TStreamerLoop::Class()) {
00382
00383 TStreamerLoop *bp = (TStreamerLoop *)element;
00384 TString countname;
00385 countname = bname;
00386 Ssiz_t dot = countname.Last('.');
00387 if (dot>=0) {
00388 countname.Remove(dot+1);
00389 } else {
00390 countname = "";
00391 }
00392 countname += bp->GetCountName();
00393 brOfCounter = (TBranchElement *)fTree->GetBranch(countname);
00394 countname.Form("%s[%s]",name.Data(),bp->GetCountName());
00395 SetTitle(countname);
00396
00397 }
00398
00399 if (splitlevel > 0) {
00400
00401 const char* elem_type = element->GetTypeName();
00402 fSTLtype = TMath::Abs(TClassEdit::IsSTLCont(elem_type));
00403 if (element->CannotSplit()) {
00404 fSplitLevel = 0;
00405 } else if (element->IsA() == TStreamerBase::Class()) {
00406
00407
00408
00409
00410
00411 fType = 1;
00412 TClass* clOfElement = TClass::GetClass(element->GetName());
00413 Int_t nbranches = fBranches.GetEntriesFast();
00414
00415
00416
00417
00418
00419 if (!strcmp(name, clOfElement->GetName())) {
00420
00421
00422
00423
00424
00425
00426
00427
00428 Unroll("", fBranchClass.GetClass(), clOfElement, pointer, basketsize, splitlevel+splitSTLP, 0);
00429 SetReadLeavesPtr();
00430 return;
00431 }
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445 Unroll(name, clOfElement, clOfElement, pointer, basketsize, splitlevel+splitSTLP, 0);
00446 if (strchr(bname, '.')) {
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457 SetReadLeavesPtr();
00458 return;
00459 }
00460 if (nbranches == fBranches.GetEntriesFast()) {
00461
00462 if (strlen(bname)) {
00463 name.Form("%s.%s", bname, clOfElement->GetName());
00464 } else {
00465 name.Form("%s", clOfElement->GetName());
00466 }
00467 SetName(name);
00468 SetTitle(name);
00469 }
00470 SetReadLeavesPtr();
00471 return;
00472 } else if (!strcmp(elem_type, "TClonesArray") || !strcmp(elem_type, "TClonesArray*")) {
00473
00474 Bool_t ispointer = !strcmp(elem_type,"TClonesArray*");
00475 TClonesArray *clones;
00476 if (ispointer) {
00477 char **ppointer = (char**)(pointer);
00478 clones = (TClonesArray*)(*ppointer);
00479 } else {
00480 clones = (TClonesArray*)pointer;
00481 }
00482
00483 fEntryOffsetLen = 0;
00484
00485 TLeaf* leaf = new TLeafElement(this, name, fID, fStreamerType);
00486 fNleaves = 1;
00487 fLeaves.Add(leaf);
00488 fTree->GetListOfLeaves()->Add(leaf);
00489 if (!clones) return;
00490 TClass* clOfClones = clones->GetClass();
00491 if (!clOfClones) {
00492 SetReadLeavesPtr();
00493 return;
00494 }
00495 fType = 3;
00496
00497
00498
00499
00500 fClonesName = clOfClones->GetName();
00501 TString aname;
00502 aname.Form(" (%s)", clOfClones->GetName());
00503 TString atitle = element->GetTitle();
00504 if (!atitle.Contains(aname)) {
00505 atitle += aname;
00506 element->SetTitle(atitle.Data());
00507 }
00508 TString branchname( name );
00509 branchname += "_";
00510 SetTitle(branchname);
00511 leaf->SetName(branchname);
00512 leaf->SetTitle(branchname);
00513 Unroll(name, clOfClones, clOfClones, pointer, basketsize, splitlevel+splitSTLP, 31);
00514 BuildTitle(name);
00515 SetReadLeavesPtr();
00516 return;
00517 } else if (((fSTLtype >= TClassEdit::kVector) && (fSTLtype < TClassEdit::kEnd)) || ((fSTLtype > -TClassEdit::kEnd) && (fSTLtype <= -TClassEdit::kVector))) {
00518
00519 TClass* contCl = TClass::GetClass(elem_type);
00520 fCollProxy = contCl->GetCollectionProxy()->Generate();
00521 TClass* valueClass = GetCollectionProxy()->GetValueClass();
00522
00523 Bool_t cansplit = kTRUE;
00524 if (!valueClass) {
00525 cansplit = kFALSE;
00526 } else if ((valueClass == TString::Class()) || (valueClass == TClass::GetClass("string"))) {
00527 cansplit = kFALSE;
00528 } else if (GetCollectionProxy()->HasPointers() && !splitSTLP ) {
00529 cansplit = kFALSE;
00530 } else if (!valueClass->CanSplit() && !(GetCollectionProxy()->HasPointers() && splitSTLP)) {
00531 cansplit = kFALSE;
00532 } else if (valueClass->GetCollectionProxy()) {
00533
00534
00535
00536 cansplit = kFALSE;
00537 }
00538 if (cansplit) {
00539
00540 fType = 4;
00541
00542 TLeaf *leaf = new TLeafElement(this, name, fID, fStreamerType);
00543 fNleaves = 1;
00544 fLeaves.Add(leaf);
00545 fTree->GetListOfLeaves()->Add(leaf);
00546
00547
00548
00549 fClonesName = valueClass->GetName();
00550 TString aname;
00551 aname.Form(" (%s)", valueClass->GetName());
00552 TString atitle = element->GetTitle();
00553 if (!atitle.Contains(aname)) {
00554 atitle += aname;
00555 element->SetTitle(atitle.Data());
00556 }
00557 TString branchname (name);
00558 branchname += "_";
00559 SetTitle(branchname);
00560 leaf->SetName(branchname);
00561 leaf->SetTitle(branchname);
00562
00563 Unroll(name, valueClass, valueClass, pointer, basketsize, splitlevel+splitSTLP, 41);
00564 BuildTitle(name);
00565 SetReadLeavesPtr();
00566 return;
00567 }
00568 } else if (!strchr(elem_type, '*') && ((fStreamerType == TVirtualStreamerInfo::kObject) || (fStreamerType == TVirtualStreamerInfo::kAny))) {
00569
00570
00571
00572
00573
00574 fType = 2;
00575 TClass* clm = TClass::GetClass(elem_type);
00576 Int_t err = Unroll(name, clm, clm, pointer, basketsize, splitlevel+splitSTLP, 0);
00577 if (err >= 0) {
00578
00579
00580 SetReadLeavesPtr();
00581 return;
00582 }
00583 }
00584 }
00585 }
00586
00587
00588
00589
00590
00591 TLeaf* leaf = new TLeafElement(this, GetTitle(), fID, fStreamerType);
00592 leaf->SetTitle(GetTitle());
00593 fNleaves = 1;
00594 fLeaves.Add(leaf);
00595 fTree->GetListOfLeaves()->Add(leaf);
00596
00597
00598
00599
00600
00601
00602 if (brOfCounter) {
00603 SetBranchCount(brOfCounter);
00604 }
00605
00606 SetReadLeavesPtr();
00607 }
00608
00609
00610 TBranchElement::TBranchElement(TTree *tree, const char* bname, TClonesArray* clones, Int_t basketsize, Int_t splitlevel, Int_t compress)
00611 : TBranch()
00612 , fClassName("TClonesArray")
00613 , fParentName()
00614 , fInfo((TStreamerInfo*)TClonesArray::Class()->GetStreamerInfo())
00615 , fTargetClass( fClassName )
00616 , fCurrentClass()
00617 , fParentClass()
00618 , fBranchClass(TClonesArray::Class())
00619 , fBranchID(-1)
00620 , fReadActionSequence(0)
00621 , fIterators(0)
00622 , fPtrIterators(0)
00623 {
00624
00625
00626
00627
00628 Init(tree, 0, bname, clones, basketsize, splitlevel, compress);
00629 }
00630
00631
00632 TBranchElement::TBranchElement(TBranch *parent, const char* bname, TClonesArray* clones, Int_t basketsize, Int_t splitlevel, Int_t compress)
00633 : TBranch()
00634 , fClassName("TClonesArray")
00635 , fParentName()
00636 , fInfo((TStreamerInfo*)TClonesArray::Class()->GetStreamerInfo())
00637 , fTargetClass( fClassName )
00638 , fCurrentClass()
00639 , fParentClass()
00640 , fBranchClass(TClonesArray::Class())
00641 , fBranchID(-1)
00642 , fReadActionSequence(0)
00643 , fIterators(0)
00644 , fPtrIterators(0)
00645 {
00646
00647
00648
00649
00650 Init(parent ? parent->GetTree() : 0, parent, bname, clones, basketsize, splitlevel, compress);
00651 }
00652
00653
00654 void TBranchElement::Init(TTree *tree, TBranch *parent, const char* bname, TClonesArray* clones, Int_t basketsize, Int_t splitlevel, Int_t compress)
00655 {
00656
00657
00658
00659
00660 fCollProxy = 0;
00661 fSplitLevel = splitlevel;
00662 fID = 0;
00663 fInit = kTRUE;
00664 fStreamerType = -1;
00665 fType = 0;
00666 fClassVersion = TClonesArray::Class()->GetClassVersion();
00667 fCheckSum = fInfo->GetCheckSum();
00668 fBranchCount = 0;
00669 fBranchCount2 = 0;
00670 fObject = 0;
00671 fOnfileObject = 0;
00672 fMaximum = 0;
00673 fBranchOffset = 0;
00674 fSTLtype = TClassEdit::kNotSTL;
00675 fInitOffsets = kFALSE;
00676
00677 fTree = tree;
00678 fMother = parent ? parent->GetMother() : this;
00679 fParent = parent;
00680 fDirectory = fTree->GetDirectory();
00681 fFileName = "";
00682
00683 SetName(bname);
00684 const char* name = GetName();
00685 SetTitle(name);
00686
00687 fCompress = compress;
00688 if (compress == -1 && fTree->GetDirectory()) {
00689 TFile *bfile = fTree->GetDirectory()->GetFile();
00690 if (bfile) fCompress = bfile->GetCompressionLevel();
00691 }
00692
00693 if (basketsize < 100) basketsize = 100;
00694 fBasketSize = basketsize;
00695 fBasketBytes = new Int_t[fMaxBaskets];
00696 fBasketEntry = new Long64_t[fMaxBaskets];
00697 fBasketSeek = new Long64_t[fMaxBaskets];
00698
00699 for (Int_t i=0;i<fMaxBaskets;i++) {
00700 fBasketBytes[i] = 0;
00701 fBasketEntry[i] = 0;
00702 fBasketSeek[i] = 0;
00703 }
00704
00705
00706
00707 SetAutoDelete(kFALSE);
00708
00709
00710 if (splitlevel%TTree::kSplitCollectionOfPointers > 0) {
00711 TClass* clonesClass = clones->GetClass();
00712 if (!clonesClass) {
00713 Error("Init","Missing class object of the TClonesArray %s\n",clones->GetName());
00714 return;
00715 }
00716 fType = 3;
00717
00718 TLeaf* leaf = new TLeafElement(this, name, fID, fStreamerType);
00719 fNleaves = 1;
00720 fLeaves.Add(leaf);
00721 fTree->GetListOfLeaves()->Add(leaf);
00722
00723 fClonesName = clonesClass->GetName();
00724 std::string branchname = name + std::string("_");
00725 SetTitle(branchname.c_str());
00726 leaf->SetName(branchname.c_str());
00727 leaf->SetTitle(branchname.c_str());
00728 Unroll(name, clonesClass, clonesClass, 0, basketsize, splitlevel, 31);
00729 BuildTitle(name);
00730 SetReadLeavesPtr();
00731 return;
00732 }
00733
00734 if (!clones->GetClass() || CanSelfReference(clones->GetClass())) {
00735 SetBit(kBranchObject);
00736 }
00737 TLeaf *leaf = new TLeafElement(this, GetTitle(), fID, fStreamerType);
00738 leaf->SetTitle(GetTitle());
00739 fNleaves = 1;
00740 fLeaves.Add(leaf);
00741 fTree->GetListOfLeaves()->Add(leaf);
00742
00743 SetReadLeavesPtr();
00744 }
00745
00746
00747 TBranchElement::TBranchElement(TTree *tree, const char* bname, TVirtualCollectionProxy* cont, Int_t basketsize, Int_t splitlevel, Int_t compress)
00748 : TBranch()
00749 , fClassName(cont->GetCollectionClass()->GetName())
00750 , fParentName()
00751 , fTargetClass( fClassName )
00752 , fCurrentClass()
00753 , fParentClass()
00754 , fBranchClass(cont->GetCollectionClass())
00755 , fBranchID(-1)
00756 , fReadActionSequence(0)
00757 , fIterators(0)
00758 , fPtrIterators(0)
00759 {
00760
00761
00762
00763
00764 Init(tree, 0, bname, cont, basketsize, splitlevel, compress);
00765 }
00766
00767
00768 TBranchElement::TBranchElement(TBranch *parent, const char* bname, TVirtualCollectionProxy* cont, Int_t basketsize, Int_t splitlevel, Int_t compress)
00769 : TBranch()
00770 , fClassName(cont->GetCollectionClass()->GetName())
00771 , fParentName()
00772 , fTargetClass( fClassName )
00773 , fCurrentClass()
00774 , fParentClass()
00775 , fBranchClass(cont->GetCollectionClass())
00776 , fBranchID(-1)
00777 , fReadActionSequence(0)
00778 , fIterators(0)
00779 , fPtrIterators(0)
00780 {
00781
00782
00783
00784
00785 Init(parent ? parent->GetTree() : 0, parent, bname, cont, basketsize, splitlevel, compress);
00786 }
00787
00788
00789 void TBranchElement::Init(TTree *tree, TBranch *parent, const char* bname, TVirtualCollectionProxy* cont, Int_t basketsize, Int_t splitlevel, Int_t compress)
00790 {
00791
00792
00793
00794
00795 fCollProxy = cont->Generate();
00796 TString name( bname );
00797 if (name[name.Length()-1]=='.') {
00798 name.Remove(name.Length()-1);
00799 }
00800 fInitOffsets = kFALSE;
00801 fSplitLevel = splitlevel;
00802 fInfo = 0;
00803 fID = -1;
00804 fInit = kTRUE;
00805 fStreamerType = -1;
00806 fType = 0;
00807 fClassVersion = cont->GetCollectionClass()->GetClassVersion();
00808 fCheckSum = cont->GetCollectionClass()->GetCheckSum();
00809 fBranchCount = 0;
00810 fBranchCount2 = 0;
00811 fObject = 0;
00812 fOnfileObject = 0;
00813 fMaximum = 0;
00814 fBranchOffset = 0;
00815 fSTLtype = TClassEdit::kNotSTL;
00816
00817 fTree = tree;
00818 fMother = parent ? parent->GetMother() : this;
00819 fParent = parent;
00820 fDirectory = fTree->GetDirectory();
00821 fFileName = "";
00822
00823 SetName(name);
00824 SetTitle(name);
00825
00826 fCompress = compress;
00827 if ((compress == -1) && fTree->GetDirectory()) {
00828 TFile* bfile = fTree->GetDirectory()->GetFile();
00829 if (bfile) {
00830 fCompress = bfile->GetCompressionLevel();
00831 }
00832 }
00833
00834 if (basketsize < 100) {
00835 basketsize = 100;
00836 }
00837 fBasketSize = basketsize;
00838
00839 fBasketBytes = new Int_t[fMaxBaskets];
00840 fBasketEntry = new Long64_t[fMaxBaskets];
00841 fBasketSeek = new Long64_t[fMaxBaskets];
00842
00843 for (Int_t i = 0; i < fMaxBaskets; ++i) {
00844 fBasketBytes[i] = 0;
00845 fBasketEntry[i] = 0;
00846 fBasketSeek[i] = 0;
00847 }
00848
00849
00850
00851 SetAutoDelete(kFALSE);
00852
00853
00854 if ( (splitlevel%TTree::kSplitCollectionOfPointers > 0 && fBranchClass.GetClass() && fBranchClass.GetClass()->CanSplit()) ||
00855 (cont->HasPointers() && splitlevel > TTree::kSplitCollectionOfPointers && cont->GetValueClass() && cont->GetValueClass()->CanSplit() ) )
00856 {
00857 fType = 4;
00858
00859 TLeaf* leaf = new TLeafElement(this, name, fID, fStreamerType);
00860 fNleaves = 1;
00861 fLeaves.Add(leaf);
00862 fTree->GetListOfLeaves()->Add(leaf);
00863
00864 TClass* valueClass = cont->GetValueClass();
00865 if (!valueClass) {
00866 return;
00867 }
00868 fClonesName = valueClass->GetName();
00869 TString branchname( name );
00870 branchname += "_";
00871 SetTitle(branchname);
00872 leaf->SetName(branchname);
00873 leaf->SetTitle(branchname);
00874 Unroll(name, valueClass, valueClass, 0, basketsize, splitlevel, 41);
00875 BuildTitle(name);
00876 SetReadLeavesPtr();
00877 return;
00878 }
00879
00880 TLeaf *leaf = new TLeafElement(this, GetTitle(), fID, fStreamerType);
00881 leaf->SetTitle(GetTitle());
00882 fNleaves = 1;
00883 fLeaves.Add(leaf);
00884 fTree->GetListOfLeaves()->Add(leaf);
00885 SetReadLeavesPtr();
00886 }
00887
00888
00889 TBranchElement::~TBranchElement()
00890 {
00891
00892
00893
00894 if (fOnfileObject && TestBit(kOwnOnfileObj)) {
00895 delete fOnfileObject;
00896 fOnfileObject = 0;
00897 }
00898 ResetAddress();
00899
00900 delete[] fBranchOffset;
00901 fBranchOffset = 0;
00902
00903 fInfo = 0;
00904 fBranchCount2 = 0;
00905 fBranchCount = 0;
00906
00907 if (fType == 4) {
00908
00909
00910 delete fCollProxy;
00911 }
00912 fCollProxy = 0;
00913
00914 delete fReadActionSequence;
00915 delete fIterators;
00916 delete fPtrIterators;
00917 }
00918
00919
00920
00921
00922
00923 inline TStreamerInfo* TBranchElement::GetInfoImp() const
00924 {
00925
00926
00927 if (!fInfo || (fInfo && (!fInit || !fInfo->IsCompiled()))) {
00928 const_cast<TBranchElement*>(this)->InitInfo();
00929 }
00930 return fInfo;
00931 }
00932
00933
00934 TStreamerInfo* TBranchElement::GetInfo() const
00935 {
00936
00937
00938 return GetInfoImp();
00939 }
00940
00941
00942 void TBranchElement::Browse(TBrowser* b)
00943 {
00944
00945
00946 Int_t nbranches = fBranches.GetEntriesFast();
00947 if (nbranches > 0) {
00948 TList persistentBranches;
00949 TBranch* branch=0;
00950 TIter iB(&fBranches);
00951 while((branch=(TBranch*)iB())) {
00952 if (branch->IsFolder()) persistentBranches.Add(branch);
00953 else {
00954
00955 TClass* cl=0;
00956 if (strlen(GetClonesName()))
00957
00958
00959 cl=TClass::GetClass(GetClonesName());
00960 else {
00961 cl=TClass::GetClass(GetClassName());
00962
00963
00964
00965 ULong_t *elems=0;
00966 TStreamerElement *element=0;
00967 TClass* clsub=0;
00968 if (fID>=0 && GetInfoImp()
00969 && ((elems=GetInfoImp()->GetElems()))
00970 && ((element=(TStreamerElement *)elems[fID]))
00971 && ((clsub=element->GetClassPointer())))
00972 cl=clsub;
00973 }
00974 if (cl) {
00975 TString strMember=branch->GetName();
00976 Size_t mempos=strMember.Last('.');
00977 if (mempos!=kNPOS)
00978 strMember.Remove(0, (Int_t)mempos+1);
00979 mempos=strMember.First('[');
00980 if (mempos!=kNPOS)
00981 strMember.Remove((Int_t)mempos);
00982 TDataMember* m=cl->GetDataMember(strMember);
00983 if (!m || m->IsPersistent()) persistentBranches.Add(branch);
00984 } else persistentBranches.Add(branch);
00985 }
00986 }
00987 persistentBranches.Browse(b);
00988
00989 if (GetBrowsables() && GetBrowsables()->GetSize())
00990 GetBrowsables()->Browse(b);
00991 } else {
00992 if (GetBrowsables() && GetBrowsables()->GetSize()) {
00993 GetBrowsables()->Browse(b);
00994 return;
00995 }
00996
00997
00998 TString slash("/");
00999 TString escapedSlash("\\/");
01000 TString name = GetName();
01001 Int_t pos = name.First('[');
01002 if (pos != kNPOS) {
01003 name.Remove(pos);
01004 }
01005 TString mothername;
01006 if (GetMother()) {
01007 mothername = GetMother()->GetName();
01008 pos = mothername.First('[');
01009 if (pos != kNPOS) {
01010 mothername.Remove(pos);
01011 }
01012 Int_t len = mothername.Length();
01013 if (len) {
01014 if (mothername(len-1) != '.') {
01015
01016
01017
01018
01019 TString doublename = mothername;
01020 doublename.Append(".");
01021 Int_t isthere = (name.Index(doublename) == 0);
01022 if (!isthere) {
01023 name.Prepend(doublename);
01024 } else {
01025 if (GetMother()->FindBranch(mothername)) {
01026 doublename.Append(mothername);
01027 isthere = (name.Index(doublename) == 0);
01028 if (!isthere) {
01029 mothername.Append(".");
01030 name.Prepend(mothername);
01031 }
01032 } else {
01033
01034
01035 }
01036 }
01037 } else {
01038
01039
01040 if (name.Index(mothername) == kNPOS) {
01041 name.Prepend(mothername);
01042 }
01043 }
01044 }
01045 }
01046 name.ReplaceAll(slash, escapedSlash);
01047 GetTree()->Draw(name, "", b ? b->GetDrawOption() : "");
01048 if (gPad) {
01049 gPad->Update();
01050 }
01051 }
01052 }
01053
01054
01055 void TBranchElement::BuildTitle(const char* name)
01056 {
01057
01058
01059 TString branchname;
01060
01061 Int_t nbranches = fBranches.GetEntries();
01062
01063 for (Int_t i = 0; i < nbranches; ++i) {
01064 TBranchElement* bre = (TBranchElement*) fBranches.At(i);
01065 if (fType == 3) {
01066 bre->SetType(31);
01067 } else if (fType == 4) {
01068 bre->SetType(41);
01069 } else {
01070 Error("BuildTitle", "This cannot happen, fType of parent is not 3 or 4!");
01071 }
01072 bre->fCollProxy = GetCollectionProxy();
01073 bre->BuildTitle(name);
01074 const char* fin = strrchr(bre->GetTitle(), '.');
01075 if (fin == 0) {
01076 continue;
01077 }
01078
01079 bre->SetBranchCount(this);
01080 TLeafElement* lf = (TLeafElement*) bre->GetListOfLeaves()->At(0);
01081
01082
01083 branchname = fin+1;
01084 Ssiz_t dim = branchname.First('[');
01085 if (dim>=0) {
01086 branchname.Remove(dim);
01087 }
01088 branchname += Form("[%s_]",name);
01089 bre->SetTitle(branchname);
01090 if (lf) {
01091 lf->SetTitle(branchname);
01092 }
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105 Int_t stype = bre->GetStreamerType();
01106
01107 if ((stype > 40) && (stype < 61)) {
01108 TString name2 (bre->GetName());
01109 Ssiz_t bn = name2.Last('.');
01110 if (bn<0) {
01111 continue;
01112 }
01113 TStreamerBasicPointer *el = (TStreamerBasicPointer*)bre->GetInfoImp()->GetElements()->FindObject(name2.Data()+bn+1);
01114 name2.Remove(bn+1);
01115 if (el) name2 += el->GetCountName();
01116 TBranchElement *bc2 = (TBranchElement*)fBranches.FindObject(name2);
01117 bre->SetBranchCount2(bc2);
01118 }
01119 bre->SetReadLeavesPtr();
01120 }
01121 }
01122
01123
01124 Int_t TBranchElement::Fill()
01125 {
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135 Int_t nbytes = 0;
01136 Int_t nwrite = 0;
01137 Int_t nerror = 0;
01138 Int_t nbranches = fBranches.GetEntriesFast();
01139
01140 ValidateAddress();
01141
01142
01143
01144
01145
01146 if (fID < 0) {
01147 if (!fObject) {
01148 Error("Fill", "attempt to fill branch %s while addresss is not set", GetName());
01149 return 0;
01150 }
01151 }
01152
01153
01154
01155
01156
01157
01158
01159 if ((fType >= -1) && (fType < 10)) {
01160 TBranchRef* bref = fTree->GetBranchRef();
01161 if (bref) {
01162 fBranchID = bref->SetParent(this, fBranchID);
01163 }
01164 }
01165
01166 if (!nbranches) {
01167
01168 if (!TestBit(kDoNotProcess)) {
01169 nwrite = TBranch::Fill();
01170 if (nwrite < 0) {
01171 Error("Fill", "Failed filling branch:%s, nbytes=%d", GetName(), nwrite);
01172 ++nerror;
01173 } else {
01174 nbytes += nwrite;
01175 }
01176 }
01177 } else {
01178
01179 if (fType == 3 || fType == 4) {
01180
01181 nwrite = TBranch::Fill();
01182 if (nwrite < 0) {
01183 Error("Fill", "Failed filling branch:%s, nbytes=%d", GetName(), nwrite);
01184 ++nerror;
01185 } else {
01186 nbytes += nwrite;
01187 }
01188 } else {
01189 ++fEntries;
01190 }
01191 for (Int_t i = 0; i < nbranches; ++i) {
01192 TBranchElement* branch = (TBranchElement*) fBranches[i];
01193 if (!branch->TestBit(kDoNotProcess)) {
01194 nwrite = branch->Fill();
01195 if (nwrite < 0) {
01196 Error("Fill", "Failed filling branch:%s.%s, nbytes=%d", GetName(), branch->GetName(), nwrite);
01197 nerror++;
01198 } else {
01199 nbytes += nwrite;
01200 }
01201 }
01202 }
01203 }
01204
01205 if (fTree->Debug() > 0) {
01206
01207 Long64_t entry = fEntries;
01208 if ((entry >= fTree->GetDebugMin()) && (entry <= fTree->GetDebugMax())) {
01209 printf("Fill: %lld, branch=%s, nbytes=%d\n", entry, GetName(), nbytes);
01210 }
01211 }
01212
01213 if (nerror != 0) {
01214 return -1;
01215 }
01216
01217 return nbytes;
01218 }
01219
01220
01221 void TBranchElement::FillLeaves(TBuffer& b)
01222 {
01223
01224
01225
01226
01227
01228 ValidateAddress();
01229
01230
01231
01232
01233
01234 if (!fObject) {
01235 return;
01236 }
01237
01238
01239
01240
01241
01242 if (fType <=2) {
01243 if (TestBit(kBranchObject)) {
01244 b.MapObject((TObject*) fObject);
01245 } else if (TestBit(kBranchAny)) {
01246 b.MapObject(fObject, fBranchClass);
01247 }
01248 } else {
01249
01250
01251 }
01252
01253
01254
01255
01256
01257 if (fType < 0) {
01258
01259
01260 fBranchClass->Streamer(fObject,b);
01261 return;
01262
01263 } else if (fType <= 2) {
01264
01265
01266
01267
01268
01269 TStreamerInfo* si = GetInfoImp();
01270 if (!si) {
01271 Error("FillLeaves", "Cannot get streamer info for branch '%s'", GetName());
01272 return;
01273 }
01274 Int_t n = si->WriteBufferAux(b, &fObject, fID, 1, 0, 0);
01275 if ((fStreamerType == TVirtualStreamerInfo::kCounter) && (n > fMaximum)) {
01276 fMaximum = n;
01277 }
01278 } else if (fType == 3) {
01279
01280 if (fTree->GetMakeClass()) {
01281
01282
01283
01284 TClass* cl = TClass::GetClass(GetClonesName());
01285 TVirtualStreamerInfo* si = cl->GetStreamerInfo();
01286 if (!si) {
01287 Error("FillLeaves", "Cannot get streamer info for branch '%s' class '%s'", GetName(), cl->GetName());
01288 return;
01289 }
01290 b.ForceWriteInfo(si,kFALSE);
01291 Int_t* nptr = (Int_t*) fAddress;
01292 b << *nptr;
01293 } else {
01294 TClonesArray* clones = (TClonesArray*) fObject;
01295 Int_t n = clones->GetEntriesFast();
01296 if (n > fMaximum) {
01297 fMaximum = n;
01298 }
01299 b << n;
01300 }
01301 } else if (fType == 4) {
01302
01303 Int_t n = 0;
01304 {
01305
01306 TVirtualCollectionProxy::TPushPop helper(GetCollectionProxy(), fObject);
01307 n = GetCollectionProxy()->Size();
01308 }
01309 if (n > fMaximum) {
01310 fMaximum = n;
01311 }
01312 b << n;
01313 } else if (fType == 31) {
01314
01315 if (fTree->GetMakeClass()) {
01316
01317 if (!fAddress) {
01318
01319
01320 return;
01321 }
01322 Int_t atype = fStreamerType;
01323 if (atype > 54) {
01324
01325
01326
01327
01328
01329
01330
01331 return;
01332 }
01333 Int_t* nn = (Int_t*) fBranchCount->GetAddress();
01334 if (!nn) {
01335 Error("FillLeaves", "The branch counter address was zero!");
01336 return;
01337 }
01338 Int_t n = *nn;
01339 if (atype > 40) {
01340
01341 Error("FillLeaves", "Clonesa: %s, n=%d, sorry not supported yet", GetName(), n);
01342 return;
01343 }
01344 if (atype > 20) {
01345 atype -= 20;
01346 TLeafElement* leaf = (TLeafElement*) fLeaves.UncheckedAt(0);
01347 n = n * leaf->GetLenStatic();
01348 }
01349 switch (atype) {
01350
01351 case TVirtualStreamerInfo::kChar : { b.WriteFastArray((Char_t*) fAddress, n); break; }
01352 case TVirtualStreamerInfo::kShort : { b.WriteFastArray((Short_t*) fAddress, n); break; }
01353 case TVirtualStreamerInfo::kInt : { b.WriteFastArray((Int_t*) fAddress, n); break; }
01354 case TVirtualStreamerInfo::kLong : { b.WriteFastArray((Long_t*) fAddress, n); break; }
01355 case TVirtualStreamerInfo::kFloat : { b.WriteFastArray((Float_t*) fAddress, n); break; }
01356 case TVirtualStreamerInfo::kCounter : { b.WriteFastArray((Int_t*) fAddress, n); break; }
01357
01358 case TVirtualStreamerInfo::kDouble : { b.WriteFastArray((Double_t*) fAddress, n); break; }
01359 case TVirtualStreamerInfo::kDouble32 : {
01360 TVirtualStreamerInfo* si = GetInfoImp();
01361 TStreamerElement* se = (TStreamerElement*) si->GetElems()[fID];
01362 Double_t* xx = (Double_t*) fAddress;
01363 for (Int_t ii = 0; ii < n; ++ii) {
01364 b.WriteDouble32(&(xx[ii]),se);
01365 }
01366 break;
01367 }
01368 case TVirtualStreamerInfo::kFloat16 : {
01369 TVirtualStreamerInfo* si = GetInfoImp();
01370 TStreamerElement* se = (TStreamerElement*) si->GetElems()[fID];
01371 Float_t* xx = (Float_t*) fAddress;
01372 for (Int_t ii = 0; ii < n; ++ii) {
01373 b.WriteFloat16(&(xx[ii]),se);
01374 }
01375 break;
01376 }
01377
01378 case TVirtualStreamerInfo::kUChar : { b.WriteFastArray((UChar_t*) fAddress, n); break; }
01379 case TVirtualStreamerInfo::kUShort : { b.WriteFastArray((UShort_t*) fAddress, n); break; }
01380 case TVirtualStreamerInfo::kUInt : { b.WriteFastArray((UInt_t*) fAddress, n); break; }
01381 case TVirtualStreamerInfo::kULong : { b.WriteFastArray((ULong_t*) fAddress, n); break; }
01382
01383 case TVirtualStreamerInfo::kBits : { b.WriteFastArray((UInt_t*) fAddress, n); break; }
01384 case TVirtualStreamerInfo::kLong64 : { b.WriteFastArray((Long64_t*) fAddress, n); break; }
01385 case TVirtualStreamerInfo::kULong64 : { b.WriteFastArray((ULong64_t*) fAddress, n); break; }
01386 case TVirtualStreamerInfo::kBool : { b.WriteFastArray((Bool_t*) fAddress, n); break; }
01387 }
01388 } else {
01389 TClonesArray* clones = (TClonesArray*) fObject;
01390 Int_t n = clones->GetEntriesFast();
01391 TStreamerInfo* si = (TStreamerInfo*)GetInfoImp();
01392 if (!si) {
01393 Error("FillLeaves", "Cannot get streamer info for branch '%s'", GetName());
01394 return;
01395 }
01396 si->WriteBufferClones(b, clones, n, fID, fOffset);
01397 }
01398 } else if (fType == 41) {
01399
01400
01401
01402 Int_t n = 0;
01403 TVirtualCollectionProxy::TPushPop helper(GetCollectionProxy(), fObject);
01404 n = GetCollectionProxy()->Size();
01405
01406 TStreamerInfo* si = (TStreamerInfo*)GetInfoImp();
01407 if (!si) {
01408 Error("FillLeaves", "Cannot get streamer info for branch '%s'", GetName());
01409 return;
01410 }
01411 if( fSplitLevel >= TTree::kSplitCollectionOfPointers )
01412 si->WriteBufferSTLPtrs(b, GetCollectionProxy(), n, fID, fOffset );
01413 else
01414 si->WriteBufferSTL(b, GetCollectionProxy(), n, fID, fOffset );
01415 }
01416 }
01417
01418
01419 static void R__CleanName(std::string &name)
01420 {
01421
01422
01423
01424 if (name[name.length()-1]==']') {
01425 std::size_t dim = name.find_first_of("[");
01426 if (dim != std::string::npos) {
01427 name.erase(dim);
01428 }
01429 }
01430 if (name[name.size()-1] != '.') {
01431 name += '.';
01432 }
01433 }
01434
01435
01436 TBranch* TBranchElement::FindBranch(const char *name)
01437 {
01438
01439
01440
01441
01442
01443
01444
01445
01446 if (fID >= 0) {
01447 TVirtualStreamerInfo* si = GetInfoImp();
01448 TStreamerElement* se = (TStreamerElement*) si->GetElems()[fID];
01449 if (se && se->IsBase()) {
01450
01451 UInt_t len = strlen(name);
01452 std::string longnm;
01453 longnm.reserve(fName.Length()+len+3);
01454 longnm = fName.Data();
01455 R__CleanName(longnm);
01456 longnm += name;
01457 std::string longnm_parent;
01458 longnm_parent.reserve(fName.Length()+len+3);
01459 longnm_parent = (GetMother()->GetSubBranch(this)->GetName());
01460 R__CleanName(longnm_parent);
01461 longnm_parent += name;
01462
01463 UInt_t namelen = strlen(name);
01464
01465 TBranch* branch = 0;
01466 Int_t nbranches = fBranches.GetEntries();
01467 for(Int_t i = 0; i < nbranches; ++i) {
01468 branch = (TBranch*) fBranches.UncheckedAt(i);
01469
01470 const char *brname = branch->GetName();
01471 UInt_t brlen = strlen(brname);
01472 if (brname[brlen-1]==']') {
01473 const char *dim = strchr(brname,'[');
01474 if (dim) {
01475 brlen = dim - brname;
01476 }
01477 }
01478 if (namelen == brlen
01479 && strncmp(name,brname,brlen) == 0) {
01480 return branch;
01481 }
01482 if (brlen == longnm.length()
01483 && strncmp(longnm.c_str(),brname,brlen) == 0) {
01484 return branch;
01485 }
01486
01487 if (brlen == longnm_parent.length()
01488 && strncmp(longnm_parent.c_str(),brname,brlen) == 0) {
01489 return branch;
01490 }
01491
01492 if (namelen>brlen && name[brlen]=='.' && strncmp(name,brname,brlen)==0) {
01493
01494 return branch->FindBranch(name+brlen+1);
01495 }
01496 }
01497 }
01498 }
01499 TBranch *result = TBranch::FindBranch(name);
01500 if (!result) {
01501
01502 Int_t nbranches = fBranches.GetEntries();
01503 for(Int_t i = 0; i < nbranches; ++i) {
01504 TObject *obj = fBranches.UncheckedAt(i);
01505 if(obj->IsA() != TBranchElement :: Class() )
01506 continue;
01507 TBranchElement *br = (TBranchElement*)obj;
01508 TVirtualStreamerInfo* si = br->GetInfoImp();
01509 if (si && br->GetID() >= 0) {
01510 TStreamerElement* se = (TStreamerElement*) si->GetElems()[br->GetID()];
01511 if (se && se->IsBase()) {
01512 result = br->FindBranch(name);
01513 }
01514 }
01515 }
01516 }
01517 return result;
01518 }
01519
01520
01521 TLeaf* TBranchElement::FindLeaf(const char *name)
01522 {
01523
01524
01525 TLeaf *leaf = TBranch::FindLeaf(name);
01526
01527 if (leaf==0 && GetListOfLeaves()->GetEntries()==1) {
01528 TBranch *br = GetMother()->GetSubBranch( this );
01529 if( br->IsA() != TBranchElement::Class() )
01530 return 0;
01531
01532 TBranchElement *parent = (TBranchElement*)br;
01533 if (parent==this || parent->GetID()<0 ) return 0;
01534
01535 TVirtualStreamerInfo* si = parent->GetInfoImp();
01536 TStreamerElement* se = (TStreamerElement*) si->GetElems()[parent->GetID()];
01537
01538 if (! se->IsBase() ) return 0;
01539
01540 br = GetMother()->GetSubBranch( parent );
01541 if( br->IsA() != TBranchElement::Class() )
01542 return 0;
01543
01544 TBranchElement *grand_parent = (TBranchElement*)br;
01545
01546 std::string longname( grand_parent->GetName() );
01547 R__CleanName(longname);
01548 longname += name;
01549
01550 std::string leafname( GetListOfLeaves()->At(0)->GetName() );
01551
01552 if ( longname == leafname ) {
01553 return (TLeaf*)GetListOfLeaves()->At(0);
01554 }
01555 }
01556 return leaf;
01557 }
01558
01559
01560 char* TBranchElement::GetAddress() const
01561 {
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577 ValidateAddress();
01578 return fAddress;
01579 }
01580
01581
01582 void TBranchElement::InitInfo()
01583 {
01584
01585
01586 if (!fInfo) {
01587
01588 TClass* cl = fBranchClass.GetClass();
01589
01590
01591
01592
01593 TClass* targetClass = 0;
01594 if( fTargetClass.GetClassName()[0]) {
01595 targetClass = fTargetClass;
01596 if( !targetClass ) {
01597 Error( "InitInfo", "The target class dictionary is not present!" );
01598 return;
01599 }
01600 } else {
01601 targetClass = cl;
01602 }
01603
01604 if (cl) {
01605
01606
01607
01608 {
01609 if( targetClass != cl ) {
01610 fInfo = (TStreamerInfo*)targetClass->GetConversionStreamerInfo( cl, fClassVersion );
01611 } else {
01612 fInfo = (TStreamerInfo*)cl->GetStreamerInfo(fClassVersion);
01613 }
01614 }
01615
01616
01617
01618
01619 if (fCheckSum && (cl->IsForeign() || (!cl->IsLoaded() && (fClassVersion == 1) && cl->GetStreamerInfos()->At(1) && (fCheckSum != ((TVirtualStreamerInfo*) cl->GetStreamerInfos()->At(1))->GetCheckSum())))) {
01620
01621
01622
01623
01624 TStreamerInfo* info;
01625 if( targetClass != cl )
01626 info = (TStreamerInfo*)targetClass->GetConversionStreamerInfo( cl, fCheckSum );
01627 else {
01628 info = (TStreamerInfo*)cl->FindStreamerInfo( fCheckSum );
01629 if (info) {
01630
01631 info = (TStreamerInfo*)cl->GetStreamerInfo(info->GetClassVersion());
01632 }
01633 }
01634 if( info ) {
01635 fInfo = info;
01636
01637
01638
01639
01640 }
01641 }
01642 }
01643 }
01644
01645
01646
01647
01648
01649
01650 if (fInfo) {
01651
01652 if ( GetID()>-1 && (!fInfo->IsCompiled() || fInfo->IsOptimized()) ) {
01653
01654
01655
01656 fInfo->SetBit(TVirtualStreamerInfo::kCannotOptimize);
01657 fInfo->Compile();
01658 }
01659 if (!fInit) {
01660
01661
01662
01663
01664
01665 if (GetID() > -1) {
01666
01667 std::string s(GetName());
01668 size_t pos = s.rfind('.');
01669 if (pos != std::string::npos) {
01670 s = s.substr(pos+1);
01671 }
01672 while ((pos = s.rfind('[')) != std::string::npos) {
01673 s = s.substr(0, pos);
01674 }
01675 int offset = 0;
01676 TStreamerElement* elt = fInfo->GetStreamerElement(s.c_str(), offset);
01677 if (elt && offset!=TStreamerInfo::kMissing) {
01678 size_t ndata = fInfo->GetNdata();
01679 ULong_t* elems = fInfo->GetElems();
01680 fIDs.clear();
01681 for (size_t i = 0; i < ndata; ++i) {
01682 if (((TStreamerElement*) elems[i]) == elt) {
01683 if (elt->TestBit (TStreamerElement::kCache)
01684 && elt->TestBit(TStreamerElement::kRepeat)
01685 && (i+1) < ndata
01686 && s == ((TStreamerElement*) elems[i])->GetName())
01687 {
01688
01689
01690
01691
01692
01693 fID = i;
01694 fIDs.push_back(fID+1);
01695 } else {
01696 fID = i;
01697 }
01698 if (elt->TestBit (TStreamerElement::kCache)) {
01699 SetBit(TBranchElement::kCache);
01700 }
01701 break;
01702 }
01703 }
01704 for (size_t i = fID+1+(fIDs.size()); i < ndata; ++i) {
01705 TStreamerElement *nextel = ((TStreamerElement*) elems[i]);
01706
01707 if (fType==31||fType==41) {
01708
01709
01710 if (nextel->GetType() == TStreamerInfo::kObject
01711 || nextel->GetType() == TStreamerInfo::kAny) {
01712 continue;
01713 }
01714 }
01715 if (nextel->GetOffset() == TStreamerInfo::kMissing) {
01716
01717
01718 continue;
01719 }
01720 if (nextel->IsA() != TStreamerArtificial::Class()
01721 || nextel->GetType() == TStreamerInfo::kCacheDelete ) {
01722 break;
01723 }
01724 fIDs.push_back(i);
01725 }
01726 } else if (elt && offset==TStreamerInfo::kMissing) {
01727
01728 fIDs.clear();
01729 size_t ndata = fInfo->GetNdata();
01730 ULong_t* elems = fInfo->GetElems();
01731 for (size_t i = 0; i < ndata; ++i) {
01732 if (((TStreamerElement*) elems[i]) == elt) {
01733 fID = i;
01734 break;
01735 }
01736 }
01737 } else {
01738
01739
01740
01741
01742 }
01743 if (fOnfileObject==0 && (fType==31 || fType==41 || (0 <= fType && fType <=2) ) && fInfo->GetNdata()
01744 && ((TStreamerElement*) fInfo->GetElems()[0])->GetType() == TStreamerInfo::kCacheNew)
01745 {
01746 Int_t arrlen = 1;
01747 if (fType==31 || fType==41) {
01748 TLeaf *leaf = (TLeaf*)fLeaves.At(0);
01749 if (leaf) {
01750 arrlen = leaf->GetMaximum();
01751 }
01752 }
01753 fOnfileObject = new TVirtualArray( ((TStreamerElement*) fInfo->GetElems()[0])->GetClassPointer(), arrlen );
01754
01755 TObjArray *branches = GetMother()->GetSubBranch(this)->GetListOfBranches();
01756 Int_t nbranches = branches->GetEntriesFast();
01757 TBranchElement *lastbranch = this;
01758 for (Int_t i = 0; i < nbranches; ++i) {
01759 TBranchElement* subbranch = (TBranchElement*)branches->At(i);
01760 if (this!=subbranch && subbranch->fBranchClass == fBranchClass && subbranch->fCheckSum == fCheckSum) {
01761 subbranch->fOnfileObject = fOnfileObject;
01762 lastbranch = subbranch;
01763 }
01764 }
01765 lastbranch->SetBit(kOwnOnfileObj);
01766 }
01767 }
01768 fInit = kTRUE;
01769
01770
01771 SetReadActionSequence();
01772 } else if (!fReadActionSequence) {
01773
01774 SetReadActionSequence();
01775 }
01776 SetReadLeavesPtr();
01777 }
01778 }
01779
01780
01781 TVirtualCollectionProxy* TBranchElement::GetCollectionProxy()
01782 {
01783
01784
01785 if (fCollProxy) {
01786 return fCollProxy;
01787 }
01788 TBranchElement* thiscast = const_cast<TBranchElement*>(this);
01789 if (fType == 4) {
01790
01791 const char* className = 0;
01792 if (fID < 0) {
01793
01794 if (fBranchClass.GetClass()) {
01795 className = fBranchClass.GetClass()->GetName();
01796 }
01797 } else {
01798
01799 TVirtualStreamerInfo* si = thiscast->GetInfoImp();
01800 TStreamerElement* se = (TStreamerElement*) si->GetElems()[fID];
01801 className = se->GetTypeName();
01802 }
01803 TClass* cl = TClass::GetClass(className);
01804 TVirtualCollectionProxy* proxy = cl->GetCollectionProxy();
01805 fCollProxy = proxy->Generate();
01806 fSTLtype = className ? TClassEdit::IsSTLCont(className) : 0;
01807 if (fSTLtype < 0) {
01808 fSTLtype = -fSTLtype;
01809 }
01810 } else if (fType == 41) {
01811
01812 thiscast->fCollProxy = fBranchCount->GetCollectionProxy();
01813 }
01814 return fCollProxy;
01815 }
01816
01817
01818 TClass* TBranchElement::GetCurrentClass()
01819 {
01820
01821
01822 TClass* cl = fCurrentClass;
01823 if (cl) {
01824 return cl;
01825 }
01826
01827 TStreamerInfo* brInfo = (TStreamerInfo*)GetInfoImp();
01828 if (!brInfo) {
01829 cl = TClass::GetClass(GetClassName());
01830 R__ASSERT(cl && cl->GetCollectionProxy());
01831 fCurrentClass = cl;
01832 return cl;
01833 }
01834 TClass* motherCl = brInfo->GetClass();
01835 if (motherCl->GetCollectionProxy()) {
01836 cl = motherCl->GetCollectionProxy()->GetCollectionClass();
01837 if (cl) {
01838 fCurrentClass = cl;
01839 }
01840 return cl;
01841 }
01842 if (GetID() < 0 || GetID()>=brInfo->GetNdata()) {
01843 return 0;
01844 }
01845 TStreamerElement* currentStreamerElement = ((TStreamerElement*) brInfo->GetElems()[GetID()]);
01846 TDataMember* dm = (TDataMember*) motherCl->GetListOfDataMembers()->FindObject(currentStreamerElement->GetName());
01847
01848 TString newType;
01849 if (!dm) {
01850
01851 if (!motherCl->IsLoaded()) {
01852 TVirtualStreamerInfo* newInfo = motherCl->GetStreamerInfo();
01853 if (newInfo != brInfo) {
01854 TStreamerElement* newElems = (TStreamerElement*) newInfo->GetElements()->FindObject(currentStreamerElement->GetName());
01855 if (newElems) {
01856 newType = newElems->GetClassPointer()->GetName();
01857 }
01858 }
01859 if (newType.Length()==0) {
01860 newType = currentStreamerElement->GetClassPointer()->GetName();
01861 }
01862 }
01863 } else {
01864 newType = dm->GetTypeName();
01865 }
01866 cl = TClass::GetClass(newType);
01867 if (cl) {
01868 fCurrentClass = cl;
01869 }
01870 return cl;
01871 }
01872
01873
01874 Int_t TBranchElement::GetEntry(Long64_t entry, Int_t getall)
01875 {
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889 fReadEntry = entry;
01890
01891
01892
01893
01894
01895
01896 TBranchRef* bref = fTree->GetBranchRef();
01897 if (bref) {
01898 fBranchID = bref->SetParent(this, fBranchID);
01899 bref->SetReadEntry(entry);
01900 }
01901
01902 Int_t nbytes = 0;
01903
01904 if (IsAutoDelete()) {
01905 SetBit(kDeleteObject);
01906 SetAddress(fAddress);
01907 }
01908 SetupAddresses();
01909
01910 Int_t nbranches = fBranches.GetEntriesFast();
01911 if (nbranches) {
01912
01913
01914
01915
01916 if ((fType == 3) || (fType == 4)) {
01917 Int_t nb = TBranch::GetEntry(entry, getall);
01918 if (nb < 0) {
01919 return nb;
01920 }
01921 nbytes += nb;
01922 }
01923 switch(fSTLtype) {
01924 case TClassEdit::kSet:
01925 case TClassEdit::kMultiSet:
01926 case TClassEdit::kMap:
01927 case TClassEdit::kMultiMap:
01928 break;
01929 default:
01930 for (Int_t i = 0; i < nbranches; ++i) {
01931 TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
01932 Int_t nb = branch->GetEntry(entry, getall);
01933 if (nb < 0) {
01934 return nb;
01935 }
01936 nbytes += nb;
01937 }
01938 break;
01939 }
01940 } else {
01941
01942 if (fBranchCount && (fBranchCount->GetReadEntry() != entry)) {
01943 Int_t nb = fBranchCount->TBranch::GetEntry(entry, getall);
01944 if (nb < 0) {
01945 return nb;
01946 }
01947 nbytes += nb;
01948 }
01949 Int_t nb = TBranch::GetEntry(entry, getall);
01950 if (nb < 0) {
01951 return nb;
01952 }
01953 nbytes += nb;
01954 }
01955
01956 if (fTree->Debug() > 0) {
01957 if ((entry >= fTree->GetDebugMin()) && (entry <= fTree->GetDebugMax())) {
01958 Info("GetEntry", "%lld, branch=%s, nbytes=%d", entry, GetName(), nbytes);
01959 }
01960 }
01961 return nbytes;
01962 }
01963
01964
01965 Int_t TBranchElement::GetExpectedType(TClass *&expectedClass,EDataType &expectedType)
01966 {
01967
01968
01969
01970
01971
01972 expectedClass = 0;
01973 expectedType = kOther_t;
01974
01975 Int_t type = GetStreamerType();
01976 if ((type == -1) || (fID == -1)) {
01977 expectedClass = fBranchClass;
01978 } else {
01979
01980
01981
01982 TStreamerElement* element = (TStreamerElement*) GetInfoImp()->GetElems()[fID];
01983 if (element) {
01984 expectedClass = element->GetClassPointer();
01985 if (!expectedClass) {
01986 TDataType* data = gROOT->GetType(element->GetTypeNameBasic());
01987 if (!data) {
01988 Error("GetExpectedType", "Did not find the type number for %s", element->GetTypeNameBasic());
01989 return 1;
01990 } else {
01991 expectedType = (EDataType) data->GetType();
01992 }
01993 }
01994 } else {
01995 Error("GetExpectedType", "Did not find the type for %s",GetName());
01996 return 2;
01997 }
01998 }
01999 return 0;
02000 }
02001
02002
02003 const char* TBranchElement::GetIconName() const
02004 {
02005
02006
02007 if (IsFolder()) {
02008 return "TBranchElement-folder";
02009 } else {
02010 return "TBranchElement-leaf";
02011 }
02012 }
02013
02014
02015 Bool_t TBranchElement::GetMakeClass() const
02016 {
02017
02018
02019
02020 return TestBit(kDecomposedObj);
02021 }
02022
02023
02024 Int_t TBranchElement::GetMaximum() const
02025 {
02026
02027
02028 if (fBranchCount) {
02029 return fBranchCount->GetMaximum();
02030 }
02031 return fMaximum;
02032 }
02033
02034
02035 char* TBranchElement::GetObject() const
02036 {
02037
02038
02039 ValidateAddress();
02040 return fObject;
02041 }
02042
02043
02044 TClass* TBranchElement::GetParentClass()
02045 {
02046
02047 return fParentClass.GetClass();
02048 }
02049
02050
02051 const char* TBranchElement::GetTypeName() const
02052 {
02053
02054
02055 if (fType == 3 || fType == 4) {
02056 return "Int_t";
02057 }
02058
02059 if ((fStreamerType < 1) || (fStreamerType > 59)) {
02060 if (fBranchClass.GetClass()) {
02061 if (fID>=0) {
02062 ULong_t* elems = GetInfoImp()->GetElems();
02063 return ((TStreamerElement*) elems[fID])->GetTypeName();
02064 } else {
02065 return fBranchClass.GetClass()->GetName();
02066 }
02067 } else {
02068 return 0;
02069 }
02070 }
02071 const char *types[20] = {
02072 "",
02073 "Char_t",
02074 "Short_t",
02075 "Int_t",
02076 "Long_t",
02077 "Float_t",
02078 "Int_t",
02079 "char*",
02080 "Double_t",
02081 "Double32_t",
02082 "",
02083 "UChar_t",
02084 "UShort_t",
02085 "UInt_t",
02086 "ULong_t",
02087 "UInt_t",
02088 "Long64_t",
02089 "ULong64_t",
02090 "Bool_t",
02091 "Float16_t"
02092 };
02093 Int_t itype = fStreamerType % 20;
02094 return types[itype];
02095 }
02096
02097
02098 Double_t TBranchElement::GetValue(Int_t j, Int_t len, Bool_t subarr) const
02099 {
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110 ValidateAddress();
02111
02112 Int_t prID = fID;
02113 char *object = fObject;
02114 if (TestBit(kCache)) {
02115 if (GetInfoImp()->GetElements()->At(fID)->TestBit(TStreamerElement::kRepeat)) {
02116 prID = fID+1;
02117 } else if (fOnfileObject) {
02118 object = fOnfileObject->GetObjectAt(0);
02119 }
02120 }
02121
02122 if (!j && fBranchCount) {
02123 Int_t entry = fTree->GetReadEntry();
02124
02125
02126 if (entry != fBranchCount->GetReadEntry()) {
02127 fBranchCount->TBranch::GetEntry(entry);
02128 }
02129 if (fBranchCount2 && entry != fBranchCount2->GetReadEntry()) {
02130 fBranchCount2->TBranch::GetEntry(entry);
02131 }
02132 }
02133
02134 if (fTree->GetMakeClass()) {
02135 if (!fAddress) {
02136 return 0;
02137 }
02138 if ((fType == 3) || (fType == 4)) {
02139
02140 return (Double_t) fNdata;
02141 } else if ((fType == 31) || (fType == 41)) {
02142
02143 Int_t atype = fStreamerType;
02144 if (atype < 20) {
02145 atype += 20;
02146 }
02147 return GetInfoImp()->GetValue(fAddress, atype, j, 1);
02148 } else if (fType <= 2) {
02149
02150
02151 if ((fStreamerType > 40) && (fStreamerType < 55)) {
02152 Int_t atype = fStreamerType - 20;
02153 return GetInfoImp()->GetValue(fAddress, atype, j, 1);
02154 } else {
02155 return GetInfoImp()->GetValue(object, prID, j, -1);
02156 }
02157 }
02158 }
02159
02160 if (fType == 31) {
02161 TClonesArray* clones = (TClonesArray*) object;
02162 if (subarr) {
02163 return GetInfoImp()->GetValueClones(clones, prID, j, len, fOffset);
02164 }
02165 return GetInfoImp()->GetValueClones(clones, prID, j/len, j%len, fOffset);
02166 } else if (fType == 41) {
02167 TVirtualCollectionProxy::TPushPop helper(((TBranchElement*) this)->GetCollectionProxy(), object);
02168 if( fSplitLevel < TTree::kSplitCollectionOfPointers )
02169 {
02170 if (subarr)
02171 return GetInfoImp()->GetValueSTL(((TBranchElement*) this)->GetCollectionProxy(), prID, j, len, fOffset);
02172
02173 return GetInfoImp()->GetValueSTL(((TBranchElement*) this)->GetCollectionProxy(), prID, j/len, j%len, fOffset);
02174 }
02175 else
02176 {
02177 if (subarr)
02178 return GetInfoImp()->GetValueSTLP(((TBranchElement*) this)->GetCollectionProxy(), prID, j, len, fOffset);
02179 return GetInfoImp()->GetValueSTLP(((TBranchElement*) this)->GetCollectionProxy(), prID, j/len, j%len, fOffset);
02180 }
02181 } else {
02182 if (GetInfoImp()) {
02183 return GetInfoImp()->GetValue(object, prID, j, -1);
02184 }
02185 return 0;
02186 }
02187 }
02188
02189
02190 void* TBranchElement::GetValuePointer() const
02191 {
02192
02193
02194
02195 ValidateAddress();
02196
02197 Int_t prID = fID;
02198 char *object = fObject;
02199 if (TestBit(kCache)) {
02200 if (GetInfoImp()->GetElements()->At(fID)->TestBit(TStreamerElement::kRepeat)) {
02201 prID = fID+1;
02202 } else if (fOnfileObject) {
02203 object = fOnfileObject->GetObjectAt(0);
02204 }
02205 }
02206
02207 if (fBranchCount) {
02208 Int_t entry = fTree->GetReadEntry();
02209 fBranchCount->TBranch::GetEntry(entry);
02210 if (fBranchCount2) fBranchCount2->TBranch::GetEntry(entry);
02211 }
02212 if (fTree->GetMakeClass()) {
02213 if (!fAddress) {
02214 return 0;
02215 }
02216 if (fType == 3) {
02217
02218 return 0;
02219 } else if (fType == 4) {
02220
02221 return 0;
02222 } else if (fType == 31) {
02223
02224
02225
02226 return 0;
02227 } else if (fType == 41) {
02228
02229
02230
02231 return 0;
02232 } else if (fType <= 2) {
02233
02234 if (fStreamerType > 40 && fStreamerType < 55) {
02235
02236
02237 return 0;
02238 } else {
02239
02240 return 0;
02241 }
02242 }
02243 }
02244
02245 if (fType == 31) {
02246 return 0;
02247 } else if (fType == 41) {
02248 return 0;
02249 } else {
02250
02251 if (!GetInfoImp() || !object) return 0;
02252 char **val = (char**)(object+GetInfoImp()->GetOffsets()[fID]);
02253 return *val;
02254 }
02255 }
02256
02257
02258 void TBranchElement::InitializeOffsets()
02259 {
02260
02261
02262
02263
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276 Int_t nbranches = fBranches.GetEntriesFast();
02277
02278 if (fID < 0) {
02279
02280 if (CanSelfReference(fBranchClass)) {
02281 if (fBranchClass.GetClass()->InheritsFrom(TObject::Class())) {
02282 SetBit(kBranchObject);
02283 } else {
02284 SetBit(kBranchAny);
02285 }
02286 }
02287 }
02288 if (nbranches) {
02289
02290 delete[] fBranchOffset;
02291 fBranchOffset = 0;
02292 fBranchOffset = new Int_t[nbranches];
02293
02294 if (!fBranchClass.GetClass()) {
02295 Warning("InitializeOffsets", "No branch class set for branch: %s", GetName());
02296 fInitOffsets = kTRUE;
02297 return;
02298 }
02299
02300 if (!GetInfoImp()) {
02301 Warning("InitializeOffsets", "No streamer info available for branch: %s of class: %s", GetName(), fBranchClass.GetClass()->GetName());
02302 fInitOffsets = kTRUE;
02303 return;
02304 }
02305
02306
02307
02308
02309
02310
02311 TStreamerElement* branchElem = 0;
02312 Int_t localOffset = 0;
02313 TClass* branchClass = fBranchClass.GetClass();
02314 if (fID > -1) {
02315
02316
02317
02318
02319
02320
02321 TVirtualStreamerInfo* si = GetInfoImp();
02322
02323 ULong_t* elems = si->GetElems();
02324 if (!elems) {
02325 Warning("InitializeOffsets", "Streamer info for branch: %s has no elements array!", GetName());
02326 fInitOffsets = kTRUE;
02327 return;
02328 }
02329
02330 branchElem = (TStreamerElement*) elems[fID];
02331 if (!branchElem) {
02332 Warning("InitializeOffsets", "Cannot get streamer element for branch: %s!", GetName());
02333 fInitOffsets = kTRUE;
02334 return;
02335 }
02336 localOffset = branchElem->GetOffset();
02337 branchClass = branchElem->GetClassPointer();
02338 if (localOffset == TStreamerInfo::kMissing) {
02339 fObject = 0;
02340 }
02341 }
02342 if (!branchClass) {
02343 Error("InitializeOffsets", "Could not find class for branch: %s", GetName());
02344 fInitOffsets = kTRUE;
02345 return;
02346 }
02347
02348
02349
02350
02351
02352 TString stlParentName;
02353 Bool_t stlParentNameUpdated = kFALSE;
02354 if( fType == 4 && fSplitLevel > TTree::kSplitCollectionOfPointers )
02355 {
02356 TBranch *br = GetMother()->GetSubBranch( this );
02357 stlParentName = br->GetName();
02358 stlParentName.Strip( TString::kTrailing, '.' );
02359
02360
02361
02362
02363 }
02364
02365
02366 for (Int_t subBranchIdx = 0; subBranchIdx < nbranches; ++subBranchIdx) {
02367 fBranchOffset[subBranchIdx] = 0;
02368 TBranchElement* subBranch = dynamic_cast<TBranchElement*> (fBranches[subBranchIdx]);
02369 if (subBranch == 0) {
02370
02371 continue;
02372 }
02373
02374 TVirtualStreamerInfo* sinfo = subBranch->GetInfoImp();
02375 if (!sinfo) {
02376 Warning("InitializeOffsets", "No streamer info for branch: %s subbranch: %s", GetName(), subBranch->GetName());
02377 fInitOffsets = kTRUE;
02378 return;
02379 }
02380 ULong_t* subBranchElems = sinfo->GetElems();
02381 if (!subBranchElems) {
02382 Warning("InitializeOffsets", "No elements array for branch: %s subbranch: %s", GetName(), subBranch->GetName());
02383 fInitOffsets = kTRUE;
02384 return;
02385 }
02386
02387 TStreamerElement* subBranchElement = (TStreamerElement*) subBranchElems[subBranch->fID];
02388 if (!subBranchElement) {
02389 Warning("InitializeOffsets", "No streamer element for branch: %s subbranch: %s", GetName(), subBranch->GetName());
02390 fInitOffsets = kTRUE;
02391 return;
02392 }
02393
02394 localOffset = subBranchElement->GetOffset();
02395 if (localOffset == TStreamerInfo::kMissing) {
02396 subBranch->fObject = 0;
02397 }
02398
02399 {
02400 Int_t streamerType = subBranchElement->GetType();
02401 if (streamerType > TStreamerInfo::kObject
02402 && subBranch->GetListOfBranches()->GetEntries()==0
02403 && CanSelfReference(subBranchElement->GetClass()))
02404 {
02405 subBranch->SetBit(kBranchAny);
02406 } else {
02407 subBranch->ResetBit(kBranchAny);
02408 }
02409 }
02410
02411 if (subBranchElement->GetNewType()<0) {
02412 subBranch->ResetBit(kBranchAny);
02413 subBranch->ResetBit(kBranchObject);
02414 }
02415
02416
02417 TBranch* mother = GetMother();
02418 if (!mother) {
02419 Warning("InitializeOffsets", "Branch '%s' has no mother!", GetName());
02420 fInitOffsets = kTRUE;
02421 return;
02422 }
02423 TString motherName(mother->GetName());
02424 Bool_t motherDot = kFALSE;
02425 if (motherName.Length() && strchr(motherName.Data(), '.')) {
02426 motherDot = kTRUE;
02427 }
02428 Bool_t motherDotAtEnd = kFALSE;
02429 if (motherName.Length() && (motherName[motherName.Length()-1] == '.')) {
02430 motherDotAtEnd = kTRUE;
02431 }
02432
02433 Bool_t isBaseSubBranch = kFALSE;
02434 if ((subBranch->fType == 1) || (subBranchElement && subBranchElement->IsBase())) {
02435
02436
02437
02438
02439
02440
02441
02442 isBaseSubBranch = kTRUE;
02443 }
02444
02445 Bool_t isContDataMember = kFALSE;
02446 if ((subBranch->fType == 31) || (subBranch->fType == 41)) {
02447
02448 isContDataMember = kTRUE;
02449 }
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470
02471
02472 TString dataName(subBranch->GetName());
02473 if (motherDotAtEnd) {
02474
02475 dataName.Remove(0, motherName.Length());
02476
02477 if (!stlParentNameUpdated && stlParentName.Length()) {
02478 stlParentName.Remove(0, motherName.Length());
02479 stlParentNameUpdated = kTRUE;
02480 }
02481 } else if (motherDot) {
02482
02483
02484
02485
02486
02487
02488
02489
02490 if ((fID < 0) && (subBranchElement->IsA() == TStreamerBase::Class())) {
02491
02492
02493
02494
02495 if (dataName.Length() == motherName.Length()) {
02496 dataName.Remove(0, motherName.Length());
02497
02498 if (!stlParentNameUpdated && stlParentName.Length()) {
02499 stlParentName.Remove(0, motherName.Length());
02500 }
02501 }
02502 } else {
02503
02504 if (dataName.Length() > motherName.Length()) {
02505 dataName.Remove(0, motherName.Length() + 1);
02506 if (!stlParentNameUpdated && stlParentName.Length()) {
02507 stlParentName.Remove(0, motherName.Length());
02508 }
02509 }
02510 }
02511 }
02512 stlParentNameUpdated = kTRUE;
02513 if (isBaseSubBranch) {
02514
02515
02516 TString pattern(subBranchElement->GetName());
02517 if (pattern.Length() <= dataName.Length()) {
02518 if (!strcmp(dataName.Data() + (dataName.Length() - pattern.Length()), pattern.Data())) {
02519
02520
02521
02522 dataName.Remove(dataName.Length() - pattern.Length());
02523 }
02524 }
02525
02526 if (dataName.Length()) {
02527 if (dataName[0] == '.') {
02528 dataName.Remove(0, 1);
02529 }
02530 }
02531
02532
02533 }
02534
02535
02536 TString parentName(GetName());
02537 if (motherDotAtEnd) {
02538
02539 parentName.Remove(0, motherName.Length());
02540 } else if (motherDot) {
02541
02542
02543
02544
02545
02546
02547
02548
02549 if ((fID > -1) && (mother == mother->GetSubBranch(this)) && (branchElem->IsA() == TStreamerBase::Class())) {
02550
02551
02552
02553
02554 if (parentName.Length() == motherName.Length()) {
02555 parentName.Remove(0, motherName.Length());
02556 }
02557 } else {
02558
02559 if (parentName.Length() > motherName.Length()) {
02560 parentName.Remove(0, motherName.Length() + 1);
02561 }
02562 }
02563 }
02564
02565 if (fType == 1) {
02566
02567 if (mother != mother->GetSubBranch(this)) {
02568
02569
02570
02571 TString pattern(branchElem->GetName());
02572 if (pattern.Length() <= parentName.Length()) {
02573 if (!strcmp(parentName.Data() + (parentName.Length() - pattern.Length()), pattern.Data())) {
02574
02575
02576
02577 parentName.Remove(parentName.Length() - pattern.Length());
02578 }
02579 }
02580 }
02581
02582
02583 }
02584
02585
02586
02587
02588 if (fID > -1) {
02589 RemovePrefix(dataName, parentName);
02590 }
02591
02592
02593 if (dataName.Length()) {
02594 if (dataName[0] == '.') {
02595 dataName.Remove(0, 1);
02596 }
02597 }
02598
02599
02600 if (dataName.Length()) {
02601 if (dataName[dataName.Length()-1] == '.') {
02602 dataName.Remove(dataName.Length() - 1, 1);
02603 }
02604 }
02605
02606
02607
02608
02609
02610
02611
02612
02613
02614
02615
02616
02617 Int_t offset = 0;
02618 if (dataName.Length()) {
02619
02620
02621 TClass* pClass = 0;
02622
02623
02624 TStreamerInfo *subInfo = subBranch->GetInfoImp();
02625 if (subInfo && subBranch->TestBit(kCache)) {
02626 pClass = ((TStreamerElement*)subInfo->GetElements()->At(0))->GetClassPointer();
02627 }
02628
02629 if (!pClass) {
02630 if (fType == 1) {
02631
02632
02633 pClass = branchElem->GetClassPointer();
02634 } else {
02635
02636
02637 pClass = subBranch->GetParentClass();
02638 }
02639 }
02640 if (!pClass) {
02641
02642
02643
02644 if (GetClonesName() && strlen(GetClonesName())) {
02645 pClass = TClass::GetClass(GetClonesName());
02646 if (!pClass) {
02647 Warning("InitializeOffsets", "subBranch: '%s' has no parent class, and cannot get class for clones class: '%s'!", subBranch->GetName(), GetClonesName());
02648 fInitOffsets = kTRUE;
02649 return;
02650 }
02651 Warning("InitializeOffsets", "subBranch: '%s' has no parent class! Assuming parent class is: '%s'.", subBranch->GetName(), pClass->GetName());
02652 }
02653 if (fBranchCount && fBranchCount->fCollProxy && fBranchCount->fCollProxy->GetValueClass()) {
02654 pClass = fBranchCount->fCollProxy->GetValueClass();
02655 Warning("InitializeOffsets", "subBranch: '%s' has no parent class! Assuming parent class is: '%s'.", subBranch->GetName(), pClass ? pClass->GetName() : "unknowned class");
02656 }
02657 if (!pClass) {
02658
02659
02660 pClass = branchClass;
02661
02662
02663 }
02664 }
02665
02666
02667
02668
02669
02670 if( stlParentName.Length() )
02671 {
02672 if( !strncmp( stlParentName.Data(), dataName.Data(), stlParentName.Length()-1 ))
02673 dataName.Remove( 0, stlParentName.Length()+1 );
02674 }
02675
02676
02677
02678
02679 TRealData* rd = pClass->GetRealData(dataName);
02680 if (rd && !rd->TestBit(TRealData::kTransient)) {
02681
02682 offset = rd->GetThisOffset();
02683 } else {
02684
02685 localOffset = TStreamerInfo::kMissing;
02686 }
02687 } else {
02688
02689 if (isBaseSubBranch) {
02690
02691 } else {
02692 Warning("InitializeOffsets", "Could not find the data member name for branch '%s' with parent branch '%s', assuming offset is zero!", subBranch->GetName(), GetName());
02693 }
02694 }
02695
02696
02697
02698
02699
02700 if (isContDataMember) {
02701
02702
02703
02704
02705
02706
02707 if (subBranch->fObject == 0 && localOffset == TStreamerInfo::kMissing) {
02708 subBranch->SetOffset(TStreamerInfo::kMissing);
02709 } else {
02710 if (isBaseSubBranch) {
02711
02712
02713 subBranch->SetOffset(offset);
02714 } else {
02715
02716
02717 subBranch->SetOffset(offset - localOffset);
02718 }
02719 }
02720 } else {
02721
02722 Int_t isSplit = 0 != subBranch->GetListOfBranches()->GetEntriesFast();
02723 if (subBranch->fObject == 0 && localOffset == TStreamerInfo::kMissing) {
02724
02725 fBranchOffset[subBranchIdx] = TStreamerInfo::kMissing;
02726
02727 } else if (isSplit) {
02728 if (isBaseSubBranch) {
02729
02730
02731 fBranchOffset[subBranchIdx] = offset + localOffset;
02732 } else {
02733
02734
02735
02736 fBranchOffset[subBranchIdx] = offset;
02737 }
02738 } else {
02739 if (isBaseSubBranch) {
02740
02741
02742 fBranchOffset[subBranchIdx] = offset;
02743 } else {
02744
02745
02746 fBranchOffset[subBranchIdx] = offset - localOffset;
02747 }
02748 }
02749 }
02750 }
02751 }
02752
02753 fInitOffsets = kTRUE;
02754 }
02755
02756
02757 Bool_t TBranchElement::IsFolder() const
02758 {
02759
02760
02761 Int_t nbranches = fBranches.GetEntriesFast();
02762 if (nbranches >= 1) {
02763 return kTRUE;
02764 }
02765 TList* browsables = const_cast<TBranchElement*>(this)->GetBrowsables();
02766 return browsables && browsables->GetSize();
02767 }
02768
02769
02770 Bool_t TBranchElement::IsMissingCollection() const
02771 {
02772
02773
02774
02775
02776
02777
02778
02779 Bool_t ismissing = kFALSE;
02780 TBasket* basket = (TBasket*) fBaskets.UncheckedAt(fReadBasket);
02781 if (basket && fTree) {
02782 Int_t entry = fTree->GetReadEntry();
02783 Int_t first = fBasketEntry[fReadBasket];
02784 Int_t last;
02785 if (fReadBasket == fWriteBasket) {
02786 last = fEntryNumber - 1;
02787 } else {
02788 last = fBasketEntry[fReadBasket+1] - 1;
02789 }
02790 Int_t* entryOffset = basket->GetEntryOffset();
02791 Int_t bufbegin;
02792 Int_t bufnext;
02793 if (entryOffset) {
02794 bufbegin = entryOffset[entry-first];
02795
02796 if (entry < last) {
02797 bufnext = entryOffset[entry+1-first];
02798 } else {
02799 bufnext = basket->GetLast();
02800 }
02801 if (bufnext == bufbegin) {
02802 ismissing = kTRUE;
02803 } else {
02804
02805 if (basket->GetNevBufSize() == 0) {
02806 ismissing = kTRUE;
02807 }
02808 }
02809 }
02810 }
02811 return ismissing;
02812 }
02813
02814
02815 void TBranchElement::Print(Option_t* option) const
02816 {
02817
02818
02819 Int_t nbranches = fBranches.GetEntriesFast();
02820 if (strncmp(option,"debugAddress",strlen("debugAddress"))==0) {
02821 if (strlen(option)==strlen("debugAddress")) {
02822 Printf("%-24s %-16s %2s %4s %-16s %-16s %8s %8s %s\n",
02823 "Branch Name", "Streamer Class", "ID", "Type", "Class", "Parent", "pOffset", "fOffset", "fObject");
02824 }
02825 if (strlen(GetName())>24) Printf("%-24s\n%-24s ", GetName(),"");
02826 else Printf("%-24s ", GetName());
02827
02828 TBranchElement *parent = dynamic_cast<TBranchElement*>(GetMother()->GetSubBranch(this));
02829 Int_t ind = parent ? parent->GetListOfBranches()->IndexOf(this) : -1;
02830 TVirtualStreamerInfo *info = ((TBranchElement*)this)->GetInfoImp();
02831
02832 Printf("%-16s %2d %4d %-16s %-16s %8x %8x %s\n",
02833 info ? info->GetName() : "StreamerInfo unvailable", GetID(), GetType(),
02834 GetClassName(), GetParentName(),
02835 (fBranchOffset&&parent && ind>=0) ? parent->fBranchOffset[ind] : 0,
02836 GetOffset(), GetObject());
02837 for (Int_t i = 0; i < nbranches; ++i) {
02838 TBranchElement* subbranch = (TBranchElement*)fBranches.At(i);
02839 subbranch->Print("debugAddressSub");
02840 }
02841 return;
02842 }
02843 if (strncmp(option,"debugInfo",strlen("debugInfo"))==0) {
02844 Printf("Branch %s uses:\n",GetName());
02845 if (fID>=0) {
02846 ULong_t* elems = GetInfoImp()->GetElems();
02847 ((TStreamerElement*) elems[fID])->ls();
02848 for(UInt_t i=0; i< fIDs.size(); ++i) {
02849 ((TStreamerElement*) elems[fIDs[i]])->ls();
02850 }
02851 }
02852 for (Int_t i = 0; i < nbranches; ++i) {
02853 TBranchElement* subbranch = (TBranchElement*)fBranches.At(i);
02854 subbranch->Print("debugInfoSub");
02855 }
02856 return;
02857 }
02858 if (nbranches) {
02859 if (fID == -2) {
02860 if (strcmp(GetName(),GetTitle()) == 0) {
02861 Printf("*Branch :%-66s *",GetName());
02862 } else {
02863 Printf("*Branch :%-9s : %-54s *",GetName(),GetTitle());
02864 }
02865 Printf("*Entries : %8d : BranchElement (see below) *",Int_t(fEntries));
02866 Printf("*............................................................................*");
02867 }
02868 if (fType >= 2) {
02869 TBranch::Print(option);
02870 }
02871 for (Int_t i=0;i<nbranches;i++) {
02872 TBranch *branch = (TBranch*)fBranches.At(i);
02873 branch->Print(option);
02874 }
02875 } else {
02876 TBranch::Print(option);
02877 }
02878 }
02879
02880
02881 void TBranchElement::PrintValue(Int_t lenmax) const
02882 {
02883
02884
02885 ValidateAddress();
02886
02887 TStreamerInfo *info = GetInfoImp();
02888 Int_t prID = fID;
02889 char *object = fObject;
02890 if (TestBit(kCache)) {
02891 if (info->GetElements()->At(fID)->TestBit(TStreamerElement::kRepeat)) {
02892 prID = fID+1;
02893 } else if (fOnfileObject) {
02894 object = fOnfileObject->GetObjectAt(0);
02895 }
02896 }
02897
02898 if (fTree->GetMakeClass()) {
02899 if (!fAddress) {
02900 return;
02901 }
02902 if (fType == 3 || fType == 4) {
02903
02904 printf(" %-15s = %d\n", GetName(), fNdata);
02905 return;
02906 } else if (fType == 31 || fType == 41) {
02907
02908 Int_t n = TMath::Min(10, fNdata);
02909 Int_t atype = fStreamerType + TVirtualStreamerInfo::kOffsetL;
02910 if (fStreamerType == TVirtualStreamerInfo::kChar) {
02911
02912
02913
02914 atype = TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kUChar;
02915 }
02916 if (atype > 54) {
02917
02918 printf(" %-15s = %d\n", GetName(), fNdata);
02919 return;
02920 }
02921 if (fStreamerType > 20) {
02922 atype -= 20;
02923 TLeafElement* leaf = (TLeafElement*) fLeaves.UncheckedAt(0);
02924 n = n * leaf->GetLenStatic();
02925 }
02926 if (GetInfoImp()) {
02927 GetInfoImp()->PrintValue(GetName(), fAddress, atype, n, lenmax);
02928 }
02929 return;
02930 } else if (fType <= 2) {
02931
02932
02933 if ((fStreamerType > 40) && (fStreamerType < 55)) {
02934 Int_t atype = fStreamerType - 20;
02935 TBranchElement* counterElement = (TBranchElement*) fBranchCount;
02936 Int_t n = (Int_t) counterElement->GetValue(0, 0);
02937 if (GetInfoImp()) {
02938 GetInfoImp()->PrintValue(GetName(), fAddress, atype, n, lenmax);
02939 }
02940 } else {
02941 if (GetInfoImp()) {
02942 GetInfoImp()->PrintValue(GetName(), object, prID, -1, lenmax);
02943 }
02944 }
02945 return;
02946 }
02947 } else if (fType == 3) {
02948 printf(" %-15s = %d\n", GetName(), fNdata);
02949 } else if (fType == 31) {
02950 TClonesArray* clones = (TClonesArray*) object;
02951 if (GetInfoImp()) {
02952 GetInfoImp()->PrintValueClones(GetName(), clones, prID, fOffset, lenmax);
02953 }
02954 } else if (fType == 41) {
02955 TVirtualCollectionProxy::TPushPop helper(((TBranchElement*) this)->GetCollectionProxy(), object);
02956 if (GetInfoImp()) {
02957 GetInfoImp()->PrintValueSTL(GetName(), ((TBranchElement*) this)->GetCollectionProxy(), prID, fOffset, lenmax);
02958 }
02959 } else {
02960 if (GetInfoImp()) {
02961 GetInfoImp()->PrintValue(GetName(), object, prID, -1, lenmax);
02962 }
02963 }
02964 }
02965
02966
02967 void TBranchElement::ReadLeavesImpl(TBuffer&)
02968 {
02969
02970
02971 Fatal("ReadLeaves","The ReadLeaves function has not been configured for %s",GetName());
02972 }
02973
02974
02975 void TBranchElement::ReadLeavesMakeClass(TBuffer& b)
02976 {
02977
02978
02979
02980 ValidateAddress();
02981
02982 if (fType == 3 || fType == 4) {
02983
02984 Int_t *n = (Int_t*) fAddress;
02985 b >> n[0];
02986 if ((n[0] < 0) || (n[0] > fMaximum)) {
02987 if (IsMissingCollection()) {
02988 n[0] = 0;
02989 b.SetBufferOffset(b.Length() - sizeof(n));
02990 } else {
02991 Error("ReadLeaves", "Incorrect size read for the container in %s\nThe size read is %d when the maximum is %d\nThe size is reset to 0 for this entry (%lld)", GetName(), n[0], fMaximum, GetReadEntry());
02992 n[0] = 0;
02993 }
02994 }
02995 fNdata = n[0];
02996 if (fType == 4) {
02997 Int_t nbranches = fBranches.GetEntriesFast();
02998 switch(fSTLtype) {
02999 case TClassEdit::kSet:
03000 case TClassEdit::kMultiSet:
03001 case TClassEdit::kMap:
03002 case TClassEdit::kMultiMap:
03003 for (Int_t i=0; i<nbranches; i++) {
03004 TBranch *branch = (TBranch*)fBranches[i];
03005 Int_t nb = branch->GetEntry(GetReadEntry(), 1);
03006 if (nb < 0) {
03007 break;
03008 }
03009 }
03010 break;
03011 default:
03012 break;
03013 }
03014 }
03015 return;
03016 } else if (fType == 31 || fType == 41) {
03017 fNdata = fBranchCount->GetNdata();
03018 Int_t atype = fStreamerType;
03019
03020 if (atype > 54) return;
03021 if (!fAddress) {
03022 return;
03023 }
03024 Int_t n = fNdata;
03025 if (atype>40) {
03026 atype -= 40;
03027 if (!fBranchCount2) return;
03028 const char *len_where = (char*)fBranchCount2->fAddress;
03029 if (!len_where) return;
03030 Int_t len_atype = fBranchCount2->fStreamerType;
03031 Int_t length;
03032 Int_t k;
03033 Char_t isArray;
03034 for( k=0; k<n; k++) {
03035 char **where = &(((char**)fAddress)[k]);
03036 delete [] *where;
03037 *where = 0;
03038 switch(len_atype) {
03039 case 1: {length = ((Char_t*) len_where)[k]; break;}
03040 case 2: {length = ((Short_t*) len_where)[k]; break;}
03041 case 3: {length = ((Int_t*) len_where)[k]; break;}
03042 case 4: {length = ((Long_t*) len_where)[k]; break;}
03043
03044 case 6: {length = ((Int_t*) len_where)[k]; break;}
03045
03046 case 11: {length = ((UChar_t*) len_where)[k]; break;}
03047 case 12: {length = ((UShort_t*) len_where)[k]; break;}
03048 case 13: {length = ((UInt_t*) len_where)[k]; break;}
03049 case 14: {length = ((ULong_t*) len_where)[k]; break;}
03050 case 15: {length = ((UInt_t*) len_where)[k]; break;}
03051 case 16: {length = ((Long64_t*) len_where)[k]; break;}
03052 case 17: {length = ((ULong64_t*)len_where)[k]; break;}
03053 case 18: {length = ((Bool_t*) len_where)[k]; break;}
03054 default: continue;
03055 }
03056 b >> isArray;
03057 if (length <= 0) continue;
03058 if (isArray == 0) continue;
03059 switch (atype) {
03060 case 1: {*where=new char[sizeof(Char_t)*length]; b.ReadFastArray((Char_t*) *where, length); break;}
03061 case 2: {*where=new char[sizeof(Short_t)*length]; b.ReadFastArray((Short_t*) *where, length); break;}
03062 case 3: {*where=new char[sizeof(Int_t)*length]; b.ReadFastArray((Int_t*) *where, length); break;}
03063 case 4: {*where=new char[sizeof(Long_t)*length]; b.ReadFastArray((Long_t*) *where, length); break;}
03064 case 5: {*where=new char[sizeof(Float_t)*length]; b.ReadFastArray((Float_t*) *where, length); break;}
03065 case 6: {*where=new char[sizeof(Int_t)*length]; b.ReadFastArray((Int_t*) *where, length); break;}
03066 case 8: {*where=new char[sizeof(Double_t)*length]; b.ReadFastArray((Double_t*)*where, length); break;}
03067 case 11: {*where=new char[sizeof(UChar_t)*length]; b.ReadFastArray((UChar_t*) *where, length); break;}
03068 case 12: {*where=new char[sizeof(UShort_t)*length]; b.ReadFastArray((UShort_t*)*where, length); break;}
03069 case 13: {*where=new char[sizeof(UInt_t)*length]; b.ReadFastArray((UInt_t*) *where, length); break;}
03070 case 14: {*where=new char[sizeof(ULong_t)*length]; b.ReadFastArray((ULong_t*) *where, length); break;}
03071 case 15: {*where=new char[sizeof(UInt_t)*length]; b.ReadFastArray((UInt_t*) *where, length); break;}
03072 case 16: {*where=new char[sizeof(Long64_t)*length]; b.ReadFastArray((Long64_t*) *where, length); break;}
03073 case 17: {*where=new char[sizeof(ULong64_t)*length]; b.ReadFastArray((ULong64_t*)*where, length); break;}
03074 case 18: {*where=new char[sizeof(Bool_t)*length]; b.ReadFastArray((Bool_t*) *where, length); break;}
03075 }
03076 }
03077 return;
03078 }
03079 if (atype > 20) {
03080 atype -= 20;
03081 TLeafElement *leaf = (TLeafElement*)fLeaves.UncheckedAt(0);
03082 n *= leaf->GetLenStatic();
03083 }
03084 switch (atype) {
03085 case 1: {b.ReadFastArray((Char_t*) fAddress, n); break;}
03086 case 2: {b.ReadFastArray((Short_t*) fAddress, n); break;}
03087 case 3: {b.ReadFastArray((Int_t*) fAddress, n); break;}
03088 case 4: {b.ReadFastArray((Long_t*) fAddress, n); break;}
03089 case 5: {b.ReadFastArray((Float_t*) fAddress, n); break;}
03090 case 6: {b.ReadFastArray((Int_t*) fAddress, n); break;}
03091 case 8: {b.ReadFastArray((Double_t*)fAddress, n); break;}
03092 case 11: {b.ReadFastArray((UChar_t*) fAddress, n); break;}
03093 case 12: {b.ReadFastArray((UShort_t*)fAddress, n); break;}
03094 case 13: {b.ReadFastArray((UInt_t*) fAddress, n); break;}
03095 case 14: {b.ReadFastArray((ULong_t*) fAddress, n); break;}
03096 case 15: {b.ReadFastArray((UInt_t*) fAddress, n); break;}
03097 case 16: {b.ReadFastArray((Long64_t*)fAddress, n); break;}
03098 case 17: {b.ReadFastArray((ULong64_t*)fAddress, n); break;}
03099 case 18: {b.ReadFastArray((Bool_t*) fAddress, n); break;}
03100 case 9: {
03101 TVirtualStreamerInfo* si = GetInfoImp();
03102 TStreamerElement* se = (TStreamerElement*) si->GetElems()[fID];
03103 Double_t *xx = (Double_t*) fAddress;
03104 for (Int_t ii=0;ii<n;ii++) {
03105 b.ReadDouble32(&(xx[ii]),se);
03106 }
03107 break;
03108 }
03109 case 19: {
03110 TVirtualStreamerInfo* si = GetInfoImp();
03111 TStreamerElement* se = (TStreamerElement*) si->GetElems()[fID];
03112 Float_t *xx = (Float_t*) fAddress;
03113 for (Int_t ii=0;ii<n;ii++) {
03114 b.ReadFloat16(&(xx[ii]),se);
03115 }
03116 break;
03117 }
03118 }
03119 return;
03120 } else if (fType <= 2) {
03121
03122 if (fStreamerType > 40 && fStreamerType < 55) {
03123 Int_t atype = fStreamerType - 40;
03124 Int_t n;
03125 if (fBranchCount==0) {
03126
03127
03128 TString countname( GetName() );
03129 Ssiz_t dot = countname.Last('.');
03130 if (dot>=0) {
03131 countname.Remove(dot+1);
03132 } else {
03133 countname = "";
03134 }
03135 TString counter( GetTitle() );
03136 Ssiz_t loc = counter.Last('[');
03137 if (loc>=0) {
03138 counter.Remove(0,loc+1);
03139 }
03140 loc = counter.Last(']');
03141 if (loc>=0) {
03142 counter.Remove(loc);
03143 }
03144 countname += counter;
03145 SetBranchCount((TBranchElement *)fTree->GetBranch(countname));
03146 }
03147 if (fBranchCount) {
03148 n = (Int_t)fBranchCount->GetValue(0,0);
03149 } else {
03150 Warning("ReadLeaves","Missing fBranchCount for %s. Data will not be read correctly by the MakeClass mode.",GetName());
03151 n = 0;
03152 }
03153 fNdata = n;
03154 Char_t isArray;
03155 b >> isArray;
03156 switch (atype) {
03157 case 1: {b.ReadFastArray((Char_t*) fAddress, n); break;}
03158 case 2: {b.ReadFastArray((Short_t*) fAddress, n); break;}
03159 case 3: {b.ReadFastArray((Int_t*) fAddress, n); break;}
03160 case 4: {b.ReadFastArray((Long_t*) fAddress, n); break;}
03161 case 5: {b.ReadFastArray((Float_t*) fAddress, n); break;}
03162 case 6: {b.ReadFastArray((Int_t*) fAddress, n); break;}
03163 case 8: {b.ReadFastArray((Double_t*)fAddress, n); break;}
03164 case 11: {b.ReadFastArray((UChar_t*) fAddress, n); break;}
03165 case 12: {b.ReadFastArray((UShort_t*)fAddress, n); break;}
03166 case 13: {b.ReadFastArray((UInt_t*) fAddress, n); break;}
03167 case 14: {b.ReadFastArray((ULong_t*) fAddress, n); break;}
03168 case 15: {b.ReadFastArray((UInt_t*) fAddress, n); break;}
03169 case 16: {b.ReadFastArray((Long64_t*) fAddress, n); break;}
03170 case 17: {b.ReadFastArray((ULong64_t*)fAddress, n); break;}
03171 case 18: {b.ReadFastArray((Bool_t*) fAddress, n); break;}
03172 case 9: {
03173 TVirtualStreamerInfo* si = GetInfoImp();
03174 TStreamerElement* se = (TStreamerElement*) si->GetElems()[fID];
03175 Double_t *xx = (Double_t*) fAddress;
03176 for (Int_t ii=0;ii<n;ii++) {
03177 b.ReadDouble32(&(xx[ii]),se);
03178 }
03179 break;
03180 }
03181 case 19: {
03182 TVirtualStreamerInfo* si = GetInfoImp();
03183 TStreamerElement* se = (TStreamerElement*) si->GetElems()[fID];
03184 Float_t *xx = (Float_t*) fAddress;
03185 for (Int_t ii=0;ii<n;ii++) {
03186 b.ReadFloat16(&(xx[ii]),se);
03187 }
03188 break;
03189 }
03190 }
03191 } else {
03192 fNdata = 1;
03193 if (fAddress) {
03194 if (fType<0) {
03195
03196
03197
03198 fBranchClass->Streamer(fObject,b);
03199 } else {
03200 GetInfoImp()->ReadBuffer(b, (char**) &fObject, fID);
03201 }
03202 if (fStreamerType == TVirtualStreamerInfo::kCounter) {
03203 fNdata = (Int_t) GetValue(0, 0);
03204 }
03205 } else {
03206 fNdata = 0;
03207 }
03208 }
03209 return;
03210 }
03211 }
03212
03213
03214 void TBranchElement::ReadLeavesCollection(TBuffer& b)
03215 {
03216
03217
03218
03219 ValidateAddress();
03220 if (fObject == 0)
03221 {
03222
03223
03224 return;
03225 }
03226
03227 R__PushCache onfileObject(((TBufferFile&)b),fOnfileObject);
03228
03229
03230 Int_t n;
03231 b >> n;
03232 if ((n < 0) || (n > fMaximum)) {
03233 if (IsMissingCollection()) {
03234 n = 0;
03235 b.SetBufferOffset(b.Length()-sizeof(n));
03236 } else {
03237 Error("ReadLeaves", "Incorrect size read for the container in %s\n\tThe size read is %d while the maximum is %d\n\tThe size is reset to 0 for this entry (%lld)", GetName(), n, fMaximum, GetReadEntry());
03238 n = 0;
03239 }
03240 }
03241 fNdata = n;
03242 if (!fObject) {
03243 return;
03244 }
03245
03246
03247
03248
03249
03250
03251
03252 TVirtualCollectionProxy* proxy = GetCollectionProxy();
03253 TVirtualCollectionProxy::TPushPop helper(proxy, fObject);
03254 void* alternate = proxy->Allocate(fNdata, true);
03255 if(fSTLtype != TClassEdit::kVector && proxy->HasPointers() && fSplitLevel > TTree::kSplitCollectionOfPointers ) {
03256 fPtrIterators->CreateIterators(alternate);
03257 } else {
03258 fIterators->CreateIterators(alternate);
03259 }
03260
03261 Int_t nbranches = fBranches.GetEntriesFast();
03262 switch (fSTLtype) {
03263 case TClassEdit::kSet:
03264 case TClassEdit::kMultiSet:
03265 case TClassEdit::kMap:
03266 case TClassEdit::kMultiMap:
03267 for (Int_t i = 0; i < nbranches; ++i) {
03268 TBranch *branch = (TBranch*) fBranches[i];
03269 Int_t nb = branch->GetEntry(GetReadEntry(), 1);
03270 if (nb < 0) {
03271
03272
03273 break;
03274 }
03275 }
03276 break;
03277 default:
03278 break;
03279 }
03280
03281
03282
03283 if( proxy->HasPointers() && fSplitLevel > TTree::kSplitCollectionOfPointers )
03284 {
03285 TClass *elClass = proxy->GetValueClass();
03286
03287
03288
03289
03290
03291 Int_t i = 0;
03292 if( !fNdata || *(void**)proxy->At( 0 ) != 0 )
03293 i = fNdata;
03294
03295 for( ; i < fNdata; ++i )
03296 {
03297 void **el = (void**)proxy->At( i );
03298
03299 *el = elClass->New();
03300 }
03301 }
03302
03303 proxy->Commit(alternate);
03304 }
03305
03306
03307 void TBranchElement::ReadLeavesCollectionSplitPtrMember(TBuffer& b)
03308 {
03309
03310
03311
03312 ValidateAddress();
03313 if (fObject == 0)
03314 {
03315
03316
03317 return;
03318 }
03319
03320 R__PushCache onfileObject(((TBufferFile&)b),fOnfileObject);
03321
03322
03323 fNdata = fBranchCount->GetNdata();
03324 if (!fNdata || !fObject) {
03325 return;
03326 }
03327 TStreamerInfo *info = GetInfoImp();
03328 if (info == 0) return;
03329
03330 TVirtualCollectionProxy *proxy = GetCollectionProxy();
03331 TVirtualCollectionProxy::TPushPop helper(proxy, fObject);
03332
03333
03334 TVirtualCollectionPtrIterators *iter = fBranchCount->fPtrIterators;
03335 b.ReadSequence(*fReadActionSequence,iter->fBegin,iter->fEnd);
03336
03337
03338
03339
03340
03341
03342
03343
03344
03345 }
03346
03347
03348 void TBranchElement::ReadLeavesCollectionSplitVectorPtrMember(TBuffer& b)
03349 {
03350
03351
03352
03353 ValidateAddress();
03354 if (fObject == 0)
03355 {
03356
03357
03358 return;
03359 }
03360
03361 R__PushCache onfileObject(((TBufferFile&)b),fOnfileObject);
03362
03363
03364 fNdata = fBranchCount->GetNdata();
03365 if (!fNdata || !fObject) {
03366 return;
03367 }
03368 TStreamerInfo *info = GetInfoImp();
03369 if (info == 0) return;
03370
03371 TVirtualCollectionProxy *proxy = GetCollectionProxy();
03372 TVirtualCollectionProxy::TPushPop helper(proxy, fObject);
03373
03374
03375 TVirtualCollectionIterators *iter = fBranchCount->fIterators;
03376 b.ReadSequenceVecPtr(*fReadActionSequence,iter->fBegin,iter->fEnd);
03377 }
03378
03379
03380 void TBranchElement::ReadLeavesCollectionMember(TBuffer& b)
03381 {
03382
03383
03384
03385 ValidateAddress();
03386 if (fObject == 0)
03387 {
03388
03389
03390 return;
03391 }
03392
03393 R__PushCache onfileObject(((TBufferFile&)b),fOnfileObject);
03394
03395
03396 fNdata = fBranchCount->GetNdata();
03397 if (!fNdata || !fObject) {
03398 return;
03399 }
03400 TStreamerInfo *info = GetInfoImp();
03401 if (info == 0) return;
03402
03403
03404
03405 TVirtualCollectionProxy *proxy = GetCollectionProxy();
03406 TVirtualCollectionProxy::TPushPop helper(proxy, fObject);
03407
03408 TVirtualCollectionIterators *iter = fBranchCount->fIterators;
03409 b.ReadSequence(*fReadActionSequence,iter->fBegin,iter->fEnd);
03410 }
03411
03412
03413 void TBranchElement::ReadLeavesClones(TBuffer& b)
03414 {
03415
03416
03417
03418 ValidateAddress();
03419 if (fObject == 0)
03420 {
03421
03422
03423 return;
03424 }
03425
03426 R__PushCache onfileObject(((TBufferFile&)b),fOnfileObject);
03427
03428
03429 Int_t n;
03430 b >> n;
03431 if ((n < 0) || (n > fMaximum)) {
03432 if (IsMissingCollection()) {
03433 n = 0;
03434 b.SetBufferOffset(b.Length()-sizeof(n));
03435 } else {
03436 Error("ReadLeaves", "Incorrect size read for the container in %s\n\tThe size read is %d while the maximum is %d\n\tThe size is reset to 0 for this entry (%lld)", GetName(), n, fMaximum, GetReadEntry());
03437 n = 0;
03438 }
03439 }
03440 fNdata = n;
03441 TClonesArray* clones = (TClonesArray*) fObject;
03442 if (!clones) {
03443 return;
03444 }
03445 if (clones->IsZombie()) {
03446 return;
03447 }
03448 clones->Clear();
03449 clones->ExpandCreateFast(fNdata);
03450 }
03451
03452
03453 void TBranchElement::ReadLeavesClonesMember(TBuffer& b)
03454 {
03455
03456
03457
03458 ValidateAddress();
03459
03460 if (fObject == 0)
03461 {
03462
03463
03464 return;
03465 }
03466
03467 R__PushCache onfileObject(((TBufferFile&)b),fOnfileObject);
03468
03469
03470 fNdata = fBranchCount->GetNdata();
03471 TClonesArray* clones = (TClonesArray*) fObject;
03472 if (!clones) {
03473 return;
03474 }
03475 if (clones->IsZombie()) {
03476 return;
03477 }
03478 TStreamerInfo *info = GetInfoImp();
03479 if (info==0) return;
03480
03481
03482 char **arr = (char **)clones->GetObjectRef(0);
03483 char **end = arr + fNdata;
03484 b.ReadSequenceVecPtr(*fReadActionSequence,arr,end);
03485 }
03486
03487
03488 void TBranchElement::ReadLeavesMember(TBuffer& b)
03489 {
03490
03491
03492
03493
03494 R__ASSERT(fBranchCount==0);
03495 R__ASSERT(fStreamerType != TVirtualStreamerInfo::kCounter);
03496
03497 ValidateAddress();
03498 if (fObject == 0)
03499 {
03500
03501
03502 return;
03503 }
03504
03505 R__PushCache onfileObject(((TBufferFile&)b),fOnfileObject);
03506
03507
03508
03509
03510 if (TestBit(kBranchObject)) {
03511 b.MapObject((TObject*) fObject);
03512 } else if (TestBit(kBranchAny)) {
03513 b.MapObject(fObject, fBranchClass);
03514 }
03515
03516 fNdata = 1;
03517 TStreamerInfo *info = GetInfoImp();
03518 if (!info) {
03519 return;
03520 }
03521
03522 b.ReadSequence(*fReadActionSequence, fObject);
03523 }
03524
03525
03526 void TBranchElement::ReadLeavesMemberBranchCount(TBuffer& b)
03527 {
03528
03529
03530
03531
03532 R__ASSERT(fStreamerType != TVirtualStreamerInfo::kCounter);
03533
03534 ValidateAddress();
03535 if (fObject == 0)
03536 {
03537
03538
03539 return;
03540 }
03541
03542 R__PushCache onfileObject(((TBufferFile&)b),fOnfileObject);
03543
03544
03545
03546
03547 if (TestBit(kBranchObject)) {
03548 b.MapObject((TObject*) fObject);
03549 } else if (TestBit(kBranchAny)) {
03550 b.MapObject(fObject, fBranchClass);
03551 }
03552
03553 fNdata = (Int_t) fBranchCount->GetValue(0, 0);
03554 TStreamerInfo *info = GetInfoImp();
03555 if (!info) {
03556 return;
03557 }
03558
03559 b.ReadSequence(*fReadActionSequence, fObject);
03560 }
03561
03562
03563 void TBranchElement::ReadLeavesMemberCounter(TBuffer& b)
03564 {
03565
03566
03567
03568
03569 ValidateAddress();
03570 if (fObject == 0)
03571 {
03572
03573
03574 return;
03575 }
03576
03577 R__PushCache onfileObject(((TBufferFile&)b),fOnfileObject);
03578
03579
03580
03581
03582
03583 if (TestBit(kBranchObject)) {
03584 b.MapObject((TObject*) fObject);
03585 } else if (TestBit(kBranchAny)) {
03586 b.MapObject(fObject, fBranchClass);
03587 }
03588
03589 TStreamerInfo *info = GetInfoImp();
03590 if (!info) {
03591 return;
03592 }
03593
03594 b.ReadSequence(*fReadActionSequence, fObject);
03595 fNdata = (Int_t) GetValue(0, 0);
03596 }
03597
03598
03599 void TBranchElement::ReadLeavesCustomStreamer(TBuffer& b)
03600 {
03601
03602
03603
03604 ValidateAddress();
03605 if (fObject == 0)
03606 {
03607
03608
03609 return;
03610 }
03611
03612 R__PushCache onfileObject(((TBufferFile&)b),fOnfileObject);
03613 fBranchClass->Streamer(fObject,b);
03614 }
03615
03616
03617 void TBranchElement::ReleaseObject()
03618 {
03619
03620
03621 if (fObject && TestBit(kDeleteObject)) {
03622 if (IsAutoDelete() && fAddress != (char*)&fObject) {
03623 *((char**) fAddress) = 0;
03624 }
03625 ResetBit(kDeleteObject);
03626 if (fType == 3) {
03627
03628 TClonesArray::Class()->Destructor(fObject);
03629 fObject = 0;
03630 if ((fStreamerType == TVirtualStreamerInfo::kObjectp) ||
03631 (fStreamerType == TVirtualStreamerInfo::kObjectP)) {
03632
03633
03634 *((char**) fAddress) = 0;
03635 }
03636 } else if (fType == 4) {
03637
03638 TVirtualCollectionProxy* proxy = GetCollectionProxy();
03639 if (!proxy) {
03640 Warning("ReleaseObject", "Cannot delete allocated STL container because I do not have a proxy! branch: %s", GetName());
03641 fObject = 0;
03642 } else {
03643 proxy->Destructor(fObject);
03644 fObject = 0;
03645 }
03646 if (fStreamerType == TVirtualStreamerInfo::kSTLp) {
03647
03648
03649 *((char**) fAddress) = 0;
03650 }
03651 } else {
03652
03653 TClass* cl = fBranchClass.GetClass();
03654 if (!cl) {
03655 Warning("ReleaseObject", "Cannot delete allocated object because I cannot instantiate a TClass object for its class! branch: '%s' class: '%s'", GetName(), fBranchClass.GetClassName());
03656 fObject = 0;
03657 } else {
03658 cl->Destructor(fObject);
03659 fObject = 0;
03660 }
03661 }
03662 }
03663 }
03664
03665
03666 void TBranchElement::Reset(Option_t* option)
03667 {
03668
03669
03670
03671
03672
03673
03674 Int_t nbranches = fBranches.GetEntriesFast();
03675 for (Int_t i = 0; i < nbranches; ++i) {
03676 TBranch* branch = (TBranch*) fBranches[i];
03677 branch->Reset(option);
03678 }
03679 fBranchID = -1;
03680 TBranch::Reset(option);
03681 }
03682
03683
03684 void TBranchElement::ResetAddress()
03685 {
03686
03687
03688 for (Int_t i = 0; i < fNleaves; ++i) {
03689 TLeaf* leaf = (TLeaf*) fLeaves.UncheckedAt(i);
03690
03691 leaf->SetAddress(0);
03692 }
03693
03694
03695
03696
03697 Int_t nbranches = fBranches.GetEntriesFast();
03698 for (Int_t i = 0; i < nbranches; ++i) {
03699 TBranch* br = (TBranch*) fBranches[i];
03700 if (br) br->ResetAddress();
03701 }
03702
03703
03704
03705
03706
03707 ReleaseObject();
03708
03709 ResetBit(kAddressSet);
03710 fAddress = 0;
03711 fObject = 0;
03712 }
03713
03714
03715 void TBranchElement::ResetDeleteObject()
03716 {
03717
03718
03719
03720
03721
03722 ResetBit(kDeleteObject);
03723 Int_t nb = fBranches.GetEntriesFast();
03724 for (Int_t i = 0; i < nb; ++i) {
03725 TBranch* br = (TBranch*) fBranches[i];
03726 if (br->InheritsFrom(TBranchElement::Class())) {
03727 ((TBranchElement*) br)->ResetDeleteObject();
03728 }
03729 }
03730 }
03731
03732
03733 void TBranchElement::SetAddress(void* addr)
03734 {
03735
03736
03737
03738
03739
03740
03741
03742
03743
03744
03745
03746
03747
03748
03749
03750
03751
03752
03753
03754
03755
03756
03757
03758
03759
03760
03761
03762
03763
03764
03765
03766
03767
03768
03769
03770
03771
03772
03773
03774
03775
03776
03777
03778
03779
03780
03781
03782
03783
03784
03785
03786
03787
03788
03789
03790
03791
03792
03793
03794
03795
03796
03797
03798
03799
03800
03801
03802
03803
03804
03805
03806
03807
03808
03809
03810
03811
03812
03813
03814
03815
03816
03817
03818
03819
03820
03821
03822
03823
03824
03825
03826
03827
03828
03829
03830
03831
03832
03833
03834
03835
03836
03837
03838
03839
03840
03841
03842
03843
03844
03845
03846
03847
03848 if (TestBit(kDoNotProcess)) {
03849 return;
03850 }
03851
03852
03853
03854
03855
03856 if (fType < -1) {
03857 return;
03858 }
03859
03860
03861
03862
03863
03864 if (Long_t(addr) == -1) {
03865
03866
03867 fAddress = (char*) -1;
03868 fObject = (char*) -1;
03869 ResetBit(kDeleteObject);
03870 return;
03871 }
03872
03873
03874
03875
03876
03877 fReadEntry = -1;
03878
03879
03880
03881
03882 TClass* clOfBranch = fBranchClass.GetClass();
03883 if( fTargetClass.GetClassName()[0] ) {
03884 clOfBranch = fTargetClass;
03885 }
03886
03887
03888
03889
03890
03891 TVirtualStreamerInfo *info = GetInfoImp();
03892
03893
03894
03895
03896
03897
03898
03899 if (fObject && TestBit(kDeleteObject)){
03900 ReleaseObject();
03901 }
03902
03903
03904
03905
03906
03907 fAddress = (char*) addr;
03908 if (fAddress != (char*)(&fObject)) {
03909 fObject = 0;
03910 }
03911 ResetBit(kDeleteObject);
03912
03913
03914
03915
03916
03917
03918 if (fTree->GetMakeClass()) {
03919 if (fID > -1) {
03920
03921 if (!info) {
03922
03923
03924 fObject = fAddress;
03925 } else {
03926
03927
03928 fObject = fAddress - info->GetOffsets()[fID];
03929 }
03930 return;
03931 }
03932 }
03933
03934
03935
03936
03937
03938
03939
03940 if (fType == 3) {
03941
03942 TClass* clm = TClass::GetClass(GetClonesName());
03943 if (clm) {
03944
03945 clm->BuildRealData();
03946 clm->GetStreamerInfo();
03947 }
03948 TClass* newType = GetCurrentClass();
03949 if (newType && (newType != TClonesArray::Class())) {
03950
03951
03952
03953 Bool_t matched = kFALSE;
03954 if (newType->GetCollectionProxy()) {
03955 TClass *content = newType->GetCollectionProxy()->GetValueClass();
03956 if (clm == content) {
03957 matched = kTRUE;
03958 } else {
03959 Warning("SetAddress", "The type of %s was changed from TClonesArray to %s but the content do not match (was %s)!", GetName(), newType->GetName(), GetClonesName());
03960 }
03961 } else {
03962 Warning("SetAddress", "The type of the %s was changed from TClonesArray to %s but we do not have a TVirtualCollectionProxy for that container type!", GetName(), newType->GetName());
03963 }
03964 if (matched) {
03965
03966 SetType(4);
03967
03968 fSTLtype = TMath::Abs(TClassEdit::IsSTLCont(newType->GetName()));
03969 fCollProxy = newType->GetCollectionProxy()->Generate();
03970
03971 SwitchContainer(GetListOfBranches());
03972 SetReadLeavesPtr();
03973
03974 if(fSTLtype != TClassEdit::kVector && fCollProxy->HasPointers() && fSplitLevel > TTree::kSplitCollectionOfPointers ) {
03975 fPtrIterators = new TVirtualCollectionPtrIterators(fCollProxy);
03976 } else {
03977 fIterators = new TVirtualCollectionIterators(fCollProxy);
03978 }
03979 } else {
03980
03981 fAddress = 0;
03982 }
03983 }
03984 } else if (fType == 4) {
03985
03986 TClass* newType = GetCurrentClass();
03987 if (newType && (newType != GetCollectionProxy()->GetCollectionClass())) {
03988
03989 TVirtualCollectionProxy* newProxy = newType->GetCollectionProxy();
03990 TVirtualCollectionProxy* oldProxy = GetCollectionProxy();
03991 if (newProxy && (oldProxy->GetValueClass() == newProxy->GetValueClass()) && ((!oldProxy->GetValueClass() && (oldProxy->GetType() == newProxy->GetType())) || (oldProxy->GetValueClass() && (oldProxy->HasPointers() == newProxy->HasPointers())))) {
03992 if (fSTLtype == TClassEdit::kNotSTL) {
03993 fSTLtype = TMath::Abs(TClassEdit::IsSTLCont(newType->GetName()));
03994 }
03995 delete fCollProxy;
03996 Int_t nbranches = GetListOfBranches()->GetEntries();
03997 fCollProxy = newType->GetCollectionProxy()->Generate();
03998 for (Int_t i = 0; i < nbranches; ++i) {
03999 TBranchElement* br = (TBranchElement*) GetListOfBranches()->UncheckedAt(i);
04000 br->fCollProxy = 0;
04001 if (br->fReadActionSequence) {
04002 br->SetReadActionSequence();
04003 }
04004 }
04005 SetReadActionSequence();
04006 SetReadLeavesPtr();
04007 delete fIterators;
04008 delete fPtrIterators;
04009 if(fSTLtype != TClassEdit::kVector && fCollProxy->HasPointers() && fSplitLevel > TTree::kSplitCollectionOfPointers ) {
04010 fPtrIterators = new TVirtualCollectionPtrIterators(fCollProxy);
04011 } else {
04012 fIterators = new TVirtualCollectionIterators(fCollProxy);
04013 }
04014 }
04015 else if ((newType == TClonesArray::Class()) && (oldProxy->GetValueClass() && !oldProxy->HasPointers() && oldProxy->GetValueClass()->InheritsFrom(TObject::Class())))
04016 {
04017
04018
04019
04020
04021
04022
04023
04024
04025
04026
04027 SetType(3);
04028
04029 fSTLtype = kNone;
04030 switch(fStreamerType) {
04031 case TVirtualStreamerInfo::kAny:
04032 case TVirtualStreamerInfo::kSTL:
04033 fStreamerType = TVirtualStreamerInfo::kObject;
04034 break;
04035 case TVirtualStreamerInfo::kAnyp:
04036 case TVirtualStreamerInfo::kSTLp:
04037 fStreamerType = TVirtualStreamerInfo::kObjectp;
04038 break;
04039 case TVirtualStreamerInfo::kAnyP:
04040 fStreamerType = TVirtualStreamerInfo::kObjectP;
04041 break;
04042 }
04043 fClonesName = oldProxy->GetValueClass()->GetName();
04044 delete fCollProxy;
04045 fCollProxy = 0;
04046 TClass* clm = TClass::GetClass(GetClonesName());
04047 if (clm) {
04048 clm->BuildRealData();
04049 clm->GetStreamerInfo();
04050 }
04051 SwitchContainer(GetListOfBranches());
04052 SetReadLeavesPtr();
04053 delete fIterators;
04054 fIterators = 0;
04055 delete fPtrIterators;
04056 fPtrIterators =0;
04057 } else {
04058
04059 fAddress = 0;
04060 }
04061 } else {
04062 if (!fIterators && !fPtrIterators) {
04063 if(fSTLtype != TClassEdit::kVector && GetCollectionProxy()->HasPointers() && fSplitLevel > TTree::kSplitCollectionOfPointers ) {
04064 fPtrIterators = new TVirtualCollectionPtrIterators(GetCollectionProxy());
04065 } else {
04066 fIterators = new TVirtualCollectionIterators(GetCollectionProxy());
04067 }
04068 }
04069 }
04070 }
04071
04072
04073
04074
04075
04076
04077
04078
04079
04080
04081
04082
04083
04084
04085
04086
04087
04088
04089 if (fType == 3) {
04090
04091 if (fAddress) {
04092
04093 if (fStreamerType == TVirtualStreamerInfo::kObject) {
04094
04095
04096 fObject = fAddress;
04097
04098 TClonesArray* clones = (TClonesArray*) fObject;
04099 if (!clones->GetClass()) {
04100 new(fObject) TClonesArray(GetClonesName());
04101 }
04102 } else {
04103
04104
04105 if ((fStreamerType != -1) &&
04106 (fStreamerType != TVirtualStreamerInfo::kObjectp) &&
04107 (fStreamerType != TVirtualStreamerInfo::kObjectP)) {
04108 Error("SetAddress", "TClonesArray with fStreamerType: %d", fStreamerType);
04109 } else if (fStreamerType == -1) {
04110
04111 TClonesArray** pp = (TClonesArray**) fAddress;
04112 if (!*pp) {
04113
04114 *pp = new TClonesArray(GetClonesName());
04115 }
04116 fObject = (char*) *pp;
04117 } else {
04118
04119
04120
04121 TClonesArray** pp = (TClonesArray**) fAddress;
04122 if (!*pp) {
04123
04124 *pp = new TClonesArray(GetClonesName());
04125 }
04126 fObject = (char*) *pp;
04127 }
04128 }
04129 } else {
04130
04131 if (fStreamerType == TVirtualStreamerInfo::kObject) {
04132
04133
04134 Error("SetAddress", "Embedded TClonesArray given a zero address for branch '%s'", GetName());
04135 } else {
04136
04137
04138 if ((fStreamerType != -1) &&
04139 (fStreamerType != TVirtualStreamerInfo::kObjectp) &&
04140 (fStreamerType != TVirtualStreamerInfo::kObjectP)) {
04141 Error("SetAddress", "TClonesArray with fStreamerType: %d", fStreamerType);
04142 } else if (fStreamerType == -1) {
04143
04144
04145 SetBit(kDeleteObject);
04146 fObject = (char*) new TClonesArray(GetClonesName());
04147 fAddress = (char*) &fObject;
04148 } else {
04149
04150 Error("SetAddress", "Embedded pointer to a TClonesArray given a zero address for branch '%s'", GetName());
04151 }
04152 }
04153 }
04154 } else if (fType == 4) {
04155
04156
04157
04158 TVirtualCollectionProxy* proxy = GetCollectionProxy();
04159 if (fAddress) {
04160
04161 if ((fStreamerType == TVirtualStreamerInfo::kObject) ||
04162 (fStreamerType == TVirtualStreamerInfo::kAny) ||
04163 (fStreamerType == TVirtualStreamerInfo::kSTL)) {
04164
04165
04166
04167
04168 fObject = fAddress;
04169 } else {
04170
04171
04172 if ((fStreamerType != -1) && (fStreamerType != TVirtualStreamerInfo::kSTLp)) {
04173 Error("SetAddress", "STL container with fStreamerType: %d", fStreamerType);
04174 } else if (fStreamerType == -1) {
04175
04176 void** pp = (void**) fAddress;
04177 if (!*pp) {
04178
04179 *pp = proxy->New();
04180 if (!(*pp)) {
04181 Error("SetAddress", "Failed to allocate STL container for branch '%s'", GetName());
04182
04183
04184
04185 fAddress = 0;
04186 }
04187 }
04188 fObject = (char*) *pp;
04189 } else {
04190
04191
04192
04193 void** pp = (void**) fAddress;
04194 if (!*pp) {
04195
04196 *pp = proxy->New();
04197 if (!(*pp)) {
04198 Error("SetAddress", "Failed to allocate STL container for branch '%s'", GetName());
04199
04200
04201
04202 fAddress = 0;
04203 }
04204 }
04205 fObject = (char*) *pp;
04206 }
04207 }
04208 } else {
04209
04210 if ((fStreamerType == TVirtualStreamerInfo::kObject) ||
04211 (fStreamerType == TVirtualStreamerInfo::kAny) ||
04212 (fStreamerType == TVirtualStreamerInfo::kSTL)) {
04213
04214
04215
04216
04217 Error("SetAddress", "Embedded STL container given a zero address for branch '%s'", GetName());
04218 } else {
04219
04220
04221 if ((fStreamerType != -1) && (fStreamerType != TVirtualStreamerInfo::kSTLp)) {
04222 Error("SetAddress", "STL container with fStreamerType: %d", fStreamerType);
04223 } else if (fStreamerType == -1) {
04224
04225 SetBit(kDeleteObject);
04226 fObject = (char*) proxy->New();
04227 if (fObject) {
04228 fAddress = (char*) &fObject;
04229 } else {
04230 Error("SetAddress", "Failed to allocate STL container for branch '%s'", GetName());
04231
04232
04233
04234 fAddress = 0;
04235 }
04236 } else {
04237
04238 Error("SetAddress", "Embedded pointer to an STL container given a zero address for branch '%s'", GetName());
04239 }
04240 }
04241 }
04242 } else if (fType == 41) {
04243
04244
04245 GetCollectionProxy();
04246
04247 fObject = fAddress;
04248 } else if (fID < 0) {
04249
04250 char** pp = (char**) fAddress;
04251 if (pp && *pp) {
04252
04253 fObject = *pp;
04254 } else {
04255
04256 if (clOfBranch) {
04257 if (!pp) {
04258
04259 SetBit(kDeleteObject);
04260 }
04261 fObject = (char*) clOfBranch->New();
04262 if (pp) {
04263 *pp = fObject;
04264 } else {
04265 fAddress = (char*) &fObject;
04266 }
04267 } else {
04268 Error("SetAddress", "I have no TClass for branch %s, so I cannot allocate an I/O buffer!", GetName());
04269 if (pp) {
04270 fObject = 0;
04271 *pp = 0;
04272 }
04273 }
04274 }
04275 } else {
04276
04277 fObject = fAddress;
04278 }
04279
04280 if (!info) {
04281
04282 return;
04283 }
04284
04285
04286
04287 if (!fInitOffsets) {
04288 InitializeOffsets();
04289 }
04290
04291
04292
04293
04294 Int_t nbranches = fBranches.GetEntriesFast();
04295 for (Int_t i = 0; i < nbranches; ++i) {
04296 TBranch* abranch = (TBranch*) fBranches.UncheckedAt(i);
04297
04298 if (fBranchOffset[i] != TStreamerInfo::kMissing) {
04299 abranch->SetAddress(fObject + fBranchOffset[i]);
04300 abranch->SetBit(kAddressSet);
04301 } else {
04302
04303
04304
04305
04306 abranch->SetBit(kAddressSet);
04307 }
04308 }
04309 }
04310
04311
04312 void TBranchElement::SetBasketSize(Int_t buffsize)
04313 {
04314
04315
04316 TBranch::SetBasketSize(buffsize);
04317 Int_t nbranches = fBranches.GetEntriesFast();
04318 for (Int_t i = 0; i < nbranches; ++i) {
04319 TBranch* branch = (TBranch*) fBranches[i];
04320 branch->SetBasketSize(fBasketSize);
04321 }
04322 }
04323
04324
04325 void TBranchElement::SetBranchCount(TBranchElement* brOfCounter)
04326 {
04327
04328
04329 fBranchCount = brOfCounter;
04330 if (fBranchCount==0) return;
04331
04332 TLeafElement* leafOfCounter = (TLeafElement*) brOfCounter->GetListOfLeaves()->At(0);
04333 TLeafElement* leaf = (TLeafElement*) GetListOfLeaves()->At(0);
04334 if (leafOfCounter && leaf) {
04335 leaf->SetLeafCount(leafOfCounter);
04336 } else {
04337 if (!leafOfCounter) {
04338 Warning("SetBranchCount", "Counter branch %s for branch %s has no leaves!", brOfCounter->GetName(), GetName());
04339 }
04340 if (!leaf) {
04341 Warning("SetBranchCount", "Branch %s has no leaves!", GetName());
04342 }
04343 }
04344 }
04345
04346
04347 Bool_t TBranchElement::SetMakeClass(Bool_t decomposeObj)
04348 {
04349
04350
04351
04352
04353
04354 if (decomposeObj)
04355 SetBit(kDecomposedObj);
04356 else
04357 ResetBit(kDecomposedObj);
04358
04359 Int_t nbranches = fBranches.GetEntriesFast();
04360 for (Int_t i = 0; i < nbranches; ++i) {
04361 TBranchElement* branch = (TBranchElement*) fBranches[i];
04362 branch->SetMakeClass(decomposeObj);
04363 }
04364 SetReadLeavesPtr();
04365
04366 return kTRUE;
04367 }
04368
04369
04370 void TBranchElement::SetObject(void* obj)
04371 {
04372
04373
04374 if (TestBit(kDoNotProcess)) {
04375 return;
04376 }
04377 fObject = (char*)obj;
04378 SetAddress( &fObject );
04379 }
04380
04381
04382 void TBranchElement::SetOffset(Int_t offset)
04383 {
04384
04385
04386
04387
04388
04389
04390 if (fReadActionSequence) {
04391 fReadActionSequence->AddToOffset(offset - fOffset);
04392 }
04393 fOffset = offset;
04394 }
04395
04396
04397 void TBranchElement::SetReadActionSequence()
04398 {
04399
04400
04401 if (fInfo == 0) {
04402
04403 return;
04404 }
04405
04406
04407 TStreamerInfoActions::TActionSequence *original = 0;
04408 TStreamerInfoActions::TActionSequence *transient = 0;
04409 if (fType == 41) {
04410 if( fSplitLevel >= TTree::kSplitCollectionOfPointers && fBranchCount->fSTLtype == TClassEdit::kVector) {
04411 original = fInfo->GetReadMemberWiseActions(kTRUE);
04412 } else {
04413 TVirtualStreamerInfo *info = GetInfoImp();
04414 if (GetParentClass() == info->GetClass()) {
04415 if( fTargetClass.GetClassName()[0] && fBranchClass != fTargetClass ) {
04416 original = GetCollectionProxy()->GetConversionReadMemberWiseActions(fBranchClass.GetClass(), fClassVersion);
04417 } else {
04418 original = GetCollectionProxy()->GetReadMemberWiseActions(fClassVersion);
04419 }
04420 } else {
04421
04422
04423 transient = TStreamerInfoActions::TActionSequence::CreateReadMemberWiseActions(info,*GetCollectionProxy());
04424 original = transient;
04425 }
04426 }
04427 } else if (fType == 31) {
04428 original = fInfo->GetReadMemberWiseActions(kTRUE);
04429 } else if (0<=fType && fType<=2) {
04430
04431 original = fInfo->GetReadMemberWiseActions(kFALSE);
04432 }
04433 if (original) {
04434 fIDs.insert(fIDs.begin(),fID);
04435 if (fReadActionSequence) delete fReadActionSequence;
04436 fReadActionSequence = original->CreateSubSequence(fIDs,fOffset);
04437 fIDs.erase(fIDs.begin());
04438 }
04439 delete transient;
04440 }
04441
04442
04443 void TBranchElement::SetReadLeavesPtr()
04444 {
04445
04446
04447 if (TestBit(kDecomposedObj)) {
04448 fReadLeaves = (ReadLeaves_t)&TBranchElement::ReadLeavesMakeClass;
04449 } else if (fType == 4) {
04450 fReadLeaves = (ReadLeaves_t)&TBranchElement::ReadLeavesCollection;
04451 } else if (fType == 41) {
04452 if( fSplitLevel >= TTree::kSplitCollectionOfPointers ) {
04453 if (fBranchCount->fSTLtype == TClassEdit::kVector) {
04454 fReadLeaves = (ReadLeaves_t)&TBranchElement::ReadLeavesCollectionSplitVectorPtrMember;
04455 } else {
04456 fReadLeaves = (ReadLeaves_t)&TBranchElement::ReadLeavesCollectionSplitPtrMember;
04457 }
04458 } else {
04459 fReadLeaves = (ReadLeaves_t)&TBranchElement::ReadLeavesCollectionMember;
04460 }
04461 } else if (fType == 3) {
04462 fReadLeaves = (ReadLeaves_t)&TBranchElement::ReadLeavesClones;
04463 } else if (fType == 31) {
04464 fReadLeaves = (ReadLeaves_t)&TBranchElement::ReadLeavesClonesMember;
04465 } else if (fType < 0) {
04466 fReadLeaves = (ReadLeaves_t)&TBranchElement::ReadLeavesCustomStreamer;
04467 } else if (fType <=2) {
04468
04469 if (fBranchCount) {
04470 fReadLeaves = (ReadLeaves_t)&TBranchElement::ReadLeavesMemberBranchCount;
04471 } else if (fStreamerType == TVirtualStreamerInfo::kCounter) {
04472 fReadLeaves = (ReadLeaves_t)&TBranchElement::ReadLeavesMemberCounter;
04473 } else {
04474 fReadLeaves = (ReadLeaves_t)&TBranchElement::ReadLeavesMember;
04475 }
04476 } else {
04477 Fatal("SetReadLeavePtr","Unexpected branch type %d for %s",fType,GetName());
04478 }
04479
04480 SetReadActionSequence();
04481 }
04482
04483
04484 void TBranchElement::SetTargetClass(const char *name)
04485 {
04486
04487
04488
04489 if (name == 0) return;
04490
04491 if (strcmp(fTargetClass.GetClassName(),name) != 0 )
04492 {
04493
04494
04495
04496 fInfo = 0;
04497 fInit = kFALSE;
04498 fInitOffsets = kFALSE;
04499 delete fReadActionSequence;
04500 fReadActionSequence = 0;
04501
04502 Int_t nbranches = fBranches.GetEntriesFast();
04503 for (Int_t i = 0; i < nbranches; ++i) {
04504 TBranchElement *sub = (TBranchElement*) fBranches[i];
04505 if (sub->fTargetClass == fTargetClass ) {
04506 sub->SetTargetClass(name);
04507 }
04508 if (sub->fParentClass == fTargetClass ) {
04509 sub->SetParentClass(TClass::GetClass(name));
04510 }
04511 }
04512 fTargetClass = name;
04513 }
04514
04515 }
04516
04517
04518 void TBranchElement::SetupAddresses()
04519 {
04520
04521
04522
04523
04524
04525 ValidateAddress();
04526
04527 if (fAddress || fTree->GetMakeClass()) {
04528
04529 return;
04530 }
04531
04532 if (TestBit(kDoNotProcess|kAddressSet)) {
04533
04534
04535
04536 return;
04537 }
04538
04539
04540
04541
04542 if( fType == 41 && fSplitLevel >= TTree::kSplitCollectionOfPointers )
04543 {
04544 TBranchElement *parent = (TBranchElement *)GetMother()->GetSubBranch( this );
04545
04546 TVirtualStreamerInfo *sinfo = GetInfoImp();
04547 if (sinfo && sinfo->IsCompiled())
04548 {
04549
04550
04551
04552 sinfo->BuildOld();
04553 }
04554
04555 if( !parent->GetAddress() )
04556 parent->SetAddress( 0 );
04557 return;
04558 }
04559
04560
04561
04562
04563 TBranchElement* mother = (TBranchElement*) GetMother();
04564 if (!mother) {
04565 return;
04566 }
04567 TClass* cl = TClass::GetClass(mother->GetClassName());
04568
04569 {
04570 TVirtualStreamerInfo *sinfo = GetInfoImp();
04571
04572 if (sinfo && sinfo->IsCompiled()) {
04573
04574
04575
04576 sinfo->BuildOld();
04577 }
04578 }
04579
04580 if (!cl) {
04581 return;
04582 }
04583
04584 if (!mother->GetAddress()) {
04585
04586 Bool_t motherStatus = mother->TestBit(kDoNotProcess);
04587 mother->ResetBit(kDoNotProcess);
04588
04589 mother->SetAddress(0);
04590 mother->SetBit(kDoNotProcess, motherStatus);
04591 }
04592 }
04593
04594
04595 void TBranchElement::Streamer(TBuffer& R__b)
04596 {
04597
04598 if (R__b.IsReading()) {
04599 R__b.ReadClassBuffer(TBranchElement::Class(), this);
04600 fParentClass.SetName(fParentName);
04601 fBranchClass.SetName(fClassName);
04602 fTargetClass.SetName( fClassName );
04603
04604
04605
04606 ResetBit(kDeleteObject|kCache|kOwnOnfileObj|kAddressSet);
04607
04608 if ((fType == 0) && (fLeaves.GetEntriesFast() == 0)) {
04609 TLeaf* leaf = new TLeafElement(this, GetTitle(), fID, fStreamerType);
04610 leaf->SetTitle(GetTitle());
04611 fNleaves = 1;
04612 fLeaves.Add(leaf);
04613 fTree->GetListOfLeaves()->Add(leaf);
04614 }
04615
04616 }
04617 else {
04618 TDirectory* dirsav = fDirectory;
04619 fDirectory = 0;
04620 {
04621
04622 Int_t classVersion = fClassVersion;
04623
04624 if (fClassVersion < 0) {
04625 fClassVersion = -fClassVersion;
04626 }
04627
04628
04629
04630
04631 R__b.WriteClassBuffer(TBranchElement::Class(), this);
04632
04633 fClassVersion = classVersion;
04634 }
04635
04636
04637
04638
04639 {
04640 R__b.ForceWriteInfo(GetInfoImp(), kTRUE);
04641 }
04642
04643
04644
04645
04646
04647
04648 if (fType == 3) {
04649
04650
04651
04652
04653
04654 const char* nm = GetClonesName();
04655 if (nm && strlen(nm)) {
04656 TClass* cl = TClass::GetClass(nm);
04657 if (cl) {
04658 R__b.ForceWriteInfo(cl->GetStreamerInfo(), kTRUE);
04659 }
04660 }
04661 }
04662 else if (fType == 4) {
04663
04664
04665
04666
04667
04668 TVirtualCollectionProxy* cp = GetCollectionProxy();
04669 if (cp) {
04670 TClass* cl = cp->GetValueClass();
04671 if (cl) {
04672 R__b.ForceWriteInfo(cl->GetStreamerInfo(), kTRUE);
04673 }
04674 }
04675 }
04676
04677
04678 if (!dirsav) {
04679
04680 return;
04681 }
04682 if (!dirsav->IsWritable()) {
04683 fDirectory = dirsav;
04684 return;
04685 }
04686 TDirectory* pdirectory = fTree->GetDirectory();
04687 if (!pdirectory) {
04688 fDirectory = dirsav;
04689 return;
04690 }
04691 const char* treeFileName = pdirectory->GetFile()->GetName();
04692 TBranch* mother = GetMother();
04693 const char* motherFileName = treeFileName;
04694 if (mother && (mother != this)) {
04695 motherFileName = mother->GetFileName();
04696 }
04697 if ((fFileName.Length() > 0) && strcmp(motherFileName, fFileName.Data())) {
04698 dirsav->WriteTObject(this);
04699 }
04700 fDirectory = dirsav;
04701 }
04702 }
04703
04704
04705 Int_t TBranchElement::Unroll(const char* name, TClass* clParent, TClass* cl, char* ptr, Int_t basketsize, Int_t splitlevel, Int_t btype)
04706 {
04707
04708
04709
04710
04711
04712
04713
04714
04715
04716
04717
04718
04719
04720
04721
04722
04723
04724
04725
04726
04727
04728
04729
04730
04731
04732
04733
04734
04735
04736
04737
04738
04739
04740
04741
04742
04743 Int_t splitSTLP = splitlevel - (splitlevel%TTree::kSplitCollectionOfPointers);
04744 splitlevel %= TTree::kSplitCollectionOfPointers;
04745
04746
04747 TString branchname;
04748
04749 if ((cl == TObject::Class()) && clParent->CanIgnoreTObjectStreamer()) {
04750 return 0;
04751 }
04752
04753
04754
04755
04756
04757
04758
04759
04760 TStreamerInfo* sinfo = fTree->BuildStreamerInfo(cl);
04761 if (splitlevel > 0) {
04762 sinfo->SetBit(TVirtualStreamerInfo::kCannotOptimize);
04763 sinfo->Compile();
04764 }
04765
04766
04767
04768
04769
04770 if (!sinfo) {
04771 return 0;
04772 }
04773
04774 Int_t ndata = sinfo->GetNdata();
04775 ULong_t* elems = sinfo->GetElems();
04776
04777 if ((ndata == 1) && cl->GetCollectionProxy() && !strcmp(((TStreamerElement*) elems[0])->GetName(), "This")) {
04778
04779
04780
04781 return 1;
04782 }
04783
04784 for (Int_t elemID = 0; elemID < ndata; ++elemID) {
04785
04786 TStreamerElement* elem = (TStreamerElement*) elems[elemID];
04787 if (elem->IsA() == TStreamerArtificial::Class()) {
04788 continue;
04789 }
04790 if (elem->TestBit(TStreamerElement::kRepeat)) {
04791 continue;
04792 }
04793 Int_t offset = elem->GetOffset();
04794
04795
04796 if (elem->IsA() == TStreamerBase::Class()) {
04797
04798 TClass* clOfBase = TClass::GetClass(elem->GetName());
04799 if ((clOfBase->Property() & kIsAbstract) && cl->InheritsFrom(TCollection::Class())) {
04800
04801
04802 return -1;
04803 }
04804 if ((btype == 31) || (btype == 41)) {
04805
04806
04807
04808
04809
04810
04811
04812
04813
04814 Int_t unroll = Unroll(name, clParent, clOfBase, ptr + offset, basketsize, splitlevel+splitSTLP, btype);
04815 if (unroll < 0) {
04816
04817 if (strlen(name)) {
04818 branchname.Form("%s.%s", name, elem->GetFullName());
04819 } else {
04820 branchname.Form("%s", elem->GetFullName());
04821 }
04822 TBranchElement* branch = new TBranchElement(this, branchname, sinfo, elemID, 0, basketsize, 0, btype);
04823 branch->SetParentClass(clParent);
04824 fBranches.Add(branch);
04825 }
04826 } else if (clOfBase->GetListOfRealData()->GetSize()) {
04827
04828 if (strlen(name)) {
04829 branchname.Form("%s.%s", name, elem->GetFullName());
04830
04831
04832
04833
04834
04835 TBranchElement* branch = new TBranchElement(this, name, sinfo, elemID, ptr + offset, basketsize, splitlevel+splitSTLP, btype);
04836
04837 branch->SetName(branchname);
04838 branch->SetTitle(branchname);
04839 branch->SetParentClass(clParent);
04840 fBranches.Add(branch);
04841 } else {
04842 branchname.Form("%s", elem->GetFullName());
04843 TBranchElement* branch = new TBranchElement(this, branchname, sinfo, elemID, ptr + offset, basketsize, splitlevel+splitSTLP, btype);
04844 branch->SetParentClass(clParent);
04845 fBranches.Add(branch);
04846 }
04847 }
04848 } else {
04849
04850 if (strlen(name)) {
04851 branchname.Form("%s.%s", name, elem->GetFullName());
04852 } else {
04853 branchname.Form("%s", elem->GetFullName());
04854 }
04855 if ((splitlevel > 1) && ((elem->IsA() == TStreamerObject::Class()) || (elem->IsA() == TStreamerObjectAny::Class()))) {
04856
04857
04858
04859
04860
04861 TClass* elemClass = TClass::GetClass(elem->GetTypeName());
04862 if (elemClass->Property() & kIsAbstract) {
04863 return -1;
04864 }
04865 if (elem->CannotSplit()) {
04866
04867 TBranchElement* branch = new TBranchElement(this, branchname, sinfo, elemID, ptr + offset, basketsize, 0, btype);
04868 branch->SetParentClass(clParent);
04869 fBranches.Add(branch);
04870 } else if (elemClass->InheritsFrom(TClonesArray::Class())) {
04871
04872 Int_t subSplitlevel = splitlevel-1;
04873 if (btype == 31 || btype == 41 || elem->CannotSplit()) {
04874
04875 subSplitlevel = 0;
04876 }
04877 TBranchElement* branch = new TBranchElement(this, branchname, sinfo, elemID, ptr + offset, basketsize, subSplitlevel, btype);
04878 branch->SetParentClass(clParent);
04879 fBranches.Add(branch);
04880 } else {
04881
04882
04883
04884
04885
04886
04887
04888 Int_t unroll = Unroll(branchname, clParent, elemClass, ptr + offset, basketsize, splitlevel-1+splitSTLP, btype);
04889 if (unroll < 0) {
04890
04891 TBranchElement* branch = new TBranchElement(this, branchname, sinfo, elemID, ptr + offset, basketsize, 0, btype);
04892 branch->SetParentClass(clParent);
04893 fBranches.Add(branch);
04894 }
04895 }
04896 }
04897 else if( elem->GetClassPointer() &&
04898 elem->GetClassPointer()->GetCollectionProxy() &&
04899 elem->GetClassPointer()->GetCollectionProxy()->HasPointers() &&
04900 splitSTLP && fType != 4 )
04901 {
04902
04903 TBranchSTL* branch = new TBranchSTL( this, branchname,
04904 elem->GetClassPointer()->GetCollectionProxy(),
04905 basketsize, splitlevel - 1+splitSTLP, sinfo, elemID );
04906 branch->SetAddress( ptr+offset );
04907 fBranches.Add( branch );
04908 }
04909 else if ((elem->IsA() == TStreamerSTL::Class()) && !elem->IsaPointer()) {
04910
04911
04912
04913 Int_t subSplitlevel = splitlevel - 1;
04914 if ((btype == 31) || (btype == 41) || elem->CannotSplit()) {
04915
04916 subSplitlevel = 0;
04917 }
04918 TBranchElement* branch = new TBranchElement(this, branchname, sinfo, elemID, ptr + offset, basketsize, subSplitlevel+splitSTLP, btype);
04919 branch->SetParentClass(clParent);
04920 fBranches.Add(branch);
04921 } else if (((btype != 31) && (btype != 41)) && ptr && ((elem->GetClassPointer() == TClonesArray::Class()) || ((elem->IsA() == TStreamerSTL::Class()) && !elem->CannotSplit()))) {
04922
04923
04924
04925
04926
04927
04928 TBranchElement* branch = new TBranchElement(this, branchname, sinfo, elemID, ptr + offset, basketsize, splitlevel-1+splitSTLP, btype);
04929 branch->SetParentClass(clParent);
04930 fBranches.Add(branch);
04931 } else {
04932
04933 TBranchElement* branch = new TBranchElement(this, branchname, sinfo, elemID, 0, basketsize, splitSTLP, btype);
04934 branch->SetType(btype);
04935 branch->SetParentClass(clParent);
04936 fBranches.Add(branch);
04937 }
04938 }
04939 }
04940
04941 return 1;
04942 }
04943
04944
04945 void TBranchElement::UpdateFile()
04946 {
04947
04948
04949
04950
04951
04952
04953
04954
04955 TBranch::UpdateFile();
04956 }