23 ClassImp(ROOT::Detail::TBranchProxy);
25 using namespace ROOT::Internal;
27 ROOT::Detail::TBranchProxy::TBranchProxy() :
28 fDirector(0), fInitialized(false), fIsMember(false), fIsClone(false), fIsaPointer(false),
29 fHasLeafCount(false), fBranchName(
""), fParent(0), fDataMember(
""),
30 fClassName(
""), fClass(0), fElement(0), fMemberOffset(0), fOffset(0), fArrayLength(1),
31 fBranch(0), fBranchCount(0),
33 fRead(-1), fWhere(0),fCollection(0)
38 ROOT::Detail::TBranchProxy::TBranchProxy(TBranchProxyDirector* boss,
const char* top,
40 fDirector(boss), fInitialized(false), fIsMember(false), fIsClone(false), fIsaPointer(false),
41 fHasLeafCount(false), fBranchName(top), fParent(0), fDataMember(
""),
42 fClassName(
""), fClass(0), fElement(0), fMemberOffset(0), fOffset(0), fArrayLength(1),
43 fBranch(0), fBranchCount(0),
45 fRead(-1), fWhere(0),fCollection(0)
49 if (fBranchName.Length() && fBranchName[fBranchName.Length()-1]!=
'.' && name) {
50 ((TString&)fBranchName).Append(
".");
52 if (name) ((TString&)fBranchName).Append(name);
56 ROOT::Detail::TBranchProxy::TBranchProxy(TBranchProxyDirector* boss,
const char *top,
const char *name,
const char *membername) :
57 fDirector(boss), fInitialized(false), fIsMember(true), fIsClone(false), fIsaPointer(false),
58 fHasLeafCount(false), fBranchName(top), fParent(0), fDataMember(membername),
59 fClassName(
""), fClass(0), fElement(0), fMemberOffset(0), fOffset(0), fArrayLength(1),
60 fBranch(0), fBranchCount(0),
62 fRead(-1), fWhere(0),fCollection(0)
66 if (name && strlen(name)) {
67 if (fBranchName.Length() && fBranchName[fBranchName.Length()-1]!=
'.') {
68 ((TString&)fBranchName).Append(
".");
70 ((TString&)fBranchName).Append(name);
75 ROOT::Detail::TBranchProxy::TBranchProxy(TBranchProxyDirector* boss, Detail::TBranchProxy *parent,
const char* membername,
const char* top,
77 fDirector(boss), fInitialized(false), fIsMember(true), fIsClone(false), fIsaPointer(false),
78 fHasLeafCount(false), fBranchName(top), fParent(parent), fDataMember(membername),
79 fClassName(
""), fClass(0), fElement(0), fMemberOffset(0), fOffset(0), fArrayLength(1),
80 fBranch(0), fBranchCount(0),
82 fRead(-1), fWhere(0),fCollection(0)
86 if (name && strlen(name)) {
87 if (fBranchName.Length() && fBranchName[fBranchName.Length()-1]!=
'.') {
88 ((TString&)fBranchName).Append(
".");
90 ((TString&)fBranchName).Append(name);
95 ROOT::Detail::TBranchProxy::TBranchProxy(TBranchProxyDirector* boss, TBranch* branch,
const char* membername) :
96 fDirector(boss), fInitialized(false), fIsMember(membername != 0 && membername[0]), fIsClone(false), fIsaPointer(false),
97 fHasLeafCount(false), fBranchName(branch->GetName()), fParent(0), fDataMember(membername),
98 fClassName(
""), fClass(0), fElement(0), fMemberOffset(0), fOffset(0), fArrayLength(1),
99 fBranch(0), fBranchCount(0),
101 fRead(-1), fWhere(0),fCollection(0)
111 static std::string GetFriendBranchName(TTree* directorTree, TBranch* branch,
const char* fullBranchName)
115 if (directorTree->GetTree() == branch->GetTree())
116 return branch->GetName();
119 std::string sFullBranchName = fullBranchName;
120 std::string::size_type pos = sFullBranchName.rfind(branch->GetName());
121 if (pos != std::string::npos) {
122 sFullBranchName.erase(pos);
123 sFullBranchName += branch->GetName();
125 return sFullBranchName;
130 ROOT::Detail::TBranchProxy::TBranchProxy(TBranchProxyDirector* boss,
const char* branchname, TBranch* branch,
const char* membername) :
131 fDirector(boss), fInitialized(false), fIsMember(membername != 0 && membername[0]), fIsClone(false), fIsaPointer(false),
132 fHasLeafCount(false), fBranchName(GetFriendBranchName(boss->GetTree(), branch, branchname)), fParent(0), fDataMember(membername),
133 fClassName(
""), fClass(0), fElement(0), fMemberOffset(0), fOffset(0), fArrayLength(1),
134 fBranch(0), fBranchCount(0),
136 fRead(-1), fWhere(0),fCollection(0)
143 ROOT::Detail::TBranchProxy::~TBranchProxy()
146 if (fNotify.IsLinked() && fDirector && fDirector->GetTree())
147 fNotify.RemoveLink(*(fDirector->GetTree()));
150 void ROOT::Detail::TBranchProxy::Reset()
164 fInitialized =
false;
165 fHasLeafCount =
false;
170 void ROOT::Detail::TBranchProxy::Print()
174 std::cout <<
"fBranchName " << fBranchName << std::endl;
176 std::cout <<
"fBranch " << fBranch << std::endl;
177 if (fBranchCount) std::cout <<
"fBranchCount " << fBranchCount << std::endl;
180 Bool_t ROOT::Detail::TBranchProxy::Setup()
186 if (!fDirector->GetTree()) {
189 if (!fNotify.IsLinked()) {
190 fNotify.PrependLink(*fDirector->GetTree());
194 if (!fParent->Setup()) {
198 TClass *pcl = fParent->GetClass();
201 if (pcl==TClonesArray::Class()) {
204 Int_t i = fDirector->GetReadEntry();
205 if (i<0) fDirector->SetReadEntry(0);
206 if (fParent->Read()) {
207 if (i<0) fDirector->SetReadEntry(i);
209 TClonesArray *clones;
210 clones = (TClonesArray*)fParent->GetStart();
212 if (clones) pcl = clones->GetClass();
214 }
else if (pcl->GetCollectionProxy()) {
217 if (fCollection)
delete fCollection;
218 fCollection = pcl->GetCollectionProxy()->Generate();
219 pcl = fCollection->GetValueClass();
222 Error(
"Setup",
"Not finding TClass for collecion for the data member %s seems no longer be in class %s",fDataMember.Data(),fParent->GetClass()->GetName());
227 fElement = (TStreamerElement*)pcl->GetStreamerInfo()->GetStreamerElement(fDataMember, fOffset);
229 fIsaPointer = fElement->IsaPointer();
230 fClass = fElement->GetClassPointer();
231 fMemberOffset = fElement->GetOffset();
232 fArrayLength = fElement->GetArrayLength();
234 Error(
"Setup",
"Data member %s seems no longer be in class %s",fDataMember.Data(),pcl->GetName());
238 fIsClone = (fClass==TClonesArray::Class());
240 fWhere = fParent->fWhere;
242 if (fParent->IsaPointer()) {
256 fBranch = fDirector->GetTree()->GetBranch(fBranchName.Data());
270 TLeaf *leaf = (TLeaf*) fBranch->GetListOfLeaves()->At(0);
271 if (leaf) leaf = leaf->GetLeafCount();
273 fBranchCount = leaf->GetBranch();
280 fWhere = (
double*)fBranch->GetAddress();
282 if (!fWhere && fBranch->IsA()==TBranchElement::Class()
283 && ((TBranchElement*)fBranch)->GetMother()) {
285 TBranchElement* be = ((TBranchElement*)fBranch);
287 be->GetMother()->SetAddress(0);
288 fWhere = (
double*)fBranch->GetAddress();
291 if (fBranch->IsA()==TBranch::Class()) {
292 TLeaf *leaf2 =
nullptr;
293 if (fDataMember.Length()) {
294 leaf2 = fBranch->GetLeaf(fDataMember);
295 }
else if (!fWhere) {
296 leaf2 = (TLeaf*)fBranch->GetListOfLeaves()->At(0);
297 fWhere = leaf2->GetValuePointer();
300 fWhere = leaf2->GetValuePointer();
301 fArrayLength = leaf2->GetLen();
302 if (leaf2->GetLeafCount()) {
303 fLeafCount = leaf2->GetLeafCount();
304 fHasLeafCount =
true;
310 fBranch->SetAddress(0);
311 fWhere = (
double*)fBranch->GetAddress();
315 if (fWhere && fBranch->IsA()==TBranchElement::Class()) {
317 TBranchElement* be = ((TBranchElement*)fBranch);
319 TStreamerInfo * info = be->GetInfo();
320 Int_t
id = be->GetID();
321 if (be->GetType() == 3) {
322 fClassName =
"TClonesArray";
323 fClass = TClonesArray::Class();
325 fOffset = info->GetElementOffset(
id);
326 fElement = (TStreamerElement*)info->GetElements()->At(
id);
327 fIsaPointer = fElement->IsaPointer();
328 fClass = fElement->GetClassPointer();
330 if ((fIsMember || (be->GetType()!=3 && be->GetType() !=4))
331 && (be->GetType()!=31 && be->GetType()!=41)) {
333 if (fClass==TClonesArray::Class()) {
334 Int_t i = be->GetTree()->GetReadEntry();
338 TClonesArray *clones;
339 if ( fIsMember && be->GetType()==3 ) {
340 clones = (TClonesArray*)be->GetObject();
341 }
else if (fIsaPointer) {
342 clones = (TClonesArray*)*(
void**)((
char*)fWhere+fOffset);
344 clones = (TClonesArray*)((
char*)fWhere+fOffset);
346 if (!fIsMember) fIsClone =
true;
347 fClass = clones->GetClass();
348 }
else if (fClass && fClass->GetCollectionProxy()) {
350 fCollection = fClass->GetCollectionProxy()->Generate();
351 fClass = fCollection->GetValueClass();
355 if (fClass) fClassName = fClass->GetName();
357 fClassName = be->GetClassName();
358 fClass = TClass::GetClass(fClassName);
361 if (be->GetType()==3) {
364 if (!fIsMember) fIsClone =
true;
366 fWhere = be->GetObject();
368 }
else if (be->GetType()==4) {
371 fCollection = be->GetCollectionProxy()->Generate();
373 fWhere = be->GetObject();
379 fWhere = be->GetObject();
381 }
else if (be->GetType()==41) {
383 fCollection = be->GetCollectionProxy()->Generate();
384 fWhere = be->GetObject();
385 fOffset += be->GetOffset();
387 }
else if (be->GetType()==31) {
389 fWhere = be->GetObject();
390 fOffset += be->GetOffset();
392 }
else if (be->GetType()==2) {
395 fWhere = be->GetObject();
400 fWhere = ((
unsigned char*)be->GetObject()) + fOffset;
404 fClassName = fBranch->GetClassName();
405 fClass = TClass::GetClass(fClassName);
428 if ( fBranch->IsA()==TBranchElement::Class() &&
429 (((TBranchElement*)fBranch)->GetType()==3 || fClass==TClonesArray::Class()) &&
435 if ( fBranch->IsA()==TBranchElement::Class() &&
436 fClass==TClonesArray::Class() &&
437 (((TBranchElement*)fBranch)->GetType()==31 || ((TBranchElement*)fBranch)->GetType()==3) ) {
439 TBranchElement *bcount = ((TBranchElement*)fBranch)->GetBranchCount();
442 TString bname = fBranch->GetName();
443 TString bcname = bcount->GetName();
444 member = bname.Remove(0,bcname.Length()+1);
446 member = fDataMember;
449 fMemberOffset = fClass->GetDataMemberOffset(member);
451 if (fMemberOffset<0) {
452 Error(
"Setup",
"%s",Form(
"Negative offset %d for %s in %s",
453 fMemberOffset,fBranch->GetName(),
454 bcount?bcount->GetName():
"unknown"));
459 fElement = (TStreamerElement*)
460 fClass->GetStreamerInfo()->GetElements()->FindObject(fDataMember);
462 fMemberOffset = fElement->GetOffset();
468 member += fDataMember;
469 fMemberOffset = fClass->GetDataMemberOffset(member);
475 }
else if (fBranch->IsA() != TBranch::Class() && fElement->IsA() != TStreamerBasicType::Class()
476 && fElement->IsA() != TStreamerSTL::Class()) {
477 Error(
"Setup",
"%s",Form(
"Missing TClass object for %s\n",fClassName.Data()));
480 if ( fBranch->IsA()==TBranchElement::Class()
481 && (((TBranchElement*)fBranch)->GetType()==31 || ((TBranchElement*)fBranch)->GetType()==3) ) {
483 fOffset = fMemberOffset;
487 fWhere = ((
unsigned char*)fWhere) + fMemberOffset;
491 if (fClass==TClonesArray::Class()) fIsClone =
true;