Logo ROOT   6.12/07
Reference Guide
TBranchProxy.cxx
Go to the documentation of this file.
1 // @(#)root/base:$Id$
2 // Author: Philippe Canal 13/05/2003
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun, Fons Rademakers and al. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /** \class ROOT::Detail::TBranchProxy
13 Base class for all the proxy object. It includes the imeplemtation
14 of the autoloading of branches as well as all the generic setup routine.
15 */
16 
17 #include "TBranchProxy.h"
18 #include "TLeaf.h"
19 #include "TBranchElement.h"
20 #include "TStreamerElement.h"
21 #include "TStreamerInfo.h"
22 
24 
25 using namespace ROOT::Internal;
26 
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),
32  fLastTree(0), fRead(-1), fWhere(0),fCollection(0), fCurrentTreeNumber(-1)
33 {
34  // Constructor.
35 };
36 
38  const char* name) :
39  fDirector(boss), fInitialized(false), fIsMember(false), fIsClone(false), fIsaPointer(false),
40  fHasLeafCount(false), fBranchName(top), fParent(0), fDataMember(""),
42  fBranch(0), fBranchCount(0),
44 {
45  // Constructor.
46 
47  if (fBranchName.Length() && fBranchName[fBranchName.Length()-1]!='.' && name) {
48  ((TString&)fBranchName).Append(".");
49  }
50  if (name) ((TString&)fBranchName).Append(name);
51  boss->Attach(this);
52 }
53 
54 ROOT::Detail::TBranchProxy::TBranchProxy(TBranchProxyDirector* boss, const char *top, const char *name, const char *membername) :
55  fDirector(boss), fInitialized(false), fIsMember(true), fIsClone(false), fIsaPointer(false),
56  fHasLeafCount(false), fBranchName(top), fParent(0), fDataMember(membername),
58  fBranch(0), fBranchCount(0),
60 {
61  // Constructor.
62 
63  if (name && strlen(name)) {
64  if (fBranchName.Length() && fBranchName[fBranchName.Length()-1]!='.') {
65  ((TString&)fBranchName).Append(".");
66  }
67  ((TString&)fBranchName).Append(name);
68  }
69  boss->Attach(this);
70 }
71 
72 ROOT::Detail::TBranchProxy::TBranchProxy(TBranchProxyDirector* boss, Detail::TBranchProxy *parent, const char* membername, const char* top,
73  const char* name) :
74  fDirector(boss), fInitialized(false), fIsMember(true), fIsClone(false), fIsaPointer(false),
75  fHasLeafCount(false), fBranchName(top), fParent(parent), fDataMember(membername),
77  fBranch(0), fBranchCount(0),
79 {
80  // Constructor.
81 
82  if (name && strlen(name)) {
83  if (fBranchName.Length() && fBranchName[fBranchName.Length()-1]!='.') {
84  ((TString&)fBranchName).Append(".");
85  }
86  ((TString&)fBranchName).Append(name);
87  }
88  boss->Attach(this);
89 }
90 
92  fDirector(boss), fInitialized(false), fIsMember(membername != 0 && membername[0]), fIsClone(false), fIsaPointer(false),
93  fHasLeafCount(false), fBranchName(branch->GetName()), fParent(0), fDataMember(membername),
95  fBranch(0), fBranchCount(0),
97 {
98  // Constructor.
99 
100  boss->Attach(this);
101 }
102 
104 {
105  // Typical Destructor
106 }
107 
109 {
110  // Completely reset the object.
111 
112  fWhere = 0;
113  fBranch = 0;
114  fBranchCount = 0;
115  fRead = -1;
116  fClass = 0;
117  fElement = 0;
118  fMemberOffset = 0;
119  fOffset = 0;
120  fArrayLength = 1;
121  fIsClone = false;
122  fInitialized = false;
123  fHasLeafCount = false;
124  fLastTree = 0;
125  delete fCollection;
126  fCollection = 0;
127  fCurrentTreeNumber = -1;
128 }
129 
131 {
132  // Display the content of the object
133 
134  std::cout << "fBranchName " << fBranchName << std::endl;
135  //std::cout << "fTree " << fDirector->fTree << std::endl;
136  std::cout << "fBranch " << fBranch << std::endl;
137  if (fBranchCount) std::cout << "fBranchCount " << fBranchCount << std::endl;
138 }
139 
141 {
142  // Initialize/cache the necessary information.
143 
144  // Should we check the type?
145 
146  if (!fDirector->GetTree()) {
147  return false;
148  }
149  if (fParent) {
150 
151  if (!fParent->Setup()) {
152  return false;
153  }
154 
155  TClass *pcl = fParent->GetClass();
156  R__ASSERT(pcl);
157 
158  if (pcl==TClonesArray::Class()) {
159  // We always skip the clones array
160 
162  if (i<0) fDirector->SetReadEntry(0);
163  if (fParent->Read()) {
164  if (i<0) fDirector->SetReadEntry(i);
165 
166  TClonesArray *clones;
167  clones = (TClonesArray*)fParent->GetStart();
168 
169  if (clones) pcl = clones->GetClass();
170  }
171  } else if (pcl->GetCollectionProxy()) {
172  // We always skip the collections.
173 
174  if (fCollection) delete fCollection;
176  pcl = fCollection->GetValueClass();
177  if (pcl == 0) {
178  // coverity[dereference] fparent is checked jus a bit earlier and can not be null here
179  Error("Setup","Not finding TClass for collecion for the data member %s seems no longer be in class %s",fDataMember.Data(),fParent->GetClass()->GetName());
180  return false;
181  }
182  }
183 
185  if (fElement == 0) {
186  Error("Setup","Data member %s seems no longer be in class %s",fDataMember.Data(),pcl->GetName());
187  return false;
188  }
189 
192 
193 
195 
197 
199 
200  fWhere = fParent->fWhere; // not really used ... it is reset by GetStart and GetClStart
201 
202  if (fParent->IsaPointer()) {
203  // fprintf(stderr,"non-split pointer de-referencing non implemented yet \n");
204  // nothing to do!
205  } else {
206  // Accumulate offsets.
207  // or not!? fOffset = fMemberOffset = fMemberOffset + fParent->fOffset;
208  }
209 
210  // This is not sufficient for following pointers
211 
212  } else if (!fBranch || fCurrentTreeNumber != fDirector->GetTree()->GetTreeNumber() || fLastTree != fDirector->GetTree()) {
213 
214  // This does not allow (yet) to precede the branch name with
215  // its mother's name
216  fBranch = fDirector->GetTree()->GetBranch(fBranchName.Data());
217  if (!fBranch) return false;
218 
219  {
220  // Calculate fBranchCount for a leaf.
221  TLeaf *leaf = (TLeaf*) fBranch->GetListOfLeaves()->At(0); // fBranch->GetLeaf(fLeafname);
222  if (leaf) leaf = leaf->GetLeafCount();
223  if (leaf) {
224  fBranchCount = leaf->GetBranch();
225  // fprintf(stderr,"for leaf %s setting up leafcount %s branchcount %s\n",
226  // fBranch->GetName(),leaf->GetName(),fBranchCount->GetName());
227  //fBranchCount->Print();
228  }
229  }
230 
231  fWhere = (double*)fBranch->GetAddress();
232 
233  if (!fWhere && fBranch->IsA()==TBranchElement::Class()
234  && ((TBranchElement*)fBranch)->GetMother()) {
235 
237 
238  be->GetMother()->SetAddress(0);
239  fWhere = (double*)fBranch->GetAddress();
240 
241  }
242  if (fBranch->IsA()==TBranch::Class()) {
243  TLeaf *leaf2 = nullptr;
244  if (fDataMember.Length()) {
245  leaf2 = fBranch->GetLeaf(fDataMember);
246  } else if (!fWhere) {
247  leaf2 = (TLeaf*)fBranch->GetListOfLeaves()->At(0); // fBranch->GetLeaf(fLeafname);
248  fWhere = leaf2->GetValuePointer();
249  }
250  if (leaf2) {
251  fWhere = leaf2->GetValuePointer();
252  fArrayLength = leaf2->GetLen();
253  if (leaf2->GetLeafCount()) {
254  fLeafCount = leaf2->GetLeafCount();
255  fHasLeafCount = true;
256  }
257  }
258  }
259 
260  if (!fWhere) {
261  fBranch->SetAddress(0);
262  fWhere = (double*)fBranch->GetAddress();
263  }
264 
265 
266  if (fWhere && fBranch->IsA()==TBranchElement::Class()) {
267 
269 
270  TStreamerInfo * info = be->GetInfo();
271  Int_t id = be->GetID();
272  if (id>=0) {
273  fOffset = info->GetElementOffset(id);
274  fElement = (TStreamerElement*)info->GetElements()->At(id);
277 
278  if ((fIsMember || (be->GetType()!=3 && be->GetType() !=4))
279  && (be->GetType()!=31 && be->GetType()!=41)) {
280 
281  if (fClass==TClonesArray::Class()) {
282  Int_t i = be->GetTree()->GetReadEntry();
283  if (i<0) i = 0;
284  be->GetEntry(i);
285 
286  TClonesArray *clones;
287  if ( fIsMember && be->GetType()==3 ) {
288  clones = (TClonesArray*)be->GetObject();
289  } else if (fIsaPointer) {
290  clones = (TClonesArray*)*(void**)((char*)fWhere+fOffset);
291  } else {
292  clones = (TClonesArray*)((char*)fWhere+fOffset);
293  }
294  if (!fIsMember) fIsClone = true;
295  fClass = clones->GetClass();
296  } else if (fClass && fClass->GetCollectionProxy()) {
297  delete fCollection;
300  }
301 
302  }
303  if (fClass) fClassName = fClass->GetName();
304  } else {
305  fClassName = be->GetClassName();
307  }
308 
309  if (be->GetType()==3) {
310  // top level TClonesArray
311 
312  if (!fIsMember) fIsClone = true;
313  fIsaPointer = false;
314  fWhere = be->GetObject();
315 
316  } else if (be->GetType()==4) {
317  // top level TClonesArray
318 
320  fIsaPointer = false;
321  fWhere = be->GetObject();
322 
323  } else if (id<0) {
324  // top level object
325 
326  fIsaPointer = false;
327  fWhere = be->GetObject();
328 
329  } else if (be->GetType()==41) {
330 
332  fWhere = be->GetObject();
333  fOffset += be->GetOffset();
334 
335  } else if (be->GetType()==31) {
336 
337  fWhere = be->GetObject();
338  fOffset += be->GetOffset();
339 
340  } else if (be->GetType()==2) {
341  // this might also be the right path for GetType()==1
342 
343  fWhere = be->GetObject();
344 
345  } else {
346 
347  // fWhere = ((unsigned char*)fWhere) + fOffset;
348  fWhere = ((unsigned char*)be->GetObject()) + fOffset;
349 
350  }
351  } else {
354  }
355 
356 
357  /*
358  fClassName = fBranch->GetClassName(); // What about TClonesArray?
359  if ( fBranch->IsA()==TBranchElement::Class() &&
360  ((TBranchElement*)fBranch)->GetType()==31 ||((TBranchElement*)fBranch)->GetType()==3 ) {
361 
362  Int_t id = ((TBranchElement*)fBranch)->GetID();
363  if (id>=0) {
364 
365  fElement = ((TStreamerElement*)(((TBranchElement*)fBranch)->GetInfo())->GetElements()->At(id));
366  fClass = fElement->GetClassPointer();
367  if (fClass) fClassName = fClass->GetName();
368 
369  }
370  }
371  if (fClass==0 && fClassName.Length()) fClass = TClass::GetClass(fClassName);
372  */
373  //fprintf(stderr,"For %s fClass is %p which is %s\n",
374  // fBranchName.Data(),fClass,fClass==0?"not set":fClass->GetName());
375 
376  if ( fBranch->IsA()==TBranchElement::Class() &&
377  (((TBranchElement*)fBranch)->GetType()==3 || fClass==TClonesArray::Class()) &&
378  !fIsMember ) {
379  fIsClone = true;
380  }
381 
382  if (fIsMember) {
383  if ( fBranch->IsA()==TBranchElement::Class() &&
385  (((TBranchElement*)fBranch)->GetType()==31 || ((TBranchElement*)fBranch)->GetType()==3) ) {
386 
388  TString member;
389  if (bcount) {
390  TString bname = fBranch->GetName();
391  TString bcname = bcount->GetName();
392  member = bname.Remove(0,bcname.Length()+1);
393  } else {
394  member = fDataMember;
395  }
396 
398 
399  if (fMemberOffset<0) {
400  Error("Setup","%s",Form("Negative offset %d for %s in %s",
402  bcount?bcount->GetName():"unknown"));
403  }
404 
405  } else if (fClass) {
406 
409  if (fElement)
411  else {
412  // Need to compose the proper sub name
413 
414  TString member;
415 
416  member += fDataMember;
418 
419  }
420  // The extra condition (fElement is not a TStreamerSTL) is to handle the case where fBranch is a
421  // TBranchElement and fElement is a TStreamerSTL. Without the extra condition we get an error
422  // message, although the vector (i.e. the TBranchElement) is accessible.
423  } else if (fBranch->IsA() != TBranch::Class() && fElement->IsA() != TStreamerBasicType::Class()
424  && fElement->IsA() != TStreamerSTL::Class()) {
425  Error("Setup","%s",Form("Missing TClass object for %s\n",fClassName.Data()));
426  }
427 
428  if ( fBranch->IsA()==TBranchElement::Class()
429  && (((TBranchElement*)fBranch)->GetType()==31 || ((TBranchElement*)fBranch)->GetType()==3) ) {
430 
432 
433  } else {
434 
435  fWhere = ((unsigned char*)fWhere) + fMemberOffset;
436  }
437  }
438  }
439  if (fClass==TClonesArray::Class()) fIsClone = true;
440  if (fWhere!=0) {
442  fCurrentTreeNumber = fLastTree->GetTreeNumber();
443  fInitialized = true;
444  return true;
445  } else {
446  return false;
447  }
448 }
Describe Streamer information for one class version.
Definition: TStreamerInfo.h:43
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
virtual const char * GetClassName() const
Return the name of the user class whose content is stored in this branch, if any. ...
Definition: TBranch.cxx:1266
std::string GetName(const std::string &scope_name)
Definition: Cppyy.cxx:145
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
Definition: TLeaf.h:32
TVirtualCollectionProxy * GetCollectionProxy()
Return the collection proxy describing the branch content, if any.
virtual void SetAddress(void *add)
Set address of this branch.
Definition: TBranch.cxx:2240
Int_t GetType() const
virtual TClass * GetValueClass() const =0
virtual TClass * GetClassPointer() const
Returns a pointer to the TClass of this element.
TVirtualStreamerInfo * GetStreamerInfo(Int_t version=0) const
returns a pointer to the TVirtualStreamerInfo object for version If the object does not exist...
Definition: TClass.cxx:4420
TStreamerInfo * GetInfo() const
Get streamer info for the branch class.
#define R__ASSERT(e)
Definition: TError.h:96
TStreamerElement * fElement
Definition: TBranchProxy.h:84
Int_t GetOffset() const
Definition: TBranch.h:183
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition: TClass.cxx:2816
virtual void * GetStart(UInt_t=0)
Definition: TBranchProxy.h:221
Int_t GetArrayLength() const
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
TObject * At(Int_t idx) const
Definition: TObjArray.h:165
TBranchElement * GetBranchCount() const
void Class()
Definition: Class.C:29
virtual TObject * FindObject(const char *name) const
Find an object in this collection using its name.
Definition: TObjArray.cxx:414
virtual TLeaf * GetLeaf(const char *name) const
Return pointer to the 1st Leaf named name in thisBranch.
Definition: TBranch.cxx:1636
Int_t GetID() const
virtual Int_t GetEntry(Long64_t entry=0, Int_t getall=0)
Read all branches of a BranchElement and return total number of bytes.
virtual Int_t GetLen() const
Return the number of effective elements of this leaf.
Definition: TLeaf.cxx:307
char * GetObject() const
Return a pointer to our object.
char * Form(const char *fmt,...)
virtual TLeaf * GetLeafCount() const
Definition: TLeaf.h:72
virtual void * GetValuePointer() const
Definition: TLeaf.h:81
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:75
Int_t GetElementOffset(Int_t id) const
A Branch for the case of an object.
#define ClassImp(name)
Definition: Rtypes.h:359
virtual TObjArray * GetElements() const =0
virtual Bool_t IsaPointer() const
virtual const char * GetClassName() const
Return the name of the user class whose content is stored in this branch, if any. ...
Long_t GetDataMemberOffset(const char *membername) const
return offset for member name.
Definition: TClass.cxx:3308
TObjArray * GetListOfLeaves()
Definition: TBranch.h:195
Internal::TBranchProxyDirector * fDirector
Definition: TBranchProxy.h:68
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2887
TClass * GetClass() const
Definition: TClonesArray.h:56
TObjArray * GetElements() const
An array of clone (identical) objects.
Definition: TClonesArray.h:32
TTree * GetTree() const
Definition: TBranch.h:200
virtual char * GetAddress() const
Definition: TBranch.h:162
Base class for all the proxy object.
Definition: TBranchProxy.h:66
TBranch * GetBranch() const
Definition: TLeaf.h:71
A TTree is a list of TBranches.
Definition: TBranch.h:59
Int_t GetOffset() const
TVirtualCollectionProxy * fCollection
Definition: TBranchProxy.h:99
TBranch * GetMother() const
Get our top-level parent branch in the tree.
Definition: TBranch.cxx:1709
char name[80]
Definition: TGX11.cxx:109
void Error(ErrorHandler_t func, int code, const char *va_(fmt),...)
Write error message and call a handler, if required.
virtual TVirtualCollectionProxy * Generate() const =0
void Attach(Detail::TBranchProxy *p)