#include "TClass.h"
#include "Riostream.h"
#include "TBaseClass.h"
#include "TBrowser.h"
#include "TBuffer.h"
#include "TClassGenerator.h"
#include "TClassEdit.h"
#include "TClassMenuItem.h"
#include "TClassRef.h"
#include "TClassTable.h"
#include "TDataMember.h"
#include "TDataType.h"
#include "TError.h"
#include "TExMap.h"
#include "TInterpreter.h"
#include "TMemberInspector.h"
#include "TMethod.h"
#include "TMethodArg.h"
#include "TMethodCall.h"
#include "TObjArray.h"
#include "TROOT.h"
#include "TRealData.h"
#include "TStreamer.h"
#include "TStreamerElement.h"
#include "TVirtualStreamerInfo.h"
#include "TVirtualCollectionProxy.h"
#include "TVirtualIsAProxy.h"
#include "TVirtualRefProxy.h"
#include "TVirtualMutex.h"
#include "TVirtualPad.h"
#include "THashTable.h"
#include "TSchemaRuleSet.h"
#include "TGenericClassInfo.h"
#include <cstdio>
#include <cctype>
#include <set>
#include <sstream>
#include <string>
#include <map>
#include <cmath>
#include <assert.h>
using namespace std;
TVirtualMutex* gCINTMutex = 0;
void *gMmallocDesc = 0;
Int_t TClass::fgClassCount;
TClass::ENewType TClass::fgCallingNew = kRealNew;
static std::multimap<void*, Version_t> gObjectVersionRepository;
static void RegisterAddressInRepository(const char * , void *location, const TClass *what)
{
Version_t version = what->GetClassVersion();
gObjectVersionRepository.insert(std::pair<void* const,Version_t>(location, version));
#if 0
std::pair<std::map<void*, Version_t>::iterator, Bool_t> tmp = gObjectVersionRepository.insert(std::pair<void*,Version_t>(location, version));
if (!tmp.second) {
Warning(where, "Reregistering an object of class '%s' version %d at address %p", what->GetName(), version, p);
gObjectVersionRepository.erase(tmp.first);
tmp = gObjectVersionRepository.insert(std::pair<void*,Version_t>(location, version));
if (!tmp.second) {
Warning(where, "Failed to reregister an object of class '%s' version %d at address %p", what->GetName(), version, location);
}
}
#endif
}
static void UnregisterAddressInRepository(const char * , void *location, const TClass *what)
{
std::multimap<void*, Version_t>::iterator cur = gObjectVersionRepository.find(location);
for (; cur != gObjectVersionRepository.end();) {
std::multimap<void*, Version_t>::iterator tmp = cur++;
if ((tmp->first == location) && (tmp->second == what->GetClassVersion())) {
gObjectVersionRepository.erase(tmp);
} else {
break;
}
}
}
static void MoveAddressInRepository(const char *where, void *oldadd, void *newadd, const TClass *what)
{
UnregisterAddressInRepository(where,oldadd,what);
RegisterAddressInRepository(where,newadd,what);
}
namespace ROOT {
#define R__USE_STD_MAP
class TMapTypeToTClass {
#if defined R__USE_STD_MAP
public:
#ifdef R__GLOBALSTL
typedef map<string,TClass*> IdMap_t;
#else
typedef std::map<std::string,TClass*> IdMap_t;
#endif
typedef IdMap_t::key_type key_type;
typedef IdMap_t::const_iterator const_iterator;
typedef IdMap_t::size_type size_type;
#ifdef R__WIN32
typedef TClass* mapped_type;
#else
typedef IdMap_t::mapped_type mapped_type;
#endif
private:
IdMap_t fMap;
public:
void Add(const key_type &key, mapped_type &obj) {
fMap[key] = obj;
}
mapped_type Find(const key_type &key) const {
IdMap_t::const_iterator iter = fMap.find(key);
mapped_type cl = 0;
if (iter != fMap.end()) cl = iter->second;
return cl;
}
void Remove(const key_type &key) { fMap.erase(key); }
#else
private:
TMap fMap;
public:
void Add(const char *key, TClass *&obj) {
TObjString *realkey = new TObjString(key);
fMap.Add(realkey, obj);
}
TClass* Find(const char *key) const {
const TPair *a = (const TPair *)fMap.FindObject(key);
if (a) return (TClass*) a->Value();
return 0;
}
void Remove(const char *key) {
TObjString realkey(key);
TObject *actual = fMap.Remove(&realkey);
delete actual;
}
#endif
};
}
IdMap_t *TClass::fgIdMap = new IdMap_t;
void TClass::AddClass(TClass *cl)
{
if (!cl) return;
gROOT->GetListOfClasses()->Add(cl);
if (cl->GetTypeInfo()) {
fgIdMap->Add(cl->GetTypeInfo()->name(),cl);
}
}
void TClass::RemoveClass(TClass *oldcl)
{
if (!oldcl) return;
gROOT->GetListOfClasses()->Remove(oldcl);
if (oldcl->GetTypeInfo()) {
fgIdMap->Remove(oldcl->GetTypeInfo()->name());
}
}
class TDumpMembers : public TMemberInspector {
public:
TDumpMembers() { }
void Inspect(TClass *cl, const char *parent, const char *name, const void *addr);
};
void TDumpMembers::Inspect(TClass *cl, const char *pname, const char *mname, const void *add)
{
const Int_t kvalue = 30;
#ifdef R__B64
const Int_t ktitle = 50;
#else
const Int_t ktitle = 42;
#endif
const Int_t kline = 1024;
Int_t cdate = 0;
Int_t ctime = 0;
UInt_t *cdatime = 0;
char line[kline];
TDataMember *member = cl->GetDataMember(mname);
if (!member) return;
TDataType *membertype = member->GetDataType();
Bool_t isdate = kFALSE;
if (strcmp(member->GetName(),"fDatime") == 0 && strcmp(member->GetTypeName(),"UInt_t") == 0) {
isdate = kTRUE;
}
Bool_t isbits = kFALSE;
if (strcmp(member->GetName(),"fBits") == 0 && strcmp(member->GetTypeName(),"UInt_t") == 0) {
isbits = kTRUE;
}
Int_t i;
for (i = 0;i < kline; i++) line[i] = ' ';
line[kline-1] = 0;
sprintf(line,"%s%s ",pname,mname);
i = strlen(line); line[i] = ' ';
char *pointer = (char*)add;
char **ppointer = (char**)(pointer);
if (member->IsaPointer()) {
char **p3pointer = (char**)(*ppointer);
if (!p3pointer)
sprintf(&line[kvalue],"->0");
else if (!member->IsBasic())
sprintf(&line[kvalue],"->%lx ", (Long_t)p3pointer);
else if (membertype) {
if (!strcmp(membertype->GetTypeName(), "char")) {
i = strlen(*ppointer);
if (kvalue+i >= kline) i=kline-kvalue;
Bool_t isPrintable = kTRUE;
for (Int_t j = 0; j < i; j++) {
if (!std::isprint((*ppointer)[j])) {
isPrintable = kFALSE;
break;
}
}
if (isPrintable) {
strncpy(line + kvalue, *ppointer, i);
line[kvalue+i] = 0;
} else {
line[kvalue] = 0;
}
} else {
strcpy(&line[kvalue], membertype->AsString(p3pointer));
}
} else if (!strcmp(member->GetFullTypeName(), "char*") ||
!strcmp(member->GetFullTypeName(), "const char*")) {
i = strlen(*ppointer);
if (kvalue+i >= kline) i=kline-kvalue;
Bool_t isPrintable = kTRUE;
for (Int_t j = 0; j < i; j++) {
if (!std::isprint((*ppointer)[j])) {
isPrintable = kFALSE;
break;
}
}
if (isPrintable) {
strncpy(line + kvalue, *ppointer, i);
line[kvalue+i] = 0;
} else {
line[kvalue] = 0;
}
} else {
sprintf(&line[kvalue],"->%lx ", (Long_t)p3pointer);
}
} else if (membertype)
if (isdate) {
cdatime = (UInt_t*)pointer;
TDatime::GetDateTime(cdatime[0],cdate,ctime);
sprintf(&line[kvalue],"%d/%d",cdate,ctime);
} else if (isbits) {
sprintf(&line[kvalue],"0x%08x", *(UInt_t*)pointer);
} else {
strcpy(&line[kvalue], membertype->AsString(pointer));
}
else
sprintf(&line[kvalue],"->%lx ", (Long_t)pointer);
if (isdate == kFALSE && strcmp(member->GetFullTypeName(), "char*") &&
strcmp(member->GetFullTypeName(), "const char*")) {
i = strlen(&line[0]); line[i] = ' ';
Int_t lentit = strlen(member->GetTitle());
if (lentit > 250-ktitle) lentit = 250-ktitle;
strncpy(&line[ktitle],member->GetTitle(),lentit);
line[ktitle+lentit] = 0;
}
Printf("%s", line);
}
THashTable* TClass::fgClassTypedefHash = 0;
THashTable* TClass::fgClassShortTypedefHash = 0;
TClass::TNameMapNode::TNameMapNode (const char* typedf, const char* orig)
: TObjString (typedf),
fOrigName (orig)
{
}
class TBuildRealData : public TMemberInspector {
private:
void *fRealDataObject;
TClass *fRealDataClass;
public:
TBuildRealData(void *obj, TClass *cl) {
fRealDataObject = obj;
fRealDataClass = cl;
}
void Inspect(TClass *cl, const char *parent, const char *name, const void *addr);
};
void TBuildRealData::Inspect(TClass* cl, const char* pname, const char* mname, const void* add)
{
TDataMember* dm = cl->GetDataMember(mname);
if (!dm) {
return;
}
Bool_t isTransient = kFALSE;
if (!dm->IsPersistent()) {
isTransient = kTRUE;
}
char rname[512];
strcpy(rname, pname);
if (cl != fRealDataClass) {
if (!fRealDataClass->InheritsFrom(cl)) {
char* dot = strchr(rname, '.');
if (!dot) {
return;
}
*dot = 0;
if (!fRealDataClass->GetDataMember(rname)) {
if (!fRealDataClass->GetBaseDataMember(rname)) {
return;
}
}
*dot = '.';
}
}
strcat(rname, mname);
Long_t offset = Long_t(((Long_t) add) - ((Long_t) fRealDataObject));
if (dm->IsaPointer()) {
if (!dm->IsBasic()) {
TRealData* rd = new TRealData(rname, offset, dm);
if (isTransient) { rd->SetBit(TRealData::kTransient); };
fRealDataClass->GetListOfRealData()->Add(rd);
} else {
TRealData* rd = new TRealData(rname, offset, dm);
if (isTransient) { rd->SetBit(TRealData::kTransient); };
fRealDataClass->GetListOfRealData()->Add(rd);
}
} else {
TRealData* rd = new TRealData(rname, offset, dm);
if (isTransient) { rd->SetBit(TRealData::kTransient); };
if (!dm->IsBasic()) {
rd->SetIsObject(kTRUE);
TClass* dmclass = TClass::GetClass(dm->GetTypeName(),kTRUE,isTransient);
if (!dmclass) {
dmclass = TClass::GetClass(dm->GetTrueTypeName(),kTRUE,isTransient);
}
if (dmclass) {
if (dmclass->Property()) {
if (dmclass->Property() & kIsAbstract) {
fprintf(stderr, "TBuildRealDataRecursive::Inspect(): data member class: '%s' is abstract.\n", dmclass->GetName());
}
}
if ((dmclass != cl) && !dm->IsaPointer()) {
if (dmclass->GetCollectionProxy()) {
TClass* valcl = dmclass->GetCollectionProxy()->GetValueClass();
if (valcl) valcl->BuildRealData();
} else {
dmclass->BuildRealData(const_cast<void*>(add));
}
}
}
}
fRealDataClass->GetListOfRealData()->Add(rd);
}
}
class TAutoInspector : public TMemberInspector {
public:
Int_t fCount;
TBrowser *fBrowser;
TAutoInspector(TBrowser *b) { fBrowser = b; fCount = 0; }
virtual ~TAutoInspector() { }
virtual void Inspect(TClass *cl, const char *parent, const char *name, const void *addr);
};
void TAutoInspector::Inspect(TClass *cl, const char *tit, const char *name,
const void *addr)
{
if(tit && strchr(tit,'.')) return ;
if (fCount && !fBrowser) return;
TString ts;
if (!cl) return;
if (*name == '*') name++;
int ln = strcspn(name,"[ ");
TString iname(name,ln);
ClassInfo_t *classInfo = cl->GetClassInfo();
if (!classInfo) return;
DataMemberInfo_t *m = gCint->DataMemberInfo_Factory(classInfo);
TString mname;
int found=0;
while (gCint->DataMemberInfo_Next(m)) {
mname = gCint->DataMemberInfo_Name(m);
mname.ReplaceAll("*","");
if ((found = (iname==mname))) break;
}
assert(found);
Long_t prop = gCint->DataMemberInfo_Property(m) | gCint->DataMemberInfo_TypeProperty(m);
if (prop & G__BIT_ISSTATIC) return;
if (prop & G__BIT_ISFUNDAMENTAL) return;
if (prop & G__BIT_ISENUM) return;
if (mname == "G__virtualinfo") return;
int size = sizeof(void*);
int nmax = 1;
if (prop & G__BIT_ISARRAY) {
for (int dim = 0; dim < gCint->DataMemberInfo_ArrayDim(m); dim++) nmax *= gCint->DataMemberInfo_MaxIndex(m,dim);
}
std::string clmName(TClassEdit::ShortType(gCint->DataMemberInfo_TypeName(m),
TClassEdit::kDropTrailStar) );
TClass * clm = TClass::GetClass(clmName.c_str());
R__ASSERT(clm);
if (!(prop&G__BIT_ISPOINTER)) {
size = clm->Size();
if (size==0) size = gCint->DataMemberInfo_TypeSize(m);
}
gCint->DataMemberInfo_Delete(m);
TVirtualCollectionProxy *proxy = clm->GetCollectionProxy();
for(int i=0; i<nmax; i++) {
char *ptr = (char*)addr + i*size;
void *obj = (prop&G__BIT_ISPOINTER) ? *((void**)ptr) : (TObject*)ptr;
if (!obj) continue;
fCount++;
if (!fBrowser) return;
TString bwname;
TClass *actualClass = clm->GetActualClass(obj);
if (clm->IsTObject()) {
TObject *tobj = (TObject*)clm->DynamicCast(TObject::Class(),obj);
bwname = tobj->GetName();
} else {
bwname = actualClass->GetName();
bwname += "::";
bwname += mname;
}
if (!clm->IsTObject() ||
bwname.Length()==0 ||
strcmp(bwname.Data(),actualClass->GetName())==0) {
bwname = name;
int l = strcspn(bwname.Data(),"[ ");
if (l<bwname.Length() && bwname[l]=='[') {
char cbuf[12]; sprintf(cbuf,"[%02d]",i);
ts.Replace(0,999,bwname,l);
ts += cbuf;
bwname = (const char*)ts;
}
}
if (proxy==0) {
fBrowser->Add(obj,clm,bwname);
} else {
TClass *valueCl = proxy->GetValueClass();
if (valueCl==0) {
fBrowser->Add( obj, clm, bwname );
} else {
TVirtualCollectionProxy::TPushPop env(proxy, obj);
TClass *actualCl = 0;
int sz = proxy->Size();
char fmt[] = {"#%09d"};
fmt[3] = '0'+(int)log10(double(sz))+1;
char buf[20];
for (int ii=0;ii<sz;ii++) {
void *p = proxy->At(ii);
if (proxy->HasPointers()) {
p = *((void**)p);
if(!p) continue;
actualCl = valueCl->GetActualClass(p);
p = actualCl->DynamicCast(valueCl,p,0);
}
fCount++;
sprintf(buf,fmt,ii);
ts = bwname;
ts += buf;
fBrowser->Add( p, actualCl, ts );
}
}
}
}
}
ClassImp(TClass)
TClass::TClass() : TDictionary(), fNew(0), fNewArray(0), fDelete(0),
fDeleteArray(0), fDestructor(0), fDirAutoAdd(0), fSizeof(-1),
fVersionUsed(kFALSE), fOffsetStreamer(0), fStreamerType(kNone),
fCurrentInfo(0), fRefStart(0), fRefProxy(0),
fSchemaRules( 0 )
{
fDeclFileLine = -2;
fBase = 0;
fData = 0;
fMethod = 0;
fRealData = 0;
fClassInfo = 0;
fAllPubData = 0;
fAllPubMethod = 0;
fCheckSum = 0;
fCollectionProxy= 0;
fStreamer = 0;
fStreamerInfo = 0;
fShowMembers = 0;
fIsA = 0;
fGlobalIsA = 0;
fIsAMethod = 0;
fTypeInfo = 0;
fInterStreamer = 0;
ResetInstanceCount();
fClassMenuList = new TList();
fClassMenuList->Add(new TClassMenuItem(TClassMenuItem::kPopupStandardList, this));
fContextMenuTitle = "";
fConversionStreamerInfo = 0;
}
TClass::TClass(const char *name, Bool_t silent) : TDictionary(), fNew(0), fNewArray(0),
fDelete(0), fDeleteArray(0), fDestructor(0),
fDirAutoAdd(0),
fSizeof(-1), fVersionUsed(kFALSE),
fOffsetStreamer(0), fStreamerType(kNone),
fCurrentInfo(0), fRefStart(0), fRefProxy(0),
fSchemaRules(0)
{
if (!gROOT)
::Fatal("TClass::TClass", "ROOT system not initialized");
SetName(name);
fClassVersion = 0;
fDeclFileName = "";
fImplFileName = "";
fDeclFileLine = -2;
fImplFileLine = 0;
fBase = 0;
fData = 0;
fMethod = 0;
fRealData = 0;
fClassInfo = 0;
fAllPubData = 0;
fAllPubMethod = 0;
fCheckSum = 0;
fCollectionProxy= 0;
fTypeInfo = 0;
fIsA = 0;
fGlobalIsA = 0;
fIsAMethod = 0;
fShowMembers = 0;
fStreamerInfo = 0;
fStreamer = 0;
fInterStreamer = 0;
ResetInstanceCount();
fClassMenuList = new TList();
fContextMenuTitle = "";
fClassMenuList->Add(new TClassMenuItem(TClassMenuItem::kPopupStandardList, this));
if (!fClassInfo) {
SetBit(kLoading);
if (!gInterpreter)
::Fatal("TClass::TClass", "gInterpreter not initialized");
gInterpreter->SetClassInfo(this);
if (!fClassInfo) {
gInterpreter->InitializeDictionaries();
gInterpreter->SetClassInfo(this);
}
if (!silent && !fClassInfo && fName.First('@')==kNPOS)
::Warning("TClass::TClass", "no dictionary for class %s is available", name);
ResetBit(kLoading);
}
if (fClassInfo) SetTitle(gCint->ClassInfo_Title(fClassInfo));
fConversionStreamerInfo = 0;
}
TClass::TClass(const char *name, Version_t cversion,
const char *dfil, const char *ifil, Int_t dl, Int_t il, Bool_t silent)
: TDictionary(), fNew(0), fNewArray(0), fDelete(0), fDeleteArray(0),
fDestructor(0), fDirAutoAdd(0), fSizeof(-1), fVersionUsed(kFALSE), fOffsetStreamer(0),
fStreamerType(kNone), fCurrentInfo(0), fRefStart(0), fRefProxy(0),
fSchemaRules(0)
{
Init(name,cversion, 0, 0, 0, dfil, ifil, dl, il,silent);
SetBit(kUnloaded);
}
TClass::TClass(const char *name, Version_t cversion,
const type_info &info, TVirtualIsAProxy *isa,
ShowMembersFunc_t showmembers,
const char *dfil, const char *ifil, Int_t dl, Int_t il,
Bool_t silent)
: TDictionary(), fNew(0), fNewArray(0), fDelete(0), fDeleteArray(0),
fDestructor(0), fDirAutoAdd(0), fSizeof(-1), fVersionUsed(kFALSE), fOffsetStreamer(0),
fStreamerType(kNone), fCurrentInfo(0), fRefStart(0), fRefProxy(0),
fSchemaRules( 0 )
{
Init(name, cversion, &info, isa, showmembers, dfil, ifil, dl, il, silent);
}
void TClass::ForceReload (TClass* oldcl)
{
TClass::RemoveClass(oldcl);
if (oldcl->CanIgnoreTObjectStreamer()) {
IgnoreTObjectStreamer();
}
TVirtualStreamerInfo *info;
TIter next(oldcl->GetStreamerInfos());
while ((info = (TVirtualStreamerInfo*)next())) {
info->Clear("build");
info->SetClass(this);
fStreamerInfo->AddAtAndExpand(info,info->GetClassVersion());
}
oldcl->GetStreamerInfos()->Clear();
oldcl->ReplaceWith(this);
delete oldcl;
}
void TClass::Init(const char *name, Version_t cversion,
const type_info *typeinfo, TVirtualIsAProxy *isa,
ShowMembersFunc_t showmembers,
const char *dfil, const char *ifil, Int_t dl, Int_t il,
Bool_t silent)
{
if (!gROOT)
::Fatal("TClass::TClass", "ROOT system not initialized");
SetName(name);
fClassVersion = cversion;
fDeclFileName = dfil ? dfil : "";
fImplFileName = ifil ? ifil : "";
fDeclFileLine = dl;
fImplFileLine = il;
fBase = 0;
fData = 0;
fMethod = 0;
fRealData = 0;
fClassInfo = 0;
fAllPubData = 0;
fAllPubMethod = 0;
fCheckSum = 0;
fCollectionProxy= 0;
fTypeInfo = typeinfo;
fIsA = isa;
if ( fIsA ) fIsA->SetClass(this);
fGlobalIsA = 0;
fIsAMethod = 0;
fShowMembers = showmembers;
fStreamer = 0;
fStreamerInfo = new TObjArray(fClassVersion+2+10,-1);
fProperty = -1;
fInterStreamer = 0;
fClassMenuList = 0;
fContextMenuTitle = "";
fConversionStreamerInfo = 0;
ResetInstanceCount();
TClass *oldcl = (TClass*)gROOT->GetListOfClasses()->FindObject(name);
if (oldcl && oldcl->TestBit(kLoading)) {
return;
}
if (oldcl) {
gROOT->RemoveClass(oldcl);
if (oldcl->CanIgnoreTObjectStreamer()) {
IgnoreTObjectStreamer();
}
TVirtualStreamerInfo *info;
TIter next(oldcl->GetStreamerInfos());
while ((info = (TVirtualStreamerInfo*)next())) {
info->Clear("build");
info->SetClass(this);
fStreamerInfo->AddAtAndExpand(info,info->GetClassVersion());
}
oldcl->GetStreamerInfos()->Clear();
}
SetBit(kLoading);
TClass::AddClass(this);
Bool_t isStl = kFALSE;
if (!fClassInfo) {
Bool_t shouldLoad = kFALSE;
isStl = TClassEdit::IsSTLCont(name);
if (gInterpreter->CheckClassInfo(name)) shouldLoad = kTRUE;
else if (fImplFileLine>=0) {
shouldLoad = ! isStl;
}
if (shouldLoad) {
if (!gInterpreter)
::Fatal("TClass::TClass", "gInterpreter not initialized");
gInterpreter->SetClassInfo(this);
if (!fClassInfo) {
gInterpreter->InitializeDictionaries();
gInterpreter->SetClassInfo(this);
if (IsZombie()) {
TClass::RemoveClass(this);
return;
}
}
}
}
if (!silent && !fClassInfo && !isStl && fName.First('@')==kNPOS)
::Warning("TClass::TClass", "no dictionary for class %s is available", name);
fgClassCount++;
SetUniqueID(fgClassCount);
TString resolvedThis;
if (strchr (name, '<')) {
resolvedThis = TClassEdit::ResolveTypedef (name, kTRUE);
if (resolvedThis != name) {
if (!fgClassTypedefHash) {
fgClassTypedefHash = new THashTable (100, 5);
fgClassTypedefHash->SetOwner (kTRUE);
}
fgClassTypedefHash->Add (new TNameMapNode (resolvedThis, name));
SetBit (kHasNameMapNode);
}
TString resolvedShort =
TClassEdit::ResolveTypedef
(TClassEdit::ShortType(name,
TClassEdit::kDropStlDefault).c_str(),
kTRUE);
if (resolvedShort != name) {
if (!fgClassShortTypedefHash) {
fgClassShortTypedefHash = new THashTable (100, 5);
fgClassShortTypedefHash->SetOwner (kTRUE);
}
fgClassShortTypedefHash->Add (new TNameMapNode (resolvedShort, name));
SetBit (kHasNameMapNode);
}
}
if (oldcl) {
oldcl->ReplaceWith(this);
delete oldcl;
} else if (resolvedThis.Length() > 0 && fgClassTypedefHash) {
if (resolvedThis != name) {
oldcl = (TClass*)gROOT->GetListOfClasses()->FindObject(resolvedThis);
if (oldcl && oldcl != this)
ForceReload (oldcl);
}
TIter next( fgClassTypedefHash->GetListForObject (resolvedThis) );
while ( TNameMapNode* htmp = static_cast<TNameMapNode*> (next()) ) {
if (resolvedThis != htmp->String()) continue;
oldcl = (TClass*)gROOT->GetListOfClasses()->FindObject(htmp->fOrigName);
if (oldcl && oldcl != this) {
ForceReload (oldcl);
}
}
}
if (fClassInfo) SetTitle(gCint->ClassInfo_Title(fClassInfo));
ResetBit(kLoading);
fClassMenuList = new TList();
fClassMenuList->Add(new TClassMenuItem(TClassMenuItem::kPopupStandardList,this));
Int_t stl = TClassEdit::IsSTLCont(GetName(), 0);
if ( stl || !strncmp(GetName(),"stdext::hash_",13) || !strncmp(GetName(),"__gnu_cxx::hash_",16) ) {
fCollectionProxy = TVirtualStreamerInfo::Factory()->GenEmulatedProxy( GetName() );
fSizeof = fCollectionProxy->Sizeof();
if (fStreamer==0) {
fStreamer = TVirtualStreamerInfo::Factory()->GenEmulatedClassStreamer( GetName() );
}
}
}
TClass::TClass(const TClass& cl) :
TDictionary(cl),
fStreamerInfo(cl.fStreamerInfo),
fConversionStreamerInfo( cl.fConversionStreamerInfo ),
fRealData(cl.fRealData),
fBase(cl.fBase),
fData(cl.fData),
fMethod(cl.fMethod),
fAllPubData(cl.fAllPubData),
fAllPubMethod(cl.fAllPubMethod),
fDeclFileName(cl.fDeclFileName),
fImplFileName(cl.fImplFileName),
fDeclFileLine(cl.fDeclFileLine),
fImplFileLine(cl.fImplFileLine),
fInstanceCount(cl.fInstanceCount),
fOnHeap(cl.fOnHeap),
fCheckSum(cl.fCheckSum),
fCollectionProxy(cl.fCollectionProxy),
fClassVersion(cl.fClassVersion),
fClassInfo(cl.fClassInfo),
fContextMenuTitle(cl.fContextMenuTitle),
fClassMenuList(cl.fClassMenuList),
fTypeInfo(cl.fTypeInfo),
fShowMembers(cl.fShowMembers),
fStreamer(cl.fStreamer),
fSharedLibs(cl.fSharedLibs),
fIsA(cl.fIsA),
fGlobalIsA(cl.fGlobalIsA),
fIsAMethod(cl.fIsAMethod),
fNew(cl.fNew),
fNewArray(cl.fNewArray),
fDelete(cl.fDelete),
fDeleteArray(cl.fDeleteArray),
fDestructor(cl.fDestructor),
fDirAutoAdd(cl.fDirAutoAdd),
fSizeof(cl.fSizeof),
fVersionUsed(cl.fVersionUsed),
fProperty(cl.fProperty),
fInterStreamer(cl.fInterStreamer),
fOffsetStreamer(cl.fOffsetStreamer),
fStreamerType(cl.fStreamerType),
fCurrentInfo(cl.fCurrentInfo),
fRefStart(cl.fRefStart)
{
R__ASSERT(0 );
}
TClass& TClass::operator=(const TClass& cl)
{
if(this!=&cl) {
R__ASSERT(0 );
}
return *this;
}
TClass::~TClass()
{
if (fgClassTypedefHash && TestBit (kHasNameMapNode)) {
TString resolvedThis = TClassEdit::ResolveTypedef (GetName(), kTRUE);
TIter next (fgClassTypedefHash->GetListForObject (resolvedThis));
while ( TNameMapNode* htmp = static_cast<TNameMapNode*> (next()) ) {
if (resolvedThis == htmp->String() && htmp->fOrigName == GetName()) {
fgClassTypedefHash->Remove (htmp);
delete htmp;
break;
}
}
}
if (fgClassShortTypedefHash && TestBit (kHasNameMapNode)) {
TString resolvedShort =
TClassEdit::ResolveTypedef
(TClassEdit::ShortType(GetName(),
TClassEdit::kDropStlDefault).c_str(),
kTRUE);
TIter next (fgClassShortTypedefHash->GetListForObject (resolvedShort));
while ( TNameMapNode* htmp = static_cast<TNameMapNode*> (next()) ) {
if (resolvedShort == htmp->String() && htmp->fOrigName == GetName()) {
fgClassShortTypedefHash->Remove (htmp);
delete htmp;
break;
}
}
}
delete fStreamer; fStreamer =0;
delete fAllPubData; fAllPubData =0;
delete fAllPubMethod; fAllPubMethod=0;
if (fRefStart) {
fRefStart->ListReset();
fRefStart = 0;
}
if (fBase)
fBase->Delete();
delete fBase; fBase=0;
if (fData)
fData->Delete();
delete fData; fData = 0;
if (fMethod)
fMethod->Delete();
delete fMethod; fMethod=0;
if (fRealData)
fRealData->Delete();
delete fRealData; fRealData=0;
if (fStreamerInfo)
fStreamerInfo->Delete();
delete fStreamerInfo; fStreamerInfo=0;
if (fDeclFileLine >= -1)
TClass::RemoveClass(this);
gCint->ClassInfo_Delete(fClassInfo);
fClassInfo=0;
if (fClassMenuList)
fClassMenuList->Delete();
delete fClassMenuList; fClassMenuList=0;
if ( fInterStreamer ) gCint->CallFunc_Delete((CallFunc_t*)fInterStreamer);
fInterStreamer=0;
if ( fIsA ) delete fIsA;
if ( fRefProxy ) fRefProxy->Release();
fRefProxy = 0;
delete fStreamer;
delete fCollectionProxy;
delete fIsAMethod;
delete fSchemaRules;
delete fConversionStreamerInfo;
}
void TClass::AdoptSchemaRules( ROOT::TSchemaRuleSet *rules )
{
delete fSchemaRules;
fSchemaRules = rules;
fSchemaRules->SetClass( this );
}
const ROOT::TSchemaRuleSet* TClass::GetSchemaRules() const
{
return fSchemaRules;
}
ROOT::TSchemaRuleSet* TClass::GetSchemaRules(Bool_t create)
{
if (create && fSchemaRules == 0) {
fSchemaRules = new ROOT::TSchemaRuleSet();
fSchemaRules->SetClass( this );
}
return fSchemaRules;
}
void TClass::AddImplFile(const char* filename, int line) {
fImplFileName = filename;
fImplFileLine = line;
}
void TClass::AddRef(TClassRef *ref)
{
if (fRefStart==0) {
fRefStart = ref;
} else {
fRefStart->fPrevious = ref;
ref->fNext = fRefStart;
fRefStart = ref;
}
}
Int_t TClass::AutoBrowse(TObject *obj, TBrowser *b)
{
if (!obj) return 0;
char cbuf[1000]; *cbuf=0;
TAutoInspector insp(b);
obj->ShowMembers(insp,cbuf);
return insp.fCount;
}
Int_t TClass::Browse(void *obj, TBrowser *b) const
{
if (!obj) return 0;
if (fShowMembers) {
char cbuf[1000]; *cbuf=0;
TClass *actual = GetActualClass(obj);
if (actual!=this) {
actual->Browse(obj,b);
} else {
TAutoInspector insp(b);
fShowMembers(obj,insp,cbuf);
return insp.fCount;
}
} else if (GetCollectionProxy()) {
} else if (IsTObject()) {
if (!fInterStreamer) {
const_cast<TClass*>(this)->CalculateStreamerOffset();
}
TObject* realTObject = (TObject*)((size_t)obj + fOffsetStreamer);
realTObject->Browse(b);
}
return 0;
}
void TClass::Browse(TBrowser *b)
{
if (!fClassInfo) return;
if (b) {
if (!fRealData) BuildRealData();
b->Add(GetListOfDataMembers(), "Data Members");
b->Add(GetListOfRealData(), "Real Data Members");
b->Add(GetListOfMethods(), "Methods");
b->Add(GetListOfBases(), "Base Classes");
}
}
void TClass::BuildRealData(void* pointer)
{
if (fRealData) {
return;
}
if (!fClassInfo || TClassEdit::IsSTLCont(GetName(), 0)) {
fRealData = new TList;
BuildEmulatedRealData("", 0, this);
return;
}
void* realDataObject = pointer;
if ((!pointer) && (Property() & kIsAbstract)) {
return;
}
if (!realDataObject) {
if (!strcmp(GetName(), "TROOT")) {
realDataObject = gROOT;
} else if (!strcmp(GetName(), "TGWin32")) {
realDataObject = gVirtualX;
} else if (!strcmp(GetName(), "TGQt")) {
realDataObject = gVirtualX;
} else {
realDataObject = New();
}
}
if (realDataObject) {
char parent[256];
parent[0] = 0;
fRealData = new TList;
TBuildRealData brd(realDataObject, this);
Bool_t isATObject = InheritsFrom(TObject::Class());
if (fShowMembers) {
fShowMembers(realDataObject, brd, parent);
} else {
if (isATObject) {
if (!fInterStreamer) {
CalculateStreamerOffset();
}
TObject* realTObject = (TObject*)((size_t)realDataObject + fOffsetStreamer);
realTObject->ShowMembers(brd, parent);
} else {
R__LOCKGUARD2(gCINTMutex);
CallFunc_t *func = gCint->CallFunc_Factory();
void* address = 0;
Long_t offset = 0;
gCint->CallFunc_SetFuncProto(func,fClassInfo,"ShowMembers", "TMemberInspector&,char*", &offset);
if (!gCint->CallFunc_IsValid(func)) {
if (strcmp(GetName(), "string") != 0) {
Error("BuildRealData", "Cannot find any ShowMembers function for %s!", GetName());
}
} else {
gCint->CallFunc_SetArg(func,(long) &brd);
gCint->CallFunc_SetArg(func,(long) parent);
address = (void*) (((long) realDataObject) + offset);
gCint->CallFunc_Exec(func,address);
}
gCint->CallFunc_Delete(func);
}
}
TBaseClass* base = 0;
TIter next(GetListOfBases());
while ((base = (TBaseClass*) next())) {
if (base->IsSTLContainer()) {
continue;
}
TClass* c = base->GetClassPointer();
if (c) {
c->BuildRealData(((char*) realDataObject) + base->GetDelta());
}
}
}
if (!pointer && realDataObject && (realDataObject != gROOT) && (realDataObject != gVirtualX)) {
Int_t delta = GetBaseClassOffset(TObject::Class());
if (delta >= 0) {
TObject* tobj = (TObject*) (((char*) realDataObject) + delta);
tobj->SetBit(kZombie);
delete tobj;
tobj = 0;
} else {
Destructor(realDataObject);
realDataObject = 0;
}
}
}
void TClass::BuildEmulatedRealData(const char *name, Long_t offset, TClass *cl)
{
TIter next(GetStreamerInfo()->GetElements());
TStreamerElement *element;
while ((element = (TStreamerElement*)next())) {
Int_t etype = element->GetType();
Long_t eoffset = element->GetOffset();
TClass *cle = element->GetClassPointer();
if (etype == TVirtualStreamerInfo::kTObject ||
etype == TVirtualStreamerInfo::kTNamed ||
etype == TVirtualStreamerInfo::kBase) {
if (cle) cle->BuildEmulatedRealData(name,offset+eoffset,cl);
} else if (etype == TVirtualStreamerInfo::kObject || etype == TVirtualStreamerInfo::kAny) {
TRealData *rd = new TRealData(Form("%s%s",name,element->GetFullName()),offset+eoffset,0);
if (gDebug > 0) printf(" Class: %s, adding TRealData=%s, offset=%ld\n",cl->GetName(),rd->GetName(),rd->GetThisOffset());
cl->GetListOfRealData()->Add(rd);
TString rdname(Form("%s%s.",name,element->GetFullName()));
if (cle) cle->BuildEmulatedRealData(rdname,offset+eoffset,cl);
} else {
TString rdname(Form("%s%s",name,element->GetFullName()));
TRealData *rd = new TRealData(rdname,offset+eoffset,0);
if (gDebug > 0) printf(" Class: %s, adding TRealData=%s, offset=%ld\n",cl->GetName(),rd->GetName(),rd->GetThisOffset());
cl->GetListOfRealData()->Add(rd);
}
}
}
void TClass::CalculateStreamerOffset()
{
if (!fInterStreamer && fClassInfo) {
CallFunc_t *f = gCint->CallFunc_Factory();
gCint->CallFunc_SetFuncProto(f,fClassInfo,"Streamer","TBuffer&",&fOffsetStreamer);
fInterStreamer = f;
fOffsetStreamer = GetBaseClassOffset(TObject::Class());
}
}
Bool_t TClass::CanSplit() const
{
if (fRefProxy) return kFALSE;
if (InheritsFrom("TRef")) return kFALSE;
if (InheritsFrom("TRefArray")) return kFALSE;
if (InheritsFrom("TArray")) return kFALSE;
if (fName.BeginsWith("TVectorT<")) return kFALSE;
if (fName.BeginsWith("TMatrixT<")) return kFALSE;
if (InheritsFrom("TCollection") && !InheritsFrom("TClonesArray")) return kFALSE;
if (GetShowMembersWrapper()==0 && GetStreamer()!=0) {
if (GetCollectionProxy()==0) {
return kFALSE;
} else {
if (GetCollectionProxy()->HasPointers()) return kFALSE;
TClass *valueClass = GetCollectionProxy()->GetValueClass();
if (valueClass == 0) return kFALSE;
if (valueClass==TString::Class() || valueClass==TClass::GetClass("string"))
return kFALSE;
if (!valueClass->CanSplit()) return kFALSE;
if (valueClass->GetCollectionProxy() != 0) return kFALSE;
Int_t stl = -TClassEdit::IsSTLCont(GetName(), 0);
if ((stl==TClassEdit::kMap || stl==TClassEdit::kMultiMap)
&& valueClass->GetClassInfo()==0)
{
return kFALSE;
}
}
}
TClass *ncThis = const_cast<TClass*>(this);
TIter nextb(ncThis->GetListOfBases());
TBaseClass *base;
while((base = (TBaseClass*)nextb())) {
if (!TClass::GetClass(base->GetName())) return kFALSE;
}
return kTRUE;
}
void TClass::CopyCollectionProxy(const TVirtualCollectionProxy &orig)
{
delete fCollectionProxy;
fCollectionProxy = orig.Generate();
}
void TClass::Draw(Option_t *option)
{
if (!fClassInfo) return;
TVirtualPad *padsav = gPad;
TString opt=option;
if (!padsav || !opt.Contains("same")) {
TVirtualPad *padclass = (TVirtualPad*)(gROOT->GetListOfCanvases())->FindObject("R__class");
if (!padclass) {
gROOT->ProcessLine("new TCanvas(\"R__class\",\"class\",20,20,1000,750);");
} else {
padclass->cd();
}
}
if (gPad) gPad->DrawClassObject(this,option);
if (padsav) padsav->cd();
}
void TClass::Dump(void *obj) const
{
Printf("==>Dumping object at:%lx, class=%s\n",(Long_t)obj,GetName());
char parent[256];
parent[0] = 0;
TDumpMembers dm;
if (fShowMembers) {
fShowMembers(obj,dm, parent);
} else {
R__LOCKGUARD2(gCINTMutex);
CallFunc_t *func = gCint->CallFunc_Factory();
void *address;
Long_t offset;
gCint->CallFunc_SetFuncProto(func,fClassInfo,"ShowMembers","TMemberInspector&,char*", &offset);
if (!gCint->CallFunc_IsValid(func)) {
Printf("==>No Showmembers functions ... dumping disabled\n");
} else {
gCint->CallFunc_SetArg(func,(long)&dm);
gCint->CallFunc_SetArg(func,(long)parent);
address = (void*)((long)obj + offset);
gCint->CallFunc_Exec(func,address);
}
gCint->CallFunc_Delete(func);
}
}
char *TClass::EscapeChars(const char *text) const
{
static char name[128];
Int_t nch = strlen(text);
if (nch > 127) nch = 127;
Int_t icur = -1;
for (Int_t i = 0; i < nch; i++) {
icur++;
if (text[i] == '\"' || text[i] == '[' || text[i] == '~' ||
text[i] == ']' || text[i] == '&' || text[i] == '#' ||
text[i] == '!' || text[i] == '^' || text[i] == '<' ||
text[i] == '?' || text[i] == '>') {
name[icur] = '@';
icur++;
}
name[icur] = text[i];
}
name[icur+1] = 0;
return name;
}
TClass *TClass::GetActualClass(const void *object) const
{
if (object==0 || !IsLoaded() ) return (TClass*)this;
if (fIsA) {
return (*fIsA)(object);
} else if (fGlobalIsA) {
return fGlobalIsA(this,object);
} else {
if (fIsAMethod==0) {
fIsAMethod = new TMethodCall((TClass*)this, "IsA", "");
if (!fIsAMethod->GetMethod()) {
delete fIsAMethod;
fIsAMethod = 0;
Error("IsA","Can not find any IsA function for %s!",GetName());
return (TClass*)this;
}
}
char * char_result = 0;
fIsAMethod->Execute((void*)object, &char_result);
return (TClass*)char_result;
}
}
TClass *TClass::GetBaseClass(const char *classname)
{
if (strcmp(GetName(), classname) == 0) return this;
if (!fClassInfo) return 0;
TObjLink *lnk = GetListOfBases() ? fBase->FirstLink() : 0;
while (lnk) {
TClass *c, *c1;
TBaseClass *base = (TBaseClass*) lnk->GetObject();
c = base->GetClassPointer();
if (c) {
if (strcmp(c->GetName(), classname) == 0) return c;
c1 = c->GetBaseClass(classname);
if (c1) return c1;
}
lnk = lnk->Next();
}
return 0;
}
TClass *TClass::GetBaseClass(const TClass *cl)
{
if (cl == this) return this;
if (!fClassInfo) return 0;
TObjLink *lnk = GetListOfBases() ? fBase->FirstLink() : 0;
while (lnk) {
TClass *c, *c1;
TBaseClass *base = (TBaseClass*) lnk->GetObject();
c = base->GetClassPointer();
if (c) {
if (cl == c) return c;
c1 = c->GetBaseClass(cl);
if (c1) return c1;
}
lnk = lnk->Next();
}
return 0;
}
Int_t TClass::GetBaseClassOffsetRecurse(const TClass *cl)
{
if (cl == this) return 0;
if (!fClassInfo) {
TVirtualStreamerInfo *sinfo = GetCurrentStreamerInfo();
if (!sinfo) return -1;
TStreamerElement *element;
Int_t offset = 0;
TObjArray &elems = *(sinfo->GetElements());
Int_t size = elems.GetLast()+1;
for(Int_t i=0; i<size; i++) {
element = (TStreamerElement*)elems[i];
if (element->IsA() == TStreamerBase::Class()) {
TStreamerBase *base = (TStreamerBase*)element;
TClass *baseclass = base->GetClassPointer();
if (!baseclass) return -1;
Int_t subOffset = baseclass->GetBaseClassOffsetRecurse(cl);
if (subOffset == -2) return -2;
if (subOffset != -1) return offset+subOffset;
offset += baseclass->Size();
}
}
return -1;
}
TClass *c;
Int_t off;
TBaseClass *inh;
TObjLink *lnk = 0;
if (fBase==0) lnk = GetListOfBases()->FirstLink();
else lnk = fBase->FirstLink();
while (lnk) {
inh = (TBaseClass *)lnk->GetObject();
c = inh->GetClassPointer(kTRUE);
if (c) {
if (cl == c) {
if ((inh->Property() & G__BIT_ISVIRTUALBASE) != 0)
return -2;
return inh->GetDelta();
}
off = c->GetBaseClassOffsetRecurse(cl);
if (off == -2) return -2;
if (off != -1) return off + inh->GetDelta();
}
lnk = lnk->Next();
}
return -1;
}
Int_t TClass::GetBaseClassOffset(const TClass *cl)
{
Int_t offset = GetBaseClassOffsetRecurse (cl);
if (offset == -2) {
if (cl->GetClassInfo()) {
Long_t base_tagnum = gCint->ClassInfo_Tagnum(cl->GetClassInfo());
BaseClassInfo_t *t = gCint->BaseClassInfo_Factory(GetClassInfo());
while (gCint->BaseClassInfo_Next(t,0)) {
if (gCint->BaseClassInfo_Tagnum(t) == base_tagnum) {
if ((gCint->BaseClassInfo_Property(t) & G__BIT_ISVIRTUALBASE) != 0) {
break;
}
int off = gCint->BaseClassInfo_Offset(t);
gCint->BaseClassInfo_Delete(t);
return off;
}
}
gCint->BaseClassInfo_Delete(t);
}
offset = -1;
}
return offset;
}
TClass *TClass::GetBaseDataMember(const char *datamember)
{
if (!fClassInfo) return 0;
TDataMember *dm = GetDataMember(datamember);
if (dm) return this;
TBaseClass *inh;
TIter next(GetListOfBases());
while ((inh = (TBaseClass *) next())) {
TClass *c = inh->GetClassPointer();
if (c) {
TClass *cdm = c->GetBaseDataMember(datamember);
if (cdm) return cdm;
}
}
return 0;
}
namespace {
struct TClassLocalStorage {
TClassLocalStorage() : fCollectionProxy(0), fStreamer(0) {};
TVirtualCollectionProxy *fCollectionProxy;
TClassStreamer *fStreamer;
static TClassLocalStorage *GetStorage(const TClass *cl) {
void **thread_ptr = (*gThreadTsd)(0,1);
if (thread_ptr) {
if (*thread_ptr==0) *thread_ptr = new TExMap();
TExMap *lmap = (TExMap*)(*thread_ptr);
ULong_t hash = TString::Hash(&cl, sizeof(void*));
ULong_t local = 0;
UInt_t slot;
if ((local = (ULong_t)lmap->GetValue(hash, (Long_t)cl, slot)) != 0) {
} else {
local = (ULong_t) new TClassLocalStorage();
lmap->AddAt(slot, hash, (Long_t)cl, local);
}
return (TClassLocalStorage*)local;
}
return 0;
}
};
}
TVirtualCollectionProxy *TClass::GetCollectionProxy() const
{
if (gThreadTsd && fCollectionProxy) {
TClassLocalStorage *local = TClassLocalStorage::GetStorage(this);
if (local == 0) return fCollectionProxy;
if (local->fCollectionProxy==0) local->fCollectionProxy = fCollectionProxy->Generate();
return local->fCollectionProxy;
}
return fCollectionProxy;
}
TClassStreamer *TClass::GetStreamer() const
{
if (gThreadTsd && fStreamer) {
TClassLocalStorage *local = TClassLocalStorage::GetStorage(this);
if (local==0) return fStreamer;
if (local->fStreamer==0) {
local->fStreamer = fStreamer->Generate();
const type_info &orig = ( typeid(*fStreamer) );
const type_info © = ( typeid(*local->fStreamer) );
if (strcmp(orig.name(),copy.name())!=0) {
Warning("GetStreamer","For %s, the TClassStreamer passed does not properly implement the Generate method (%s vs %s\n",GetName(),orig.name(),copy.name());
}
}
return local->fStreamer;
}
return fStreamer;
}
TVirtualIsAProxy* TClass::GetIsAProxy() const
{
return fIsA;
}
TClass *TClass::GetClass(const char *name, Bool_t load, Bool_t silent)
{
if (!name || !strlen(name)) return 0;
if (!gROOT->GetListOfClasses()) return 0;
TClass *cl = (TClass*)gROOT->GetListOfClasses()->FindObject(name);
if (!cl) {
TString resolvedName = TClassEdit::ResolveTypedef(name,kTRUE).c_str();
cl = (TClass*)gROOT->GetListOfClasses()->FindObject(resolvedName);
}
if (cl) {
if (cl->IsLoaded()) return cl;
load = kTRUE;
if (TClassEdit::IsSTLCont(name)) {
const char *altname = gCint->GetInterpreterTypeName(name);
if (altname && strcmp(altname,name)!=0) {
gROOT->GetListOfClasses()->Remove(cl);
TClass *newcl = GetClass(altname,load);
assert(newcl!=cl);
cl->ReplaceWith(newcl);
delete cl;
return newcl;
}
}
} else {
if (!TClassEdit::IsSTLCont(name)) {
TDataType *objType = gROOT->GetType(name, load);
if (objType) {
const char *typdfName = objType->GetTypeName();
if (typdfName && strcmp(typdfName, name)) {
cl = TClass::GetClass(typdfName, load);
return cl;
}
}
} else {
cl = gROOT->FindSTLClass(name,kFALSE);
if (cl) {
if (cl->IsLoaded()) return cl;
return TClass::GetClass(cl->GetName(),kTRUE);
}
}
}
if (!load) return 0;
TClass *loadedcl = 0;
if (cl) loadedcl = gROOT->LoadClass(cl->GetName());
else loadedcl = gROOT->LoadClass(name);
if (loadedcl) return loadedcl;
if (cl) return cl;
static const char *full_string_name = "basic_string<char,char_traits<char>,allocator<char> >";
if (strcmp(name,full_string_name)==0
|| ( strncmp(name,"std::",5)==0 && ((strcmp(name+5,"string")==0)||(strcmp(name+5,full_string_name)==0)))) {
return TClass::GetClass("string");
}
if (TClassEdit::IsSTLCont(name)) {
return gROOT->FindSTLClass(name,kTRUE);
} else if ( strncmp(name,"std::",5)==0 ) {
return TClass::GetClass(name+5,load);
} else if ( strstr(name,"std::") != 0 ) {
TString rname( TClassEdit::ResolveTypedef(name,kTRUE) );
if (rname != name) {
return TClass::GetClass( rname, load );
}
}
if (!strcmp(name, "long long")||!strcmp(name,"unsigned long long"))
return 0;
char *modifiable_name = new char[strlen(name)*2];
strcpy(modifiable_name,name);
if (gInterpreter->CheckClassInfo(modifiable_name)) {
const char *altname = gInterpreter->GetInterpreterTypeName(modifiable_name,kTRUE);
if (strcmp(altname,name)!=0) {
delete [] modifiable_name;
return GetClass(altname,load);
}
TClass *ncl = new TClass(name, 1, 0, 0, -1, -1, silent);
if (!ncl->IsZombie()) {
delete [] modifiable_name;
return ncl;
}
delete ncl;
}
delete [] modifiable_name;
return 0;
}
TClass *TClass::GetClass(const type_info& typeinfo, Bool_t load, Bool_t )
{
if (!gROOT->GetListOfClasses()) return 0;
TClass* cl = fgIdMap->Find(typeinfo.name());
if (cl) {
if (cl->IsLoaded()) return cl;
load = kTRUE;
} else {
}
if (!load) return 0;
VoidFuncPtr_t dict = TClassTable::GetDict(typeinfo);
if (dict) {
(dict)();
cl = GetClass(typeinfo,kFALSE);
if (cl) cl->PostLoadCheck();
return cl;
}
if (cl) return cl;
TIter next(gROOT->GetListOfClassGenerators());
TClassGenerator *gen;
while( (gen = (TClassGenerator*) next()) ) {
cl = gen->GetClass(typeinfo,load);
if (cl) {
cl->PostLoadCheck();
return cl;
}
}
return 0;
}
VoidFuncPtr_t TClass::GetDict (const char *cname)
{
return TClassTable::GetDict(cname);
}
VoidFuncPtr_t TClass::GetDict (const type_info& info)
{
return TClassTable::GetDict(info);
}
TDataMember *TClass::GetDataMember(const char *datamember) const
{
if (!fClassInfo) return 0;
const Int_t size_buffer = 256;
char memb[size_buffer];
char *s = (char*)datamember;
while (*s == '*') s++;
size_t len = strlen(s);
if (len > size_buffer - 2)
len = size_buffer - 2;
strncpy(memb, s, len);
memb[len] = 0;
if ((s = strchr(memb, '['))) {
*s = 0;
len = strlen(memb);
}
TDataMember *dm;
TIter next(((TClass*)this)->GetListOfDataMembers());
while ((dm = (TDataMember *) next()))
if (len >= size_buffer - 2) {
if (strncmp(memb, dm->GetName(), len) == 0)
return dm;
} else
if (strcmp(memb, dm->GetName()) == 0)
return dm;
return 0;
}
Long_t TClass::GetDataMemberOffset(const char *name) const
{
TRealData *rd = GetRealData(name);
if (rd) return rd->GetThisOffset();
return 0;
}
TRealData* TClass::GetRealData(const char* name) const
{
if (!fRealData) {
const_cast<TClass*>(this)->BuildRealData();
}
if (!fRealData) {
return 0;
}
if (!name) {
return 0;
}
TRealData* rd = (TRealData*) fRealData->FindObject(name);
if (rd) {
return rd;
}
std::string givenName(name);
std::string::size_type firstBracket = givenName.find_first_of("[");
if (firstBracket != std::string::npos) {
std::string nameNoDim(givenName.substr(0, firstBracket));
TObjLink* lnk = fRealData->FirstLink();
while (lnk) {
TObject* obj = lnk->GetObject();
std::string objName(obj->GetName());
std::string::size_type pos = objName.find_first_of("[");
if (pos != std::string::npos) {
objName.erase(pos);
if (objName == nameNoDim) {
return static_cast<TRealData*>(obj);
}
}
lnk = lnk->Next();
}
}
std::ostringstream ptrname;
ptrname << "*" << givenName;
rd = (TRealData*) fRealData->FindObject(ptrname.str().c_str());
if (rd) {
return rd;
}
std::string::size_type firstDot = givenName.find_first_of(".");
if (firstDot == std::string::npos) {
return 0;
}
std::string::size_type lastDot = givenName.find_last_of(".");
std::ostringstream starname;
starname << givenName.substr(0, lastDot) << ".*" << givenName.substr(lastDot + 1);
rd = (TRealData*) fRealData->FindObject(starname.str().c_str());
if (rd) {
return rd;
}
std::string firstDotName(givenName.substr(firstDot + 1));
rd = (TRealData*) fRealData->FindObject(firstDotName.c_str());
if (rd) {
return rd;
}
std::string::size_type firstDotBracket = firstDotName.find_first_of("[");
if (firstDotBracket != std::string::npos) {
std::string nameNoDim(firstDotName.substr(0, firstDotBracket));
TObjLink* lnk = fRealData->FirstLink();
while (lnk) {
TObject* obj = lnk->GetObject();
std::string objName(obj->GetName());
std::string::size_type pos = objName.find_first_of("[");
if (pos != std::string::npos) {
objName.erase(pos);
if (objName == nameNoDim) {
return static_cast<TRealData*>(obj);
}
}
lnk = lnk->Next();
}
}
ptrname.str("");
ptrname << "*" << firstDotName;
rd = (TRealData*) fRealData->FindObject(ptrname.str().c_str());
if (rd) {
return rd;
}
std::string::size_type bracket = starname.str().find_first_of("[");
if (bracket == std::string::npos) {
return 0;
}
rd = (TRealData*) fRealData->FindObject(starname.str().substr(0, bracket).c_str());
if (rd) {
return rd;
}
return 0;
}
const char *TClass::GetSharedLibs()
{
if (!gInterpreter) return 0;
if (fSharedLibs.IsNull())
fSharedLibs = gInterpreter->GetClassSharedLibs(fName);
return !fSharedLibs.IsNull() ? fSharedLibs.Data() : 0;
}
TList *TClass::GetListOfBases()
{
if (!fBase) {
if (!fClassInfo) return 0;
if (!gInterpreter)
Fatal("GetListOfBases", "gInterpreter not initialized");
gInterpreter->CreateListOfBaseClasses(this);
}
return fBase;
}
TList *TClass::GetListOfDataMembers()
{
if (!fClassInfo) {
if (!fData) fData = new TList;
return fData;
}
if (!fData) {
if (!gInterpreter)
Fatal("GetListOfDataMembers", "gInterpreter not initialized");
gInterpreter->CreateListOfDataMembers(this);
}
return fData;
}
TList *TClass::GetListOfMethods()
{
if (!fClassInfo) {
if (!fMethod) fMethod = new TList;
return fMethod;
}
if (!fMethod) {
if (!gInterpreter)
Fatal("GetListOfMethods", "gInterpreter not initialized");
gInterpreter->CreateListOfMethods(this);
} else {
gInterpreter->UpdateListOfMethods(this);
}
return fMethod;
}
TList *TClass::GetListOfAllPublicMethods()
{
if (!fAllPubMethod) {
fAllPubMethod = new TList;
fAllPubMethod->AddAll(GetListOfMethods());
TIter nextBaseClass(GetListOfBases());
TBaseClass *pB;
TMethod *p;
while ((pB = (TBaseClass*) nextBaseClass())) {
if (!pB->GetClassPointer()) continue;
TIter next(pB->GetClassPointer()->GetListOfAllPublicMethods());
TList temp;
while ((p = (TMethod*) next()))
if (!fAllPubMethod->Contains(p->GetName()))
temp.Add(p);
fAllPubMethod->AddAll(&temp);
temp.Clear();
}
TIter next(fAllPubMethod);
while ((p = (TMethod*) next()))
if (!(p->Property() & kIsPublic)) fAllPubMethod->Remove(p);
}
return fAllPubMethod;
}
TList *TClass::GetListOfAllPublicDataMembers()
{
if (!fAllPubData) {
fAllPubData = new TList;
TIter next(GetListOfDataMembers());
TDataMember *p;
while ((p = (TDataMember*) next()))
if (p->Property() & kIsPublic) fAllPubData->Add(p);
TIter next_BaseClass(GetListOfBases());
TBaseClass *pB;
while ((pB = (TBaseClass*) next_BaseClass())) {
if (!pB->GetClassPointer()) continue;
fAllPubData->AddAll(pB->GetClassPointer()->GetListOfAllPublicDataMembers() );
}
}
return fAllPubData;
}
void TClass::GetMenuItems(TList *list)
{
if (!fClassInfo) return;
TIter nextBase(GetListOfBases(), kIterBackward);
TBaseClass *baseClass;
while ((baseClass = (TBaseClass *) nextBase())) {
TClass *base = baseClass->GetClassPointer();
if (base) base->GetMenuItems(list);
}
TMethod *method, *m;
TIter next(GetListOfMethods(), kIterBackward);
while ((method = (TMethod*)next())) {
m = (TMethod*)list->FindObject(method->GetName());
if (method->IsMenuItem()) {
if (!m)
list->AddFirst(method);
} else {
if (m && m->GetNargs() == method->GetNargs())
list->Remove(m);
}
}
}
Bool_t TClass::IsFolder(void *obj) const
{
return Browse(obj,(TBrowser*)0);
}
void TClass::RemoveRef(TClassRef *ref)
{
if (ref==fRefStart) {
fRefStart = ref->fNext;
if (fRefStart) fRefStart->fPrevious = 0;
ref->fPrevious = ref->fNext = 0;
} else {
TClassRef *next = ref->fNext;
ref->fPrevious->fNext = next;
if (next) next->fPrevious = ref->fPrevious;
ref->fPrevious = ref->fNext = 0;
}
}
void TClass::ReplaceWith(TClass *newcl, Bool_t recurse) const
{
TIter nextClass(gROOT->GetListOfClasses());
TClass *acl;
TVirtualStreamerInfo *info;
TList tobedeleted;
TString corename( TClassEdit::ResolveTypedef(newcl->GetName()) );
if ( strchr( corename.Data(), '<' ) == 0 ) {
recurse = kFALSE;
}
while ((acl = (TClass*)nextClass())) {
if (recurse && acl!=newcl && acl!=this) {
TString aclCorename( TClassEdit::ResolveTypedef(acl->GetName()) );
if (aclCorename == corename) {
acl->ReplaceWith(newcl, kFALSE);
tobedeleted.Add(acl);
}
}
TIter nextInfo(acl->GetStreamerInfos());
while ((info = (TVirtualStreamerInfo*)nextInfo())) {
info->Update(this, newcl);
}
if (acl->GetCollectionProxy() && acl->GetCollectionProxy()->GetValueClass()==this) {
acl->GetCollectionProxy()->SetValueClass(newcl);
}
}
TIter delIter( &tobedeleted );
while ((acl = (TClass*)delIter())) {
delete acl;
}
}
void TClass::ResetClassInfo(Long_t tagnum)
{
if (fClassInfo && gCint->ClassInfo_Tagnum(fClassInfo) != tagnum) {
gCint->ClassInfo_Init(fClassInfo,(Int_t)tagnum);
if (fBase) {
fBase->Delete();
delete fBase; fBase = 0;
}
}
}
void TClass::ResetMenuList()
{
if (fClassMenuList)
fClassMenuList->Delete();
else
fClassMenuList = new TList();
fClassMenuList->Add(new TClassMenuItem(TClassMenuItem::kPopupStandardList, this));
}
void TClass::MakeCustomMenuList()
{
TClassMenuItem *menuItem;
fClassMenuList->Delete();
TList* methodList = new TList;
GetMenuItems(methodList);
TMethod *method;
TMethodArg *methodArg;
TClass *classPtr = 0;
TIter next(methodList);
while ((method = (TMethod*) next())) {
if (classPtr != method->GetClass()) {
menuItem = new TClassMenuItem(TClassMenuItem::kPopupSeparator, this);
fClassMenuList->AddLast(menuItem);
classPtr = method->GetClass();
}
TString sig;
TList* margsList = method->GetListOfMethodArgs();
TIter nextarg(margsList);
while ((methodArg = (TMethodArg*)nextarg())) {
sig = sig+","+methodArg->GetFullTypeName();
}
if (sig.Length()!=0) sig.Remove(0,1);
menuItem = new TClassMenuItem(TClassMenuItem::kPopupUserFunction, this,
method->GetName(), method->GetName(),0,
sig.Data(),-1,TClassMenuItem::kIsSelf);
if (method->IsMenuItem() == kMenuToggle) menuItem->SetToggle();
fClassMenuList->Add(menuItem);
}
delete methodList;
}
void TClass::Move(void *arenaFrom, void *arenaTo) const
{
if (!fClassInfo && !fCollectionProxy) {
MoveAddressInRepository("TClass::Move",arenaFrom,arenaTo,this);
}
}
TMethod *TClass::GetMethodAny(const char *method)
{
if (!fClassInfo) return 0;
TMethod *m;
TIter next(GetListOfMethods());
while ((m = (TMethod *) next())) {
if (strcmp(method, m->GetName()) == 0) return m;
}
return 0;
}
TMethod *TClass::GetMethodAllAny(const char *method)
{
if (!fClassInfo) return 0;
TMethod *m;
TIter next(GetListOfMethods());
while ((m = (TMethod *) next())) {
if (strcmp(method, m->GetName()) == 0) return m;
}
TBaseClass *base;
TIter nextb(GetListOfBases());
while ((base = (TBaseClass *) nextb())) {
TClass *c = base->GetClassPointer();
if (c) {
m = c->GetMethodAllAny(method);
if (m) return m;
}
}
return 0;
}
TMethod *TClass::GetMethod(const char *method, const char *params)
{
if (!fClassInfo) return 0;
if (!gInterpreter)
Fatal("GetMethod", "gInterpreter not initialized");
Long_t faddr = (Long_t)gInterpreter->GetInterfaceMethod(this, method,
params);
if (!faddr) return 0;
TMethod *m;
#if defined(R__WIN32)
m = GetClassMethod(method,params);
#else
if (faddr == (Long_t)gCint->GetExecByteCode()) {
m = GetClassMethod(method,params);
} else {
m = GetClassMethod(faddr);
}
#endif
if (m) return m;
TBaseClass *base;
TIter next(GetListOfBases());
while ((base = (TBaseClass *) next())) {
TClass *c = base->GetClassPointer();
if (c) {
m = c->GetMethod(method,params);
if (m) return m;
}
}
Error("GetMethod",
"\nDid not find matching TMethod <%s> with \"%s\" for %s",
method,params,GetName());
return 0;
}
TMethod *TClass::GetMethodWithPrototype(const char *method, const char *proto)
{
if (!fClassInfo) return 0;
if (!gInterpreter)
Fatal("GetMethod", "gInterpreter not initialized");
Long_t faddr = (Long_t)gInterpreter->GetInterfaceMethodWithPrototype(this,
method, proto);
if (!faddr) return 0;
TMethod *m = GetClassMethod(faddr);
if (m) return m;
TBaseClass *base;
TIter next(GetListOfBases());
while ((base = (TBaseClass *) next())) {
TClass *c = base->GetClassPointer();
if (c) {
m = c->GetMethodWithPrototype(method,proto);
if (m) return m;
}
}
Error("GetMethod", "Did not find matching TMethod (should never happen)");
return 0;
}
TMethod *TClass::GetClassMethod(Long_t faddr)
{
if (!fClassInfo) return 0;
TMethod *m;
TIter next(GetListOfMethods());
while ((m = (TMethod *) next())) {
if (faddr == (Long_t)m->InterfaceMethod())
return m;
}
return 0;
}
TMethod *TClass::GetClassMethod(const char *name, const char* params)
{
if (!fClassInfo) return 0;
R__LOCKGUARD2(gCINTMutex);
CallFunc_t *func = gCint->CallFunc_Factory();
Long_t offset;
gCint->CallFunc_SetFunc(func,GetClassInfo(), name, params, &offset);
MethodInfo_t *info = gCint->CallFunc_FactoryMethod(func);
TMethod request(info,this);
TMethod *m;
TIter next(GetListOfMethods());
while ((m = (TMethod *) next())) {
if (!strcmp(name,m->GetName())
&&!strcmp(request.GetSignature(),m->GetSignature())) {
gCint->CallFunc_Delete(func);
return m;
}
}
gCint->CallFunc_Delete(func);
return 0;
}
Int_t TClass::GetNdata()
{
if (!fClassInfo) return 0;
TList *lm = GetListOfDataMembers();
if (lm)
return lm->GetSize();
else
return 0;
}
Int_t TClass::GetNmethods()
{
if (!fClassInfo) return 0;
TList *lm = GetListOfMethods();
if (lm)
return lm->GetSize();
else
return 0;
}
TVirtualStreamerInfo* TClass::GetStreamerInfo(Int_t version) const
{
if (version == 0) {
version = fClassVersion;
}
if (!fStreamerInfo) {
fStreamerInfo = new TObjArray(version + 10, -1);
} else {
Int_t ninfos = fStreamerInfo->GetSize();
if ((version < -1) || (version >= ninfos)) {
Error("GetStreamerInfo", "class: %s, attempting to access a wrong version: %d", GetName(), version);
version = 0;
}
}
TVirtualStreamerInfo* sinfo = (TVirtualStreamerInfo*) fStreamerInfo->At(version);
if (!sinfo && (version != fClassVersion)) {
sinfo = (TVirtualStreamerInfo*) fStreamerInfo->At(fClassVersion);
}
if (!sinfo) {
sinfo = TVirtualStreamerInfo::Factory()->NewInfo(const_cast<TClass*>(this));
fStreamerInfo->AddAtAndExpand(sinfo, fClassVersion);
if (gDebug > 0) {
printf("Creating StreamerInfo for class: %s, version: %d\n", GetName(), fClassVersion);
}
if (fClassInfo || fCollectionProxy) {
sinfo->Build();
}
} else {
if (!sinfo->GetOffsets()) {
sinfo->BuildOld();
}
if (sinfo->IsOptimized() && !TVirtualStreamerInfo::CanOptimize()) {
sinfo->Compile();
}
}
if (version == fClassVersion) {
fCurrentInfo = sinfo;
}
return sinfo;
}
void TClass::IgnoreTObjectStreamer(Bool_t ignore)
{
if ( ignore && TestBit(kIgnoreTObjectStreamer)) return;
if (!ignore && !TestBit(kIgnoreTObjectStreamer)) return;
TVirtualStreamerInfo *sinfo = GetCurrentStreamerInfo();
if (sinfo) {
if (sinfo->GetOffsets()) {
Error("IgnoreTObjectStreamer","Must be called before the creation of StreamerInfo");
return;
}
}
if (ignore) SetBit (kIgnoreTObjectStreamer);
else ResetBit(kIgnoreTObjectStreamer);
}
Bool_t TClass::InheritsFrom(const char *classname) const
{
if (strcmp(GetName(), classname) == 0) return kTRUE;
if (!fClassInfo) return InheritsFrom(TClass::GetClass("classname"));
if (((TClass *)this)->GetBaseClass(classname)) return kTRUE;
return kFALSE;
}
Bool_t TClass::InheritsFrom(const TClass *cl) const
{
if (cl == this) return kTRUE;
if (!fClassInfo) {
TVirtualStreamerInfo *sinfo = ((TClass *)this)->GetCurrentStreamerInfo();
if (sinfo==0) sinfo = GetStreamerInfo();
TIter next(sinfo->GetElements());
TStreamerElement *element;
while ((element = (TStreamerElement*)next())) {
if (element->IsA() == TStreamerBase::Class()) {
TClass *clbase = element->GetClassPointer();
if (!clbase) return kFALSE;
if (clbase->InheritsFrom(cl)) return kTRUE;
}
}
return kFALSE;
}
if (((TClass *)this)->GetBaseClass(cl)) return kTRUE;
return kFALSE;
}
void *TClass::DynamicCast(const TClass *cl, void *obj, Bool_t up)
{
if (cl == this) return obj;
if (!fClassInfo) return 0;
Int_t off;
if ((off = GetBaseClassOffset(cl)) != -1) {
if (up)
return (void*)((Long_t)obj+off);
else
return (void*)((Long_t)obj-off);
}
return 0;
}
void *TClass::New(ENewType defConstructor) const
{
void* p = 0;
if (fNew) {
fgCallingNew = defConstructor;
p = fNew(0);
fgCallingNew = kRealNew;
if (!p) {
Error("New", "cannot create object of class %s", GetName());
}
} else if (fClassInfo) {
fgCallingNew = defConstructor;
R__LOCKGUARD2(gCINTMutex);
p = gCint->ClassInfo_New(GetClassInfo());
fgCallingNew = kRealNew;
if (!p) {
Error("New", "cannot create object of class %s", GetName());
}
} else if (!fClassInfo && fCollectionProxy) {
fgCallingNew = defConstructor;
p = fCollectionProxy->New();
fgCallingNew = kRealNew;
if (!p) {
Error("New", "cannot create object of class %s", GetName());
}
} else if (!fClassInfo && !fCollectionProxy) {
Bool_t statsave = GetObjectStat();
SetObjectStat(kFALSE);
TVirtualStreamerInfo* sinfo = GetStreamerInfo();
if (!sinfo) {
Error("New", "Cannot construct class '%s' version %d, no streamer info available!", GetName(), fClassVersion);
return 0;
}
fgCallingNew = defConstructor;
p = sinfo->New();
fgCallingNew = kRealNew;
SetObjectStat(statsave);
if (p) {
RegisterAddressInRepository("New",p,this);
}
} else {
Error("New", "This cannot happen!");
}
return p;
}
void *TClass::New(void *arena, ENewType defConstructor) const
{
void* p = 0;
if (fNew) {
fgCallingNew = defConstructor;
p = fNew(arena);
fgCallingNew = kRealNew;
if (!p) {
Error("New with placement", "cannot create object of class %s version %d at address %p", GetName(), fClassVersion, arena);
}
} else if (fClassInfo) {
fgCallingNew = defConstructor;
R__LOCKGUARD2(gCINTMutex);
p = gCint->ClassInfo_New(GetClassInfo(),arena);
fgCallingNew = kRealNew;
if (!p) {
Error("New with placement", "cannot create object of class %s version %d at address %p", GetName(), fClassVersion, arena);
}
} else if (!fClassInfo && fCollectionProxy) {
fgCallingNew = defConstructor;
p = fCollectionProxy->New(arena);
fgCallingNew = kRealNew;
} else if (!fClassInfo && !fCollectionProxy) {
Bool_t statsave = GetObjectStat();
SetObjectStat(kFALSE);
TVirtualStreamerInfo* sinfo = GetStreamerInfo();
if (!sinfo) {
Error("New with placement", "Cannot construct class '%s' version %d at address %p, no streamer info available!", GetName(), fClassVersion, arena);
return 0;
}
fgCallingNew = defConstructor;
p = sinfo->New(arena);
fgCallingNew = kRealNew;
SetObjectStat(statsave);
if (p) {
RegisterAddressInRepository("TClass::New with placement",p,this);
}
} else {
Error("New with placement", "This cannot happen!");
}
return p;
}
void *TClass::NewArray(Long_t nElements, ENewType defConstructor) const
{
void* p = 0;
if (fNewArray) {
fgCallingNew = defConstructor;
p = fNewArray(nElements, 0);
fgCallingNew = kRealNew;
if (!p) {
Error("NewArray", "cannot create object of class %s version %d", GetName(), fClassVersion);
}
} else if (fClassInfo) {
fgCallingNew = defConstructor;
R__LOCKGUARD2(gCINTMutex);
p = gCint->ClassInfo_New(GetClassInfo(),nElements);
fgCallingNew = kRealNew;
if (!p) {
Error("NewArray", "cannot create object of class %s version %d", GetName(), fClassVersion);
}
} else if (!fClassInfo && fCollectionProxy) {
fgCallingNew = defConstructor;
p = fCollectionProxy->NewArray(nElements);
fgCallingNew = kRealNew;
} else if (!fClassInfo && !fCollectionProxy) {
Bool_t statsave = GetObjectStat();
SetObjectStat(kFALSE);
TVirtualStreamerInfo* sinfo = GetStreamerInfo();
if (!sinfo) {
Error("NewArray", "Cannot construct class '%s' version %d, no streamer info available!", GetName(), fClassVersion);
return 0;
}
fgCallingNew = defConstructor;
p = sinfo->NewArray(nElements);
fgCallingNew = kRealNew;
SetObjectStat(statsave);
if (p) {
RegisterAddressInRepository("TClass::NewArray",p,this);
}
} else {
Error("NewArray", "This cannot happen!");
}
return p;
}
void *TClass::NewArray(Long_t nElements, void *arena, ENewType defConstructor) const
{
void* p = 0;
if (fNewArray) {
fgCallingNew = defConstructor;
p = fNewArray(nElements, arena);
fgCallingNew = kRealNew;
if (!p) {
Error("NewArray with placement", "cannot create object of class %s version %d at address %p", GetName(), fClassVersion, arena);
}
} else if (fClassInfo) {
fgCallingNew = defConstructor;
R__LOCKGUARD2(gCINTMutex);
p = gCint->ClassInfo_New(GetClassInfo(),nElements, arena);
fgCallingNew = kRealNew;
if (!p) {
Error("NewArray with placement", "cannot create object of class %s version %d at address %p", GetName(), fClassVersion, arena);
}
} else if (!fClassInfo && fCollectionProxy) {
fgCallingNew = defConstructor;
p = fCollectionProxy->NewArray(nElements, arena);
fgCallingNew = kRealNew;
} else if (!fClassInfo && !fCollectionProxy) {
Bool_t statsave = GetObjectStat();
SetObjectStat(kFALSE);
TVirtualStreamerInfo* sinfo = GetStreamerInfo();
if (!sinfo) {
Error("NewArray with placement", "Cannot construct class '%s' version %d at address %p, no streamer info available!", GetName(), fClassVersion, arena);
return 0;
}
fgCallingNew = defConstructor;
p = sinfo->NewArray(nElements, arena);
fgCallingNew = kRealNew;
SetObjectStat(statsave);
if (fStreamerType & kEmulated) {
}
if (p) {
RegisterAddressInRepository("TClass::NewArray with placement",p,this);
}
} else {
Error("NewArray with placement", "This cannot happen!");
}
return p;
}
void TClass::Destructor(void *obj, Bool_t dtorOnly)
{
if (obj == 0) return;
void* p = obj;
if (dtorOnly && fDestructor) {
fDestructor(p);
} else if ((!dtorOnly) && fDelete) {
fDelete(p);
} else if (fClassInfo) {
if (dtorOnly) {
gCint->ClassInfo_Destruct(fClassInfo,p);
} else {
gCint->ClassInfo_Delete(fClassInfo,p);
}
} else if (!fClassInfo && fCollectionProxy) {
fCollectionProxy->Destructor(p, dtorOnly);
} else if (!fClassInfo && !fCollectionProxy) {
Bool_t inRepo = kTRUE;
Bool_t verFound = kFALSE;
std::multiset<Version_t> knownVersions;
std::multimap<void*, Version_t>::iterator iter = gObjectVersionRepository.find(p);
if (iter == gObjectVersionRepository.end()) {
inRepo = kFALSE;
} else {
for (; (iter != gObjectVersionRepository.end()) && (iter->first == p); ++iter) {
Version_t ver = iter->second;
knownVersions.insert(ver);
if (ver == fClassVersion) {
verFound = kTRUE;
}
}
}
if (!inRepo || verFound) {
TVirtualStreamerInfo* si = GetStreamerInfo();
if (si) {
si->Destructor(p, dtorOnly);
} else {
Error("Destructor", "No streamer info available for class '%s' version %d at address %p, cannot destruct emulated object!", GetName(), fClassVersion, p);
Error("Destructor", "length of fStreamerInfo is %d", fStreamerInfo->GetSize());
Int_t i = fStreamerInfo->LowerBound();
for (Int_t v = 0; v < fStreamerInfo->GetSize(); ++v, ++i) {
Error("Destructor", "fStreamerInfo->At(%d): %p", i, fStreamerInfo->At(i));
if (fStreamerInfo->At(i) != 0) {
Error("Destructor", "Doing Dump() ...");
((TVirtualStreamerInfo*)fStreamerInfo->At(i))->Dump();
}
}
}
} else {
Error("Destructor", "Loaded class %s version %d is not registered for addr %p", GetName(), fClassVersion, p);
#if 0
TVirtualStreamerInfo* si = (TVirtualStreamerInfo*) fStreamerInfo->At(objVer);
if (si) {
si->Destructor(p, dtorOnly);
} else {
Error("Destructor2", "No streamer info available for class '%s' version %d, cannot destruct object at addr: %p", GetName(), objVer, p);
Error("Destructor2", "length of fStreamerInfo is %d", fStreamerInfo->GetSize());
Int_t i = fStreamerInfo->LowerBound();
for (Int_t v = 0; v < fStreamerInfo->GetSize(); ++v, ++i) {
Error("Destructor2", "fStreamerInfo->At(%d): %p", i, fStreamerInfo->At(i));
if (fStreamerInfo->At(i) != 0) {
Error("Destructor2", "Doing Dump() ...");
((TVirtualStreamerInfo*)fStreamerInfo->At(i))->Dump();
}
}
}
#endif
}
if (inRepo && verFound && p) {
UnregisterAddressInRepository("TClass::Destructor",p,this);
}
} else {
Error("Destructor", "This cannot happen! (class %s)", GetName());
}
}
void TClass::DeleteArray(void *ary, Bool_t dtorOnly)
{
if (ary == 0) return;
void* p = ary;
if (fDeleteArray) {
if (dtorOnly) {
Error("DeleteArray", "Destructor only is not supported!");
} else {
fDeleteArray(ary);
}
} else if (fClassInfo) {
R__LOCKGUARD2(gCINTMutex);
gCint->ClassInfo_DeleteArray(GetClassInfo(),ary, dtorOnly);
} else if (!fClassInfo && fCollectionProxy) {
fCollectionProxy->DeleteArray(ary, dtorOnly);
} else if (!fClassInfo && !fCollectionProxy) {
Bool_t inRepo = kTRUE;
Bool_t verFound = kFALSE;
std::multiset<Version_t> knownVersions;
std::multimap<void*, Version_t>::iterator iter = gObjectVersionRepository.find(p);
if (iter == gObjectVersionRepository.end()) {
inRepo = kFALSE;
} else {
for (; (iter != gObjectVersionRepository.end()) && (iter->first == p); ++iter) {
Version_t ver = iter->second;
knownVersions.insert(ver);
if (ver == fClassVersion) {
verFound = kTRUE;
}
}
}
if (!inRepo || verFound) {
TVirtualStreamerInfo* si = GetStreamerInfo();
if (si) {
si->DeleteArray(ary, dtorOnly);
} else {
Error("DeleteArray", "No streamer info available for class '%s' version %d at address %p, cannot destruct object!", GetName(), fClassVersion, ary);
Error("DeleteArray", "length of fStreamerInfo is %d", fStreamerInfo->GetSize());
Int_t i = fStreamerInfo->LowerBound();
for (Int_t v = 0; v < fStreamerInfo->GetSize(); ++v, ++i) {
Error("DeleteArray", "fStreamerInfo->At(%d): %p", v, fStreamerInfo->At(i));
if (fStreamerInfo->At(i)) {
Error("DeleteArray", "Doing Dump() ...");
((TVirtualStreamerInfo*)fStreamerInfo->At(i))->Dump();
}
}
}
} else {
Error("DeleteArray", "Loaded class version %d is not registered for addr %p", fClassVersion, p);
#if 0
TVirtualStreamerInfo* si = (TVirtualStreamerInfo*) fStreamerInfo->At(objVer);
if (si) {
si->DeleteArray(ary, dtorOnly);
} else {
Error("DeleteArray", "No streamer info available for class '%s' version %d at address %p, cannot destruct object!", GetName(), objVer, ary);
Error("DeleteArray", "length of fStreamerInfo is %d", fStreamerInfo->GetSize());
Int_t i = fStreamerInfo->LowerBound();
for (Int_t v = 0; v < fStreamerInfo->GetSize(); ++v, ++i) {
Error("DeleteArray", "fStreamerInfo->At(%d): %p", v, fStreamerInfo->At(i));
if (fStreamerInfo->At(i)) {
Error("DeleteArray", "Doing Dump() ...");
((TVirtualStreamerInfo*)fStreamerInfo->At(i))->Dump();
}
}
}
#endif
}
if (inRepo && verFound && p) {
UnregisterAddressInRepository("TClass::DeleteArray",p,this);
}
} else {
Error("DeleteArray", "This cannot happen! (class '%s')", GetName());
}
}
void TClass::SetClassVersion(Version_t version)
{
fClassVersion = version;
fCurrentInfo = 0;
}
void TClass::SetCurrentStreamerInfo(TVirtualStreamerInfo *info)
{
fCurrentInfo = info;
}
Int_t TClass::Size() const
{
if (fSizeof!=-1) return fSizeof;
if (fCollectionProxy) return fCollectionProxy->Sizeof();
if (fClassInfo) return gCint->ClassInfo_Size(GetClassInfo());
return GetStreamerInfo()->GetSize();
}
TClass *TClass::Load(TBuffer &b)
{
UInt_t maxsize = 256;
char *s = new char[maxsize];
Int_t pos = b.Length();
b.ReadString(s, maxsize);
while (strlen(s) == (maxsize - 1)) {
b.SetBufferOffset(pos);
maxsize = 2*maxsize;
delete [] s;
s = new char[maxsize];
b.ReadString(s, maxsize);
}
TClass *cl = TClass::GetClass(s, kTRUE);
if (!cl)
::Error("TClass::Load", "dictionary of class %s not found", s);
delete [] s;
return cl;
}
void TClass::Store(TBuffer &b) const
{
b.WriteString(GetName());
}
TClass *ROOT::CreateClass(const char *cname, Version_t id,
const type_info &info, TVirtualIsAProxy *isa,
ShowMembersFunc_t show,
const char *dfil, const char *ifil,
Int_t dl, Int_t il)
{
if (gMmallocDesc) {
void *msave = gMmallocDesc;
gMmallocDesc = 0;
TClass *cl = new TClass(cname, id, info, isa, show, dfil, ifil, dl, il);
gMmallocDesc = msave;
return cl;
}
return new TClass(cname, id, info, isa, show, dfil, ifil, dl, il);
}
TClass *ROOT::CreateClass(const char *cname, Version_t id,
const char *dfil, const char *ifil,
Int_t dl, Int_t il)
{
if (gMmallocDesc) {
void *msave = gMmallocDesc;
gMmallocDesc = 0;
TClass *cl = new TClass(cname, id, dfil, ifil, dl, il);
gMmallocDesc = msave;
return cl;
}
return new TClass(cname, id, dfil, ifil, dl, il);
}
TClass::ENewType TClass::IsCallingNew()
{
return fgCallingNew;
}
Bool_t TClass::IsLoaded() const
{
return (GetImplFileLine()>=0 && !TestBit(kUnloaded));
}
Bool_t TClass::IsStartingWithTObject() const
{
if (fProperty==(-1)) Property();
return TestBit(kStartWithTObject);
}
Bool_t TClass::IsTObject() const
{
if (fProperty==(-1)) Property();
return TestBit(kIsTObject);
}
Bool_t TClass::IsForeign() const
{
if (fProperty==(-1)) Property();
return TestBit(kIsForeign);
}
void TClass::PostLoadCheck()
{
if (IsLoaded() && fClassInfo && fClassVersion==1 && IsForeign() )
{
SetClassVersion(-1);
}
else if (IsLoaded() && fClassInfo && fStreamerInfo && (!IsForeign()||fClassVersion>1) )
{
TVirtualStreamerInfo *info = (TVirtualStreamerInfo*)(fStreamerInfo->At(fClassVersion));
if (info && GetListOfDataMembers() && !GetCollectionProxy()
&& (info->GetCheckSum()!=GetCheckSum() && info->GetCheckSum()!=GetCheckSum(1) && info->GetCheckSum()!=GetCheckSum(2)))
{
Bool_t warn = ! TestBit(kWarned);
if (warn && info->GetOldVersion()<=2) {
TIter nextBC(GetListOfBases());
TBaseClass *bc;
while ((bc=(TBaseClass*)nextBC()))
{if (TClassEdit::IsSTLCont(bc->GetName())) warn = kFALSE;}
}
if (warn) {
if (info->GetOnFileClassVersion()==1 && fClassVersion>1) {
Warning("PostLoadCheck","\n\
The class %s transitioned from not having a specified class version\n\
to having a specified class version (the current class version is %d).\n\
However too many different non-versioned layouts of the class have\n\
already been loaded so far. To work around this problem you can\n\
load fewer 'old' file in the same ROOT session or load the C++ library\n\
describing the class %s before opening the files or increase the version\n\
number of the class for example ClassDef(%s,%d).\n\
Do not try to write objects with the current class definition,\n\
the files might not be readable.\n",
GetName(), fClassVersion, GetName(), GetName(), fStreamerInfo->GetLast()+1);
} else {
Warning("PostLoadCheck","\n\
The StreamerInfo version %d for the class %s which was read\n\
from a file previously opened has the same version as the active class\n\
but a different checksum. You should update the version to ClassDef(%s,%d).\n\
Do not try to write objects with the current class definition,\n\
the files will not be readable.\n"
, fClassVersion, GetName(), GetName(), fStreamerInfo->GetLast()+1);
}
SetBit(kWarned);
}
}
}
}
Long_t TClass::Property() const
{
if (fProperty!=(-1)) return fProperty;
Long_t dummy;
TClass *kl = const_cast<TClass*>(this);
kl->fStreamerType = kNone;
if (InheritsFrom(TObject::Class())) {
kl->SetBit(kIsTObject);
Int_t delta = kl->GetBaseClassOffset(TObject::Class());
if (delta==0) kl->SetBit(kStartWithTObject);
kl->fStreamerType = kTObject;
}
if (fClassInfo) {
kl->fProperty = gCint->ClassInfo_Property(fClassInfo);
if (!gCint->ClassInfo_HasMethod(fClassInfo,"Streamer") ||
!gCint->ClassInfo_IsValidMethod(fClassInfo,"Streamer","TBuffer&",&dummy) ) {
kl->SetBit(kIsForeign);
kl->fStreamerType = kForeign;
} else if ( kl->fStreamerType == kNone ) {
if (strcmp( gCint->ClassInfo_FileName(fClassInfo),"{CINTEX dictionary translator}")==0) {
kl->SetBit(kIsForeign);
}
kl->fStreamerType = kInstrumented;
}
if (fStreamer) kl->fStreamerType = kExternal;
} else {
if (fStreamer) kl->fStreamerType = kExternal;
kl->fStreamerType |= kEmulated;
return 0;
}
return fProperty;
}
void TClass::SetCollectionProxy(const ROOT::TCollectionProxyInfo &info)
{
delete fCollectionProxy;
TVirtualCollectionProxy *p = TVirtualStreamerInfo::Factory()->GenExplicitProxy(info,this);
fCollectionProxy = p;
AdoptStreamer(TVirtualStreamerInfo::Factory()->GenExplicitClassStreamer(info,this));
}
void TClass::SetContextMenuTitle(const char *title)
{
fContextMenuTitle = title;
}
void TClass::SetGlobalIsA(IsAGlobalFunc_t func)
{
fGlobalIsA = func;
}
void TClass::SetUnloaded()
{
delete fIsA; fIsA = 0;
int autoload_old = gCint->SetClassAutoloading(0);
gInterpreter->SetClassInfo(this,kTRUE);
gCint->SetClassAutoloading(autoload_old);
fDeclFileName = 0;
fDeclFileLine = 0;
fImplFileName = 0;
fImplFileLine = 0;
fTypeInfo = 0;
if (fMethod) {
fMethod->Delete();
delete fMethod;
fMethod=0;
}
SetBit(kUnloaded);
}
TVirtualStreamerInfo *TClass::SetStreamerInfo(Int_t , const char * )
{
return 0;
}
UInt_t TClass::GetCheckSum(UInt_t code) const
{
if (fCheckSum && code == 0) return fCheckSum;
UInt_t id = 0;
int il;
TString name = GetName();
TString type;
il = name.Length();
for (int i=0; i<il; i++) id = id*3+name[i];
TList *tlb = ((TClass*)this)->GetListOfBases();
if (tlb) {
TIter nextBase(tlb);
TBaseClass *tbc=0;
while((tbc=(TBaseClass*)nextBase())) {
name = tbc->GetName();
il = name.Length();
for (int i=0; i<il; i++) id = id*3+name[i];
}
}
TList *tlm = ((TClass*)this)->GetListOfDataMembers();
if (tlm) {
TIter nextMemb(tlm);
TDataMember *tdm=0;
Long_t prop = 0;
while((tdm=(TDataMember*)nextMemb())) {
if (!tdm->IsPersistent()) continue;
prop = (tdm->Property());
TDataType* tdt = tdm->GetDataType();
if (tdt) prop |= tdt->Property();
if ( prop&kIsStatic) continue;
name = tdm->GetName(); il = name.Length();
if ( (code != 1) && prop&kIsEnum) id = id*3 + 1;
int i;
for (i=0; i<il; i++) id = id*3+name[i];
type = tdm->GetFullTypeName();
if (TClassEdit::IsSTLCont(type))
type = TClassEdit::ShortType( type, TClassEdit::kDropStlDefault );
il = type.Length();
for (i=0; i<il; i++) id = id*3+type[i];
int dim = tdm->GetArrayDim();
if (prop&kIsArray) {
for (int ii=0;ii<dim;ii++) id = id*3+tdm->GetMaxIndex(ii);
}
if (code != 2) {
const char *left = strstr(tdm->GetTitle(),"[");
if (left) {
const char *right = strstr(left,"]");
if (right) {
++left;
while (left != right) {
id = id*3 + *left;
++left;
}
}
}
}
}
}
if (code==0) fCheckSum = id;
return id;
}
void TClass::AdoptReferenceProxy(TVirtualRefProxy* proxy)
{
if ( fRefProxy ) {
fRefProxy->Release();
}
fRefProxy = proxy;
if ( fRefProxy ) {
fRefProxy->SetClass(this);
}
}
void TClass::AdoptMemberStreamer(const char *name, TMemberStreamer *p)
{
if (!fRealData) return;
TIter next(fRealData);
TRealData *rd;
while ((rd = (TRealData*)next())) {
if (strcmp(rd->GetName(),name) == 0) {
rd->AdoptStreamer(p);
break;
}
}
return;
}
void TClass::SetMemberStreamer(const char *name, MemberStreamerFunc_t p)
{
AdoptMemberStreamer(name,new TMemberStreamer(p));
}
Int_t TClass::ReadBuffer(TBuffer &b, void *pointer, Int_t version, UInt_t start, UInt_t count)
{
return b.ReadClassBuffer(this,pointer,version,start,count);
}
Int_t TClass::ReadBuffer(TBuffer &b, void *pointer)
{
return b.ReadClassBuffer(this,pointer);
}
Int_t TClass::WriteBuffer(TBuffer &b, void *pointer, const char * )
{
b.WriteClassBuffer(this,pointer);
return 0;
}
void TClass::Streamer(void *object, TBuffer &b, const TClass *onfile_class) const
{
switch (fStreamerType) {
case kExternal:
case kExternal|kEmulated:
{
TClassStreamer *streamer = GetStreamer();
streamer->SetOnFileClass( onfile_class );
(*streamer)(b,object);
return;
}
case kTObject:
{
if (!fInterStreamer) {
const_cast<TClass*>(this)->CalculateStreamerOffset();
}
TObject *tobj = (TObject*)((Long_t)object + fOffsetStreamer);
tobj->Streamer(b);
}
return;
case kTObject|kEmulated : {
b.ReadClassEmulated(this, object, onfile_class);
}
return;
case kInstrumented:
{
CallFunc_t *func = (CallFunc_t*)fInterStreamer;
if (!func) {
func = gCint->CallFunc_Factory();
gCint->CallFunc_SetFuncProto(func,fClassInfo,"Streamer","TBuffer&",&fOffsetStreamer);
fInterStreamer = func;
} else {
gCint->CallFunc_SetArgs(func,"");
}
gCint->CallFunc_SetArg(func,(Long_t)&b);
gCint->CallFunc_Exec(func,(char*)((Long_t)object + fOffsetStreamer) );
}
return;
case kForeign:
case kForeign|kEmulated:
case kInstrumented|kEmulated:
case kEmulated:
{
if (b.IsReading()) {
b.ReadClassBuffer(this, object, onfile_class);
} else {
b.WriteClassBuffer(this, object);
}
}
return;
default:
{
if (fProperty==(-1)) {
Property();
Streamer(object,b);
} else {
Fatal("Streamer", "fStreamerType not properly initialized (%d)", fStreamerType);
}
}
}
}
void TClass::AdoptStreamer(TClassStreamer *str)
{
if (fStreamer) delete fStreamer;
if (str) {
fStreamerType = kExternal | ( fStreamerType&kEmulated );
fStreamer = str;
} else if (fStreamer) {
fStreamer = str;
fStreamerType = kNone;
fProperty = -1;
Property();
}
}
void TClass::SetNew(ROOT::NewFunc_t newFunc)
{
fNew = newFunc;
}
void TClass::SetNewArray(ROOT::NewArrFunc_t newArrayFunc)
{
fNewArray = newArrayFunc;
}
void TClass::SetDelete(ROOT::DelFunc_t deleteFunc)
{
fDelete = deleteFunc;
}
void TClass::SetDeleteArray(ROOT::DelArrFunc_t deleteArrayFunc)
{
fDeleteArray = deleteArrayFunc;
}
void TClass::SetDestructor(ROOT::DesFunc_t destructorFunc)
{
fDestructor = destructorFunc;
}
void TClass::SetDirectoryAutoAdd(ROOT::DirAutoAdd_t autoAddFunc)
{
fDirAutoAdd = autoAddFunc;
}
TVirtualStreamerInfo *TClass::FindStreamerInfo( UInt_t checksum) const
{
return FindStreamerInfo( GetStreamerInfos(), checksum );
}
TVirtualStreamerInfo *TClass::FindStreamerInfo( TObjArray* arr, UInt_t checksum) const
{
Int_t ninfos = arr->GetEntriesFast()-1;
for (Int_t i=-1;i<ninfos;i++) {
TVirtualStreamerInfo *info = (TVirtualStreamerInfo*)arr->UncheckedAt(i);
if (!info) continue;
if (info->GetCheckSum() == checksum) {
R__ASSERT(i==info->GetClassVersion() || (i==-1&&info->GetClassVersion()==1));
return info;
}
}
return 0;
}
TVirtualStreamerInfo *TClass::GetConversionStreamerInfo( const char* classname, Int_t version ) const
{
TClass *cl = TClass::GetClass( classname );
if( !cl )
return 0;
return GetConversionStreamerInfo( cl, version );
}
TVirtualStreamerInfo *TClass::GetConversionStreamerInfo( const TClass* cl, Int_t version ) const
{
if( !cl )
return 0;
if( cl == this )
return GetStreamerInfo( version );
TObjArray* arr = 0;
if (fConversionStreamerInfo) {
std::map<std::string, TObjArray*>::iterator it;
it = fConversionStreamerInfo->find( cl->GetName() );
if( it != fConversionStreamerInfo->end() ) {
arr = it->second;
}
if( version > -1 && version < arr->GetSize() && arr->At( version ) )
return (TVirtualStreamerInfo*) arr->At( version );
}
TObjArray *clSI = cl->GetStreamerInfos();
TVirtualStreamerInfo* info = 0;
if( version > -1 && version < clSI->GetSize() )
info = (TVirtualStreamerInfo*)clSI->At( version );
if( !info )
return 0;
info = (TVirtualStreamerInfo*)info->Clone();
if( !info->BuildFor( this ) ) {
delete info;
return 0;
}
if (!info->GetOffsets()) {
info->BuildOld();
}
if (info->IsOptimized() && !TVirtualStreamerInfo::CanOptimize()) {
info->Compile();
}
if (!arr) {
arr = new TObjArray(version+10, -1);
if (!fConversionStreamerInfo) {
fConversionStreamerInfo = new std::map<std::string, TObjArray*>();
}
(*fConversionStreamerInfo)[cl->GetName()] = arr;
}
arr->AddAtAndExpand( info, info->GetClassVersion() );
return info;
}
TVirtualStreamerInfo *TClass::FindConversionStreamerInfo( const char* classname, UInt_t checksum ) const
{
TClass *cl = TClass::GetClass( classname );
if( !cl )
return 0;
return FindConversionStreamerInfo( cl, checksum );
}
TVirtualStreamerInfo *TClass::FindConversionStreamerInfo( const TClass* cl, UInt_t checksum ) const
{
if( !cl )
return 0;
if( cl == this )
return FindStreamerInfo( checksum );
TObjArray* arr = 0;
TVirtualStreamerInfo* info = 0;
if (fConversionStreamerInfo) {
std::map<std::string, TObjArray*>::iterator it;
it = fConversionStreamerInfo->find( cl->GetName() );
if( it != fConversionStreamerInfo->end() ) {
arr = it->second;
}
info = FindStreamerInfo( arr, checksum );
}
if( info )
return info;
info = cl->FindStreamerInfo( checksum );
if( !info )
return 0;
info = (TVirtualStreamerInfo*)info->Clone();
if( !info->BuildFor( this ) ) {
delete info;
return 0;
}
if (!info->GetOffsets()) {
info->BuildOld();
}
if (info->IsOptimized() && !TVirtualStreamerInfo::CanOptimize()) {
info->Compile();
}
if (!arr) {
arr = new TObjArray(16, -1);
if (!fConversionStreamerInfo) {
fConversionStreamerInfo = new std::map<std::string, TObjArray*>();
}
(*fConversionStreamerInfo)[cl->GetName()] = arr;
}
arr->AddAtAndExpand( info, info->GetClassVersion() );
return info;
}
Bool_t TClass::HasDefaultConstructor() const
{
if (fNew) return kTRUE;
if (!GetClassInfo()) return kFALSE;
return gCint->ClassInfo_HasDefaultConstructor(GetClassInfo());
}
ROOT::NewFunc_t TClass::GetNew() const
{
return fNew;
}
ROOT::NewArrFunc_t TClass::GetNewArray() const
{
return fNewArray;
}
ROOT::DelFunc_t TClass::GetDelete() const
{
return fDelete;
}
ROOT::DelArrFunc_t TClass::GetDeleteArray() const
{
return fDeleteArray;
}
ROOT::DesFunc_t TClass::GetDestructor() const
{
return fDestructor;
}
ROOT::DirAutoAdd_t TClass::GetDirectoryAutoAdd() const
{
return fDirAutoAdd;
}
Last change: Mon Dec 15 13:02:53 2008
Last generated: 2008-12-15 13:02
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.