#include "TBranchProxy.h"
#include "TLeaf.h"
#include "TBranchElement.h"
#include "TStreamerElement.h"
#include "TStreamerInfo.h"
ClassImp(ROOT::TBranchProxy);
ROOT::TBranchProxy::TBranchProxy() :
fDirector(0), fInitialized(false), fBranchName(""), fParent(0),
fDataMember(""), fIsMember(false), fIsClone(false), fIsaPointer(0),
fClassName(""), fClass(0), fElement(0), fMemberOffset(0), fOffset(0),
fBranch(0), fBranchCount(0),
fLastTree(0), fRead(-1), fWhere(0),fCollection(0), fCurrentTreeNumber(-1)
{
};
ROOT::TBranchProxy::TBranchProxy(TBranchProxyDirector* boss, const char* top,
const char* name) :
fDirector(boss), fInitialized(false), fBranchName(top), fParent(0),
fDataMember(""), fIsMember(false), fIsClone(false), fIsaPointer(false),
fClassName(""), fClass(0), fElement(0), fMemberOffset(0), fOffset(0),
fBranch(0), fBranchCount(0),
fLastTree(0), fRead(-1), fWhere(0),fCollection(0), fCurrentTreeNumber(-1)
{
if (fBranchName.Length() && fBranchName[fBranchName.Length()-1]!='.' && name) {
((TString&)fBranchName).Append(".");
}
if (name) ((TString&)fBranchName).Append(name);
boss->Attach(this);
}
ROOT::TBranchProxy::TBranchProxy(TBranchProxyDirector* boss, const char *top, const char *name, const char *membername) :
fDirector(boss), fInitialized(false), fBranchName(top), fParent(0),
fDataMember(membername), fIsMember(true), fIsClone(false), fIsaPointer(false),
fClassName(""), fClass(0), fElement(0), fMemberOffset(0), fOffset(0),
fBranch(0), fBranchCount(0),
fLastTree(0), fRead(-1), fWhere(0),fCollection(0), fCurrentTreeNumber(-1)
{
if (name && strlen(name)) {
if (fBranchName.Length() && fBranchName[fBranchName.Length()-1]!='.') {
((TString&)fBranchName).Append(".");
}
((TString&)fBranchName).Append(name);
}
boss->Attach(this);
}
ROOT::TBranchProxy::TBranchProxy(TBranchProxyDirector* boss, TBranchProxy *parent, const char* membername, const char* top,
const char* name) :
fDirector(boss), fInitialized(false), fBranchName(top), fParent(parent),
fDataMember(membername), fIsMember(true), fIsClone(false), fIsaPointer(false),
fClassName(""), fClass(0), fElement(0), fMemberOffset(0), fOffset(0),
fBranch(0), fBranchCount(0),
fLastTree(0), fRead(-1), fWhere(0),fCollection(0), fCurrentTreeNumber(-1)
{
if (name && strlen(name)) {
if (fBranchName.Length() && fBranchName[fBranchName.Length()-1]!='.') {
((TString&)fBranchName).Append(".");
}
((TString&)fBranchName).Append(name);
}
boss->Attach(this);
}
ROOT::TBranchProxy::TBranchProxy(TBranchProxyDirector* boss, TBranch* branch, const char* membername) :
fDirector(boss), fInitialized(false), fBranchName(branch->GetName()), fParent(0),
fDataMember(membername), fIsMember(membername != 0 && membername[0]), fIsClone(false), fIsaPointer(false),
fClassName(""), fClass(0), fElement(0), fMemberOffset(0), fOffset(0),
fBranch(0), fBranchCount(0),
fLastTree(0), fRead(-1), fWhere(0),fCollection(0), fCurrentTreeNumber(-1)
{
boss->Attach(this);
}
ROOT::TBranchProxy::~TBranchProxy()
{
}
void ROOT::TBranchProxy::Reset()
{
fWhere = 0;
fBranch = 0;
fBranchCount = 0;
fRead = -1;
fClass = 0;
fElement = 0;
fMemberOffset = 0;
fIsClone = false;
fInitialized = false;
fLastTree = 0;
delete fCollection;
fCollection = 0;
fCurrentTreeNumber = -1;
}
void ROOT::TBranchProxy::Print()
{
std::cout << "fBranchName " << fBranchName << std::endl;
std::cout << "fBranch " << fBranch << std::endl;
if (fBranchCount) std::cout << "fBranchCount " << fBranchCount << std::endl;
}
Bool_t ROOT::TBranchProxy::Setup()
{
if (!fDirector->GetTree()) {
return false;
}
if (fParent) {
if (!fParent->Setup()) {
return false;
}
TClass *pcl = fParent->GetClass();
R__ASSERT(pcl);
if (pcl==TClonesArray::Class()) {
Int_t i = fDirector->GetReadEntry();
if (i<0) fDirector->SetReadEntry(0);
if (fParent->Read()) {
if (i<0) fDirector->SetReadEntry(i);
TClonesArray *clones;
clones = (TClonesArray*)fParent->GetStart();
if (clones) pcl = clones->GetClass();
}
} else if (pcl->GetCollectionProxy()) {
if (fCollection) delete fCollection;
fCollection = pcl->GetCollectionProxy()->Generate();
pcl = fCollection->GetValueClass();
if (pcl == 0) {
Error("Setup","Not finding TClass for collecion for the data member %s seems no longer be in class %s",fDataMember.Data(),fParent->GetClass()->GetName());
return false;
}
}
fElement = (TStreamerElement*)pcl->GetStreamerInfo()->GetElements()->FindObject(fDataMember);
if (fElement == 0) {
Error("Setup","Data member %s seems no longer be in class %s",fDataMember.Data(),pcl->GetName());
return false;
}
fIsaPointer = fElement->IsaPointer();
fClass = fElement->GetClassPointer();
fIsClone = (fClass==TClonesArray::Class());
fOffset = fMemberOffset = fElement->GetOffset();
fWhere = fParent->fWhere;
if (fParent->IsaPointer()) {
} else {
}
} else if (!fBranch || fCurrentTreeNumber != fDirector->GetTree()->GetTreeNumber() || fLastTree != fDirector->GetTree()) {
fBranch = fDirector->GetTree()->GetBranch(fBranchName.Data());
if (!fBranch) return false;
{
TLeaf *leaf = (TLeaf*) fBranch->GetListOfLeaves()->At(0);
if (leaf) leaf = leaf->GetLeafCount();
if (leaf) {
fBranchCount = leaf->GetBranch();
}
}
fWhere = (double*)fBranch->GetAddress();
if (!fWhere && fBranch->IsA()==TBranchElement::Class()
&& ((TBranchElement*)fBranch)->GetMother()) {
TBranchElement* be = ((TBranchElement*)fBranch);
be->GetMother()->SetAddress(0);
fWhere = (double*)fBranch->GetAddress();
}
if (fBranch->IsA()==TBranch::Class()) {
TLeaf *leaf2;
if (fDataMember.Length()) {
leaf2 = fBranch->GetLeaf(fDataMember);
if (leaf2) fWhere = leaf2->GetValuePointer();
} else if (!fWhere) {
leaf2 = (TLeaf*)fBranch->GetListOfLeaves()->At(0);
fWhere = leaf2->GetValuePointer();
}
}
if (!fWhere) {
fBranch->SetAddress(0);
fWhere = (double*)fBranch->GetAddress();
}
if (fWhere && fBranch->IsA()==TBranchElement::Class()) {
TBranchElement* be = ((TBranchElement*)fBranch);
TStreamerInfo * info = be->GetInfo();
Int_t id = be->GetID();
if (id>=0) {
fOffset = info->GetElementOffset(id);
fElement = (TStreamerElement*)info->GetElements()->At(id);
fIsaPointer = fElement->IsaPointer();
fClass = fElement->GetClassPointer();
if ((fIsMember || (be->GetType()!=3 && be->GetType() !=4))
&& (be->GetType()!=31 && be->GetType()!=41)) {
if (fClass==TClonesArray::Class()) {
Int_t i = be->GetTree()->GetReadEntry();
if (i<0) i = 0;
be->GetEntry(i);
TClonesArray *clones;
if ( fIsMember && be->GetType()==3 ) {
clones = (TClonesArray*)be->GetObject();
} else if (fIsaPointer) {
clones = (TClonesArray*)*(void**)((char*)fWhere+fOffset);
} else {
clones = (TClonesArray*)((char*)fWhere+fOffset);
}
if (!fIsMember) fIsClone = true;
fClass = clones->GetClass();
} else if (fClass && fClass->GetCollectionProxy()) {
delete fCollection;
fCollection = fClass->GetCollectionProxy()->Generate();
fClass = fCollection->GetValueClass();
}
}
if (fClass) fClassName = fClass->GetName();
} else {
fClassName = be->GetClassName();
fClass = TClass::GetClass(fClassName);
}
if (be->GetType()==3) {
if (!fIsMember) fIsClone = true;
fIsaPointer = false;
fWhere = be->GetObject();
} else if (be->GetType()==4) {
fCollection = be->GetCollectionProxy()->Generate();
fIsaPointer = false;
fWhere = be->GetObject();
} else if (id<0) {
fIsaPointer = false;
fWhere = be->GetObject();
} else if (be->GetType()==41) {
fCollection = be->GetCollectionProxy()->Generate();
fWhere = be->GetObject();
fOffset += be->GetOffset();
} else if (be->GetType()==31) {
fWhere = be->GetObject();
fOffset += be->GetOffset();
} else if (be->GetType()==2) {
fWhere = be->GetObject();
} else {
fWhere = ((unsigned char*)be->GetObject()) + fOffset;
}
} else {
fClassName = fBranch->GetClassName();
fClass = TClass::GetClass(fClassName);
}
if ( fBranch->IsA()==TBranchElement::Class() &&
(((TBranchElement*)fBranch)->GetType()==3 || fClass==TClonesArray::Class()) &&
!fIsMember ) {
fIsClone = true;
}
if (fIsMember) {
if ( fBranch->IsA()==TBranchElement::Class() &&
fClass==TClonesArray::Class() &&
(((TBranchElement*)fBranch)->GetType()==31 || ((TBranchElement*)fBranch)->GetType()==3) ) {
TBranchElement *bcount = ((TBranchElement*)fBranch)->GetBranchCount();
TString member;
if (bcount) {
TString bname = fBranch->GetName();
TString bcname = bcount->GetName();
member = bname.Remove(0,bcname.Length()+1);
} else {
member = fDataMember;
}
fMemberOffset = fClass->GetDataMemberOffset(member);
if (fMemberOffset<0) {
Error("Setup","%s",Form("Negative offset %d for %s in %s",
fMemberOffset,fBranch->GetName(),
bcount?bcount->GetName():"unknown"));
}
} else if (fClass) {
fElement = (TStreamerElement*)
fClass->GetStreamerInfo()->GetElements()->FindObject(fDataMember);
if (fElement)
fMemberOffset = fElement->GetOffset();
else {
TString member;
member += fDataMember;
fMemberOffset = fClass->GetDataMemberOffset(member);
}
} else if (fBranch->IsA() != TBranch::Class() && fElement->IsA() != TStreamerBasicType::Class()) {
Error("Setup","%s",Form("Missing TClass object for %s\n",fClassName.Data()));
}
if ( fBranch->IsA()==TBranchElement::Class()
&& (((TBranchElement*)fBranch)->GetType()==31 || ((TBranchElement*)fBranch)->GetType()==3) ) {
fOffset = fMemberOffset;
} else {
fWhere = ((unsigned char*)fWhere) + fMemberOffset;
}
}
}
if (fClass==TClonesArray::Class()) fIsClone = true;
if (fWhere!=0) {
if (fCollection) {
if (IsaPointer()) {
fCollection->PushProxy( *(void**)fWhere );
} else {
fCollection->PushProxy( fWhere );
}
}
fLastTree = fDirector->GetTree();
fCurrentTreeNumber = fLastTree->GetTreeNumber();
fInitialized = true;
return true;
} else {
return false;
}
}