ROOT  6.07/01
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
TLeaf.cxx
Go to the documentation of this file.
1 // @(#)root/tree:$Id$
2 // Author: Rene Brun 12/01/96
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
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 TLeaf
13 A TLeaf describes individual elements of a TBranch
14 See TBranch structure in TTree.
15 */
16 
17 #include "TLeaf.h"
18 #include "TBranch.h"
19 #include "TTree.h"
20 #include "TVirtualPad.h"
21 #include "TBrowser.h"
22 #include "TClass.h"
23 
24 #include <ctype.h>
25 
27 
28 ////////////////////////////////////////////////////////////////////////////////
29 
30 TLeaf::TLeaf()
31  : TNamed()
32  , fNdata(0)
33  , fLen(0)
34  , fLenType(0)
35  , fOffset(0)
36  , fIsRange(kFALSE)
37  , fIsUnsigned(kFALSE)
38  , fLeafCount(0)
39  , fBranch(0)
40 {
41 }
42 
43 ////////////////////////////////////////////////////////////////////////////////
44 /// Create a Leaf.
45 ///
46 /// See the TTree and TBranch constructors for explanation of parameters.
47 
48 TLeaf::TLeaf(TBranch *parent, const char* name, const char *)
49  : TNamed(name, name)
50  , fNdata(0)
51  , fLen(0)
52  , fLenType(4)
53  , fOffset(0)
54  , fIsRange(kFALSE)
55  , fIsUnsigned(kFALSE)
56  , fLeafCount(0)
57  , fBranch(parent)
58 {
59  fLeafCount = GetLeafCounter(fLen);
60 
61  if (fLen == -1) {
62  MakeZombie();
63  return;
64  }
65 
66  const char *bracket = strchr(name, '[');
67  if (bracket) fName.ReplaceAll(bracket,"");
68 }
69 
70 ////////////////////////////////////////////////////////////////////////////////
71 /// Copy constructor.
72 
73 TLeaf::TLeaf(const TLeaf& lf) :
74  TNamed(lf),
75  fNdata(lf.fNdata),
76  fLen(lf.fLen),
77  fLenType(lf.fLenType),
78  fOffset(lf.fOffset),
79  fIsRange(lf.fIsRange),
80  fIsUnsigned(lf.fIsUnsigned),
81  fLeafCount(lf.fLeafCount),
82  fBranch(lf.fBranch)
83 {
84 }
85 
86 ////////////////////////////////////////////////////////////////////////////////
87 /// Assignment operator.
88 
90 {
91  if(this!=&lf) {
93  fNdata=lf.fNdata;
94  fLen=lf.fLen;
95  fLenType=lf.fLenType;
96  fOffset=lf.fOffset;
97  fIsRange=lf.fIsRange;
98  fIsUnsigned=lf.fIsUnsigned;
99  fLeafCount=lf.fLeafCount;
100  fBranch=lf.fBranch;
101  }
102  return *this;
103 }
104 
105 ////////////////////////////////////////////////////////////////////////////////
106 /// Destructor.
107 
109 {
110  if (fBranch) {
111  TTree* tree = fBranch->GetTree();
112  fBranch = 0;
113  if (tree) {
114  TObjArray *lst = tree->GetListOfLeaves();
115  if (lst->GetLast()!=-1) lst->Remove(this);
116  }
117  }
118  fLeafCount = 0;
119 }
120 
121 ////////////////////////////////////////////////////////////////////////////////
122 /// Browse the content of this leaf.
123 
125 {
126  if (strchr(GetName(), '.')) {
127  fBranch->GetTree()->Draw(GetName(), "", b ? b->GetDrawOption() : "");
128  } else {
129  if ((fBranch->GetListOfLeaves()->GetEntries() > 1) ||
130  (strcmp(fBranch->GetName(), GetName()) != 0)) {
131  TString name;
132  name.Form("%s.%s", fBranch->GetName(), GetName());
133  fBranch->GetTree()->Draw(name, "", b ? b->GetDrawOption() : "");
134  } else {
135  fBranch->GetTree()->Draw(GetName(), "", b ? b->GetDrawOption() : "");
136  }
137  }
138  if (gPad) {
139  gPad->Update();
140  }
141 }
142 
143 ////////////////////////////////////////////////////////////////////////////////
144 /// Pack leaf elements in Basket output buffer.
145 
147 {
148 }
149 
150 ////////////////////////////////////////////////////////////////////////////////
151 /// Return a pointer to the counter of this leaf.
152 ///
153 /// - If leaf name has the form var[nelem], where nelem is alphanumeric, then
154 /// if nelem is a leaf name, return countval = 1 and the pointer to
155 /// the leaf named nelem, otherwise return 0.
156 /// - If leaf name has the form var[nelem], where nelem is a non-negative integer, then
157 /// return countval = nelem and a null pointer.
158 /// - If leaf name has the form of a multi-dimensional array (e.g. var[nelem][nelem2]
159 /// where nelem and nelem2 are non-negative integers) then
160 /// return countval = product of all dimension sizes and a null pointer.
161 /// - If leaf name has the form var[... (and does not match the previous 2
162 /// cases) return countval = -1 and null pointer;
163 /// - Otherwise return countval = 1 and a null pointer.
164 
166 {
167  countval = 1;
168  const char* name = GetTitle();
169  char* bleft = (char*) strchr(name, '[');
170  if (!bleft) {
171  return 0;
172  }
173  bleft++;
174  Int_t nch = strlen(bleft);
175  char* countname = new char[nch+1];
176  strcpy(countname, bleft);
177  char* bright = (char*) strchr(countname, ']');
178  if (!bright) {
179  delete[] countname;
180  countname = 0;
181  countval = -1;
182  return 0;
183  }
184  char *bleft2 = (char*) strchr(countname, '[');
185  *bright = 0;
186  nch = strlen(countname);
187 
188  // Now search a branch name with a leaf name = countname
189  if (fBranch == 0) {
190  Error("GetLeafCounter","TLeaf %s is not setup properly, fBranch is null.",GetName());
191  return 0;
192  }
193  if (fBranch->GetTree() == 0) {
194  Error("GetLeafCounter","For Leaf %s, the TBranch %s is not setup properly, fTree is null.",GetName(),fBranch->GetName());
195  return 0;
196  }
197  TTree* pTree = fBranch->GetTree();
198 
199  TLeaf* leaf = (TLeaf*) GetBranch()->GetListOfLeaves()->FindObject(countname);
200  if (leaf == 0) {
201  // Try outside the branch:
202  leaf = (TLeaf*) pTree->GetListOfLeaves()->FindObject(countname);
203  }
204  //if not found, make one more trial in case the leaf name has a "."
205  if (!leaf && strchr(GetName(), '.')) {
206  char* withdot = new char[strlen(GetName())+strlen(countname)+1];
207  strcpy(withdot, GetName());
208  char* lastdot = strrchr(withdot, '.');
209  strcpy(lastdot, countname);
210  leaf = (TLeaf*) pTree->GetListOfLeaves()->FindObject(countname);
211  delete[] withdot;
212  withdot = 0;
213  }
214  if (!leaf && strchr(countname,'.')) {
215  // Not yet found and the countname has a dot in it, let's try
216  // to find the leaf using its full name
217  leaf = pTree->FindLeaf(countname);
218  }
219  Int_t i = 0;
220  if (leaf) {
221  countval = 1;
222  leaf->SetRange();
223  if (bleft2) {
224  sscanf(bleft2, "[%d]", &i);
225  countval *= i;
226  }
227  bleft = bleft2;
228  while (bleft) {
229  bleft2++;
230  bleft = (char*) strchr(bleft2, '[');
231  if (!bleft) {
232  break;
233  }
234  sscanf(bleft, "[%d]", &i);
235  countval *= i;
236  bleft2 = bleft;
237  }
238  delete[] countname;
239  countname = 0;
240  return leaf;
241  }
242  // not found in a branch/leaf. Is it a numerical value?
243  for (i = 0; i < nch; i++) {
244  if (!isdigit(countname[i])) {
245  delete[] countname;
246  countname = 0;
247  countval = -1;
248  return 0;
249  }
250  }
251  sscanf(countname, "%d", &countval);
252  if (bleft2) {
253  sscanf(bleft2, "[%d]", &i);
254  countval *= i;
255  }
256  bleft = bleft2;
257  while (bleft) {
258  bleft2++;
259  bleft = (char*) strchr(bleft2, '[');
260  if (!bleft) {
261  break;
262  }
263  sscanf(bleft, "[%d]", &i);
264  countval *= i;
265  bleft2 = bleft;
266  }
267 
268  delete[] countname;
269  countname = 0;
270  return 0;
271 }
272 
273 ////////////////////////////////////////////////////////////////////////////////
274 /// Return the number of effective elements of this leaf.
275 
277 {
278  if (fLeafCount) {
279  // -- We are a varying length array.
280  Int_t len = Int_t(fLeafCount->GetValue());
281  if (len > fLeafCount->GetMaximum()) {
282  Error("GetLen", "Leaf counter is greater than maximum! leaf: '%s' len: %d max: %d", GetName(), len, fLeafCount->GetMaximum());
283  len = fLeafCount->GetMaximum();
284  }
285  return len * fLen;
286  } else {
287  // -- We are a fixed size thing.
288  return fLen;
289  }
290 }
291 
292 ////////////////////////////////////////////////////////////////////////////////
293 /// Helper routine for TLeafX::SetAddress.
294 ///
295 /// The return value is non-zero if we owned the old
296 /// value buffer and must delete it now. The size
297 /// of the value buffer is recalculated and stored,
298 /// and a decision is made whether or not we own the
299 /// new value buffer.
300 
301 Int_t TLeaf::ResetAddress(void* addr, Bool_t calledFromDestructor)
302 {
303  // The kNewValue bit records whether or not we own
304  // the current value buffer or not. If we own it,
305  // then we are responsible for deleting it.
306  Bool_t deleteValue = kFALSE;
307  if (TestBit(kNewValue)) {
308  deleteValue = kTRUE;
309  }
310  // If we are not being called from a destructor,
311  // recalculate the value buffer size and decide
312  // whether or not we own the new value buffer.
313  if (!calledFromDestructor) {
314  // -- Recalculate value buffer size and decide ownership of value.
315  if (fLeafCount) {
316  // -- Varying length array data member.
317  fNdata = (fLeafCount->GetMaximum() + 1) * fLen;
318  } else {
319  // -- Fixed size data member.
320  fNdata = fLen;
321  }
322  // If we were provided an address, then we do not own
323  // the value, otherwise we do and must delete it later,
324  // keep track of this with bit kNewValue.
325  if (addr) {
327  } else {
328  SetBit(kNewValue);
329  }
330  }
331  return deleteValue;
332 }
333 
334 ////////////////////////////////////////////////////////////////////////////////
335 /// Set the leaf count of this leaf.
336 
338 {
339  if (IsZombie() && (fLen == -1) && leaf) {
340  // The constructor noted that it could not find the
341  // leafcount. Now that we did find it, let's remove
342  // the side-effects.
343  ResetBit(kZombie);
344  fLen = 1;
345  }
346  fLeafCount = leaf;
347 }
348 
349 ////////////////////////////////////////////////////////////////////////////////
350 /// Stream a class object.
351 
352 void TLeaf::Streamer(TBuffer &b)
353 {
354  if (b.IsReading()) {
355  UInt_t R__s, R__c;
356  Version_t R__v = b.ReadVersion(&R__s, &R__c);
357  if (R__v > 1) {
358  b.ReadClassBuffer(TLeaf::Class(), this, R__v, R__s, R__c);
359  } else {
360  // -- Process old versions before automatic schema evolution.
361  TNamed::Streamer(b);
362  b >> fLen;
363  b >> fLenType;
364  b >> fOffset;
365  b >> fIsRange;
366  b >> fIsUnsigned;
367  b >> fLeafCount;
368  b.CheckByteCount(R__s, R__c, TLeaf::IsA());
369  }
370  if (!fLen) {
371  fLen = 1;
372  }
373  // We do not own the value buffer right now.
375  SetAddress();
376  } else {
377  b.WriteClassBuffer(TLeaf::Class(), this);
378  }
379 }
380 
virtual Int_t GetLen() const
Return the number of effective elements of this leaf.
Definition: TLeaf.cxx:276
virtual ~TLeaf()
Destructor.
Definition: TLeaf.cxx:108
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:52
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
Definition: TLeaf.h:37
An array of TObjects.
Definition: TObjArray.h:39
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
Bool_t IsReading() const
Definition: TBuffer.h:83
Option_t * GetDrawOption() const
Get option used by the graphics system to draw this object.
Definition: TBrowser.h:108
short Version_t
Definition: RtypesCore.h:61
Int_t GetLast() const
Return index of last object in array.
Definition: TObjArray.cxx:528
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:635
Buffer base class used for serializing objects.
Definition: TBuffer.h:42
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
virtual TObject * Remove(TObject *obj)
Remove object from array.
Definition: TObjArray.cxx:653
Bool_t IsZombie() const
Definition: TObject.h:141
Basic string class.
Definition: TString.h:137
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
TBranch * GetBranch() const
Definition: TLeaf.h:70
Int_t fLenType
Definition: TLeaf.h:43
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:732
virtual void SetRange(Bool_t range=kTRUE)
Definition: TLeaf.h:104
virtual TObject * FindObject(const char *name) const
Find an object in this collection using its name.
Definition: TObjArray.cxx:396
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:33
void Class()
Definition: Class.C:29
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
Int_t fLen
Number of elements in fAddress data buffer.
Definition: TLeaf.h:42
virtual void SetAddress(void *add=0)
Definition: TLeaf.h:124
virtual void FillBasket(TBuffer &b)
Pack leaf elements in Basket output buffer.
Definition: TLeaf.cxx:146
virtual TLeaf * GetLeafCounter(Int_t &countval) const
Return a pointer to the counter of this leaf.
Definition: TLeaf.cxx:165
Using a TBrowser one can browse all ROOT objects.
Definition: TBrowser.h:41
TNamed & operator=(const TNamed &rhs)
TNamed assignment operator.
Definition: TNamed.cxx:40
Int_t fNdata
Definition: TLeaf.h:41
TClass * IsA() const
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2308
unsigned int UInt_t
Definition: RtypesCore.h:42
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:173
virtual TLeaf * FindLeaf(const char *name)
Find leaf..
Definition: TTree.cxx:4564
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
virtual void SetLeafCount(TLeaf *leaf)
Set the leaf count of this leaf.
Definition: TLeaf.cxx:337
TString fName
Definition: TNamed.h:36
TTree * GetTree() const
Definition: TBranch.h:183
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
tuple tree
Definition: tree.py:24
virtual void Browse(TBrowser *b)
Browse the content of this leaf.
Definition: TLeaf.cxx:124
virtual void Draw(Option_t *opt)
Default Draw method for all objects.
Definition: TTree.h:360
Bool_t fIsUnsigned
Definition: TLeaf.h:46
TObjArray * GetListOfLeaves()
Definition: TBranch.h:178
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:494
#define name(a, b)
Definition: linkTestLib0.cpp:5
Int_t fOffset
Definition: TLeaf.h:44
ClassImp(TLeaf) TLeaf
Definition: TLeaf.cxx:26
Bool_t fIsRange
Definition: TLeaf.h:45
TBranch * fBranch
Definition: TLeaf.h:48
Int_t ResetAddress(void *add, Bool_t destructor=kFALSE)
Helper routine for TLeafX::SetAddress.
Definition: TLeaf.cxx:301
void MakeZombie()
Definition: TObject.h:68
TLeaf * fLeafCount
Definition: TLeaf.h:47
#define gPad
Definition: TVirtualPad.h:288
A TTree object has a header with a name and a title.
Definition: TTree.h:98
void ResetBit(UInt_t f)
Definition: TObject.h:172
TLeaf & operator=(const TLeaf &)
Assignment operator.
Definition: TLeaf.cxx:89
A TTree is a list of TBranches.
Definition: TBranch.h:58
const Bool_t kTRUE
Definition: Rtypes.h:91
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
virtual TObjArray * GetListOfLeaves()
Definition: TTree.h:410