/*
<img align=center src="gif/classinfo.gif">
*/
//End_Html
/*
        class MyClass{
            private:
                Float_t fX1;
                    ...
            public:
                void    SetX1(Float_t x) {fX1 = x;};
                Float_t GetX1()          {return fX1;};
                    ...
        }
*/
//</pre>
//End_Html
/*
    TCanvas     *c  = new TCanvas("c");   // create a canvas
    TClass      *cl = c->IsA();            // get its class description object.
    TDataMember *dm = cl->GetDataMember("fEditable"); //This is our data member
    TMethodCall *getter = dm->GetterMethod(c); //find a method that gets value!
    Long_t l;   // declare a storage for this value;
    getter->Execute(c,"",l);  // Get this Value !!!! It will appear in l !!!
    TMethodCall *setter = dm->SetterMethod(c);
    setter->Execute(c,"0",);   // Set Value 0 !!!
*/
//</pre>
//End_Html
/*
    class MyClass{
        Int_t mydata;  // <em> *OPTIONS={GetMethod="Get";SetMethod="Set"} </em>
         ...
        Int_t Get() const { return mydata;};
        void  Set(Int_t i) {mydata=i;};
        }
*/
//</pre>
//End_Html
/*
<em>*OPTIONS={GetMethod="</em>getter<em>";SetMethod="</em>setter<em>";Items=(</em>it1<em>="</em>title1<em>",</em>it2<em>="</em>title2<em>", ... ) } </em>
*/
//</pre>
//End_Html
/*
         IntegerValue<em>  = "</em>Text Label<em>"</em>
         EnumValue   <em>  = "</em>Text Label<em>"</em>
        <em>"</em>TextValue<em>" = </em>Text Label<em>"</em>
*/
//</pre>
//End_Html
#include "TDataMember.h"
#include "TDataType.h"
#include "TROOT.h"
#include "TGlobal.h"
#include "TInterpreter.h"
#include "Strlen.h"
#include "Api.h"
#include "TMethodCall.h"
#include "TClass.h"
#include "TClassEdit.h"
#include "TMethod.h"
#include "TIterator.h"
#include "TList.h"
#include "TGlobal.h"
#include "TRealData.h"
ClassImp(TDataMember)
TDataMember::TDataMember(G__DataMemberInfo *info, TClass *cl) : TDictionary()
{
   
   
   
   fInfo        = info;
   fClass       = cl;
   fDataType    = 0;
   fOptions     = 0;
   fValueSetter = 0;
   fValueGetter = 0;
   fOffset      = -1;
   fProperty    = -1;
   fSTLCont     = -1;
   if (!fInfo && !fClass) return; 
   if (fInfo) {
      fFullTypeName = fInfo->Type()->Name();
      fTrueTypeName = fInfo->Type()->TrueName();
      fTypeName     = gInterpreter->TypeName(fFullTypeName);
      SetName(fInfo->Name());
      const char *t = fInfo->Title();
      SetTitle(t);
      if (t && t[0] != '!') SetBit(kObjIsPersistent);
      fDataType = 0;
      if (IsBasic() || IsEnum()) {
         if (IsBasic()) {
            const char *name = GetFullTypeName();
            if (strcmp(name, "unsigned char") != 0 &&
                strncmp(name, "unsigned short", sizeof ("unsigned short")) != 0 &&
                strcmp(name, "unsigned int") != 0 &&
                strncmp(name, "unsigned long", sizeof ("unsigned long")) != 0)
                
               name = GetTypeName();
            fDataType = gROOT->GetType(name);
            if (fDataType==0) {
               
               
               fDataType = gROOT->GetType(name,kTRUE);
            }
         } else {
            fDataType = gROOT->GetType("Int_t");
         }
      }
   }
   
   
   
   
   
   
   
   
   
   char cmt[2048];
   char opt[2048];
   char *opt_ptr = 0;
   char *ptr1    = 0;
   char *ptr2    = 0;
   char *ptr3    = 0;
   char *tok     = 0;
   Int_t cnt     = 0;
   Int_t token_cnt;
   Int_t i;
   strcpy(cmt,fInfo->Title());
   if ((opt_ptr=strstr(cmt,"*OPTION={"))) {
      
      
      ptr1 = strtok(opt_ptr  ,"{}");  
      ptr1 = strtok((char*)0,"{}");   
      
      strcpy(opt,ptr1);
      
      
      
      char *tokens[256];           
      token_cnt = 0;
      cnt       = 0;
      do {                          
         ptr1=strtok((char*) (cnt++ ? 0:opt),";");
         if (ptr1){
            tok=new char[strlen(ptr1)+1];
            strcpy(tok,ptr1);
            tokens[token_cnt]=tok;
            token_cnt++;
         }
      } while (ptr1);
      
      for (i=0;i<token_cnt;i++) {
         if (strstr(tokens[i],"GetMethod")) {
            ptr1 = strtok(tokens[i],"\"");    
            ptr1 = strtok(0,"\"");         
            if (GetClass()->GetMethod(ptr1,"")) 
               
               fValueGetter = new TMethodCall(GetClass(),ptr1,"");
            continue; 
         }
         if (strstr(tokens[i],"SetMethod")) {
            ptr1 = strtok(tokens[i],"\"");
            ptr1 = strtok((char*)0,"\"");    
            if (GetClass()->GetMethod(ptr1,"1"))
               
               fValueSetter = new TMethodCall(GetClass(),ptr1,"1");
         }
      }
      
      Int_t  opt_cnt    = 0;
      TList *optionlist = new TList();       
      for (i=0;i<token_cnt;i++) {
         if (strstr(tokens[i],"Items")) {
            ptr1 = strtok(tokens[i],"()");
            ptr1 = strtok((char*)0,"()");
            char opt[2048];  
            strcpy(opt,ptr1);
            
            
            
            
            
            do {
               ptr1 = strtok(opt_cnt++ ? (char*)0:opt,","); 
               if (ptr1) {
                  TOptionListItem *it = new TOptionListItem(this,1,0,0,ptr1,"");
                  optionlist->Add(it);
               }
            } while(ptr1);
         }
      }
      
      
      fOptions = new TList();                
      TIter next(optionlist);                
                                             
      TOptionListItem *it  = 0;
      TOptionListItem *it1 = 0;
      while ((it=(TOptionListItem*)next())) {
         ptr1 = it->fOptName;
         Bool_t islabel = (ptr1[0]=='\"');   // value is label or numerical?
         ptr2 = strtok(ptr1,"=\"");          
         ptr3 = strtok(0,"=\"");             
         if (islabel) {
            it1=new TOptionListItem(this,-9999,0,0,ptr3,ptr2);
            fOptions->Add(it1);
         }  else {
            
            Long_t l=0;
            Int_t  *value;
            TGlobal *enumval = gROOT->GetGlobal(ptr1,kTRUE);
            if (enumval){
               value = (Int_t*)(enumval->GetAddress());
               l     = (Long_t)(*value);
            } else if (IsEnum()) {
               TObject *obj = fClass->GetListOfDataMembers()->FindObject(ptr1);
               if (obj)
                  l = gROOT->ProcessLineFast(Form("%s::%s;",fClass->GetName(),ptr1));
               else
                  l = gROOT->ProcessLineFast(Form("%s;",ptr1));
            } else
               l = atol(ptr1);
            
            it1 = new TOptionListItem(this,l,0,0,ptr3,ptr1);
            fOptions->Add(it1);
         }
         optionlist->Remove(it);         
         delete it;                      
      }
      
      
      delete optionlist;
      
      for (i=0;i<token_cnt;i++) if(tokens[i]) delete [] tokens[i];
   
   
   } else if (IsEnum()) {
      TGlobal *global = 0;
      TDataMember::fOptions = new TList();
      char etypename[65];
      strncpy(etypename,this->GetTypeName(),64); 
      const char *gtypename = 0;
      TList *globals = (TList*)(gROOT->GetListOfGlobals(kTRUE)); 
      if (!globals) return;
      TIter nextglobal(globals);                
      while ((global=(TGlobal*)nextglobal())) { 
         gtypename = global->GetTypeName();
         if (strcmp(gtypename,etypename)==0) {
            Int_t *value = (Int_t*)(global->GetAddress());
            Long_t l     = (Long_t)(*value);
            char enumItem[128];
            strcpy(enumItem,global->GetName());
            TOptionListItem *it = new TOptionListItem(this,l,0,0,enumItem,enumItem);
            fOptions->Add(it);
         }
      }
   
   } else if (!strncmp(GetFullTypeName(),"Bool_t",6)){
      fOptions = new TList();
      TOptionListItem *it = new TOptionListItem(this,1,0,0,"ON",0);
      fOptions->Add(it);
      it = new TOptionListItem(this,0,0,0,"Off",0);
      fOptions->Add(it);
   } else fOptions = 0;
}
TDataMember::TDataMember(const TDataMember& dm) :
  TDictionary(dm),
  fInfo(dm.fInfo),
  fClass(dm.fClass),
  fDataType(dm.fDataType),
  fOffset(dm.fOffset),
  fSTLCont(dm.fSTLCont),
  fProperty(dm.fProperty),
  fTypeName(dm.fTypeName),
  fFullTypeName(dm.fFullTypeName),
  fTrueTypeName(dm.fTrueTypeName)
{ 
   
}
TDataMember& TDataMember::operator=(const TDataMember& dm) 
{
   
   if(this!=&dm) {
      TDictionary::operator=(dm);
      fInfo=dm.fInfo;
      fClass=dm.fClass;
      fDataType=dm.fDataType;
      fOffset=dm.fOffset;
      fSTLCont=dm.fSTLCont;
      fProperty=dm.fProperty;
      fTypeName=dm.fTypeName;
      fFullTypeName=dm.fFullTypeName;
      fTrueTypeName=dm.fTrueTypeName;
   } 
   return *this;
}
TDataMember::~TDataMember()
{
   
   delete fInfo;
   delete fValueSetter;
   delete fValueGetter;
   if (fOptions) {
      fOptions->Delete();
      delete fOptions;
   }
}
Int_t TDataMember::GetArrayDim() const
{
   
   return fInfo->ArrayDim();
}
const char *TDataMember::GetArrayIndex() const
{
   
   
   
   const char* val = fInfo->ValidArrayIndex();
   return (val && IsaPointer() ) ? val : "";
}
Int_t TDataMember::GetMaxIndex(Int_t dim) const
{
   
   return fInfo->MaxIndex(dim);
}
const char *TDataMember::GetTypeName() const
{
   
   if (fProperty==(-1)) Property();
   return fTypeName.Data();
}
const char *TDataMember::GetFullTypeName() const
{
   
   if (fProperty==(-1)) Property();
   return fFullTypeName.Data();
}
const char *TDataMember::GetTrueTypeName() const
{
   
   return fTrueTypeName.Data();
}
Long_t TDataMember::GetOffset() const
{
   
   if (fOffset>=0) return fOffset;
   
   if (fClass->GetDeclFileLine() < 0) {
      ((TDataMember*)this)->fOffset = fInfo->Offset();
      return fOffset;
   }
   
   
   
   
   char dmbracket[256];
   sprintf(dmbracket,"%s[",GetName());
   fClass->BuildRealData();
   TIter next(fClass->GetListOfRealData());
   TRealData *rdm;
   Int_t offset = 0;
   while ((rdm = (TRealData*)next())) {
      char *rdmc = (char*)rdm->GetName();
      
      
      if (this->IsaPointer() && rdmc[0] == '*') rdmc++;
      if (rdm->GetDataMember() != this) continue;
      if (strcmp(rdmc,GetName()) == 0) {
         offset = rdm->GetThisOffset();
         break;
      }
      if (strcmp(rdm->GetName(),GetName()) == 0) {
         if (rdm->IsObject()) {
            offset = rdm->GetThisOffset();
            break;
         }
      }
      if (strstr(rdm->GetName(),dmbracket)) {
         offset = rdm->GetThisOffset();
         break;
      }
   }
   ((TDataMember*)this)->fOffset = offset;
   return fOffset;
}
Long_t TDataMember::GetOffsetCint() const
{
   
   return fInfo->Offset();
}
Int_t TDataMember::GetUnitSize() const
{
   
   
   if (IsaPointer()) return sizeof(void*);
   if (IsEnum()    ) return sizeof(Int_t);
   if (IsBasic()   ) return GetDataType()->Size();
   TClass *cl = TClass::GetClass(GetTypeName());
   if (!cl) cl = TClass::GetClass(GetTrueTypeName());
   if ( cl) return cl->Size();
   Warning("GetUnitSize","Can not determine sizeof(%s)",GetTypeName());
   return 0;
}
Bool_t TDataMember::IsBasic() const
{
   
   if (fProperty == -1) Property();
   return (fProperty & kIsFundamental) ? kTRUE : kFALSE;
}
Bool_t TDataMember::IsEnum() const
{
   
   if (fProperty == -1) Property();
   return (fProperty & kIsEnum) ? kTRUE : kFALSE;
}
Bool_t TDataMember::IsaPointer() const
{
   
   if (fProperty == -1) Property();
   return (fProperty & kIsPointer) ? kTRUE : kFALSE;
}
int TDataMember::IsSTLContainer()
{
   
   if (fSTLCont != -1) return fSTLCont;
   fSTLCont = abs(TClassEdit::IsSTLCont(GetTrueTypeName()));
   return fSTLCont;
}
Long_t TDataMember::Property() const
{
   
   if (fProperty!=(-1)) return fProperty;
   TDataMember *t = (TDataMember*)this;
   if (!fInfo) return 0;
   t->fProperty = fInfo->Property()|fInfo->Type()->Property();
   t->fTypeName = gInterpreter->TypeName(fInfo->Type()->Name());
   t->fFullTypeName = fInfo->Type()->Name();
   t->fName = fInfo->Name();
   t->fTitle = fInfo->Title();
   return fProperty;
}
TList *TDataMember::GetOptions() const
{
   
   return fOptions;
}
TMethodCall *TDataMember::GetterMethod(TClass *cl)
{
   
   
   
   
   
   if (!fValueGetter || cl) {
      if (!cl) cl = fClass;
      if (fValueGetter) {
         TString methodname = fValueGetter->GetMethodName();
         delete fValueGetter;
         fValueGetter = new TMethodCall(cl, methodname.Data(), "");
      } else {
         
         
         
         
         const char *dataname = GetName();
         char gettername[128];
         sprintf(gettername, "Get%s", dataname+1);
         if (GetClass()->GetMethod(gettername, ""))
            return fValueGetter = new TMethodCall(cl, gettername, "");
         sprintf(gettername, "Is%s", dataname+1);
         if (GetClass()->GetMethod(gettername, ""))
            return fValueGetter = new TMethodCall(cl, gettername, "");
         sprintf(gettername, "Has%s", dataname+1);
         if (GetClass()->GetMethod(gettername, ""))
            return fValueGetter = new TMethodCall(cl, gettername, "");
      }
   }
   return fValueGetter;
}
TMethodCall *TDataMember::SetterMethod(TClass *cl)
{
   
   
   
   
   
   if (!fValueSetter || cl) {
      if (!cl) cl = fClass;
      if (fValueSetter) {
         TString methodname = fValueSetter->GetMethodName();
         TString params = fValueSetter->GetParams();
         delete fValueSetter;
         fValueSetter = new TMethodCall(cl, methodname.Data(), params.Data());
      } else {
         
         
         
         const char *dataname = GetName();
         char settername[64];
         sprintf(settername, "Set%s", dataname+1);
         if (strstr(settername, "Is")) sprintf(settername, "Set%s", dataname+3);
         if (GetClass()->GetMethod(settername, "1"))
            fValueSetter = new TMethodCall(cl, settername, "1");
         if (!fValueSetter)
            if (GetClass()->GetMethod(settername, "true"))
               fValueSetter = new TMethodCall(cl, settername, "true");
      }
   }
   return fValueSetter;
}
TOptionListItem::TOptionListItem(TDataMember *d, Long_t val, Long_t valmask,
                 Long_t tglmask,const char *name, const char *label)
{
   
   fDataMember    = d;
   fValue         = val;
   fValueMaskBit  = valmask;
   fToggleMaskBit = tglmask;
   if (name){
      fOptName = new char[strlen(name)+1];
      strcpy(fOptName,name);
   } else fOptName = 0;
   if(label){
      fOptLabel = new char[strlen(label)+1];
      strcpy(fOptLabel,label);
   } else fOptLabel = 0;
}
TOptionListItem::TOptionListItem(const TOptionListItem& oli) :
  TObject(oli),
  fDataMember(oli.fDataMember),
  fValue(oli.fValue),
  fValueMaskBit(oli.fValueMaskBit),
  fToggleMaskBit(oli.fToggleMaskBit),
  fOptName(oli.fOptName),
  fOptLabel(oli.fOptLabel)
{ 
   
}
TOptionListItem& TOptionListItem::operator=(const TOptionListItem& oli)
{
   
   if(this!=&oli) {
      TObject::operator=(oli);
      fDataMember=oli.fDataMember;
      fValue=oli.fValue;
      fValueMaskBit=oli.fValueMaskBit;
      fToggleMaskBit=oli.fToggleMaskBit;
      fOptName=oli.fOptName;
      fOptLabel=oli.fOptLabel;
   } 
   return *this;
}
TOptionListItem::~TOptionListItem()
{
   
   if (fOptName)  delete [] fOptName;
   if (fOptLabel) delete [] fOptLabel;
}
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.