TLeafObject.cxx

Go to the documentation of this file.
00001 // @(#)root/tree:$Id: TLeafObject.cxx 20882 2007-11-19 11:31:26Z rdm $
00002 // Author: Rene Brun   27/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 for a general object derived from TObject.                   //
00015 //////////////////////////////////////////////////////////////////////////
00016 
00017 #include "TLeafObject.h"
00018 #include "TBranch.h"
00019 #include "TClass.h"
00020 #include "TMethodCall.h"
00021 #include "TDataType.h"
00022 
00023 
00024 ClassImp(TLeafObject)
00025 
00026 //______________________________________________________________________________
00027 TLeafObject::TLeafObject(): TLeaf()
00028 {
00029 //*-*-*-*-*-*Default constructor for LeafObject*-*-*-*-*-*-*-*-*-*-*-*-*-*
00030 //*-*        =================================
00031    fClass      = 0;
00032    fObjAddress = 0;
00033    fVirtual    = kTRUE;
00034 }
00035 
00036 //______________________________________________________________________________
00037 TLeafObject::TLeafObject(TBranch *parent, const char *name, const char *type)
00038    :TLeaf(parent, name,type)
00039 {
00040 //*-*-*-*-*-*-*-*-*-*-*-*-*Create a LeafObject*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
00041 //*-*                      ==================
00042 //*-*
00043 
00044    SetTitle(type);
00045    fClass      = TClass::GetClass(type);
00046    fObjAddress = 0;
00047    fVirtual    = kTRUE;
00048 }
00049 
00050 //______________________________________________________________________________
00051 TLeafObject::~TLeafObject()
00052 {
00053 //*-*-*-*-*-*Default destructor for a LeafObject*-*-*-*-*-*-*-*-*-*-*-*
00054 //*-*        ==================================
00055 
00056 }
00057 
00058 
00059 //______________________________________________________________________________
00060 void TLeafObject::FillBasket(TBuffer &b)
00061 {
00062 //*-*-*-*-*-*-*-*-*-*-*Pack leaf elements in Basket output buffer*-*-*-*-*-*-*
00063 //*-*                  =========================================
00064 
00065    if (!fObjAddress) return;
00066    TObject *object  = GetObject();
00067    if (object) {
00068       if (fVirtual) {
00069          UChar_t n = strlen(object->ClassName());
00070          b << n;
00071          b.WriteFastArray(object->ClassName(),n+1);
00072       }
00073       object->Streamer(b);
00074    } else {
00075       if (fClass) {
00076          if (fClass->Property() & kIsAbstract) object = new TObject;
00077          else                                  object = (TObject *)fClass->New();
00078          object->SetBit(kInvalidObject);
00079          object->SetUniqueID(123456789);
00080          object->Streamer(b);
00081          if (fClass->Property() & kIsAbstract) delete object;
00082          else                                  fClass->Destructor(object);
00083       } else {
00084          Error("FillBasket","Attempt to write a NULL object in leaf:%s",GetName());
00085       }
00086    }
00087 }
00088 
00089 //______________________________________________________________________________
00090 TMethodCall *TLeafObject::GetMethodCall(const char *name)
00091 {
00092 //*-*-*-*-*-*-*-*Returns pointer to method corresponding to name*-*-*-*-*-*-*
00093 //*-*            ============================================
00094 //*-*
00095 //*-*    name is a string with the general form  "method(list of params)"
00096 //*-*   If list of params is omitted, () is assumed;
00097 //*-*
00098 
00099    char *namecpy = new char[strlen(name)+1];
00100    strcpy(namecpy,name);
00101    char *params = strchr(namecpy,'(');
00102    if (params) { *params = 0; params++; }
00103    else params = (char *) ")";
00104 
00105    if (!fClass) fClass      = TClass::GetClass(GetTitle());
00106    TMethodCall *m = new TMethodCall(fClass, namecpy, params);
00107    delete [] namecpy;
00108    if (m->GetMethod()) return m;
00109    Error("GetMethodCall","Unknown method:%s",name);
00110    delete m;
00111    return 0;
00112 }
00113 
00114 //______________________________________________________________________________
00115 const char *TLeafObject::GetTypeName() const
00116 {
00117 //*-*-*-*-*-*-*-*Returns name of leaf type*-*-*-*-*-*-*-*-*-*-*-*
00118 //*-*            =========================
00119 
00120    return fTitle.Data();
00121 }
00122 
00123 //______________________________________________________________________________
00124 Bool_t TLeafObject::Notify()
00125 {
00126    // This method must be overridden to handle object notifcation.
00127 
00128    fClass      = TClass::GetClass(GetTitle());
00129    return kFALSE;
00130 }
00131 
00132 //______________________________________________________________________________
00133 void TLeafObject::PrintValue(Int_t) const
00134 {
00135 // Prints leaf value
00136 
00137    printf("%lx\n",(Long_t)GetValuePointer());
00138 }
00139 
00140 //______________________________________________________________________________
00141 void TLeafObject::ReadBasket(TBuffer &b)
00142 {
00143 //*-*-*-*-*-*-*-*-*-*-*Read leaf elements from Basket input buffer*-*-*-*-*-*
00144 //*-*                  ===========================================
00145 
00146    char classname[128];
00147    UChar_t n;
00148    if (fVirtual) {
00149       b >> n;
00150       b.ReadFastArray(classname,n+1);
00151       fClass      = TClass::GetClass(classname);
00152    }
00153    if (fClass) {
00154       TObject *object;
00155       if (!fObjAddress) {
00156          Long_t *voidobj = new Long_t[1];
00157          fObjAddress  = (void **)voidobj;
00158          *fObjAddress = (TObject *)fClass->New();
00159       }
00160       object = (TObject*)(*fObjAddress);
00161       if (fBranch->IsAutoDelete()) {
00162          fClass->Destructor(object);
00163          object = (TObject *)fClass->New();
00164       }
00165       if (!object) return;
00166 
00167       if (fClass->GetClassInfo()) {
00168          object->Streamer(b);
00169       } else {
00170          //emulated class has no Streamer
00171          if (!TestBit(kWarn)) {
00172             Warning("ReadBasket","%s::Streamer not available, using TClass::ReadBuffer instead",fClass->GetName());
00173             SetBit(kWarn);
00174          }
00175          fClass->ReadBuffer(b,object);
00176       }
00177       // in case we had written a null pointer a Zombie object was created
00178       // we must delete it
00179       if (object->TestBit(kInvalidObject)) {
00180          if (object->GetUniqueID() == 123456789) {
00181             fClass->Destructor(object);
00182             object = 0;
00183          }
00184       }
00185       *fObjAddress = object;
00186    } else GetBranch()->SetAddress(0);
00187 }
00188 
00189 //______________________________________________________________________________
00190 void TLeafObject::SetAddress(void *add)
00191 {
00192 //*-*-*-*-*-*-*-*-*-*-*Set leaf buffer data address*-*-*-*-*-*
00193 //*-*                  ============================
00194 
00195    fObjAddress = (void **)add;
00196 }
00197 
00198 //______________________________________________________________________________
00199 void TLeafObject::Streamer(TBuffer &b)
00200 {
00201    // Stream an object of class TLeafObject.
00202 
00203    if (b.IsReading()) {
00204       UInt_t R__s, R__c;
00205       Version_t R__v = b.ReadVersion(&R__s, &R__c);
00206       if (R__v > 3 || R__v == 2) {
00207          b.ReadClassBuffer(TLeafObject::Class(), this, R__v, R__s, R__c);
00208          if (R__v == 2) fVirtual = kTRUE;
00209          fObjAddress = 0;
00210          fClass  = TClass::GetClass(fTitle.Data());
00211          if (!fClass) Warning("Streamer","Cannot find class:%s",fTitle.Data());
00212          return;
00213       }
00214       //====process old versions before automatic schema evolution
00215       TLeaf::Streamer(b);
00216       fObjAddress = 0;
00217       fClass  = TClass::GetClass(fTitle.Data());
00218       if (!fClass) Warning("Streamer","Cannot find class:%s",fTitle.Data());
00219       if (R__v  < 1) fVirtual = kFALSE;
00220       if (R__v == 1) fVirtual = kTRUE;
00221       if (R__v == 3) b >> fVirtual;
00222       //====end of old versions
00223 
00224    } else {
00225       b.WriteClassBuffer(TLeafObject::Class(),this);
00226    }
00227 }
00228 
00229 //______________________________________________________________________________
00230 Bool_t TLeafObject::IsOnTerminalBranch() const
00231 {
00232    // Return true if this leaf is does not have any sub-branch/leaf.
00233 
00234    if (fBranch->GetListOfBranches()->GetEntriesFast()) return kFALSE;
00235    return kTRUE;
00236 }

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