Logo ROOT   6.16/01
Reference Guide
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\ingroup tree
14
15A TLeaf describes individual elements of a TBranch
16See TBranch structure in TTree.
17*/
18
19#include "TLeaf.h"
20#include "TBranch.h"
21#include "TTree.h"
22#include "TVirtualPad.h"
23#include "TBrowser.h"
24#include "TClass.h"
25
26#include <ctype.h>
27
29
30////////////////////////////////////////////////////////////////////////////////
31
33 : TNamed()
34 , fNdata(0)
35 , fLen(0)
36 , fLenType(0)
37 , fOffset(0)
38 , fIsRange(kFALSE)
39 , fIsUnsigned(kFALSE)
40 , fLeafCount(0)
41 , fBranch(0)
42{
43}
44
45////////////////////////////////////////////////////////////////////////////////
46/// Create a Leaf.
47///
48/// See the TTree and TBranch constructors for explanation of parameters.
49
50TLeaf::TLeaf(TBranch *parent, const char* name, const char *)
51 : TNamed(name, name)
52 , fNdata(0)
53 , fLen(0)
54 , fLenType(4)
55 , fOffset(0)
56 , fIsRange(kFALSE)
57 , fIsUnsigned(kFALSE)
58 , fLeafCount(0)
59 , fBranch(parent)
60{
62
63 if (fLen == -1) {
64 MakeZombie();
65 return;
66 }
67
68 const char *bracket = strchr(name, '[');
69 if (bracket) fName.ReplaceAll(bracket,"");
70}
71
72////////////////////////////////////////////////////////////////////////////////
73/// Copy constructor.
74
75TLeaf::TLeaf(const TLeaf& lf) :
76 TNamed(lf),
77 fNdata(lf.fNdata),
78 fLen(lf.fLen),
79 fLenType(lf.fLenType),
80 fOffset(lf.fOffset),
81 fIsRange(lf.fIsRange),
82 fIsUnsigned(lf.fIsUnsigned),
83 fLeafCount(lf.fLeafCount),
84 fBranch(lf.fBranch)
85{
86}
87
88////////////////////////////////////////////////////////////////////////////////
89/// Assignment operator.
90
92{
93 if(this!=&lf) {
95 fNdata=lf.fNdata;
96 fLen=lf.fLen;
102 fBranch=lf.fBranch;
103 }
104 return *this;
105}
106
107////////////////////////////////////////////////////////////////////////////////
108/// Destructor.
109
111{
112 if (fBranch) {
114 fBranch = 0;
115 if (tree) {
116 TObjArray *lst = tree->GetListOfLeaves();
117 if (lst->GetLast()!=-1) lst->Remove(this);
118 }
119 }
120 fLeafCount = 0;
121}
122
123////////////////////////////////////////////////////////////////////////////////
124/// Browse the content of this leaf.
125
127{
128 if (strchr(GetName(), '.')) {
129 fBranch->GetTree()->Draw(GetName(), "", b ? b->GetDrawOption() : "");
130 } else {
131 if ((fBranch->GetListOfLeaves()->GetEntries() > 1) ||
132 (strcmp(fBranch->GetName(), GetName()) != 0)) {
134 if (!name.EndsWith(".")) name += ".";
135 name += GetName();
136 fBranch->GetTree()->Draw(name, "", b ? b->GetDrawOption() : "");
137 } else {
138 fBranch->GetTree()->Draw(GetName(), "", b ? b->GetDrawOption() : "");
139 }
140 }
141 if (gPad) {
142 gPad->Update();
143 }
144}
145
146////////////////////////////////////////////////////////////////////////////////
147/// Pack leaf elements in Basket output buffer.
148
150{
151}
152
153////////////////////////////////////////////////////////////////////////////////
154/// If the class supports it, generate an offset array base.
155///
156/// This class only returns `nullptr` on error.
158{
159 // In order to avoid a virtual call, we assume ROOT developers will override
160 // the default GenerateOffsetArray for cases where this function does not apply.
161
162 Int_t *retval = new Int_t[events];
163 if (R__unlikely(!retval || !fLeafCount)) {
164 return nullptr;
165 }
166
167 Int_t header = GetOffsetHeaderSize();
168 Long64_t orig_entry = std::max(fBranch->GetReadEntry(), 0LL); // -1 indicates to start at the beginning
169 Long64_t orig_leaf_entry = fLeafCount->GetBranch()->GetReadEntry();
170 Int_t len = 0;
171 for (Int_t idx = 0, offset = base; idx < events; idx++) {
172 retval[idx] = offset;
173 fLeafCount->GetBranch()->GetEntry(orig_entry + idx);
174 len = static_cast<Int_t>(fLeafCount->GetValue());
175 offset += fLenType * len + header;
176 }
177 fLeafCount->GetBranch()->GetEntry(orig_leaf_entry);
178
179 return retval;
180}
181
182////////////////////////////////////////////////////////////////////////////////
183/// Return a pointer to the counter of this leaf (if any) or store the number of elements that the leaf contains in
184/// countval.
185///
186/// - If leaf name has the form var[nelem], where nelem is alphanumeric, then
187/// if nelem is a leaf name, return countval = 1 and the pointer to
188/// the leaf named nelem, otherwise return 0.
189/// - If leaf name has the form var[nelem], where nelem is a non-negative integer, then
190/// return countval = nelem and a null pointer.
191/// - If leaf name has the form of a multi-dimensional array (e.g. var[nelem][nelem2]
192/// where nelem and nelem2 are non-negative integers) then
193/// return countval = product of all dimension sizes and a null pointer.
194/// - If leaf name has the form var[... (and does not match the previous 2
195/// cases) return countval = -1 and null pointer;
196/// - Otherwise return countval = 1 and a null pointer.
197
199{
200 countval = 1;
201 const char* name = GetTitle();
202 char* bleft = (char*) strchr(name, '[');
203 if (!bleft) {
204 return 0;
205 }
206 bleft++;
207 Int_t nch = strlen(bleft);
208 char* countname = new char[nch+1];
209 strcpy(countname, bleft);
210 char* bright = (char*) strchr(countname, ']');
211 if (!bright) {
212 delete[] countname;
213 countname = 0;
214 countval = -1;
215 return 0;
216 }
217 char *bleft2 = (char*) strchr(countname, '[');
218 *bright = 0;
219 nch = strlen(countname);
220
221 // Now search a branch name with a leaf name = countname
222 if (fBranch == 0) {
223 Error("GetLeafCounter","TLeaf %s is not setup properly, fBranch is null.",GetName());
224 delete[] countname;
225 return 0;
226 }
227 if (fBranch->GetTree() == 0) {
228 Error("GetLeafCounter","For Leaf %s, the TBranch %s is not setup properly, fTree is null.",GetName(),fBranch->GetName());
229 delete[] countname;
230 return 0;
231 }
232 TTree* pTree = fBranch->GetTree();
233
234 TLeaf* leaf = (TLeaf*) GetBranch()->GetListOfLeaves()->FindObject(countname);
235 if (leaf == 0) {
236 // Try outside the branch:
237 leaf = (TLeaf*) pTree->GetListOfLeaves()->FindObject(countname);
238 }
239 //if not found, make one more trial in case the leaf name has a "."
240 if (!leaf && strchr(GetName(), '.')) {
241 char* withdot = new char[strlen(GetName())+strlen(countname)+1];
242 strcpy(withdot, GetName());
243 char* lastdot = strrchr(withdot, '.');
244 strcpy(lastdot, countname);
245 leaf = (TLeaf*) pTree->GetListOfLeaves()->FindObject(countname);
246 delete[] withdot;
247 withdot = 0;
248 }
249 if (!leaf && strchr(countname,'.')) {
250 // Not yet found and the countname has a dot in it, let's try
251 // to find the leaf using its full name
252 leaf = pTree->FindLeaf(countname);
253 }
254 Int_t i = 0;
255 if (leaf) {
256 countval = 1;
257 leaf->SetRange();
258 if (bleft2) {
259 sscanf(bleft2, "[%d]", &i);
260 countval *= i;
261 }
262 bleft = bleft2;
263 while (bleft) {
264 bleft2++;
265 bleft = (char*) strchr(bleft2, '[');
266 if (!bleft) {
267 break;
268 }
269 sscanf(bleft, "[%d]", &i);
270 countval *= i;
271 bleft2 = bleft;
272 }
273 delete[] countname;
274 countname = 0;
275 return leaf;
276 }
277 // not found in a branch/leaf. Is it a numerical value?
278 for (i = 0; i < nch; i++) {
279 if (!isdigit(countname[i])) {
280 delete[] countname;
281 countname = 0;
282 countval = -1;
283 return 0;
284 }
285 }
286 sscanf(countname, "%d", &countval);
287 if (bleft2) {
288 sscanf(bleft2, "[%d]", &i);
289 countval *= i;
290 }
291 bleft = bleft2;
292 while (bleft) {
293 bleft2++;
294 bleft = (char*) strchr(bleft2, '[');
295 if (!bleft) {
296 break;
297 }
298 sscanf(bleft, "[%d]", &i);
299 countval *= i;
300 bleft2 = bleft;
301 }
302
303 delete[] countname;
304 countname = 0;
305 return 0;
306}
307
308////////////////////////////////////////////////////////////////////////////////
309/// Return the number of effective elements of this leaf, for the current entry.
310
312{
313 if (fLeafCount) {
314 // -- We are a varying length array.
315 Int_t len = Int_t(fLeafCount->GetValue());
316 if (len > fLeafCount->GetMaximum()) {
317 Error("GetLen", "Leaf counter is greater than maximum! leaf: '%s' len: %d max: %d", GetName(), len, fLeafCount->GetMaximum());
318 len = fLeafCount->GetMaximum();
319 }
320 return len * fLen;
321 } else {
322 // -- We are a fixed size thing.
323 return fLen;
324 }
325}
326
327////////////////////////////////////////////////////////////////////////////////
328/// Helper routine for TLeafX::SetAddress.
329///
330/// The return value is non-zero if we owned the old
331/// value buffer and must delete it now. The size
332/// of the value buffer is recalculated and stored,
333/// and a decision is made whether or not we own the
334/// new value buffer.
335
336Int_t TLeaf::ResetAddress(void* addr, Bool_t calledFromDestructor)
337{
338 // The kNewValue bit records whether or not we own
339 // the current value buffer or not. If we own it,
340 // then we are responsible for deleting it.
341 Bool_t deleteValue = kFALSE;
342 if (TestBit(kNewValue)) {
343 deleteValue = kTRUE;
344 }
345 // If we are not being called from a destructor,
346 // recalculate the value buffer size and decide
347 // whether or not we own the new value buffer.
348 if (!calledFromDestructor) {
349 // -- Recalculate value buffer size and decide ownership of value.
350 if (fLeafCount) {
351 // -- Varying length array data member.
352 fNdata = (fLeafCount->GetMaximum() + 1) * fLen;
353 } else {
354 // -- Fixed size data member.
355 fNdata = fLen;
356 }
357 // If we were provided an address, then we do not own
358 // the value, otherwise we do and must delete it later,
359 // keep track of this with bit kNewValue.
360 if (addr) {
362 } else {
364 }
365 }
366 return deleteValue;
367}
368
369////////////////////////////////////////////////////////////////////////////////
370/// Set the leaf count of this leaf.
371
373{
374 if (IsZombie() && (fLen == -1) && leaf) {
375 // The constructor noted that it could not find the
376 // leafcount. Now that we did find it, let's remove
377 // the side-effects.
379 fLen = 1;
380 }
381 fLeafCount = leaf;
382}
383
384////////////////////////////////////////////////////////////////////////////////
385/// Stream a class object.
386
387void TLeaf::Streamer(TBuffer &b)
388{
389 if (b.IsReading()) {
390 UInt_t R__s, R__c;
391 Version_t R__v = b.ReadVersion(&R__s, &R__c);
392 if (R__v > 1) {
393 b.ReadClassBuffer(TLeaf::Class(), this, R__v, R__s, R__c);
394 } else {
395 // -- Process old versions before automatic schema evolution.
396 TNamed::Streamer(b);
397 b >> fLen;
398 b >> fLenType;
399 b >> fOffset;
400 b >> fIsRange;
401 b >> fIsUnsigned;
402 b >> fLeafCount;
403 b.CheckByteCount(R__s, R__c, TLeaf::IsA());
404 }
405 if (!fLen) {
406 fLen = 1;
407 }
408 // We do not own the value buffer right now.
410 SetAddress();
411 } else {
412 b.WriteClassBuffer(TLeaf::Class(), this);
413 }
414}
415
void Class()
Definition: Class.C:29
#define R__unlikely(expr)
Definition: RConfig.hxx:578
#define b(i)
Definition: RSha256.hxx:100
int Int_t
Definition: RtypesCore.h:41
short Version_t
Definition: RtypesCore.h:61
unsigned int UInt_t
Definition: RtypesCore.h:42
const Bool_t kFALSE
Definition: RtypesCore.h:88
bool Bool_t
Definition: RtypesCore.h:59
long long Long64_t
Definition: RtypesCore.h:69
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define ClassImp(name)
Definition: Rtypes.h:363
#define gPad
Definition: TVirtualPad.h:286
A TTree is a list of TBranches.
Definition: TBranch.h:64
TTree * GetTree() const
Definition: TBranch.h:209
virtual Int_t GetEntry(Long64_t entry=0, Int_t getall=0)
Read all leaves of entry and return total number of bytes read.
Definition: TBranch.cxx:1317
Long64_t GetReadEntry() const
Definition: TBranch.h:194
TObjArray * GetListOfLeaves()
Definition: TBranch.h:204
Using a TBrowser one can browse all ROOT objects.
Definition: TBrowser.h:37
Buffer base class used for serializing objects.
Definition: TBuffer.h:40
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
Definition: TLeaf.h:32
virtual Double_t GetValue(Int_t i=0) const
Definition: TLeaf.h:135
Int_t fLenType
Number of bytes for this data type.
Definition: TLeaf.h:42
virtual Int_t GetMaximum() const
Definition: TLeaf.h:88
virtual void Browse(TBrowser *b)
Browse the content of this leaf.
Definition: TLeaf.cxx:126
Int_t fLen
Number of fixed length elements.
Definition: TLeaf.h:41
Int_t fNdata
! Number of elements in fAddress data buffer
Definition: TLeaf.h:40
virtual Int_t GetLen() const
Return the number of effective elements of this leaf, for the current entry.
Definition: TLeaf.cxx:311
Bool_t fIsUnsigned
(=kTRUE if unsigned, kFALSE otherwise)
Definition: TLeaf.h:45
virtual ~TLeaf()
Destructor.
Definition: TLeaf.cxx:110
TLeaf & operator=(const TLeaf &)
Assignment operator.
Definition: TLeaf.cxx:91
virtual void SetAddress(void *add=0)
Definition: TLeaf.h:137
virtual TLeaf * GetLeafCounter(Int_t &countval) const
Return a pointer to the counter of this leaf (if any) or store the number of elements that the leaf c...
Definition: TLeaf.cxx:198
virtual void SetRange(Bool_t range=kTRUE)
Definition: TLeaf.h:117
Int_t * GenerateOffsetArrayBase(Int_t base, Int_t events) const
If the class supports it, generate an offset array base.
Definition: TLeaf.cxx:157
virtual void FillBasket(TBuffer &b)
Pack leaf elements in Basket output buffer.
Definition: TLeaf.cxx:149
TLeaf()
Definition: TLeaf.cxx:32
TBranch * GetBranch() const
Definition: TLeaf.h:75
Int_t fOffset
Offset in ClonesArray object (if one)
Definition: TLeaf.h:43
virtual Int_t GetOffsetHeaderSize() const
Definition: TLeaf.h:36
TBranch * fBranch
! Pointer to supporting branch (we do not own the branch)
Definition: TLeaf.h:47
TLeaf * fLeafCount
Pointer to Leaf count if variable length (we do not own the counter)
Definition: TLeaf.h:46
Bool_t fIsRange
(=kTRUE if leaf has a range, kFALSE otherwise)
Definition: TLeaf.h:44
@ kNewValue
Set if we own the value buffer and so must delete it ourselves.
Definition: TLeaf.h:63
virtual void SetLeafCount(TLeaf *leaf)
Set the leaf count of this leaf.
Definition: TLeaf.cxx:372
Int_t ResetAddress(void *add, Bool_t destructor=kFALSE)
Helper routine for TLeafX::SetAddress.
Definition: TLeaf.cxx:336
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
TString fName
Definition: TNamed.h:32
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
TNamed & operator=(const TNamed &rhs)
TNamed assignment operator.
Definition: TNamed.cxx:51
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
An array of TObjects.
Definition: TObjArray.h:37
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:522
virtual TObject * FindObject(const char *name) const
Find an object in this collection using its name.
Definition: TObjArray.cxx:414
Int_t GetLast() const
Return index of last object in array.
Definition: TObjArray.cxx:561
virtual TObject * Remove(TObject *obj)
Remove object from array.
Definition: TObjArray.cxx:703
@ kZombie
object ctor failed
Definition: TObject.h:79
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
R__ALWAYS_INLINE Bool_t IsZombie() const
Definition: TObject.h:134
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
void MakeZombie()
Definition: TObject.h:49
void ResetBit(UInt_t f)
Definition: TObject.h:171
Basic string class.
Definition: TString.h:131
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:687
A TTree object has a header with a name and a title.
Definition: TTree.h:71
virtual TObjArray * GetListOfLeaves()
Definition: TTree.h:428
virtual void Draw(Option_t *opt)
Default Draw method for all objects.
Definition: TTree.h:371
virtual TLeaf * FindLeaf(const char *name)
Find leaf..
Definition: TTree.cxx:4703
Definition: tree.py:1