#include "TBranchObject.h"
#include "TBasket.h"
#include "TBranchClones.h"
#include "TBrowser.h"
#include "TClass.h"
#include "TClonesArray.h"
#include "TDataMember.h"
#include "TDataType.h"
#include "TFile.h"
#include "TLeafObject.h"
#include "TRealData.h"
#include "TStreamerInfo.h"
#include "TTree.h"
#include "TVirtualPad.h"
ClassImp(TBranchObject)
TBranchObject::TBranchObject()
: TBranch()
{
   
   fNleaves = 1;
   fOldObject = 0;
}
TBranchObject::TBranchObject(TTree *tree, const char* name, const char* classname, void* addobj, Int_t basketsize, Int_t splitlevel, Int_t compress)
: TBranch()
{
   
   Init(tree,0,name,classname,addobj,basketsize,splitlevel,compress);
}
TBranchObject::TBranchObject(TBranch *parent, const char* name, const char* classname, void* addobj, Int_t basketsize, Int_t splitlevel, Int_t compress)
: TBranch()
{
   
   Init(0,parent,name,classname,addobj,basketsize,splitlevel,compress);
}
void TBranchObject::Init(TTree *tree, TBranch *parent, const char* name, const char* classname, void* addobj, Int_t basketsize, Int_t splitlevel, Int_t compress)
{
   
   if (tree==0 && parent!=0) tree = parent->GetTree();
   fTree   = tree;
   fMother = parent ? parent->GetMother() : this;
   fParent = parent;
   TClass* cl = TClass::GetClass(classname);
   if (!cl) {
      Error("TBranchObject", "Cannot find class:%s", classname);
      return;
   }
   char** apointer = (char**) addobj;
   TObject* obj = (TObject*) (*apointer);
   Bool_t delobj = kFALSE;
   if (!obj) {
      obj = (TObject*) cl->New();
      delobj = kTRUE;
   }
   tree->BuildStreamerInfo(cl, obj);
   if (delobj) {
      cl->Destructor(obj);
   }
   SetName(name);
   SetTitle(name);
   fCompress = compress;
   if ((compress == -1) && tree->GetDirectory()) {
      TFile* bfile = tree->GetDirectory()->GetFile();
      if (bfile) {
         fCompress = bfile->GetCompressionLevel();
      }
   }
   if (basketsize < 100) {
      basketsize = 100;
   }
   fBasketSize = basketsize;
   fAddress = (char*) addobj;
   fClassName = classname;
   fBasketBytes = new Int_t[fMaxBaskets];
   fBasketEntry = new Long64_t[fMaxBaskets];
   fBasketSeek = new Long64_t[fMaxBaskets];
   fOldObject = 0;
   for (Int_t i = 0; i < fMaxBaskets; ++i) {
      fBasketBytes[i] = 0;
      fBasketEntry[i] = 0;
      fBasketSeek[i] = 0;
   }
   TLeaf* leaf = new TLeafObject(this, name, classname);
   leaf->SetAddress(addobj);
   fNleaves = 1;
   fLeaves.Add(leaf);
   tree->GetListOfLeaves()->Add(leaf);
   
   
   
   
   SetAutoDelete(kTRUE);
   fDirectory = fTree->GetDirectory();
   fFileName = "";
   
   if (!splitlevel) {
      TBasket* basket = new TBasket(name, fTree->GetName(), this);
      fBaskets.Add(basket);
   }
}
TBranchObject::~TBranchObject()
{
   
   fBranches.Delete();
}
void TBranchObject::Browse(TBrowser* b)
{
   
   Int_t nbranches = fBranches.GetEntriesFast();
   if (nbranches > 1) {
      fBranches.Browse(b);
   }
   if (GetBrowsables() && GetBrowsables()->GetSize()) {
      GetBrowsables()->Browse(b);
   }
}
Int_t TBranchObject::Fill()
{
   
   Int_t nbytes = 0;
   Int_t nbranches = fBranches.GetEntriesFast();
   if (nbranches) {
      ++fEntries;
      UpdateAddress();
      for (Int_t i = 0; i < nbranches; ++i)  {
         TBranch* branch = (TBranch*) fBranches[i];
         if (!branch->TestBit(kDoNotProcess)) {
            Int_t bc = branch->Fill();
            nbytes += bc;
         }
      }
   } else {
      if (!TestBit(kDoNotProcess)) {
         Int_t bc = TBranch::Fill();
         nbytes += bc;
      }
   }
   return nbytes;
}
Int_t TBranchObject::GetEntry(Long64_t entry, Int_t getall)
{
   
   
   
   
   
   
   
   
   if (TestBit(kDoNotProcess) && !getall) {
      return 0;
   }
   Int_t nbytes;
   Int_t nbranches = fBranches.GetEntriesFast();
   if (nbranches) {
      if (fAddress == 0) {
         
         if (!TestBit(kWarn)) {
            TClass* cl = TClass::GetClass(fClassName);
            if (cl) {
               TObject** voidobj = (TObject**) new Long_t[1];
               *voidobj = (TObject*) cl->New();
               SetAddress(voidobj);
            } else {
               Warning("GetEntry", "Cannot get class: %s", fClassName.Data());
               SetBit(kWarn);
            }
         }
      }
      nbytes = 0;
      Int_t nb;
      for (Int_t i = 0; i < nbranches; ++i)  {
         TBranch* branch = (TBranch*) fBranches[i];
         if (branch) {
            nb = branch->GetEntry(entry, getall);
            if (nb < 0) {
               return nb;
            }
            nbytes += nb;
         }
      }
   } else {
      nbytes = TBranch::GetEntry(entry, getall);
   }
   return nbytes;
}
Bool_t TBranchObject::IsFolder() const
{
   
   Int_t nbranches = fBranches.GetEntriesFast();
   if (nbranches >= 1) {
      return kTRUE;
   }
   TList* browsables = const_cast<TBranchObject*>(this)->GetBrowsables();
   return browsables && browsables->GetSize();
}
void TBranchObject::Print(Option_t* option) const
{
   
   Int_t nbranches = fBranches.GetEntriesFast();
   if (nbranches) {
      Printf("*Branch  :%-9s : %-54s *", GetName(), GetTitle());
      Printf("*Entries : %8d : BranchObject (see below)                               *", Int_t(fEntries));
      Printf("*............................................................................*");
      for (Int_t i = 0; i < nbranches; ++i)  {
         TBranch* branch = (TBranch*) fBranches.At(i);
         if (branch) {
            branch->Print(option);
         }
      }
   } else {
      TBranch::Print(option);
   }
}
void TBranchObject::Reset(Option_t* option)
{
   
   
   
   
   TBranch::Reset(option);
   Int_t nbranches = fBranches.GetEntriesFast();
   for (Int_t i = 0; i < nbranches; ++i)  {
      TBranch* branch = (TBranch*) fBranches[i];
      branch->Reset(option);
   }
}
void TBranchObject::SetAddress(void* add)
{
   
   if (TestBit(kDoNotProcess)) {
      return;
   }
   
   if (Long_t(add) == -1) {
      SetBit(kWarn);
      return;
   }
   fReadEntry = -1;
   Int_t nbranches = fBranches.GetEntriesFast();
   TLeaf* leaf = (TLeaf*) fLeaves.UncheckedAt(0);
   if (leaf) {
      leaf->SetAddress(add);
   }
   fAddress = (char*) add;
   char** ppointer = (char**) add;
   char* obj = 0;
   if (ppointer) {
      obj = *ppointer;
   }
   TClass* cl = TClass::GetClass(fClassName.Data());
   if (!cl) {
      for (Int_t i = 0; i < nbranches; ++i)  {
         TBranch* br = (TBranch*) fBranches[i];
         br->SetAddress(obj);
      }
      return;
   }
   if (ppointer && !obj) {
      obj = (char*) cl->New();
      *ppointer = obj;
   }
   if (!cl->GetListOfRealData()) {
      cl->BuildRealData(obj);
   }
   if (cl->InheritsFrom("TClonesArray")) {
      if (ppointer) {
         TClonesArray* clones = (TClonesArray*) *ppointer;
         if (!clones) {
            Error("SetAddress", "Pointer to TClonesArray is null");
            return;
         }
         TClass* clm = clones->GetClass();
         if (clm) {
            clm->BuildRealData(); 
            clm->GetStreamerInfo();
         }
      }
   }
   
   
   
   
   
   char* fullname = new char[200];
   const char* bname = GetName();
   Int_t isDot = 0;
   if (bname[strlen(bname)-1] == '.') {
      isDot = 1;
   }
   char* pointer = 0;
   TRealData* rd = 0;
   TIter next(cl->GetListOfRealData());
   while ((rd = (TRealData*) next())) {
      TDataMember* dm = rd->GetDataMember();
      if (!dm || !dm->IsPersistent()) {
         continue;
      }
      const char* rdname = rd->GetName();
      TDataType* dtype = dm->GetDataType();
      Int_t code = 0;
      if (dtype) {
         code = dm->GetDataType()->GetType();
      }
      Int_t offset = rd->GetThisOffset();
      if (ppointer) {
         pointer = obj + offset;
      }
      TBranch* branch = 0;
      if (dm->IsaPointer()) {
         TClass* clobj = 0;
         if (!dm->IsBasic()) {
            clobj = TClass::GetClass(dm->GetTypeName());
         }
         if (clobj && clobj->InheritsFrom("TClonesArray")) {
            if (isDot) {
               sprintf(fullname, "%s%s", bname, &rdname[1]);
            } else {
               sprintf(fullname, "%s", &rdname[1]);
            }
            branch = (TBranch*) fBranches.FindObject(fullname);
         } else {
            if (!clobj) {
               
               
               const char* index = dm->GetArrayIndex();
               if (strlen(index) == 0) {
                  if (code == 1) {
                     
                     if (isDot) {
                        sprintf(fullname, "%s%s", bname, &rdname[0]);
                     } else {
                        sprintf(fullname, "%s", &rdname[0]);
                     }
                  } else {
                     continue;
                  }
               }
               if (isDot) {
                  sprintf(fullname, "%s%s", bname, &rdname[0]);
               } else {
                  sprintf(fullname, "%s", &rdname[0]);
               }
               
               UInt_t cursor;
               UInt_t pos;
               for (cursor = 0, pos = 0; cursor < strlen(fullname); ++cursor) {
                  if (fullname[cursor] != '*') {
                     fullname[pos++] = fullname[cursor];
                  }
               }
               fullname[pos] = '\0';
               branch = (TBranch*) fBranches.FindObject(fullname);
            } else {
               if (!clobj->InheritsFrom(TObject::Class())) {
                  continue;
               }
               if (isDot) {
                  sprintf(fullname, "%s%s", bname, &rdname[1]);
               } else {
                  sprintf(fullname, "%s", &rdname[1]);
               }
               branch = (TBranch*) fBranches.FindObject(fullname);
            }
         }
      } else {
         if (dm->IsBasic()) {
            if (isDot) {
               sprintf(fullname, "%s%s", bname, &rdname[0]);
            } else {
               sprintf(fullname, "%s", &rdname[0]);
            }
            branch = (TBranch*) fBranches.FindObject(fullname);
         }
      }
      if (branch) {
         branch->SetAddress(pointer);
      }
   }
   delete[] fullname;
}
void TBranchObject::SetAutoDelete(Bool_t autodel)
{
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   TBranch::SetAutoDelete(autodel);
   Int_t nbranches = fBranches.GetEntriesFast();
   for (Int_t i=0;i<nbranches;i++)  {
      TBranch *branch = (TBranch*)fBranches[i];
      branch->SetAutoDelete(autodel);
   }
}
void TBranchObject::SetBasketSize(Int_t buffsize)
{
   
   TBranch::SetBasketSize(buffsize);
   Int_t nbranches = fBranches.GetEntriesFast();
   for (Int_t i = 0; i < nbranches; ++i)  {
      TBranch* branch = (TBranch*) fBranches[i];
      branch->SetBasketSize(fBasketSize);
   }
}
void TBranchObject::Streamer(TBuffer& R__b)
{
   
   if (R__b.IsReading()) {
      R__b.ReadClassBuffer(TBranchObject::Class(), this);
   } else {
      TDirectory* dirsav = fDirectory;
      fDirectory = 0;  
      R__b.WriteClassBuffer(TBranchObject::Class(), this);
      
      
      TClass::GetClass(fClassName.Data())->GetStreamerInfo()->ForceWriteInfo((TFile *)R__b.GetParent(), kTRUE);
      
      
      if (!dirsav) {
         return;
      }
      if (!dirsav->IsWritable()) {
         fDirectory = dirsav;
         return;
      }
      TDirectory* pdirectory = fTree->GetDirectory();
      if (!pdirectory) {
         fDirectory = dirsav;
         return;
      }
      const char* treeFileName = pdirectory->GetFile()->GetName();
      TBranch* mother = GetMother();
      const char* motherFileName = treeFileName;
      if (mother && (mother != this)) {
         motherFileName = mother->GetFileName();
      }
      if ((fFileName.Length() > 0) && strcmp(motherFileName, fFileName.Data())) {
         TDirectory::TContext ctxt(dirsav);
         Write();
      }
      fDirectory = dirsav;
   }
}
void TBranchObject::UpdateAddress()
{
   
   void** ppointer = (void**) fAddress;
   if (!ppointer) {
      return;
   }
   TObject* obj = (TObject*) (*ppointer);
   if (obj != fOldObject) {
      fOldObject = obj;
      SetAddress(fAddress);
   }
}
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.