TLeaf.cxx

Go to the documentation of this file.
00001 // @(#)root/tree:$Id: TLeaf.cxx 36388 2010-10-21 04:05:14Z pcanal $
00002 // Author: Rene Brun   12/01/96
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // A TLeaf describes individual elements of a TBranch                   //
00015 //       See TBranch structure in TTree.                                //
00016 //////////////////////////////////////////////////////////////////////////
00017 
00018 #include "TLeaf.h"
00019 #include "TBranch.h"
00020 #include "TTree.h"
00021 #include "TVirtualPad.h"
00022 #include "TBrowser.h"
00023 #include "TClass.h"
00024 
00025 #include <ctype.h>
00026 
00027 R__EXTERN TTree* gTree;
00028 
00029 ClassImp(TLeaf)
00030 
00031 //______________________________________________________________________________
00032 TLeaf::TLeaf()
00033    : TNamed()
00034    , fNdata(0)
00035    , fLen(0)
00036    , fLenType(0)
00037    , fOffset(0)
00038    , fIsRange(kFALSE)
00039    , fIsUnsigned(kFALSE)
00040    , fLeafCount(0)
00041    , fBranch(0)
00042 {
00043 }
00044 
00045 //______________________________________________________________________________
00046 TLeaf::TLeaf(TBranch *parent, const char* name, const char *)
00047    : TNamed(name, name)
00048    , fNdata(0)
00049    , fLen(0)
00050    , fLenType(4)
00051    , fOffset(0)
00052    , fIsRange(kFALSE)
00053    , fIsUnsigned(kFALSE)
00054    , fLeafCount(0)
00055    , fBranch(parent)
00056 {
00057    // Create a Leaf.
00058    //
00059    // See the TTree and TBranch constructors for explanation of parameters.
00060 
00061    fLeafCount = GetLeafCounter(fLen);
00062 
00063    if (fLen == -1) {
00064       MakeZombie(); 
00065       return;
00066    }
00067 
00068    const char *bracket = strchr(name, '[');
00069    if (bracket) fName.ReplaceAll(bracket,"");
00070 }
00071 
00072 //______________________________________________________________________________
00073 TLeaf::TLeaf(const TLeaf& lf) : 
00074   TNamed(lf),
00075   fNdata(lf.fNdata),
00076   fLen(lf.fLen),
00077   fLenType(lf.fLenType),
00078   fOffset(lf.fOffset),
00079   fIsRange(lf.fIsRange),
00080   fIsUnsigned(lf.fIsUnsigned),
00081   fLeafCount(lf.fLeafCount),
00082   fBranch(lf.fBranch)
00083 { 
00084    //copy constructor
00085 }
00086 
00087 //______________________________________________________________________________
00088 TLeaf& TLeaf::operator=(const TLeaf& lf) 
00089 {
00090    //assignement operator
00091    if(this!=&lf) {
00092       TNamed::operator=(lf);
00093       fNdata=lf.fNdata;
00094       fLen=lf.fLen;
00095       fLenType=lf.fLenType;
00096       fOffset=lf.fOffset;
00097       fIsRange=lf.fIsRange;
00098       fIsUnsigned=lf.fIsUnsigned;
00099       fLeafCount=lf.fLeafCount;
00100       fBranch=lf.fBranch;
00101    } 
00102    return *this;
00103 }
00104 
00105 //______________________________________________________________________________
00106 TLeaf::~TLeaf()
00107 {
00108    // -- Destructor.
00109 
00110    if (fBranch) {
00111       TTree* tree = fBranch->GetTree();
00112       fBranch = 0;
00113       if (tree) {
00114          TObjArray *lst = tree->GetListOfLeaves();
00115          if (lst->GetLast()!=-1) lst->Remove(this);
00116       }
00117    }
00118    fLeafCount = 0;
00119 }
00120 
00121 //______________________________________________________________________________
00122 void TLeaf::Browse(TBrowser* b)
00123 {
00124    // Browse the content of this leaf.
00125 
00126    if (strchr(GetName(), '.')) {
00127       fBranch->GetTree()->Draw(GetName(), "", b ? b->GetDrawOption() : "");
00128    } else {
00129       if ((fBranch->GetListOfLeaves()->GetEntries() > 1) || 
00130           (strcmp(fBranch->GetName(), GetName()) != 0)) {
00131          TString name;
00132          name.Form("%s.%s", fBranch->GetName(), GetName());
00133          fBranch->GetTree()->Draw(name, "", b ? b->GetDrawOption() : "");
00134       } else {
00135          fBranch->GetTree()->Draw(GetName(), "", b ? b->GetDrawOption() : "");
00136       }
00137    }
00138    if (gPad) {
00139       gPad->Update();
00140    }
00141 }
00142 
00143 //______________________________________________________________________________
00144 void TLeaf::FillBasket(TBuffer &)
00145 {
00146    // -- Pack leaf elements in Basket output buffer.
00147 }
00148 
00149 //______________________________________________________________________________
00150 TLeaf* TLeaf::GetLeafCounter(Int_t& countval) const
00151 {
00152    // -- Return a pointer to the counter of this leaf.
00153    //
00154    //  If leaf name has the form var[nelem], where nelem is alphanumeric, then
00155    //     If nelem is a leaf name, return countval = 1 and the pointer to 
00156    //          the leaf named nelem.
00157    //  If leaf name has the form var[nelem], where nelem is a digit, then
00158    //     return countval = nelem and a null pointer.
00159    //  If leaf name has the form of a multi dimenantion array (eg var[nelem][nelem2] 
00160    //     where nelem and nelem2 are digits) then
00161    //     return countval = product of all dimension size and a null pointer.
00162    //  If leaf name has the form var[... (and do not match the previous 2
00163    //     cases) return countval = -1 and null pointer;
00164    //  Otherwise return countval=1 and a null pointer.
00165    //
00166 
00167    countval = 1;
00168    const char* name = GetTitle();
00169    char* bleft = (char*) strchr(name, '[');
00170    if (!bleft) {
00171       return 0;
00172    }
00173    bleft++;
00174    Int_t nch = strlen(bleft);
00175    char* countname = new char[nch+1];
00176    strcpy(countname, bleft);
00177    char* bright = (char*) strchr(countname, ']');
00178    if (!bright) {
00179       delete[] countname;
00180       countname = 0;
00181       countval = -1;
00182       return 0;
00183    }
00184    char *bleft2 = (char*) strchr(countname, '[');
00185    *bright = 0;
00186    nch = strlen(countname);
00187 
00188    // Now search a branch name with a leave name = countname
00189    // We search for the leaf in the ListOfLeaves from the TTree. We can in principle
00190    // access the TTree by calling fBranch()->GetTree(), but fBranch is not set if this
00191    // method is called from the TLeaf constructor. In that case, use global pointer
00192    // gTree.
00193    // Also, if fBranch is set, but fBranch->GetTree() returns NULL, use gTree.
00194    TTree* pTree = gTree;
00195    if (fBranch && fBranch->GetTree()) {
00196       pTree = fBranch->GetTree();
00197    }
00198    TLeaf* leaf = (TLeaf*) GetBranch()->GetListOfLeaves()->FindObject(countname);
00199    if (leaf == 0) {
00200       // Try outside the branch:
00201       leaf = (TLeaf*) pTree->GetListOfLeaves()->FindObject(countname);
00202    }
00203    //if not found, make one more trial in case the leaf name has a "."
00204    if (!leaf && strchr(GetName(), '.')) {
00205       char* withdot = new char[strlen(GetName())+strlen(countname)+1];
00206       strcpy(withdot, GetName());
00207       char* lastdot = strrchr(withdot, '.');
00208       strcpy(lastdot, countname);
00209       leaf = (TLeaf*) pTree->GetListOfLeaves()->FindObject(countname);
00210       delete[] withdot;
00211       withdot = 0;
00212    }
00213    if (!leaf && strchr(countname,'.')) {
00214       // Not yet found and the countname has a dot in it, let's try
00215       // to find the leaf using its full name
00216       leaf = pTree->FindLeaf(countname);
00217    }
00218    Int_t i = 0;
00219    if (leaf) {
00220       countval = 1;
00221       leaf->SetRange();
00222       if (bleft2) {
00223          sscanf(bleft2, "[%d]", &i);
00224          countval *= i;
00225       }
00226       bleft = bleft2;
00227       while (bleft) {
00228          bleft2++;
00229          bleft = (char*) strchr(bleft2, '[');
00230          if (!bleft) {
00231             break;
00232          }
00233          sscanf(bleft, "[%d]", &i);
00234          countval *= i;
00235          bleft2 = bleft;
00236       }
00237       delete[] countname;
00238       countname = 0;
00239       return leaf;
00240    }
00241    // not found in a branch/leaf. Is it a numerical value?
00242    for (i = 0; i < nch; i++) {
00243       if (!isdigit(countname[i])) {
00244          delete[] countname;
00245          countname = 0;
00246          countval = -1;
00247          return 0;
00248       }
00249    }
00250    sscanf(countname, "%d", &countval);
00251    if (bleft2) {
00252       sscanf(bleft2, "[%d]", &i);
00253       countval *= i;
00254    }
00255    bleft = bleft2;
00256    while (bleft) {
00257       bleft2++;
00258       bleft = (char*) strchr(bleft2, '[');
00259       if (!bleft) {
00260          break;
00261       }
00262       sscanf(bleft, "[%d]", &i);
00263       countval *= i;
00264       bleft2 = bleft;
00265    }
00266 
00267    delete[] countname;
00268    countname = 0;
00269    return 0;
00270 }
00271 
00272 //______________________________________________________________________________
00273 Int_t TLeaf::GetLen() const
00274 {
00275    // -- Return the number of effective elements of this leaf.
00276 
00277    if (fLeafCount) {
00278       // -- We are a varying length array.
00279       Int_t len = Int_t(fLeafCount->GetValue());
00280       if (len > fLeafCount->GetMaximum()) {
00281          Error("GetLen", "Leaf counter is greater than maximum!  leaf: '%s' len: %d max: %d", GetName(), len, fLeafCount->GetMaximum());
00282          len = fLeafCount->GetMaximum();
00283       }
00284       return len * fLen;
00285    } else {
00286       // -- We are a fixed size thing.
00287       return fLen;
00288    }
00289 }
00290 
00291 //______________________________________________________________________________
00292 Int_t TLeaf::ResetAddress(void* addr, Bool_t calledFromDestructor)
00293 {
00294    // -- Helper routine for TLeafX::SetAddress.
00295    //
00296    // The return value is non-zero if we owned the old
00297    // value buffer and must delete it now.  The size
00298    // of the value buffer is recalculated and stored,
00299    // and a decision is made whether or not we own the
00300    // new value buffer.
00301    //
00302 
00303    // The kNewValue bit records whether or not we own
00304    // the current value buffer or not.  If we own it,
00305    // then we are responsible for deleting it.
00306    Bool_t deleteValue = kFALSE;
00307    if (TestBit(kNewValue)) {
00308       deleteValue = kTRUE;
00309    }
00310    // If we are not being called from a destructor,
00311    // recalculate the value buffer size and decide
00312    // whether or not we own the new value buffer.
00313    if (!calledFromDestructor) {
00314       // -- Recalculate value buffer size and decide ownership of value.
00315       if (fLeafCount) {
00316          // -- Varying length array data member.
00317          fNdata = (fLeafCount->GetMaximum() + 1) * fLen;
00318       } else {
00319          // -- Fixed size data member.
00320          fNdata = fLen;
00321       }
00322       // If we were provided an address, then we do not own
00323       // the value, otherwise we do and must delete it later,
00324       // keep track of this with bit kNewValue.
00325       if (addr) {
00326          ResetBit(kNewValue);
00327       } else {
00328          SetBit(kNewValue);
00329       }
00330    }
00331    return deleteValue;
00332 }
00333 
00334 //_______________________________________________________________________
00335 void TLeaf::SetLeafCount(TLeaf *leaf)
00336 { 
00337    // -- Set the leaf count of this leaf.
00338 
00339    if (IsZombie() && (fLen == -1) && leaf) {
00340       // The constructor noted that it could not find the 
00341       // leafcount.  Now that we did find it, let's remove
00342       // the side-effects.
00343       ResetBit(kZombie);
00344       fLen = 1;
00345    }
00346    fLeafCount = leaf; 
00347 }
00348 
00349 //_______________________________________________________________________
00350 void TLeaf::Streamer(TBuffer &b)
00351 {
00352    // -- Stream a class object.
00353 
00354    if (b.IsReading()) {
00355       UInt_t R__s, R__c;
00356       Version_t R__v = b.ReadVersion(&R__s, &R__c);
00357       if (R__v > 1) {
00358          b.ReadClassBuffer(TLeaf::Class(), this, R__v, R__s, R__c);
00359       } else {
00360          // -- Process old versions before automatic schema evolution.
00361          TNamed::Streamer(b);
00362          b >> fLen;
00363          b >> fLenType;
00364          b >> fOffset;
00365          b >> fIsRange;
00366          b >> fIsUnsigned;
00367          b >> fLeafCount;
00368          b.CheckByteCount(R__s, R__c, TLeaf::IsA());
00369       }
00370       if (!fLen) {
00371          fLen = 1;
00372       }
00373       // We do not own the value buffer right now.
00374       ResetBit(kNewValue);
00375       SetAddress();
00376    } else {
00377       b.WriteClassBuffer(TLeaf::Class(), this);
00378    }
00379 }
00380 

Generated on Tue Jul 5 15:34:03 2011 for ROOT_528-00b_version by  doxygen 1.5.1