// @(#)root/tree:$Name: $:$Id: TLeaf.cxx,v 1.13 2005/01/28 13:53:47 brun Exp $
// Author: Rene Brun 12/01/96
/*************************************************************************
* Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
//////////////////////////////////////////////////////////////////////////
// //
// A TLeaf describes individual elements of a TBranch //
// See TBranch structure in TTree. //
//////////////////////////////////////////////////////////////////////////
#include "TLeaf.h"
#include "TBranch.h"
#include "TTree.h"
#include "TVirtualPad.h"
#include "TBrowser.h"
#include <ctype.h>
R__EXTERN TTree *gTree;
R__EXTERN TBranch *gBranch;
ClassImp(TLeaf)
//______________________________________________________________________________
TLeaf::TLeaf(): TNamed()
{
//*-*-*-*-*-*Default constructor for Leaf*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-* ============================
fLen = 0;
//fBranch = 0;
fBranch = gBranch;
fLeafCount = 0;
fNdata = 0;
fOffset = 0;
}
//______________________________________________________________________________
TLeaf::TLeaf(const char *name, const char *)
:TNamed(name,name)
{
//*-*-*-*-*-*-*-*-*-*-*-*-*Create a Leaf*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-* =============
//
// See the TTree and TBranch constructors for explanation of parameters.
fBranch = 0;
fIsRange = 0;
fIsUnsigned = 0;
fLenType = 4;
fNdata = 0;
fOffset = 0;
fLeafCount = GetLeafCounter(fLen);
if (fLen == -1) {
MakeZombie();
return;
}
if (fLeafCount || strchr(name,'[')) {
char newname[64];
strcpy(newname,name);
char *bracket = strchr(newname,'[');
*bracket = 0;
SetName(newname);
}
fBranch = gBranch;
}
//______________________________________________________________________________
TLeaf::~TLeaf()
{
//*-*-*-*-*-*Default destructor for a Leaf*-*-*-*-*-*-*-*-*-*-*-*
//*-* ===============================
// if (fBranch) fBranch->GetListOfLeaves().Remove(this);
if (!fBranch) return;
TTree *tree = fBranch->GetTree();
fBranch = 0;
if (!tree) return;
tree->GetListOfLeaves()->Remove(this);
}
//______________________________________________________________________________
void TLeaf::Browse(TBrowser *b)
{
char name[64];
if (strchr(GetName(),'.')) {
fBranch->GetTree()->Draw(GetName(), b ? b->GetDrawOption() : "");
} else {
sprintf(name,"%s.%s",fBranch->GetName(),GetName());
fBranch->GetTree()->Draw(name, "", b ? b->GetDrawOption() : "");
}
if (gPad) gPad->Update();
}
//______________________________________________________________________________
void TLeaf::FillBasket(TBuffer &)
{
//*-*-*-*-*-*-*-*-*-*-*Pack leaf elements in Basket output buffer*-*-*-*-*-*-*
//*-* =========================================
}
//______________________________________________________________________________
TLeaf *TLeaf::GetLeafCounter(Int_t &countval) const
{
//*-*-*-*-*-*-*Return Pointer to counter of referenced Leaf*-*-*-*-*-*-*-*
//*-* ============================================
//
// If leaf name has the forme var[nelem], where nelem is alphanumeric, then
// If nelem is a leaf name, return countval = 1 and the pointer to
// the leaf named nelem.
// If leaf name has the forme var[nelem], where nelem is a digit, then
// return countval = nelem and a null pointer.
// Otherwise return countval=0 and a null pointer.
//
countval = 1;
const char *name = GetTitle();
char *bleft = (char*)strchr(name,'[');
if (!bleft) return 0;
bleft++;
Int_t nch = strlen(bleft);
char *countname = new char[nch+1];
strcpy(countname,bleft);
char *bright = (char*)strchr(countname,']');
if (!bright) { delete [] countname; return 0;}
char *bleft2 = (char*)strchr(countname,'[');
*bright = 0; nch = strlen(countname);
//*-* Now search a branch name with a leave name = countname
// We search for the leaf in the ListOfLeaves from the TTree. We can in principle
// access the TTree by calling fBranch()->GetTree(), but fBranch is not set if this
// method is called from the TLeaf constructor. In that case, use global pointer
// gTree.
// Also, if fBranch is set, but fBranch->GetTree() returns NULL, use gTree.
TTree* pTree = fBranch ? fBranch->GetTree() : gTree;
if (!pTree) pTree = gTree;
TLeaf *leaf = (TLeaf*) pTree->GetListOfLeaves()->FindObject(countname);
//if not found, make one more trial in case the leaf name has a "."
if (!leaf && strchr(GetName(),'.')) {
char *withdot = new char[1000];
strcpy(withdot,GetName());
char *lastdot = strrchr(withdot,'.');
strcpy(lastdot,countname);
leaf = (TLeaf*) pTree->GetListOfLeaves()->FindObject(countname);
delete [] withdot;
}
Int_t i;
if (leaf) {
countval = 1;
leaf->SetRange();
if (bleft2) {
sscanf(bleft2,"[%d]",&i);
countval *= i;
}
bleft = bleft2;
while(bleft) {
bleft2++;
bleft = (char*)strchr(bleft2,'[');
if (!bleft) break;
sscanf(bleft,"[%d]",&i);
countval *= i;
bleft2 = bleft;
}
delete [] countname;
return leaf;
}
//*-* not found in a branch/leaf. Is it a numerical value?
for (i=0;i<nch;i++) {
if (!isdigit(countname[i])) {
delete [] countname;
countval = -1;
return 0;
}
}
sscanf(countname,"%d",&countval);
if (bleft2) {
sscanf(bleft2,"[%d]",&i);
countval *= i;
}
bleft = bleft2;
while(bleft) {
bleft2++;
bleft = (char*)strchr(bleft2,'[');
if (!bleft) break;
sscanf(bleft,"[%d]",&i);
countval *= i;
bleft2 = bleft;
}
//*/
delete [] countname;
return 0;
}
//______________________________________________________________________________
Int_t TLeaf::GetLen() const
{
//*-*-*-*-*-*-*-*-*Return the number of effective elements of this leaf*-*-*-*
//*-* ====================================================
Int_t len;
if (fLeafCount) {
len = Int_t(fLeafCount->GetValue());
if (len > fLeafCount->GetMaximum()) {
printf("ERROR leaf:%s, len=%d and max=%d\n",GetName(),len,fLeafCount->GetMaximum());
len = fLeafCount->GetMaximum();
}
return len*fLen;
} else {
return fLen;
}
}
//______________________________________________________________________________
Int_t TLeaf::ResetAddress(void *add, Bool_t destructor)
{
//*-*-*-*-*-*-*-*-*-*-*Set leaf buffer data address*-*-*-*-*-*
//*-* ============================
//
// This function is called by all TLeafX::SetAddress
Int_t todelete = 0;
if (TestBit(kNewValue)) todelete = 1;
if (destructor) return todelete;
if (fLeafCount) fNdata = fLen*(fLeafCount->GetMaximum() + 1);
else fNdata = fLen;
ResetBit(kNewValue);
if (!add) SetBit(kNewValue);
return todelete;
}
//_______________________________________________________________________
void TLeaf::SetLeafCount(TLeaf *leaf)
{
if (IsZombie() && fLen==-1 && leaf) {
// The constructor noted that it could not find the
// leafcount. Now that we did find it, let's remove
// the side-effects
ResetBit(kZombie);
fLen = 1;
}
fLeafCount=leaf;
}
//_______________________________________________________________________
void TLeaf::Streamer(TBuffer &b)
{
//*-*-*-*-*-*-*-*-*Stream a class object*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-* =========================================
if (b.IsReading()) {
UInt_t R__s, R__c;
Version_t R__v = b.ReadVersion(&R__s, &R__c);
if (R__v > 1) {
TLeaf::Class()->ReadBuffer(b, this, R__v, R__s, R__c);
} else {
//====process old versions before automatic schema evolution
TNamed::Streamer(b);
b >> fLen;
b >> fLenType;
b >> fOffset;
b >> fIsRange;
b >> fIsUnsigned;
b >> fLeafCount;
b.CheckByteCount(R__s, R__c, TLeaf::IsA());
//====end of old versions
}
if (fLen == 0) fLen = 1;
ResetBit(kNewValue);
SetAddress();
} else {
TLeaf::Class()->WriteBuffer(b,this);
}
}
ROOT page - Class index - Class Hierarchy - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.