TBranchProxy.cxx

Go to the documentation of this file.
00001 // @(#)root/base:$Id: TBranchProxy.cxx 36449 2010-10-28 20:52:17Z pcanal $
00002 // Author: Philippe Canal  13/05/2003
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun, Fons Rademakers and al.           *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // TBranchProxy                                                         //
00015 //
00016 // Base class for all the proxy object.  It includes the imeplemtation
00017 // of the autoloading of branches as well as all the generic setup 
00018 // routine.
00019 //                                                                      //
00020 //////////////////////////////////////////////////////////////////////////
00021 
00022 #include "TBranchProxy.h"
00023 #include "TLeaf.h"
00024 #include "TBranchElement.h"
00025 #include "TStreamerElement.h"
00026 #include "TStreamerInfo.h"
00027 
00028 ClassImp(ROOT::TBranchProxy);
00029 
00030 ROOT::TBranchProxy::TBranchProxy() :
00031    fDirector(0), fInitialized(false), fBranchName(""), fParent(0),
00032    fDataMember(""), fIsMember(false), fIsClone(false), fIsaPointer(0),
00033    fClassName(""), fClass(0), fElement(0), fMemberOffset(0), fOffset(0),
00034    fBranch(0), fBranchCount(0),
00035    fLastTree(0), fRead(-1), fWhere(0),fCollection(0)
00036 {
00037    // Constructor.
00038 };
00039 
00040 ROOT::TBranchProxy::TBranchProxy(TBranchProxyDirector* boss, const char* top,
00041                                  const char* name) :
00042    fDirector(boss), fInitialized(false), fBranchName(top), fParent(0),
00043    fDataMember(""), fIsMember(false), fIsClone(false), fIsaPointer(false),
00044    fClassName(""), fClass(0), fElement(0), fMemberOffset(0), fOffset(0),
00045    fBranch(0), fBranchCount(0),
00046    fLastTree(0), fRead(-1),  fWhere(0),fCollection(0)
00047 {
00048    // Constructor.
00049 
00050    if (fBranchName.Length() && fBranchName[fBranchName.Length()-1]!='.' && name) {
00051       ((TString&)fBranchName).Append(".");
00052    }
00053    if (name) ((TString&)fBranchName).Append(name);
00054    boss->Attach(this);
00055 }
00056 
00057 ROOT::TBranchProxy::TBranchProxy(TBranchProxyDirector* boss, const char *top, const char *name, const char *membername) :
00058    fDirector(boss), fInitialized(false),  fBranchName(top), fParent(0),
00059    fDataMember(membername), fIsMember(true), fIsClone(false), fIsaPointer(false),
00060    fClassName(""), fClass(0), fElement(0), fMemberOffset(0), fOffset(0),
00061    fBranch(0), fBranchCount(0),
00062    fLastTree(0), fRead(-1), fWhere(0),fCollection(0)
00063 {
00064    // Constructor.
00065 
00066    if (name && strlen(name)) {
00067       if (fBranchName.Length() && fBranchName[fBranchName.Length()-1]!='.') {
00068          ((TString&)fBranchName).Append(".");
00069       }
00070       ((TString&)fBranchName).Append(name);
00071    }
00072    boss->Attach(this);
00073 }
00074 
00075 ROOT::TBranchProxy::TBranchProxy(TBranchProxyDirector* boss, TBranchProxy *parent, const char* membername, const char* top,
00076                                  const char* name) :
00077    fDirector(boss), fInitialized(false),  fBranchName(top), fParent(parent),
00078    fDataMember(membername), fIsMember(true), fIsClone(false), fIsaPointer(false),
00079    fClassName(""), fClass(0), fElement(0), fMemberOffset(0), fOffset(0),
00080    fBranch(0), fBranchCount(0),
00081    fLastTree(0), fRead(-1), fWhere(0),fCollection(0)
00082 {
00083    // Constructor.
00084 
00085    if (name && strlen(name)) {
00086       if (fBranchName.Length() && fBranchName[fBranchName.Length()-1]!='.') {
00087          ((TString&)fBranchName).Append(".");
00088       }
00089       ((TString&)fBranchName).Append(name);
00090    }
00091    boss->Attach(this);
00092 }
00093 
00094 ROOT::TBranchProxy::~TBranchProxy()
00095 {
00096    // Typical Destructor
00097 }
00098 
00099 void ROOT::TBranchProxy::Reset()
00100 {
00101    // Completely reset the object.
00102 
00103    fWhere = 0;
00104    fBranch = 0;
00105    fBranchCount = 0;
00106    fRead = -1;
00107    fClass = 0;
00108    fElement = 0;
00109    fMemberOffset = 0;
00110    fIsClone = false;
00111    fInitialized = false;
00112    fLastTree = 0;
00113    delete fCollection;
00114    fCollection = 0;
00115 }
00116 
00117 void ROOT::TBranchProxy::Print()
00118 {
00119    // Display the content of the object
00120 
00121    cout << "fBranchName " << fBranchName << endl;
00122    //cout << "fTree " << fDirector->fTree << endl;
00123    cout << "fBranch " << fBranch << endl;
00124    if (fBranchCount) cout << "fBranchCount " << fBranchCount << endl;
00125 }
00126 
00127 Bool_t ROOT::TBranchProxy::Setup()
00128 {
00129    // Initialize/cache the necessary information.
00130 
00131    // Should we check the type?
00132 
00133    if (!fDirector->GetTree()) {
00134       return false;
00135    }
00136    if (fParent) {
00137 
00138       fParent->Setup();
00139       
00140       TClass *pcl = fParent->GetClass();
00141       R__ASSERT(pcl);
00142 
00143       if (pcl==TClonesArray::Class()) {
00144          // We always skip the clones array
00145 
00146          Int_t i = fDirector->GetReadEntry();
00147          if (i<0)  fDirector->SetReadEntry(0);
00148          fParent->Read();
00149          if (i<0) fDirector->SetReadEntry(i);
00150 
00151          TClonesArray *clones;
00152          clones = (TClonesArray*)fParent->GetStart();
00153 
00154          pcl = clones->GetClass();
00155       } else if (pcl->GetCollectionProxy()) {
00156          // We always skip the collections.
00157 
00158          if (fCollection) delete fCollection;
00159          fCollection = pcl->GetCollectionProxy()->Generate();
00160          pcl = fCollection->GetValueClass();
00161          if (pcl == 0) {
00162             Error("Setup","Not finding TClass for collecion for the data member %s seems no longer be in class %s",fDataMember.Data(),fParent->GetClass()->GetName());
00163             return false;
00164          }         
00165       }
00166 
00167       fElement = (TStreamerElement*)pcl->GetStreamerInfo()->GetElements()->FindObject(fDataMember);
00168       if (fElement == 0) {
00169          Error("Setup","Data member %s seems no longer be in class %s",fDataMember.Data(),pcl->GetName());
00170          return false;
00171       }
00172       
00173       fIsaPointer = fElement->IsaPointer();
00174       fClass = fElement->GetClassPointer();
00175 
00176 
00177       fIsClone = (fClass==TClonesArray::Class());
00178 
00179       fOffset = fMemberOffset = fElement->GetOffset();
00180 
00181       fWhere = fParent->fWhere; // not really used ... it is reset by GetStart and GetClStart
00182 
00183       if (fParent->IsaPointer()) {
00184          // fprintf(stderr,"non-split pointer de-referencing non implemented yet \n");
00185          // nothing to do!
00186       } else {
00187          // Accumulate offsets.
00188          // or not!? fOffset = fMemberOffset = fMemberOffset + fParent->fOffset;
00189       }
00190 
00191       // This is not sufficient for following pointers
00192 
00193    } else if (!fBranch) {
00194 
00195       // This does not allow (yet) to precede the branch name with
00196       // its mother's name
00197       fBranch = fDirector->GetTree()->GetBranch(fBranchName.Data());
00198       if (!fBranch) return false;
00199 
00200       {
00201          // Calculate fBranchCount for a leaf.
00202          TLeaf *leaf = (TLeaf*) fBranch->GetListOfLeaves()->At(0); // fBranch->GetLeaf(fLeafname);
00203          if (leaf) leaf = leaf->GetLeafCount();
00204          if (leaf) {
00205             fBranchCount = leaf->GetBranch();
00206             //          fprintf(stderr,"for leaf %s setting up leafcount %s branchcount %s\n",
00207             //                  fBranch->GetName(),leaf->GetName(),fBranchCount->GetName());
00208             //fBranchCount->Print();
00209          }
00210       }
00211 
00212       fWhere = (double*)fBranch->GetAddress();
00213 
00214       if (!fWhere && fBranch->IsA()==TBranchElement::Class()
00215           && ((TBranchElement*)fBranch)->GetMother()) {
00216 
00217          TBranchElement* be = ((TBranchElement*)fBranch);
00218 
00219          be->GetMother()->SetAddress(0);
00220          fWhere =  (double*)fBranch->GetAddress();
00221 
00222       }
00223       if (fBranch->IsA()==TBranch::Class()) {
00224          TLeaf *leaf2;
00225          if (fDataMember.Length()) {
00226             leaf2 = fBranch->GetLeaf(fDataMember);
00227             fWhere = leaf2->GetValuePointer();
00228          } else if (!fWhere) {
00229             leaf2 = (TLeaf*)fBranch->GetListOfLeaves()->At(0); // fBranch->GetLeaf(fLeafname);
00230             fWhere = leaf2->GetValuePointer();
00231          }
00232       }
00233 
00234       if (!fWhere) {
00235          fBranch->SetAddress(0);
00236          fWhere =  (double*)fBranch->GetAddress();
00237       }
00238 
00239 
00240       if (fWhere && fBranch->IsA()==TBranchElement::Class()) {
00241 
00242          TBranchElement* be = ((TBranchElement*)fBranch);
00243 
00244          TStreamerInfo * info = be->GetInfo();
00245          Int_t id = be->GetID();
00246          if (id>=0) {
00247             fOffset = info->GetOffsets()[id];
00248             fElement = (TStreamerElement*)info->GetElements()->At(id);
00249             fIsaPointer = fElement->IsaPointer();
00250             fClass = fElement->GetClassPointer();
00251 
00252             if ((fIsMember || (be->GetType()!=3 && be->GetType() !=4)) 
00253                   && (be->GetType()!=31 && be->GetType()!=41)) {
00254 
00255                if (fClass==TClonesArray::Class()) {
00256                   Int_t i = be->GetTree()->GetReadEntry();
00257                   if (i<0) i = 0;
00258                   be->GetEntry(i);
00259 
00260                   TClonesArray *clones;
00261                   if ( fIsMember && be->GetType()==3 ) {
00262                      clones = (TClonesArray*)be->GetObject();
00263                   } else if (fIsaPointer) {
00264                      clones = (TClonesArray*)*(void**)((char*)fWhere+fOffset);
00265                   } else {
00266                      clones = (TClonesArray*)((char*)fWhere+fOffset);
00267                   }
00268                   if (!fIsMember) fIsClone = true;
00269                   fClass = clones->GetClass();
00270                } else if (fClass && fClass->GetCollectionProxy()) {
00271                   delete fCollection;
00272                   fCollection = fClass->GetCollectionProxy()->Generate();
00273                   fClass = fCollection->GetValueClass();
00274                }
00275 
00276             }
00277             if (fClass) fClassName = fClass->GetName();
00278          } else {
00279             fClassName = be->GetClassName();
00280             fClass = TClass::GetClass(fClassName);
00281          }
00282 
00283          if (be->GetType()==3) {
00284             // top level TClonesArray
00285 
00286             if (!fIsMember) fIsClone = true;
00287             fIsaPointer = false;
00288             fWhere = be->GetObject();
00289 
00290          } else if (be->GetType()==4) {
00291             // top level TClonesArray
00292 
00293             fCollection = be->GetCollectionProxy()->Generate();
00294             fIsaPointer = false;
00295             fWhere = be->GetObject();
00296 
00297          } else if (id<0) {
00298             // top level object
00299 
00300             fIsaPointer = false;
00301             fWhere = be->GetObject();
00302 
00303          } else if (be->GetType()==41) {
00304 
00305             fCollection = be->GetCollectionProxy()->Generate();
00306             fWhere   = be->GetObject();
00307             fOffset += be->GetOffset();
00308 
00309          } else if (be->GetType()==31) {
00310 
00311             fWhere   = be->GetObject();
00312             fOffset += be->GetOffset();
00313 
00314          } else if (be->GetType()==2) {
00315             // this might also be the right path for GetType()==1
00316 
00317             fWhere = be->GetObject();
00318 
00319          } else {
00320 
00321             // fWhere = ((unsigned char*)fWhere) + fOffset;
00322             fWhere = ((unsigned char*)be->GetObject()) + fOffset;
00323 
00324          }
00325       } else {
00326          fClassName = fBranch->GetClassName();
00327          fClass = TClass::GetClass(fClassName);
00328       }
00329 
00330 
00331       /*
00332         fClassName = fBranch->GetClassName(); // What about TClonesArray?
00333         if ( fBranch->IsA()==TBranchElement::Class() &&
00334         ((TBranchElement*)fBranch)->GetType()==31 ||((TBranchElement*)fBranch)->GetType()==3 ) {
00335 
00336         Int_t id = ((TBranchElement*)fBranch)->GetID();
00337         if (id>=0) {
00338 
00339         fElement = ((TStreamerElement*)(((TBranchElement*)fBranch)->GetInfo())->GetElements()->At(id));
00340         fClass = fElement->GetClassPointer();
00341         if (fClass) fClassName = fClass->GetName();
00342 
00343         }
00344         }
00345         if (fClass==0 && fClassName.Length()) fClass = TClass::GetClass(fClassName);
00346       */
00347       //fprintf(stderr,"For %s fClass is %p which is %s\n",
00348       //        fBranchName.Data(),fClass,fClass==0?"not set":fClass->GetName());
00349 
00350       if ( fBranch->IsA()==TBranchElement::Class() &&
00351            (((TBranchElement*)fBranch)->GetType()==3 || fClass==TClonesArray::Class()) &&
00352            !fIsMember ) {
00353          fIsClone = true;
00354       } 
00355 
00356       if (fIsMember) {
00357          if ( fBranch->IsA()==TBranchElement::Class() &&
00358               fClass==TClonesArray::Class() &&
00359               (((TBranchElement*)fBranch)->GetType()==31 || ((TBranchElement*)fBranch)->GetType()==3) ) {
00360 
00361             TBranchElement *bcount = ((TBranchElement*)fBranch)->GetBranchCount();
00362             TString member;
00363             if (bcount) {
00364                TString bname = fBranch->GetName();
00365                TString bcname = bcount->GetName();
00366                member = bname.Remove(0,bcname.Length()+1);
00367             } else {
00368                member = fDataMember;
00369             }
00370 
00371             fMemberOffset = fClass->GetDataMemberOffset(member);
00372 
00373             if (fMemberOffset<0) {
00374                Error("Setup","%s",Form("Negative offset %d for %s in %s",
00375                                   fMemberOffset,fBranch->GetName(),
00376                                   bcount?bcount->GetName():"unknown"));
00377             }
00378 
00379          } else if (fClass) {
00380 
00381             fElement = (TStreamerElement*)
00382                fClass->GetStreamerInfo()->GetElements()->FindObject(fDataMember);
00383             if (fElement)
00384                fMemberOffset = fElement->GetOffset();
00385             else {
00386                // Need to compose the proper sub name
00387 
00388                TString member;
00389 
00390                Bool_t forgotWhenThisHappens = false;
00391                R__ASSERT(forgotWhenThisHappens);
00392 
00393                member += fDataMember;
00394                fMemberOffset = fClass->GetDataMemberOffset(member);
00395 
00396             }
00397 
00398          } else if (fBranch->IsA() != TBranch::Class()) {
00399             Error("Setup","%s",Form("Missing TClass object for %s\n",fClassName.Data()));
00400          }
00401 
00402          if ( fBranch->IsA()==TBranchElement::Class()
00403               && (((TBranchElement*)fBranch)->GetType()==31 || ((TBranchElement*)fBranch)->GetType()==3) ) {
00404 
00405             fOffset = fMemberOffset;
00406 
00407          } else {
00408 
00409             fWhere = ((unsigned char*)fWhere) + fMemberOffset;
00410          }
00411       }
00412    }
00413    if (fClass==TClonesArray::Class()) fIsClone = true;
00414    if (fWhere!=0) {
00415       if (fCollection) {
00416          if (IsaPointer()) {
00417             fCollection->PushProxy( *(void**)fWhere );
00418          } else {
00419             fCollection->PushProxy( fWhere );
00420          }
00421       }
00422       fLastTree = fDirector->GetTree();
00423       fInitialized = true;
00424       return true;
00425    } else {
00426       return false;
00427    }
00428 }

Generated on Tue Jul 5 15:42:57 2011 for ROOT_528-00b_version by  doxygen 1.5.1