00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "TBranchObject.h"
00021
00022 #include "TBasket.h"
00023 #include "TBranchClones.h"
00024 #include "TBrowser.h"
00025 #include "TClass.h"
00026 #include "TClonesArray.h"
00027 #include "TDataMember.h"
00028 #include "TDataType.h"
00029 #include "TFile.h"
00030 #include "TLeafObject.h"
00031 #include "TRealData.h"
00032 #include "TStreamerInfo.h"
00033 #include "TTree.h"
00034 #include "TVirtualPad.h"
00035
00036 ClassImp(TBranchObject)
00037
00038
00039 TBranchObject::TBranchObject()
00040 : TBranch()
00041 {
00042
00043
00044 fNleaves = 1;
00045 fOldObject = 0;
00046 }
00047
00048
00049 TBranchObject::TBranchObject(TTree *tree, const char* name, const char* classname, void* addobj, Int_t basketsize, Int_t splitlevel, Int_t compress, Bool_t isptrptr )
00050 : TBranch()
00051 {
00052
00053
00054 Init(tree,0,name,classname,addobj,basketsize,splitlevel,compress,isptrptr);
00055 }
00056
00057
00058 TBranchObject::TBranchObject(TBranch *parent, const char* name, const char* classname, void* addobj, Int_t basketsize, Int_t splitlevel, Int_t compress, Bool_t isptrptr )
00059 : TBranch()
00060 {
00061
00062
00063 Init(0,parent,name,classname,addobj,basketsize,splitlevel,compress,isptrptr);
00064 }
00065
00066
00067 void TBranchObject::Init(TTree *tree, TBranch *parent, const char* name, const char* classname, void* addobj, Int_t basketsize, Int_t , Int_t compress, Bool_t isptrptr)
00068 {
00069
00070
00071 if (tree==0 && parent!=0) tree = parent->GetTree();
00072 fTree = tree;
00073 fMother = parent ? parent->GetMother() : this;
00074 fParent = parent;
00075
00076 TClass* cl = TClass::GetClass(classname);
00077
00078 if (!cl) {
00079 Error("TBranchObject", "Cannot find class:%s", classname);
00080 return;
00081 }
00082
00083 if (!isptrptr) {
00084 fOldObject = (TObject*)addobj;
00085 addobj = &fOldObject;
00086 }
00087
00088 char** apointer = (char**) addobj;
00089 TObject* obj = (TObject*) (*apointer);
00090
00091 Bool_t delobj = kFALSE;
00092 if (!obj) {
00093 obj = (TObject*) cl->New();
00094 delobj = kTRUE;
00095 }
00096
00097 tree->BuildStreamerInfo(cl, obj);
00098
00099 if (delobj) {
00100 cl->Destructor(obj);
00101 }
00102
00103 SetName(name);
00104 SetTitle(name);
00105
00106 fCompress = compress;
00107 if ((compress == -1) && tree->GetDirectory()) {
00108 TFile* bfile = tree->GetDirectory()->GetFile();
00109 if (bfile) {
00110 fCompress = bfile->GetCompressionLevel();
00111 }
00112 }
00113 if (basketsize < 100) {
00114 basketsize = 100;
00115 }
00116 fBasketSize = basketsize;
00117 fAddress = (char*) addobj;
00118 fClassName = classname;
00119 fBasketBytes = new Int_t[fMaxBaskets];
00120 fBasketEntry = new Long64_t[fMaxBaskets];
00121 fBasketSeek = new Long64_t[fMaxBaskets];
00122 fOldObject = 0;
00123
00124 for (Int_t i = 0; i < fMaxBaskets; ++i) {
00125 fBasketBytes[i] = 0;
00126 fBasketEntry[i] = 0;
00127 fBasketSeek[i] = 0;
00128 }
00129
00130 TLeaf* leaf = new TLeafObject(this, name, classname);
00131 leaf->SetAddress(addobj);
00132 fNleaves = 1;
00133 fLeaves.Add(leaf);
00134 tree->GetListOfLeaves()->Add(leaf);
00135
00136
00137
00138
00139
00140 SetAutoDelete(kTRUE);
00141
00142 fDirectory = fTree->GetDirectory();
00143 fFileName = "";
00144
00145 }
00146
00147
00148 TBranchObject::~TBranchObject()
00149 {
00150
00151 fBranches.Delete();
00152 }
00153
00154
00155 void TBranchObject::Browse(TBrowser* b)
00156 {
00157
00158
00159 Int_t nbranches = fBranches.GetEntriesFast();
00160 if (nbranches > 1) {
00161 fBranches.Browse(b);
00162 }
00163 if (GetBrowsables() && GetBrowsables()->GetSize()) {
00164 GetBrowsables()->Browse(b);
00165 }
00166 }
00167
00168
00169 Int_t TBranchObject::Fill()
00170 {
00171
00172
00173 Int_t nbytes = 0;
00174 Int_t nbranches = fBranches.GetEntriesFast();
00175 if (nbranches) {
00176 ++fEntries;
00177 UpdateAddress();
00178 for (Int_t i = 0; i < nbranches; ++i) {
00179 TBranch* branch = (TBranch*) fBranches[i];
00180 if (!branch->TestBit(kDoNotProcess)) {
00181 Int_t bc = branch->Fill();
00182 nbytes += bc;
00183 }
00184 }
00185 } else {
00186 if (!TestBit(kDoNotProcess)) {
00187 Int_t bc = TBranch::Fill();
00188 nbytes += bc;
00189 }
00190 }
00191 return nbytes;
00192 }
00193
00194
00195 Int_t TBranchObject::GetEntry(Long64_t entry, Int_t getall)
00196 {
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 if (TestBit(kDoNotProcess) && !getall) {
00207 return 0;
00208 }
00209 Int_t nbytes;
00210 Int_t nbranches = fBranches.GetEntriesFast();
00211
00212 if (nbranches) {
00213 if (fAddress == 0) {
00214 SetupAddresses();
00215 }
00216 nbytes = 0;
00217 Int_t nb;
00218 for (Int_t i = 0; i < nbranches; ++i) {
00219 TBranch* branch = (TBranch*) fBranches[i];
00220 if (branch) {
00221 nb = branch->GetEntry(entry, getall);
00222 if (nb < 0) {
00223 return nb;
00224 }
00225 nbytes += nb;
00226 }
00227 }
00228 } else {
00229 nbytes = TBranch::GetEntry(entry, getall);
00230 }
00231 return nbytes;
00232 }
00233
00234
00235 Int_t TBranchObject::GetExpectedType(TClass *&expectedClass,EDataType &expectedType)
00236 {
00237
00238
00239
00240
00241
00242 expectedClass = 0;
00243 expectedType = kOther_t;
00244 TLeafObject* lobj = (TLeafObject*) GetListOfLeaves()->At(0);
00245 if (!lobj) {
00246 Error("GetExpectedType", "Did not find any leaves in %s",GetName());
00247 return 1;
00248 }
00249 expectedClass = lobj->GetClass();
00250 return 0;
00251 }
00252
00253
00254 Bool_t TBranchObject::IsFolder() const
00255 {
00256
00257
00258 Int_t nbranches = fBranches.GetEntriesFast();
00259
00260 if (nbranches >= 1) {
00261 return kTRUE;
00262 }
00263
00264 TList* browsables = const_cast<TBranchObject*>(this)->GetBrowsables();
00265
00266 return browsables && browsables->GetSize();
00267 }
00268
00269
00270 void TBranchObject::Print(Option_t* option) const
00271 {
00272
00273
00274 Int_t nbranches = fBranches.GetEntriesFast();
00275 if (nbranches) {
00276 Printf("*Branch :%-9s : %-54s *", GetName(), GetTitle());
00277 Printf("*Entries : %8d : BranchObject (see below) *", Int_t(fEntries));
00278 Printf("*............................................................................*");
00279 for (Int_t i = 0; i < nbranches; ++i) {
00280 TBranch* branch = (TBranch*) fBranches.At(i);
00281 if (branch) {
00282 branch->Print(option);
00283 }
00284 }
00285 } else {
00286 TBranch::Print(option);
00287 }
00288 }
00289
00290
00291 void TBranchObject::Reset(Option_t* option)
00292 {
00293
00294
00295
00296
00297
00298 TBranch::Reset(option);
00299
00300 Int_t nbranches = fBranches.GetEntriesFast();
00301 for (Int_t i = 0; i < nbranches; ++i) {
00302 TBranch* branch = (TBranch*) fBranches[i];
00303 branch->Reset(option);
00304 }
00305 }
00306
00307
00308 void TBranchObject::SetAddress(void* add)
00309 {
00310
00311
00312 if (TestBit(kDoNotProcess)) {
00313 return;
00314 }
00315
00316
00317 if (Long_t(add) == -1) {
00318 SetBit(kWarn);
00319 return;
00320 }
00321
00322 fReadEntry = -1;
00323 Int_t nbranches = fBranches.GetEntriesFast();
00324
00325 TLeaf* leaf = (TLeaf*) fLeaves.UncheckedAt(0);
00326 if (leaf) {
00327 leaf->SetAddress(add);
00328 }
00329
00330 fAddress = (char*) add;
00331 char** ppointer = (char**) add;
00332
00333 char* obj = 0;
00334 if (ppointer) {
00335 obj = *ppointer;
00336 }
00337
00338 TClass* cl = TClass::GetClass(fClassName.Data());
00339
00340 if (!cl) {
00341 for (Int_t i = 0; i < nbranches; ++i) {
00342 TBranch* br = (TBranch*) fBranches[i];
00343 br->SetAddress(obj);
00344 }
00345 return;
00346 }
00347
00348 if (ppointer && !obj) {
00349 obj = (char*) cl->New();
00350 *ppointer = obj;
00351 }
00352
00353 if (!cl->GetListOfRealData()) {
00354 cl->BuildRealData(obj);
00355 }
00356
00357 if (cl->InheritsFrom(TClonesArray::Class())) {
00358 if (ppointer) {
00359 TClonesArray* clones = (TClonesArray*) *ppointer;
00360 if (!clones) {
00361 Error("SetAddress", "Pointer to TClonesArray is null");
00362 return;
00363 }
00364 TClass* clm = clones->GetClass();
00365 if (clm) {
00366 clm->BuildRealData();
00367 clm->GetStreamerInfo();
00368 }
00369 }
00370 }
00371
00372
00373
00374
00375
00376
00377
00378 char* fullname = new char[200];
00379
00380 const char* bname = GetName();
00381
00382 Int_t isDot = 0;
00383 if (bname[strlen(bname)-1] == '.') {
00384 isDot = 1;
00385 }
00386
00387 char* pointer = 0;
00388 TRealData* rd = 0;
00389 TIter next(cl->GetListOfRealData());
00390 while ((rd = (TRealData*) next())) {
00391 if (rd->TestBit(TRealData::kTransient)) continue;
00392
00393 TDataMember* dm = rd->GetDataMember();
00394 if (!dm || !dm->IsPersistent()) {
00395 continue;
00396 }
00397 const char* rdname = rd->GetName();
00398 TDataType* dtype = dm->GetDataType();
00399 Int_t code = 0;
00400 if (dtype) {
00401 code = dm->GetDataType()->GetType();
00402 }
00403 Int_t offset = rd->GetThisOffset();
00404 if (ppointer) {
00405 pointer = obj + offset;
00406 }
00407 TBranch* branch = 0;
00408 if (dm->IsaPointer()) {
00409 TClass* clobj = 0;
00410 if (!dm->IsBasic()) {
00411 clobj = TClass::GetClass(dm->GetTypeName());
00412 }
00413 if (clobj && clobj->InheritsFrom(TClonesArray::Class())) {
00414 if (isDot) {
00415 snprintf(fullname,200, "%s%s", bname, &rdname[1]);
00416 } else {
00417 snprintf(fullname,200, "%s", &rdname[1]);
00418 }
00419 branch = (TBranch*) fBranches.FindObject(fullname);
00420 } else {
00421 if (!clobj) {
00422
00423
00424 const char* index = dm->GetArrayIndex();
00425 if (strlen(index) == 0) {
00426 if (code == 1) {
00427
00428 if (isDot) {
00429 snprintf(fullname,200, "%s%s", bname, &rdname[0]);
00430 } else {
00431 snprintf(fullname,200, "%s", &rdname[0]);
00432 }
00433 } else {
00434 continue;
00435 }
00436 }
00437 if (isDot) {
00438 snprintf(fullname,200, "%s%s", bname, &rdname[0]);
00439 } else {
00440 snprintf(fullname,200, "%s", &rdname[0]);
00441 }
00442
00443 UInt_t cursor;
00444 UInt_t pos;
00445 for (cursor = 0, pos = 0; cursor < strlen(fullname); ++cursor) {
00446 if (fullname[cursor] != '*') {
00447 fullname[pos++] = fullname[cursor];
00448 }
00449 }
00450 fullname[pos] = '\0';
00451 branch = (TBranch*) fBranches.FindObject(fullname);
00452 } else {
00453 if (!clobj->InheritsFrom(TObject::Class())) {
00454 continue;
00455 }
00456 if (isDot) {
00457 snprintf(fullname,200, "%s%s", bname, &rdname[1]);
00458 } else {
00459 snprintf(fullname,200, "%s", &rdname[1]);
00460 }
00461 branch = (TBranch*) fBranches.FindObject(fullname);
00462 }
00463 }
00464 } else {
00465 if (dm->IsBasic()) {
00466 if (isDot) {
00467 snprintf(fullname,200, "%s%s", bname, &rdname[0]);
00468 } else {
00469 snprintf(fullname,200, "%s", &rdname[0]);
00470 }
00471 branch = (TBranch*) fBranches.FindObject(fullname);
00472 }
00473 }
00474 if (branch) {
00475 branch->SetAddress(pointer);
00476 }
00477 }
00478
00479 delete[] fullname;
00480 }
00481
00482
00483 void TBranchObject::SetAutoDelete(Bool_t autodel)
00484 {
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505 TBranch::SetAutoDelete(autodel);
00506
00507 Int_t nbranches = fBranches.GetEntriesFast();
00508 for (Int_t i=0;i<nbranches;i++) {
00509 TBranch *branch = (TBranch*)fBranches[i];
00510 branch->SetAutoDelete(autodel);
00511 }
00512 }
00513
00514
00515 void TBranchObject::SetBasketSize(Int_t buffsize)
00516 {
00517
00518
00519 TBranch::SetBasketSize(buffsize);
00520
00521 Int_t nbranches = fBranches.GetEntriesFast();
00522 for (Int_t i = 0; i < nbranches; ++i) {
00523 TBranch* branch = (TBranch*) fBranches[i];
00524 branch->SetBasketSize(fBasketSize);
00525 }
00526 }
00527
00528
00529 void TBranchObject::Streamer(TBuffer& R__b)
00530 {
00531
00532
00533 if (R__b.IsReading()) {
00534 R__b.ReadClassBuffer(TBranchObject::Class(), this);
00535 } else {
00536 TDirectory* dirsav = fDirectory;
00537 fDirectory = 0;
00538
00539 R__b.WriteClassBuffer(TBranchObject::Class(), this);
00540
00541
00542
00543 R__b.ForceWriteInfo(TClass::GetClass(fClassName.Data())->GetStreamerInfo(), kTRUE);
00544
00545
00546
00547 if (!dirsav) {
00548 return;
00549 }
00550 if (!dirsav->IsWritable()) {
00551 fDirectory = dirsav;
00552 return;
00553 }
00554 TDirectory* pdirectory = fTree->GetDirectory();
00555 if (!pdirectory) {
00556 fDirectory = dirsav;
00557 return;
00558 }
00559 const char* treeFileName = pdirectory->GetFile()->GetName();
00560 TBranch* mother = GetMother();
00561 const char* motherFileName = treeFileName;
00562 if (mother && (mother != this)) {
00563 motherFileName = mother->GetFileName();
00564 }
00565 if ((fFileName.Length() > 0) && strcmp(motherFileName, fFileName.Data())) {
00566 dirsav->WriteTObject(this);
00567 }
00568 fDirectory = dirsav;
00569 }
00570 }
00571
00572
00573 void TBranchObject::SetupAddresses()
00574 {
00575
00576
00577
00578
00579 if (fAddress == 0) {
00580
00581 if (!TestBit(kWarn)) {
00582 TClass* cl = TClass::GetClass(fClassName);
00583 if (cl) {
00584 TObject** voidobj = (TObject**) new Long_t[1];
00585 *voidobj = (TObject*) cl->New();
00586 SetAddress(voidobj);
00587 } else {
00588 Warning("GetEntry", "Cannot get class: %s", fClassName.Data());
00589 SetBit(kWarn);
00590 }
00591 }
00592 }
00593 }
00594
00595
00596 void TBranchObject::UpdateAddress()
00597 {
00598
00599
00600 void** ppointer = (void**) fAddress;
00601 if (!ppointer) {
00602 return;
00603 }
00604 TObject* obj = (TObject*) (*ppointer);
00605 if (obj != fOldObject) {
00606 fOldObject = obj;
00607 SetAddress(fAddress);
00608 }
00609 }
00610