#include "TBranchClones.h"
#include "TBasket.h"
#include "TClass.h"
#include "TClonesArray.h"
#include "TDataMember.h"
#include "TDataType.h"
#include "TFile.h"
#include "TLeafI.h"
#include "TRealData.h"
#include "TTree.h"
#include <cstring>
R__EXTERN TTree* gTree;
ClassImp(TBranchClones)
TBranchClones::TBranchClones()
: TBranch()
, fList(0)
, fRead(0)
, fN(0)
, fNdataMax(0)
, fBranchCount(0)
{
}
TBranchClones::TBranchClones(TTree *tree, const char* name, void* pointer, Int_t basketsize, Int_t compress, Int_t splitlevel)
: TBranch()
, fList(0)
, fRead(0)
, fN(0)
, fNdataMax(0)
, fBranchCount(0)
{
Init(tree,0,name,pointer,basketsize,compress,splitlevel);
}
TBranchClones::TBranchClones(TBranch *parent, const char* name, void* pointer, Int_t basketsize, Int_t compress, Int_t splitlevel)
: TBranch()
, fList(0)
, fRead(0)
, fN(0)
, fNdataMax(0)
, fBranchCount(0)
{
Init(0,parent,name,pointer,basketsize,compress,splitlevel);
}
void TBranchClones::Init(TTree *tree, TBranch *parent, const char* name, void* pointer, Int_t basketsize, Int_t compress, Int_t splitlevel)
{
if (tree==0 && parent!=0) tree = parent->GetTree();
fTree = tree;
fMother = parent ? parent->GetMother() : this;
fParent = parent;
TString leaflist;
TString branchname;
TString branchcount;
SetName(name);
if ((compress == -1) && tree->GetDirectory()) {
TFile* bfile = 0;
if (tree->GetDirectory()) {
bfile = tree->GetDirectory()->GetFile();
}
if (bfile) {
compress = bfile->GetCompressionLevel();
}
}
char* cpointer = (char*) pointer;
char** ppointer = (char**) pointer;
fList = (TClonesArray*) *ppointer;
fAddress = cpointer;
TClass* cl = fList->GetClass();
if (!cl) {
return;
}
tree->BuildStreamerInfo(cl);
fClassName = cl->GetName();
fSplitLevel = splitlevel;
if (basketsize < 100) {
basketsize = 100;
}
leaflist.Form("%s_/I", name);
branchcount.Form("%s_", name);
fBranchCount = new TBranch(this, branchcount, &fN, leaflist, basketsize);
fBranchCount->SetBit(kIsClone);
TLeaf* leafcount = (TLeaf*) fBranchCount->GetListOfLeaves()->UncheckedAt(0);
fDirectory = fTree->GetDirectory();
fFileName = "";
const char* itype = 0;
TRealData* rd = 0;
TIter next(cl->GetListOfRealData());
while ((rd = (TRealData *) next())) {
if (rd->TestBit(TRealData::kTransient)) continue;
if (rd->IsObject()) {
continue;
}
TDataMember* member = rd->GetDataMember();
if (!member->IsPersistent()) {
continue;
}
if (!member->IsBasic() || member->IsaPointer()) {
Warning("BranchClones", "Cannot process: %s::%s", cl->GetName(), member->GetName());
continue;
}
if ((splitlevel > 1) || fList->TestBit(TClonesArray::kForgetBits) || cl->CanIgnoreTObjectStreamer()) {
if (!std::strcmp(member->GetName(), "fBits")) {
continue;
}
if (!std::strcmp(member->GetName(), "fUniqueID")) {
continue;
}
}
tree->BuildStreamerInfo(TClass::GetClass(member->GetFullTypeName()));
TDataType* membertype = member->GetDataType();
Int_t type = membertype->GetType();
if (!type) {
Warning("BranchClones", "Cannot process: %s::%s of type zero!", cl->GetName(), member->GetName());
continue;
}
if (type == 1) {
itype = "B";
} else if (type == 2) {
itype = "S";
} else if (type == 3) {
itype = "I";
} else if (type == 5) {
itype = "F";
} else if (type == 8) {
itype = "D";
} else if (type == 9) {
itype = "D";
} else if (type == 11) {
itype = "b";
} if (type == 12) {
itype = "s";
} if (type == 13) {
itype = "i";
}
leaflist.Form("%s[%s]/%s", member->GetName(), branchcount.Data(), itype);
Int_t comp = compress;
if (type == 5) {
comp--;
}
branchname.Form("%s.%s", name, rd->GetName());
TBranch* branch = new TBranch(this, branchname, this, leaflist, basketsize, comp);
branch->SetBit(kIsClone);
TObjArray* leaves = branch->GetListOfLeaves();
TLeaf* leaf = (TLeaf*) leaves->UncheckedAt(0);
leaf->SetOffset(rd->GetThisOffset());
leaf->SetLeafCount(leafcount);
Int_t arraydim = member->GetArrayDim();
if (arraydim) {
Int_t maxindex = 1;
while (arraydim) {
maxindex *= member->GetMaxIndex(--arraydim);
}
leaf->SetLen(maxindex);
}
fBranches.Add(branch);
}
}
TBranchClones::~TBranchClones()
{
delete fBranchCount;
fBranchCount = 0;
fBranches.Delete();
fList = 0;
}
void TBranchClones::Browse(TBrowser* b)
{
fBranches.Browse(b);
}
Int_t TBranchClones::Fill()
{
Int_t i = 0;
Int_t nbytes = 0;
Int_t nbranches = fBranches.GetEntriesFast();
char** ppointer = (char**) fAddress;
if (!ppointer) {
return 0;
}
fList = (TClonesArray*) *ppointer;
fN = fList->GetEntriesFast();
fEntries++;
if (fN > fNdataMax) {
fNdataMax = fList->GetSize();
TString branchcount;
branchcount.Form("%s_", GetName());
TLeafI* leafi = (TLeafI*) fBranchCount->GetLeaf(branchcount);
leafi->SetMaximum(fNdataMax);
for (i = 0; i < nbranches; i++) {
TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
TObjArray* leaves = branch->GetListOfLeaves();
TLeaf* leaf = (TLeaf*) leaves->UncheckedAt(0);
leaf->SetAddress();
}
}
nbytes += fBranchCount->Fill();
for (i = 0; i < nbranches; i++) {
TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
TObjArray* leaves = branch->GetListOfLeaves();
TLeaf* leaf = (TLeaf*) leaves->UncheckedAt(0);
leaf->Import(fList, fN);
nbytes += branch->Fill();
}
return nbytes;
}
Int_t TBranchClones::GetEntry(Long64_t entry, Int_t getall)
{
if (TestBit(kDoNotProcess) && !getall) {
return 0;
}
Int_t nbytes = fBranchCount->GetEntry(entry, getall);
TLeaf* leafcount = (TLeaf*) fBranchCount->GetListOfLeaves()->UncheckedAt(0);
fN = Int_t(leafcount->GetValue());
if (fN <= 0) {
if (fList) {
fList->Clear();
}
return 0;
}
TBranch* branch = 0;
Int_t nbranches = fBranches.GetEntriesFast();
if (fList) {
fList->Clear();
fList->ExpandCreateFast(fN);
for (Int_t i = 0; i < nbranches; i++) {
branch = (TBranch*) fBranches.UncheckedAt(i);
if (((TLeaf*) branch->GetListOfLeaves()->UncheckedAt(0))->GetOffset() < 0) {
continue;
}
nbytes += branch->GetEntryExport(entry, getall, fList, fN);
}
} else {
for (Int_t i = 0; i < nbranches; i++) {
branch = (TBranch*) fBranches.UncheckedAt(i);
nbytes += branch->GetEntry(entry, getall);
}
}
return nbytes;
}
void TBranchClones::Print(Option_t *option) const
{
fBranchCount->Print(option);
Int_t nbranches = fBranches.GetEntriesFast();
for (Int_t i = 0; i < nbranches; i++) {
TBranch* branch = (TBranch*) fBranches.At(i);
branch->Print(option);
}
}
void TBranchClones::Reset(Option_t* option)
{
fEntries = 0;
fTotBytes = 0;
fZipBytes = 0;
Int_t nbranches = fBranches.GetEntriesFast();
for (Int_t i = 0; i < nbranches; i++) {
TBranch* branch = (TBranch*) fBranches.At(i);
branch->Reset(option);
}
fBranchCount->Reset();
}
void TBranchClones::SetAddress(void* addr)
{
fReadEntry = -1;
fAddress = (char*) addr;
char** pp= (char**) fAddress;
if (pp && (*pp == 0)) {
*pp= (char*) new TClonesArray(fClassName);
}
fList = 0;
if (pp) {
fList = (TClonesArray*) *pp;
}
fBranchCount->SetAddress(&fN);
}
void TBranchClones::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 TBranchClones::Streamer(TBuffer& b)
{
UInt_t R__s, R__c;
if (b.IsReading()) {
b.ReadVersion(&R__s, &R__c);
TNamed::Streamer(b);
b >> fCompress;
b >> fBasketSize;
b >> fEntryOffsetLen;
b >> fMaxBaskets;
b >> fWriteBasket;
b >> fEntryNumber;
b >> fEntries;
b >> fTotBytes;
b >> fZipBytes;
b >> fOffset;
b >> fBranchCount;
fClassName.Streamer(b);
fBranches.Streamer(b);
fTree = gTree;
TBranch* branch = 0;
TLeaf* leaf = 0;
Int_t nbranches = fBranches.GetEntriesFast();
for (Int_t i = 0; i < nbranches; i++) {
branch = (TBranch*) fBranches[i];
branch->SetBit(kIsClone);
leaf = (TLeaf*) branch->GetListOfLeaves()->UncheckedAt(0);
leaf->SetOffset(-1);
}
fRead = 1;
TClass* cl = TClass::GetClass((const char*) fClassName);
if (!cl) {
Warning("Streamer", "Unknown class: %s. Cannot read BranchClones: %s", fClassName.Data(), GetName());
SetBit(kDoNotProcess);
return;
}
if (!cl->GetListOfRealData()) {
cl->BuildRealData();
}
TString branchname;
TRealData* rd = 0;
TIter next(cl->GetListOfRealData());
while ((rd = (TRealData*) next())) {
if (rd->TestBit(TRealData::kTransient)) continue;
TDataMember* member = rd->GetDataMember();
if (!member || !member->IsBasic() || !member->IsPersistent()) {
continue;
}
TDataType* membertype = member->GetDataType();
if (!membertype->GetType()) {
continue;
}
branchname.Form("%s.%s", GetName(), rd->GetName());
branch = (TBranch*) fBranches.FindObject(branchname);
if (!branch) {
continue;
}
TObjArray* leaves = branch->GetListOfLeaves();
leaf = (TLeaf*) leaves->UncheckedAt(0);
leaf->SetOffset(rd->GetThisOffset());
}
b.CheckByteCount(R__s, R__c, TBranchClones::IsA());
} else {
R__c = b.WriteVersion(TBranchClones::IsA(), kTRUE);
TNamed::Streamer(b);
b << fCompress;
b << fBasketSize;
b << fEntryOffsetLen;
b << fMaxBaskets;
b << fWriteBasket;
b << fEntryNumber;
b << fEntries;
b << fTotBytes;
b << fZipBytes;
b << fOffset;
b << fBranchCount;
fClassName.Streamer(b);
fBranches.Streamer(b);
b.SetByteCount(R__c, kTRUE);
}
}
Last change: Fri Sep 19 09:32:29 2008
Last generated: 2008-09-19 09:32
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.