#include "TLeaf.h"
#include "TBranch.h"
#include "TTree.h"
#include "TVirtualPad.h"
#include "TBrowser.h"
#include "TClass.h"
#include <ctype.h>
R__EXTERN TTree* gTree;
ClassImp(TLeaf)
TLeaf::TLeaf()
: TNamed()
, fNdata(0)
, fLen(0)
, fLenType(0)
, fOffset(0)
, fIsRange(kFALSE)
, fIsUnsigned(kFALSE)
, fLeafCount(0)
, fBranch(0)
{
}
TLeaf::TLeaf(TBranch *parent, const char* name, const char *)
: TNamed(name, name)
, fNdata(0)
, fLen(0)
, fLenType(4)
, fOffset(0)
, fIsRange(kFALSE)
, fIsUnsigned(kFALSE)
, fLeafCount(0)
, fBranch(parent)
{
fLeafCount = GetLeafCounter(fLen);
if (fLen == -1) {
MakeZombie();
return;
}
const char *bracket = strchr(name, '[');
if (bracket) fName.ReplaceAll(bracket,"");
}
TLeaf::TLeaf(const TLeaf& lf) :
TNamed(lf),
fNdata(lf.fNdata),
fLen(lf.fLen),
fLenType(lf.fLenType),
fOffset(lf.fOffset),
fIsRange(lf.fIsRange),
fIsUnsigned(lf.fIsUnsigned),
fLeafCount(lf.fLeafCount),
fBranch(lf.fBranch)
{
}
TLeaf& TLeaf::operator=(const TLeaf& lf)
{
if(this!=&lf) {
TNamed::operator=(lf);
fNdata=lf.fNdata;
fLen=lf.fLen;
fLenType=lf.fLenType;
fOffset=lf.fOffset;
fIsRange=lf.fIsRange;
fIsUnsigned=lf.fIsUnsigned;
fLeafCount=lf.fLeafCount;
fBranch=lf.fBranch;
}
return *this;
}
TLeaf::~TLeaf()
{
if (fBranch) {
TTree* tree = fBranch->GetTree();
fBranch = 0;
if (tree) {
TObjArray *lst = tree->GetListOfLeaves();
if (lst->GetLast()!=-1) lst->Remove(this);
}
}
fLeafCount = 0;
}
void TLeaf::Browse(TBrowser* b)
{
if (strchr(GetName(), '.')) {
fBranch->GetTree()->Draw(GetName(), "", b ? b->GetDrawOption() : "");
} else {
if ((fBranch->GetListOfLeaves()->GetEntries() > 1) ||
(strcmp(fBranch->GetName(), GetName()) != 0)) {
TString name;
name.Form("%s.%s", fBranch->GetName(), GetName());
fBranch->GetTree()->Draw(name, "", b ? b->GetDrawOption() : "");
} else {
fBranch->GetTree()->Draw(GetName(), "", b ? b->GetDrawOption() : "");
}
}
if (gPad) {
gPad->Update();
}
}
void TLeaf::FillBasket(TBuffer &)
{
}
TLeaf* TLeaf::GetLeafCounter(Int_t& countval) const
{
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;
countname = 0;
countval = -1;
return 0;
}
char *bleft2 = (char*) strchr(countname, '[');
*bright = 0;
nch = strlen(countname);
TTree* pTree = gTree;
if (fBranch && fBranch->GetTree()) {
pTree = fBranch->GetTree();
}
TLeaf* leaf = (TLeaf*) GetBranch()->GetListOfLeaves()->FindObject(countname);
if (leaf == 0) {
leaf = (TLeaf*) pTree->GetListOfLeaves()->FindObject(countname);
}
if (!leaf && strchr(GetName(), '.')) {
char* withdot = new char[strlen(GetName())+strlen(countname)+1];
strcpy(withdot, GetName());
char* lastdot = strrchr(withdot, '.');
strcpy(lastdot, countname);
leaf = (TLeaf*) pTree->GetListOfLeaves()->FindObject(countname);
delete[] withdot;
withdot = 0;
}
if (!leaf && strchr(countname,'.')) {
leaf = pTree->FindLeaf(countname);
}
Int_t i = 0;
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;
countname = 0;
return leaf;
}
for (i = 0; i < nch; i++) {
if (!isdigit(countname[i])) {
delete[] countname;
countname = 0;
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;
countname = 0;
return 0;
}
Int_t TLeaf::GetLen() const
{
if (fLeafCount) {
Int_t len = Int_t(fLeafCount->GetValue());
if (len > fLeafCount->GetMaximum()) {
Error("GetLen", "Leaf counter is greater than maximum! leaf: '%s' len: %d max: %d", GetName(), len, fLeafCount->GetMaximum());
len = fLeafCount->GetMaximum();
}
return len * fLen;
} else {
return fLen;
}
}
Int_t TLeaf::ResetAddress(void* addr, Bool_t calledFromDestructor)
{
Bool_t deleteValue = kFALSE;
if (TestBit(kNewValue)) {
deleteValue = kTRUE;
}
if (!calledFromDestructor) {
if (fLeafCount) {
fNdata = (fLeafCount->GetMaximum() + 1) * fLen;
} else {
fNdata = fLen;
}
if (addr) {
ResetBit(kNewValue);
} else {
SetBit(kNewValue);
}
}
return deleteValue;
}
void TLeaf::SetLeafCount(TLeaf *leaf)
{
if (IsZombie() && (fLen == -1) && leaf) {
ResetBit(kZombie);
fLen = 1;
}
fLeafCount = leaf;
}
void TLeaf::Streamer(TBuffer &b)
{
if (b.IsReading()) {
UInt_t R__s, R__c;
Version_t R__v = b.ReadVersion(&R__s, &R__c);
if (R__v > 1) {
b.ReadClassBuffer(TLeaf::Class(), this, R__v, R__s, R__c);
} else {
TNamed::Streamer(b);
b >> fLen;
b >> fLenType;
b >> fOffset;
b >> fIsRange;
b >> fIsUnsigned;
b >> fLeafCount;
b.CheckByteCount(R__s, R__c, TLeaf::IsA());
}
if (!fLen) {
fLen = 1;
}
ResetBit(kNewValue);
SetAddress();
} else {
b.WriteClassBuffer(TLeaf::Class(), this);
}
}