Logo ROOT   6.10/09
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), fBranchName(""), fParent(0),
29  fDataMember(""), fIsMember(false), fIsClone(false), fIsaPointer(0),
30  fClassName(""), fClass(0), fElement(0), fMemberOffset(0), fOffset(0),
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), fBranchName(top), fParent(0),
40  fDataMember(""), fIsMember(false), fIsClone(false), fIsaPointer(false),
41  fClassName(""), fClass(0), fElement(0), fMemberOffset(0), fOffset(0),
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), fBranchName(top), fParent(0),
56  fDataMember(membername), fIsMember(true), fIsClone(false), fIsaPointer(false),
57  fClassName(""), fClass(0), fElement(0), fMemberOffset(0), fOffset(0),
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), fBranchName(top), fParent(parent),
75  fDataMember(membername), fIsMember(true), fIsClone(false), fIsaPointer(false),
76  fClassName(""), fClass(0), fElement(0), fMemberOffset(0), fOffset(0),
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), fBranchName(branch->GetName()), fParent(0),
93  fDataMember(membername), fIsMember(membername != 0 && membername[0]), fIsClone(false), fIsaPointer(false),
94  fClassName(""), fClass(0), fElement(0), fMemberOffset(0), fOffset(0),
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  fIsClone = false;
120  fInitialized = false;
121  fLastTree = 0;
122  delete fCollection;
123  fCollection = 0;
124  fCurrentTreeNumber = -1;
125 }
126 
128 {
129  // Display the content of the object
130 
131  std::cout << "fBranchName " << fBranchName << std::endl;
132  //std::cout << "fTree " << fDirector->fTree << std::endl;
133  std::cout << "fBranch " << fBranch << std::endl;
134  if (fBranchCount) std::cout << "fBranchCount " << fBranchCount << std::endl;
135 }
136 
138 {
139  // Initialize/cache the necessary information.
140 
141  // Should we check the type?
142 
143  if (!fDirector->GetTree()) {
144  return false;
145  }
146  if (fParent) {
147 
148  if (!fParent->Setup()) {
149  return false;
150  }
151 
152  TClass *pcl = fParent->GetClass();
153  R__ASSERT(pcl);
154 
155  if (pcl==TClonesArray::Class()) {
156  // We always skip the clones array
157 
159  if (i<0) fDirector->SetReadEntry(0);
160  if (fParent->Read()) {
161  if (i<0) fDirector->SetReadEntry(i);
162 
163  TClonesArray *clones;
164  clones = (TClonesArray*)fParent->GetStart();
165 
166  if (clones) pcl = clones->GetClass();
167  }
168  } else if (pcl->GetCollectionProxy()) {
169  // We always skip the collections.
170 
171  if (fCollection) delete fCollection;
173  pcl = fCollection->GetValueClass();
174  if (pcl == 0) {
175  // coverity[dereference] fparent is checked jus a bit earlier and can not be null here
176  Error("Setup","Not finding TClass for collecion for the data member %s seems no longer be in class %s",fDataMember.Data(),fParent->GetClass()->GetName());
177  return false;
178  }
179  }
180 
182  if (fElement == 0) {
183  Error("Setup","Data member %s seems no longer be in class %s",fDataMember.Data(),pcl->GetName());
184  return false;
185  }
186 
189 
190 
192 
194 
195  fWhere = fParent->fWhere; // not really used ... it is reset by GetStart and GetClStart
196 
197  if (fParent->IsaPointer()) {
198  // fprintf(stderr,"non-split pointer de-referencing non implemented yet \n");
199  // nothing to do!
200  } else {
201  // Accumulate offsets.
202  // or not!? fOffset = fMemberOffset = fMemberOffset + fParent->fOffset;
203  }
204 
205  // This is not sufficient for following pointers
206 
207  } else if (!fBranch || fCurrentTreeNumber != fDirector->GetTree()->GetTreeNumber() || fLastTree != fDirector->GetTree()) {
208 
209  // This does not allow (yet) to precede the branch name with
210  // its mother's name
211  fBranch = fDirector->GetTree()->GetBranch(fBranchName.Data());
212  if (!fBranch) return false;
213 
214  {
215  // Calculate fBranchCount for a leaf.
216  TLeaf *leaf = (TLeaf*) fBranch->GetListOfLeaves()->At(0); // fBranch->GetLeaf(fLeafname);
217  if (leaf) leaf = leaf->GetLeafCount();
218  if (leaf) {
219  fBranchCount = leaf->GetBranch();
220  // fprintf(stderr,"for leaf %s setting up leafcount %s branchcount %s\n",
221  // fBranch->GetName(),leaf->GetName(),fBranchCount->GetName());
222  //fBranchCount->Print();
223  }
224  }
225 
226  fWhere = (double*)fBranch->GetAddress();
227 
228  if (!fWhere && fBranch->IsA()==TBranchElement::Class()
229  && ((TBranchElement*)fBranch)->GetMother()) {
230 
232 
233  be->GetMother()->SetAddress(0);
234  fWhere = (double*)fBranch->GetAddress();
235 
236  }
237  if (fBranch->IsA()==TBranch::Class()) {
238  TLeaf *leaf2;
239  if (fDataMember.Length()) {
240  leaf2 = fBranch->GetLeaf(fDataMember);
241  if (leaf2) fWhere = leaf2->GetValuePointer();
242  } else if (!fWhere) {
243  leaf2 = (TLeaf*)fBranch->GetListOfLeaves()->At(0); // fBranch->GetLeaf(fLeafname);
244  fWhere = leaf2->GetValuePointer();
245  }
246  }
247 
248  if (!fWhere) {
249  fBranch->SetAddress(0);
250  fWhere = (double*)fBranch->GetAddress();
251  }
252 
253 
254  if (fWhere && fBranch->IsA()==TBranchElement::Class()) {
255 
257 
258  TStreamerInfo * info = be->GetInfo();
259  Int_t id = be->GetID();
260  if (id>=0) {
261  fOffset = info->GetElementOffset(id);
262  fElement = (TStreamerElement*)info->GetElements()->At(id);
265 
266  if ((fIsMember || (be->GetType()!=3 && be->GetType() !=4))
267  && (be->GetType()!=31 && be->GetType()!=41)) {
268 
269  if (fClass==TClonesArray::Class()) {
270  Int_t i = be->GetTree()->GetReadEntry();
271  if (i<0) i = 0;
272  be->GetEntry(i);
273 
274  TClonesArray *clones;
275  if ( fIsMember && be->GetType()==3 ) {
276  clones = (TClonesArray*)be->GetObject();
277  } else if (fIsaPointer) {
278  clones = (TClonesArray*)*(void**)((char*)fWhere+fOffset);
279  } else {
280  clones = (TClonesArray*)((char*)fWhere+fOffset);
281  }
282  if (!fIsMember) fIsClone = true;
283  fClass = clones->GetClass();
284  } else if (fClass && fClass->GetCollectionProxy()) {
285  delete fCollection;
288  }
289 
290  }
291  if (fClass) fClassName = fClass->GetName();
292  } else {
293  fClassName = be->GetClassName();
295  }
296 
297  if (be->GetType()==3) {
298  // top level TClonesArray
299 
300  if (!fIsMember) fIsClone = true;
301  fIsaPointer = false;
302  fWhere = be->GetObject();
303 
304  } else if (be->GetType()==4) {
305  // top level TClonesArray
306 
308  fIsaPointer = false;
309  fWhere = be->GetObject();
310 
311  } else if (id<0) {
312  // top level object
313 
314  fIsaPointer = false;
315  fWhere = be->GetObject();
316 
317  } else if (be->GetType()==41) {
318 
320  fWhere = be->GetObject();
321  fOffset += be->GetOffset();
322 
323  } else if (be->GetType()==31) {
324 
325  fWhere = be->GetObject();
326  fOffset += be->GetOffset();
327 
328  } else if (be->GetType()==2) {
329  // this might also be the right path for GetType()==1
330 
331  fWhere = be->GetObject();
332 
333  } else {
334 
335  // fWhere = ((unsigned char*)fWhere) + fOffset;
336  fWhere = ((unsigned char*)be->GetObject()) + fOffset;
337 
338  }
339  } else {
342  }
343 
344 
345  /*
346  fClassName = fBranch->GetClassName(); // What about TClonesArray?
347  if ( fBranch->IsA()==TBranchElement::Class() &&
348  ((TBranchElement*)fBranch)->GetType()==31 ||((TBranchElement*)fBranch)->GetType()==3 ) {
349 
350  Int_t id = ((TBranchElement*)fBranch)->GetID();
351  if (id>=0) {
352 
353  fElement = ((TStreamerElement*)(((TBranchElement*)fBranch)->GetInfo())->GetElements()->At(id));
354  fClass = fElement->GetClassPointer();
355  if (fClass) fClassName = fClass->GetName();
356 
357  }
358  }
359  if (fClass==0 && fClassName.Length()) fClass = TClass::GetClass(fClassName);
360  */
361  //fprintf(stderr,"For %s fClass is %p which is %s\n",
362  // fBranchName.Data(),fClass,fClass==0?"not set":fClass->GetName());
363 
364  if ( fBranch->IsA()==TBranchElement::Class() &&
365  (((TBranchElement*)fBranch)->GetType()==3 || fClass==TClonesArray::Class()) &&
366  !fIsMember ) {
367  fIsClone = true;
368  }
369 
370  if (fIsMember) {
371  if ( fBranch->IsA()==TBranchElement::Class() &&
373  (((TBranchElement*)fBranch)->GetType()==31 || ((TBranchElement*)fBranch)->GetType()==3) ) {
374 
376  TString member;
377  if (bcount) {
378  TString bname = fBranch->GetName();
379  TString bcname = bcount->GetName();
380  member = bname.Remove(0,bcname.Length()+1);
381  } else {
382  member = fDataMember;
383  }
384 
386 
387  if (fMemberOffset<0) {
388  Error("Setup","%s",Form("Negative offset %d for %s in %s",
390  bcount?bcount->GetName():"unknown"));
391  }
392 
393  } else if (fClass) {
394 
397  if (fElement)
399  else {
400  // Need to compose the proper sub name
401 
402  TString member;
403 
404  member += fDataMember;
406 
407  }
408  // The extra condition (fElement is not a TStreamerSTL) is to handle the case where fBranch is a
409  // TBranchElement and fElement is a TStreamerSTL. Without the extra condition we get an error
410  // message, although the vector (i.e. the TBranchElement) is accessible.
411  } else if (fBranch->IsA() != TBranch::Class() && fElement->IsA() != TStreamerBasicType::Class()
412  && fElement->IsA() != TStreamerSTL::Class()) {
413  Error("Setup","%s",Form("Missing TClass object for %s\n",fClassName.Data()));
414  }
415 
416  if ( fBranch->IsA()==TBranchElement::Class()
417  && (((TBranchElement*)fBranch)->GetType()==31 || ((TBranchElement*)fBranch)->GetType()==3) ) {
418 
420 
421  } else {
422 
423  fWhere = ((unsigned char*)fWhere) + fMemberOffset;
424  }
425  }
426  }
427  if (fClass==TClonesArray::Class()) fIsClone = true;
428  if (fWhere!=0) {
430  fCurrentTreeNumber = fLastTree->GetTreeNumber();
431  fInitialized = true;
432  return true;
433  } else {
434  return false;
435  }
436 }
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:1256
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:2148
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:4360
TStreamerInfo * GetInfo() const
Get streamer info for the branch class.
#define R__ASSERT(e)
Definition: TError.h:96
TStreamerElement * fElement
Definition: TBranchProxy.h:83
Int_t GetOffset() const
Definition: TBranch.h:172
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition: TClass.cxx:2814
virtual void * GetStart(UInt_t=0)
Definition: TBranchProxy.h:197
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:396
virtual TLeaf * GetLeaf(const char *name) const
Return pointer to the 1st Leaf named name in thisBranch.
Definition: TBranch.cxx:1552
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.
char * GetObject() const
Return a pointer to our object.
char * Form(const char *fmt,...)
virtual TLeaf * GetLeafCount() const
Definition: TLeaf.h:66
virtual void * GetValuePointer() const
Definition: TLeaf.h:75
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:71
Int_t GetElementOffset(Int_t id) const
A Branch for the case of an object.
#define ClassImp(name)
Definition: Rtypes.h:336
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:3253
TObjArray * GetListOfLeaves()
Definition: TBranch.h:183
Internal::TBranchProxyDirector * fDirector
Definition: TBranchProxy.h:67
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:2885
TClass * GetClass() const
Definition: TClonesArray.h:57
TObjArray * GetElements() const
An array of clone (identical) objects.
Definition: TClonesArray.h:32
TTree * GetTree() const
Definition: TBranch.h:188
virtual char * GetAddress() const
Definition: TBranch.h:151
Base class for all the proxy object.
Definition: TBranchProxy.h:65
TBranch * GetBranch() const
Definition: TLeaf.h:65
A TTree is a list of TBranches.
Definition: TBranch.h:57
Int_t GetOffset() const
TVirtualCollectionProxy * fCollection
Definition: TBranchProxy.h:94
TBranch * GetMother() const
Get our top-level parent branch in the tree.
Definition: TBranch.cxx:1625
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)