[ROOT] Automatic Browser

From: Victor Perevoztchikov (perev@bnl.gov)
Date: Thu Mar 01 2001 - 01:57:30 MET


Hi Rene,

as I promised you in Chicago, I send you another small class.

This class provide automatic browsing of objects. User can define his
Browse method as:

  void TObject::Browse(TBrowser *b)
  {
    TAutoBrowse::Browse(this,b);
  }
  
It is enough to browse complex object. This method is based on ShowMember
function. Actually, if define such Browse method for TObject, all objects
inherited from TObject will be automatically browsable. But it is your
decision. 

We, in STAR use this method to browse very complicated objects, so it is well
debuged.

Victor

-- 
Victor M. Perevoztchikov   perev@bnl.gov  perev@vxcern.cern.ch       
Brookhaven National Laboratory MS 510A PO Box 5000 Upton NY 11973-5000
tel office : 631-344-7894; fax 631-344-4206; home 631-345-2690

#ifndef _TAUTOBROWSE_
#define _TAUTOBROWSE_ 2001
class TObject;

class TAutoBrowse  
{
protected:
  TAutoBrowse(){};
 ~TAutoBrowse(){};
public:
static Int_t Browse(TObject *obj, TBrowser *browser);
};
#endif //  _STAUTOBROWSE_



#include <stdio.h>
#include <stdlib.h>
#include "TROOT.h"
#include "TClass.h"
#include "TBaseClass.h"
#include "TDataMember.h"
#include "TMethod.h"
#include "TMethodArg.h"
#include "TDataType.h"
#include "Api.h"
#include "TBrowser.h"
#include "TMemberInspector.h"
#include "TError.h"
#include "TAutoBrowse.h"


class MyAutoInspector : public TMemberInspector {
//
//      class MyAutoInspector is local for this file

public:
MyAutoInspector(TBrowser *b){fBrowser=b;fCount=0;};
virtual ~MyAutoInspector(){};
virtual void Inspect(TClass* cl, const char* parent, const char* name, void* addr);

Int_t fCount;
TBrowser *fBrowser;
};      

//______________________________________________________________________________
void MyAutoInspector::Inspect(TClass* kl, const char* tit , const char* name, void* addr)
{
  if(tit && strchr(tit,'.'))    return ;
  if (fCount && !fBrowser) return;

  TString ts;

  if (!kl) return;
  if (*(kl->GetName()) == 'T') return;
  if (*name == '*') name++;
  int ln = strcspn(name,"[ ");
  TString iname(name,ln);
  
  G__ClassInfo *classInfo = kl->GetClassInfo();         
  if (!classInfo)               return;
  G__ClassInfo &cl = *classInfo;


//              Browse data members
  G__DataMemberInfo m(cl);
  TString mname;

  int found=0;
  while (m.Next()) {    // MemberLoop
     mname = m.Name();
     mname.ReplaceAll("*","");
     if ((found = (iname==mname))) break;
  }     
  assert(found);

  // we skip: non TObjects
  //  - the member G__virtualinfo inserted by the CINT RTTI system

  long prop = m.Property() | m.Type()->Property();
  if (prop & G__BIT_ISSTATIC)   return;
  if (prop & G__BIT_ISFUNDAMENTAL)      return;
  if (prop & G__BIT_ISENUM)             return;
  if (strcmp(m.Type()->Fullname(),"TObject") && !m.Type()->IsBase("TObject"))
                                        return;
  if (mname == "G__virtualinfo")        return;

  int  size = sizeof(void*);
  if (!(prop&G__BIT_ISPOINTER)) size = m.Type()->Size(); 

  int nmax = 1;
  if (prop & G__BIT_ISARRAY) {
    for (int dim = 0; dim < m.ArrayDim(); dim++) nmax *= m.MaxIndex(dim);
  }

  for(int i=0; i<nmax; i++) {
    char *ptr = (char*)addr + i*size;
    TObject *obj = (prop&G__BIT_ISPOINTER) ? *((TObject**)ptr) : (TObject*)ptr;
    if (!obj)           continue;
    fCount++;
    if (!fBrowser)      return;
    const char *bwname = obj->GetName();
    if (!bwname[0] || strcmp(bwname,obj->ClassName())==0) {
      bwname = name;
      if (strcmp(bwname,"fOrBrowser")==0) {
        ts.Replace(0,999,tit,strlen(tit)-1);
        bwname = (const char*)ts;
      } else {
        int l = strcspn(bwname,"[ ");
        if (bwname[l]=='[') {
          char cbuf[12]; sprintf(cbuf,"[%02d]",i);
          ts.Replace(0,999,bwname,l);
          ts += cbuf;
          bwname = (const char*)ts;
        }
      }  
    }  
   
    fBrowser->Add(obj,bwname);
  }

}    

//______________________________________________________________________________
Int_t TAutoBrowse::Browse(TObject *obj,TBrowser *browser)
{

//  Browse external object inherited from TObject
//  It passes through inheritance tree and calls TBrowser::Add
//  in appropriate cases

      

  if(!obj)      return 0;
  char cbuf[1000]; *cbuf=0;

  MyAutoInspector insp(browser);
  ((TObject*)obj)->ShowMembers(insp,cbuf);
  return insp.fCount;
}



This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:50:38 MET