00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "TClass.h"
00028
00029 #include "Riostream.h"
00030 #include "TBaseClass.h"
00031 #include "TBrowser.h"
00032 #include "TBuffer.h"
00033 #include "TClassGenerator.h"
00034 #include "TClassEdit.h"
00035 #include "TClassMenuItem.h"
00036 #include "TClassRef.h"
00037 #include "TClassTable.h"
00038 #include "TDataMember.h"
00039 #include "TDataType.h"
00040 #include "TError.h"
00041 #include "TExMap.h"
00042 #include "THashList.h"
00043 #include "TInterpreter.h"
00044 #include "TMemberInspector.h"
00045 #include "TMethod.h"
00046 #include "TMethodArg.h"
00047 #include "TMethodCall.h"
00048 #include "TObjArray.h"
00049 #include "TROOT.h"
00050 #include "TRealData.h"
00051 #include "TStreamer.h"
00052 #include "TStreamerElement.h"
00053 #include "TVirtualStreamerInfo.h"
00054 #include "TVirtualCollectionProxy.h"
00055 #include "TVirtualIsAProxy.h"
00056 #include "TVirtualRefProxy.h"
00057 #include "TVirtualMutex.h"
00058 #include "TVirtualPad.h"
00059 #include "THashTable.h"
00060 #include "TSchemaRuleSet.h"
00061 #include "TGenericClassInfo.h"
00062 #include "TIsAProxy.h"
00063 #include "TSchemaRule.h"
00064 #include "TSystem.h"
00065
00066 #include <cstdio>
00067 #include <cctype>
00068 #include <set>
00069 #include <sstream>
00070 #include <string>
00071 #include <map>
00072 #include <typeinfo>
00073 #include <cmath>
00074 #include <assert.h>
00075
00076 using namespace std;
00077
00078
00079
00080
00081 TVirtualMutex* gCINTMutex = 0;
00082
00083 void *gMmallocDesc = 0;
00084 namespace {
00085 class TMmallocDescTemp {
00086 private:
00087 void *fSave;
00088 public:
00089 TMmallocDescTemp(void *value = 0) : fSave(gMmallocDesc) { gMmallocDesc = value; }
00090 ~TMmallocDescTemp() { gMmallocDesc = fSave; }
00091 };
00092 }
00093
00094 Int_t TClass::fgClassCount;
00095 TClass::ENewType TClass::fgCallingNew = kRealNew;
00096
00097 static std::multimap<void*, Version_t> gObjectVersionRepository;
00098
00099 static void RegisterAddressInRepository(const char * , void *location, const TClass *what)
00100 {
00101
00102
00103 Version_t version = what->GetClassVersion();
00104
00105
00106
00107
00108
00109 gObjectVersionRepository.insert(std::pair<void* const,Version_t>(location, version));
00110
00111 #if 0
00112
00113 std::pair<std::map<void*, Version_t>::iterator, Bool_t> tmp = gObjectVersionRepository.insert(std::pair<void*,Version_t>(location, version));
00114 if (!tmp.second) {
00115 Warning(where, "Reregistering an object of class '%s' version %d at address %p", what->GetName(), version, p);
00116 gObjectVersionRepository.erase(tmp.first);
00117 tmp = gObjectVersionRepository.insert(std::pair<void*,Version_t>(location, version));
00118 if (!tmp.second) {
00119 Warning(where, "Failed to reregister an object of class '%s' version %d at address %p", what->GetName(), version, location);
00120 }
00121 }
00122 #endif
00123 }
00124
00125 static void UnregisterAddressInRepository(const char * , void *location, const TClass *what)
00126 {
00127 std::multimap<void*, Version_t>::iterator cur = gObjectVersionRepository.find(location);
00128 for (; cur != gObjectVersionRepository.end();) {
00129 std::multimap<void*, Version_t>::iterator tmp = cur++;
00130 if ((tmp->first == location) && (tmp->second == what->GetClassVersion())) {
00131
00132
00133 gObjectVersionRepository.erase(tmp);
00134 } else {
00135
00136 break;
00137 }
00138 }
00139 }
00140
00141 static void MoveAddressInRepository(const char *where, void *oldadd, void *newadd, const TClass *what)
00142 {
00143 UnregisterAddressInRepository(where,oldadd,what);
00144 RegisterAddressInRepository(where,newadd,what);
00145 }
00146
00147
00148
00149 namespace ROOT {
00150 #define R__USE_STD_MAP
00151 class TMapTypeToTClass {
00152 #if defined R__USE_STD_MAP
00153
00154
00155 public:
00156 #ifdef R__GLOBALSTL
00157 typedef map<string,TClass*> IdMap_t;
00158 #else
00159 typedef std::map<std::string,TClass*> IdMap_t;
00160 #endif
00161 typedef IdMap_t::key_type key_type;
00162 typedef IdMap_t::const_iterator const_iterator;
00163 typedef IdMap_t::size_type size_type;
00164 #ifdef R__WIN32
00165
00166 typedef TClass* mapped_type;
00167 #else
00168 typedef IdMap_t::mapped_type mapped_type;
00169 #endif
00170
00171 private:
00172 IdMap_t fMap;
00173
00174 public:
00175 void Add(const key_type &key, mapped_type &obj) {
00176 fMap[key] = obj;
00177 }
00178 mapped_type Find(const key_type &key) const {
00179 IdMap_t::const_iterator iter = fMap.find(key);
00180 mapped_type cl = 0;
00181 if (iter != fMap.end()) cl = iter->second;
00182 return cl;
00183 }
00184 void Remove(const key_type &key) { fMap.erase(key); }
00185 #else
00186 private:
00187 TMap fMap;
00188
00189 public:
00190 #ifdef R__COMPLETE_MEM_TERMINATION
00191 TMapTypeToTClass() {
00192 TIter next(&fMap);
00193 TObjString *key;
00194 while((key = (TObjString*)next())) {
00195 delete key;
00196 }
00197 }
00198 #endif
00199 void Add(const char *key, TClass *&obj) {
00200 TObjString *realkey = new TObjString(key);
00201 fMap.Add(realkey, obj);
00202 }
00203 TClass* Find(const char *key) const {
00204 const TPair *a = (const TPair *)fMap.FindObject(key);
00205 if (a) return (TClass*) a->Value();
00206 return 0;
00207 }
00208 void Remove(const char *key) {
00209 TObjString realkey(key);
00210 TObject *actual = fMap.Remove(&realkey);
00211 delete actual;
00212 }
00213 #endif
00214 };
00215 }
00216 #ifdef R__COMPLETE_MEM_TERMINATION
00217 static IdMap_t gIdMapObject;
00218 IdMap_t *TClass::fgIdMap = &gIdMapObject;
00219 #else
00220 IdMap_t *TClass::fgIdMap = new IdMap_t;
00221 #endif
00222
00223 void TClass::AddClass(TClass *cl)
00224 {
00225
00226
00227 if (!cl) return;
00228 gROOT->GetListOfClasses()->Add(cl);
00229 if (cl->GetTypeInfo()) {
00230 fgIdMap->Add(cl->GetTypeInfo()->name(),cl);
00231 }
00232 }
00233
00234
00235
00236 void TClass::RemoveClass(TClass *oldcl)
00237 {
00238
00239
00240 if (!oldcl) return;
00241 gROOT->GetListOfClasses()->Remove(oldcl);
00242 if (oldcl->GetTypeInfo()) {
00243 fgIdMap->Remove(oldcl->GetTypeInfo()->name());
00244 }
00245 }
00246
00247
00248
00249
00250 class TDumpMembers : public TMemberInspector {
00251
00252 public:
00253 TDumpMembers() { }
00254 void Inspect(TClass *cl, const char *parent, const char *name, const void *addr);
00255 };
00256
00257
00258 void TDumpMembers::Inspect(TClass *cl, const char *pname, const char *mname, const void *add)
00259 {
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270 const Int_t kvalue = 30;
00271 #ifdef R__B64
00272 const Int_t ktitle = 50;
00273 #else
00274 const Int_t ktitle = 42;
00275 #endif
00276 const Int_t kline = 1024;
00277 Int_t cdate = 0;
00278 Int_t ctime = 0;
00279 UInt_t *cdatime = 0;
00280 char line[kline];
00281
00282 TDataType *membertype;
00283 TString memberTypeName;
00284 const char *memberName;
00285 const char *memberFullTypeName;
00286 const char *memberTitle;
00287 Bool_t isapointer;
00288 Bool_t isbasic;
00289
00290 if (TDataMember *member = cl->GetDataMember(mname)) {
00291 memberTypeName = member->GetTypeName();
00292 memberName = member->GetName();
00293 memberFullTypeName = member->GetFullTypeName();
00294 memberTitle = member->GetTitle();
00295 isapointer = member->IsaPointer();
00296 isbasic = member->IsBasic();
00297 membertype = member->GetDataType();
00298 } else if (!cl->IsLoaded()) {
00299
00300
00301 TVirtualStreamerInfo *info = cl->GetStreamerInfo();
00302 if (!info) return;
00303 const char *cursor = mname;
00304 while ( (*cursor)=='*' ) ++cursor;
00305 TString elname( cursor );
00306 Ssiz_t pos = elname.Index("[");
00307 if ( pos != kNPOS ) {
00308 elname.Remove( pos );
00309 }
00310 TStreamerElement *element = (TStreamerElement*)info->GetElements()->FindObject(elname.Data());
00311 if (!element) return;
00312 memberFullTypeName = element->GetTypeName();
00313
00314 memberTypeName = memberFullTypeName;
00315 memberTypeName = memberTypeName.Strip(TString::kTrailing, '*');
00316 if (memberTypeName.Index("const ")==0) memberTypeName.Remove(0,6);
00317
00318 memberName = element->GetName();
00319 memberTitle = element->GetTitle();
00320 isapointer = element->IsaPointer() || element->GetType() == TVirtualStreamerInfo::kCharStar;
00321 membertype = gROOT->GetType(memberFullTypeName);
00322
00323 isbasic = membertype !=0;
00324 } else {
00325 return;
00326 }
00327
00328
00329 Bool_t isdate = kFALSE;
00330 if (strcmp(memberName,"fDatime") == 0 && strcmp(memberTypeName,"UInt_t") == 0) {
00331 isdate = kTRUE;
00332 }
00333 Bool_t isbits = kFALSE;
00334 if (strcmp(memberName,"fBits") == 0 && strcmp(memberTypeName,"UInt_t") == 0) {
00335 isbits = kTRUE;
00336 }
00337
00338 Int_t i;
00339 for (i = 0;i < kline; i++) line[i] = ' ';
00340 line[kline-1] = 0;
00341 snprintf(line,kline,"%s%s ",pname,mname);
00342 i = strlen(line); line[i] = ' ';
00343
00344
00345 char *pointer = (char*)add;
00346 char **ppointer = (char**)(pointer);
00347
00348 if (isapointer) {
00349 char **p3pointer = (char**)(*ppointer);
00350 if (!p3pointer)
00351 snprintf(&line[kvalue],kline-kvalue,"->0");
00352 else if (!isbasic)
00353 snprintf(&line[kvalue],kline-kvalue,"->%lx ", (Long_t)p3pointer);
00354 else if (membertype) {
00355 if (!strcmp(membertype->GetTypeName(), "char")) {
00356 i = strlen(*ppointer);
00357 if (kvalue+i > kline) i=kline-1-kvalue;
00358 Bool_t isPrintable = kTRUE;
00359 for (Int_t j = 0; j < i; j++) {
00360 if (!std::isprint((*ppointer)[j])) {
00361 isPrintable = kFALSE;
00362 break;
00363 }
00364 }
00365 if (isPrintable) {
00366 strncpy(line + kvalue, *ppointer, i);
00367 line[kvalue+i] = 0;
00368 } else {
00369 line[kvalue] = 0;
00370 }
00371 } else {
00372 strncpy(&line[kvalue], membertype->AsString(p3pointer), TMath::Min(kline-1-kvalue,(int)strlen(membertype->AsString(p3pointer))));
00373 }
00374 } else if (!strcmp(memberFullTypeName, "char*") ||
00375 !strcmp(memberFullTypeName, "const char*")) {
00376 i = strlen(*ppointer);
00377 if (kvalue+i >= kline) i=kline-1-kvalue;
00378 Bool_t isPrintable = kTRUE;
00379 for (Int_t j = 0; j < i; j++) {
00380 if (!std::isprint((*ppointer)[j])) {
00381 isPrintable = kFALSE;
00382 break;
00383 }
00384 }
00385 if (isPrintable) {
00386 strncpy(line + kvalue, *ppointer, i);
00387 line[kvalue+i] = 0;
00388 } else {
00389 line[kvalue] = 0;
00390 }
00391 } else {
00392 snprintf(&line[kvalue],kline-kvalue,"->%lx ", (Long_t)p3pointer);
00393 }
00394 } else if (membertype)
00395 if (isdate) {
00396 cdatime = (UInt_t*)pointer;
00397 TDatime::GetDateTime(cdatime[0],cdate,ctime);
00398 snprintf(&line[kvalue],kline-kvalue,"%d/%d",cdate,ctime);
00399 } else if (isbits) {
00400 snprintf(&line[kvalue],kline-kvalue,"0x%08x", *(UInt_t*)pointer);
00401 } else {
00402 strncpy(&line[kvalue], membertype->AsString(pointer), TMath::Min(kline-1-kvalue,(int)strlen(membertype->AsString(pointer))));
00403 }
00404 else
00405 snprintf(&line[kvalue],kline-kvalue,"->%lx ", (Long_t)pointer);
00406
00407
00408 if (isdate == kFALSE && strcmp(memberFullTypeName, "char*") && strcmp(memberFullTypeName, "const char*")) {
00409 i = strlen(&line[0]); line[i] = ' ';
00410 Int_t lentit = strlen(memberTitle);
00411 if (lentit > 250-ktitle) lentit = 250-ktitle;
00412 strncpy(&line[ktitle],memberTitle,lentit);
00413 line[ktitle+lentit] = 0;
00414 }
00415 Printf("%s", line);
00416 }
00417
00418 THashTable* TClass::fgClassTypedefHash = 0;
00419 THashTable* TClass::fgClassShortTypedefHash = 0;
00420
00421
00422
00423
00424 TClass::TNameMapNode::TNameMapNode (const char* typedf, const char* orig)
00425 : TObjString (typedf),
00426 fOrigName (orig)
00427 {
00428 }
00429
00430
00431
00432 class TBuildRealData : public TMemberInspector {
00433
00434 private:
00435 void *fRealDataObject;
00436 TClass *fRealDataClass;
00437 UInt_t fBits;
00438
00439 public:
00440 TBuildRealData(void *obj, TClass *cl) : fBits(0) {
00441 fRealDataObject = obj;
00442 fRealDataClass = cl;
00443 }
00444 void Inspect(TClass *cl, const char *parent, const char *name, const void *addr);
00445
00446
00447 void SetBit(UInt_t f, Bool_t set);
00448 void SetBit(UInt_t f) { fBits |= f & TObject::kBitMask; }
00449 void ResetBit(UInt_t f) { fBits &= ~(f & TObject::kBitMask); }
00450 Bool_t TestBit(UInt_t f) const { return (Bool_t) ((fBits & f) != 0); }
00451 Int_t TestBits(UInt_t f) const { return (Int_t) (fBits & f); }
00452 void InvertBit(UInt_t f) { fBits ^= f & TObject::kBitMask; }
00453 };
00454
00455
00456 void TBuildRealData::Inspect(TClass* cl, const char* pname, const char* mname, const void* add)
00457 {
00458
00459
00460 TDataMember* dm = cl->GetDataMember(mname);
00461 if (!dm) {
00462 return;
00463 }
00464
00465 Bool_t isTransient = kFALSE;
00466
00467 if (!dm->IsPersistent()) {
00468
00469
00470 isTransient = kTRUE;
00471 }
00472
00473 TString rname( pname );
00474
00475
00476 if (cl != fRealDataClass) {
00477 if (!fRealDataClass->InheritsFrom(cl)) {
00478 Ssiz_t dot = rname.Index('.');
00479 if (dot == kNPOS) {
00480 return;
00481 }
00482 rname[dot] = '\0';
00483 if (!fRealDataClass->GetDataMember(rname)) {
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498 if (!fRealDataClass->GetBaseDataMember(rname)) {
00499 return;
00500 }
00501 }
00502 rname[dot] = '.';
00503 }
00504 }
00505 rname += mname;
00506 Long_t offset = Long_t(((Long_t) add) - ((Long_t) fRealDataObject));
00507
00508 if (dm->IsaPointer()) {
00509
00510 if (!dm->IsBasic()) {
00511
00512 TRealData* rd = new TRealData(rname, offset, dm);
00513 if (isTransient) { rd->SetBit(TRealData::kTransient); };
00514 fRealDataClass->GetListOfRealData()->Add(rd);
00515 } else {
00516
00517 TRealData* rd = new TRealData(rname, offset, dm);
00518 if (isTransient) { rd->SetBit(TRealData::kTransient); };
00519 fRealDataClass->GetListOfRealData()->Add(rd);
00520 }
00521 } else {
00522
00523 TRealData* rd = new TRealData(rname, offset, dm);
00524 if (isTransient) { rd->SetBit(TRealData::kTransient); };
00525 if (!dm->IsBasic()) {
00526 rd->SetIsObject(kTRUE);
00527
00528
00529
00530
00531
00532
00533 TClass* dmclass = TClass::GetClass(dm->GetTypeName(), kTRUE, isTransient || TestBit(TRealData::kTransient));
00534 if (!dmclass) {
00535 dmclass = TClass::GetClass(dm->GetTrueTypeName(), kTRUE, isTransient || TestBit(TRealData::kTransient));
00536 }
00537 if (dmclass) {
00538 if (dmclass->Property()) {
00539 if (dmclass->Property() & kIsAbstract) {
00540 fprintf(stderr, "TBuildRealDataRecursive::Inspect(): data member class: '%s' is abstract.\n", dmclass->GetName());
00541 }
00542 }
00543 if ((dmclass != cl) && !dm->IsaPointer()) {
00544 if (dmclass->GetCollectionProxy()) {
00545 TClass* valcl = dmclass->GetCollectionProxy()->GetValueClass();
00546 if (valcl && !(valcl->Property() & kIsAbstract)) valcl->BuildRealData(0, isTransient || TestBit(TRealData::kTransient));
00547 } else {
00548 dmclass->BuildRealData(const_cast<void*>(add), isTransient || TestBit(TRealData::kTransient));
00549 }
00550 }
00551 }
00552 }
00553 fRealDataClass->GetListOfRealData()->Add(rd);
00554 }
00555 }
00556
00557
00558
00559
00560
00561
00562 class TAutoInspector : public TMemberInspector {
00563
00564 public:
00565 Int_t fCount;
00566 TBrowser *fBrowser;
00567
00568 TAutoInspector(TBrowser *b) { fBrowser = b; fCount = 0; }
00569 virtual ~TAutoInspector() { }
00570 virtual void Inspect(TClass *cl, const char *parent, const char *name, const void *addr);
00571 };
00572
00573
00574 void TAutoInspector::Inspect(TClass *cl, const char *tit, const char *name,
00575 const void *addr)
00576 {
00577
00578
00579 if(tit && strchr(tit,'.')) return ;
00580 if (fCount && !fBrowser) return;
00581
00582 TString ts;
00583
00584 if (!cl) return;
00585
00586 if (*name == '*') name++;
00587 int ln = strcspn(name,"[ ");
00588 TString iname(name,ln);
00589
00590 ClassInfo_t *classInfo = cl->GetClassInfo();
00591 if (!classInfo) return;
00592
00593
00594 DataMemberInfo_t *m = gCint->DataMemberInfo_Factory(classInfo);
00595 TString mname;
00596
00597 int found=0;
00598 while (gCint->DataMemberInfo_Next(m)) {
00599 mname = gCint->DataMemberInfo_Name(m);
00600 mname.ReplaceAll("*","");
00601 if ((found = (iname==mname))) break;
00602 }
00603 assert(found);
00604
00605
00606
00607
00608
00609 Long_t prop = gCint->DataMemberInfo_Property(m) | gCint->DataMemberInfo_TypeProperty(m);
00610 if (prop & G__BIT_ISSTATIC) return;
00611 if (prop & G__BIT_ISFUNDAMENTAL) return;
00612 if (prop & G__BIT_ISENUM) return;
00613 if (mname == "G__virtualinfo") return;
00614
00615 int size = sizeof(void*);
00616
00617 int nmax = 1;
00618 if (prop & G__BIT_ISARRAY) {
00619 for (int dim = 0; dim < gCint->DataMemberInfo_ArrayDim(m); dim++) nmax *= gCint->DataMemberInfo_MaxIndex(m,dim);
00620 }
00621
00622 std::string clmName(TClassEdit::ShortType(gCint->DataMemberInfo_TypeName(m),
00623 TClassEdit::kDropTrailStar) );
00624 TClass * clm = TClass::GetClass(clmName.c_str());
00625 R__ASSERT(clm);
00626 if (!(prop&G__BIT_ISPOINTER)) {
00627 size = clm->Size();
00628 if (size==0) size = gCint->DataMemberInfo_TypeSize(m);
00629 }
00630
00631
00632 gCint->DataMemberInfo_Delete(m);
00633 TVirtualCollectionProxy *proxy = clm->GetCollectionProxy();
00634
00635 for(int i=0; i<nmax; i++) {
00636
00637 char *ptr = (char*)addr + i*size;
00638
00639 void *obj = (prop&G__BIT_ISPOINTER) ? *((void**)ptr) : (TObject*)ptr;
00640
00641 if (!obj) continue;
00642
00643 fCount++;
00644 if (!fBrowser) return;
00645
00646 TString bwname;
00647 TClass *actualClass = clm->GetActualClass(obj);
00648 if (clm->IsTObject()) {
00649 TObject *tobj = (TObject*)clm->DynamicCast(TObject::Class(),obj);
00650 bwname = tobj->GetName();
00651 } else {
00652 bwname = actualClass->GetName();
00653 bwname += "::";
00654 bwname += mname;
00655 }
00656
00657 if (!clm->IsTObject() ||
00658 bwname.Length()==0 ||
00659 strcmp(bwname.Data(),actualClass->GetName())==0) {
00660 bwname = name;
00661 int l = strcspn(bwname.Data(),"[ ");
00662 if (l<bwname.Length() && bwname[l]=='[') {
00663 char cbuf[12]; snprintf(cbuf,12,"[%02d]",i);
00664 ts.Replace(0,999,bwname,l);
00665 ts += cbuf;
00666 bwname = (const char*)ts;
00667 }
00668 }
00669
00670 if (proxy==0) {
00671
00672 fBrowser->Add(obj,clm,bwname);
00673
00674 } else {
00675 TClass *valueCl = proxy->GetValueClass();
00676
00677 if (valueCl==0) {
00678
00679 fBrowser->Add( obj, clm, bwname );
00680
00681 } else {
00682 TVirtualCollectionProxy::TPushPop env(proxy, obj);
00683 TClass *actualCl = 0;
00684
00685 int sz = proxy->Size();
00686
00687 char fmt[] = {"#%09d"};
00688 fmt[3] = '0'+(int)log10(double(sz))+1;
00689 char buf[20];
00690 for (int ii=0;ii<sz;ii++) {
00691 void *p = proxy->At(ii);
00692
00693 if (proxy->HasPointers()) {
00694 p = *((void**)p);
00695 if(!p) continue;
00696 actualCl = valueCl->GetActualClass(p);
00697 p = actualCl->DynamicCast(valueCl,p,0);
00698 }
00699 fCount++;
00700 snprintf(buf,20,fmt,ii);
00701 ts = bwname;
00702 ts += buf;
00703 fBrowser->Add( p, actualCl, ts );
00704 }
00705 }
00706 }
00707 }
00708 }
00709
00710
00711
00712
00713
00714 ClassImp(TClass)
00715
00716
00717 TClass::TClass() :
00718 TDictionary(),
00719 fStreamerInfo(0), fConversionStreamerInfo(0), fRealData(0),
00720 fBase(0), fData(0), fMethod(0), fAllPubData(0), fAllPubMethod(0),
00721 fClassMenuList(0),
00722 fDeclFileName(""), fImplFileName(""), fDeclFileLine(0), fImplFileLine(0),
00723 fInstanceCount(0), fOnHeap(0),
00724 fCheckSum(0), fCollectionProxy(0), fClassVersion(0), fClassInfo(0),
00725 fTypeInfo(0), fShowMembers(0), fInterShowMembers(0),
00726 fStreamer(0), fIsA(0), fGlobalIsA(0), fIsAMethod(0),
00727 fNew(0), fNewArray(0), fDelete(0), fDeleteArray(0),
00728 fDestructor(0), fDirAutoAdd(0), fStreamerFunc(0), fSizeof(-1),
00729 fProperty(0),fVersionUsed(kFALSE),
00730 fIsOffsetStreamerSet(kFALSE), fOffsetStreamer(0), fStreamerType(kNone),
00731 fCurrentInfo(0), fRefStart(0), fRefProxy(0),
00732 fSchemaRules(0), fStreamerImpl(&TClass::StreamerDefault)
00733 {
00734
00735
00736 R__LOCKGUARD2(gCINTMutex);
00737 fDeclFileLine = -2;
00738 }
00739
00740
00741 TClass::TClass(const char *name, Bool_t silent) :
00742 TDictionary(name),
00743 fStreamerInfo(0), fConversionStreamerInfo(0), fRealData(0),
00744 fBase(0), fData(0), fMethod(0), fAllPubData(0), fAllPubMethod(0),
00745 fClassMenuList(0),
00746 fDeclFileName(""), fImplFileName(""), fDeclFileLine(0), fImplFileLine(0),
00747 fInstanceCount(0), fOnHeap(0),
00748 fCheckSum(0), fCollectionProxy(0), fClassVersion(0), fClassInfo(0),
00749 fTypeInfo(0), fShowMembers(0), fInterShowMembers(0),
00750 fStreamer(0), fIsA(0), fGlobalIsA(0), fIsAMethod(0),
00751 fNew(0), fNewArray(0), fDelete(0), fDeleteArray(0),
00752 fDestructor(0), fDirAutoAdd(0), fStreamerFunc(0), fSizeof(-1),
00753 fProperty(0),fVersionUsed(kFALSE),
00754 fIsOffsetStreamerSet(kFALSE), fOffsetStreamer(0), fStreamerType(kNone),
00755 fCurrentInfo(0), fRefStart(0), fRefProxy(0),
00756 fSchemaRules(0), fStreamerImpl(&TClass::StreamerDefault)
00757 {
00758
00759
00760
00761
00762
00763
00764
00765 R__LOCKGUARD2(gCINTMutex);
00766
00767 if (!gROOT)
00768 ::Fatal("TClass::TClass", "ROOT system not initialized");
00769
00770 fDeclFileLine = -2;
00771
00772 SetBit(kLoading);
00773 if (!gInterpreter)
00774 ::Fatal("TClass::TClass", "gInterpreter not initialized");
00775
00776 gInterpreter->SetClassInfo(this);
00777 if (!fClassInfo) {
00778 gInterpreter->InitializeDictionaries();
00779 gInterpreter->SetClassInfo(this);
00780 }
00781 if (!silent && !fClassInfo && fName.First('@')==kNPOS)
00782 ::Warning("TClass::TClass", "no dictionary for class %s is available", name);
00783 ResetBit(kLoading);
00784
00785 if (fClassInfo) SetTitle(gCint->ClassInfo_Title(fClassInfo));
00786 fConversionStreamerInfo = 0;
00787 }
00788
00789
00790 TClass::TClass(const char *name, Version_t cversion,
00791 const char *dfil, const char *ifil, Int_t dl, Int_t il, Bool_t silent) :
00792 TDictionary(name),
00793 fStreamerInfo(0), fConversionStreamerInfo(0), fRealData(0),
00794 fBase(0), fData(0), fMethod(0), fAllPubData(0), fAllPubMethod(0),
00795 fClassMenuList(0),
00796 fDeclFileName(""), fImplFileName(""), fDeclFileLine(0), fImplFileLine(0),
00797 fInstanceCount(0), fOnHeap(0),
00798 fCheckSum(0), fCollectionProxy(0), fClassVersion(0), fClassInfo(0),
00799 fTypeInfo(0), fShowMembers(0), fInterShowMembers(0),
00800 fStreamer(0), fIsA(0), fGlobalIsA(0), fIsAMethod(0),
00801 fNew(0), fNewArray(0), fDelete(0), fDeleteArray(0),
00802 fDestructor(0), fDirAutoAdd(0), fStreamerFunc(0), fSizeof(-1),
00803 fProperty(0),fVersionUsed(kFALSE),
00804 fIsOffsetStreamerSet(kFALSE), fOffsetStreamer(0), fStreamerType(kNone),
00805 fCurrentInfo(0), fRefStart(0), fRefProxy(0),
00806 fSchemaRules(0), fStreamerImpl(&TClass::StreamerDefault)
00807 {
00808
00809
00810 R__LOCKGUARD2(gCINTMutex);
00811 Init(name,cversion, 0, 0, 0, dfil, ifil, dl, il,silent);
00812 SetBit(kUnloaded);
00813 }
00814
00815
00816 TClass::TClass(const char *name, Version_t cversion,
00817 const type_info &info, TVirtualIsAProxy *isa,
00818 ShowMembersFunc_t showmembers,
00819 const char *dfil, const char *ifil, Int_t dl, Int_t il,
00820 Bool_t silent) :
00821 TDictionary(name),
00822 fStreamerInfo(0), fConversionStreamerInfo(0), fRealData(0),
00823 fBase(0), fData(0), fMethod(0), fAllPubData(0), fAllPubMethod(0),
00824 fClassMenuList(0),
00825 fDeclFileName(""), fImplFileName(""), fDeclFileLine(0), fImplFileLine(0),
00826 fInstanceCount(0), fOnHeap(0),
00827 fCheckSum(0), fCollectionProxy(0), fClassVersion(0), fClassInfo(0),
00828 fTypeInfo(0), fShowMembers(0), fInterShowMembers(0),
00829 fStreamer(0), fIsA(0), fGlobalIsA(0), fIsAMethod(0),
00830 fNew(0), fNewArray(0), fDelete(0), fDeleteArray(0),
00831 fDestructor(0), fDirAutoAdd(0), fSizeof(-1),
00832 fProperty(0),fVersionUsed(kFALSE),
00833 fIsOffsetStreamerSet(kFALSE), fOffsetStreamer(0), fStreamerType(kNone),
00834 fCurrentInfo(0), fRefStart(0), fRefProxy(0),
00835 fSchemaRules(0), fStreamerImpl(&TClass::StreamerDefault)
00836 {
00837
00838
00839
00840 R__LOCKGUARD2(gCINTMutex);
00841
00842 Init(name, cversion, &info, isa, showmembers, dfil, ifil, dl, il, silent);
00843 }
00844
00845
00846 void TClass::ForceReload (TClass* oldcl)
00847 {
00848
00849
00850
00851 TClass::RemoveClass(oldcl);
00852
00853 if (oldcl->CanIgnoreTObjectStreamer()) {
00854 IgnoreTObjectStreamer();
00855 }
00856
00857 TVirtualStreamerInfo *info;
00858 TIter next(oldcl->GetStreamerInfos());
00859 while ((info = (TVirtualStreamerInfo*)next())) {
00860 info->Clear("build");
00861 info->SetClass(this);
00862 fStreamerInfo->AddAtAndExpand(info,info->GetClassVersion());
00863 }
00864 oldcl->GetStreamerInfos()->Clear();
00865
00866 oldcl->ReplaceWith(this);
00867 delete oldcl;
00868 }
00869
00870
00871 void TClass::Init(const char *name, Version_t cversion,
00872 const type_info *typeinfo, TVirtualIsAProxy *isa,
00873 ShowMembersFunc_t showmembers,
00874 const char *dfil, const char *ifil, Int_t dl, Int_t il,
00875 Bool_t silent)
00876 {
00877
00878
00879 if (!gROOT)
00880 ::Fatal("TClass::TClass", "ROOT system not initialized");
00881
00882
00883 SetName(TClassEdit::ShortType(name, TClassEdit::kDropStlDefault).c_str());
00884 fClassVersion = cversion;
00885 fDeclFileName = dfil ? dfil : "";
00886 fImplFileName = ifil ? ifil : "";
00887 fDeclFileLine = dl;
00888 fImplFileLine = il;
00889 fTypeInfo = typeinfo;
00890 fIsA = isa;
00891 if ( fIsA ) fIsA->SetClass(this);
00892 fShowMembers = showmembers;
00893 fStreamerInfo = new TObjArray(fClassVersion+2+10,-1);
00894 fProperty = -1;
00895
00896 ResetInstanceCount();
00897
00898 TClass *oldcl = (TClass*)gROOT->GetListOfClasses()->FindObject(fName.Data());
00899
00900 if (oldcl && oldcl->TestBit(kLoading)) {
00901
00902 return;
00903 }
00904
00905 if (oldcl) {
00906 gROOT->RemoveClass(oldcl);
00907
00908
00909
00910 if (oldcl->CanIgnoreTObjectStreamer()) {
00911 IgnoreTObjectStreamer();
00912 }
00913 TVirtualStreamerInfo *info;
00914
00915 TIter next(oldcl->GetStreamerInfos());
00916 while ((info = (TVirtualStreamerInfo*)next())) {
00917
00918 info->Clear("build");
00919 info->SetClass(this);
00920 fStreamerInfo->AddAtAndExpand(info,info->GetClassVersion());
00921 }
00922 oldcl->GetStreamerInfos()->Clear();
00923
00924
00925 fSchemaRules = oldcl->fSchemaRules;
00926 oldcl->fSchemaRules = 0;
00927
00928 }
00929
00930 SetBit(kLoading);
00931
00932 TClass::AddClass(this);
00933
00934 Bool_t isStl = TClassEdit::IsSTLCont(fName);
00935
00936 if (!fClassInfo) {
00937 Bool_t shouldLoad = kFALSE;
00938
00939 if (gInterpreter->CheckClassInfo(fName)) shouldLoad = kTRUE;
00940 else if (fImplFileLine>=0) {
00941
00942
00943
00944
00945
00946
00947
00948
00949 shouldLoad = ! isStl;
00950 }
00951
00952 if (shouldLoad) {
00953 if (!gInterpreter)
00954 ::Fatal("TClass::TClass", "gInterpreter not initialized");
00955
00956 gInterpreter->SetClassInfo(this);
00957 if (!fClassInfo) {
00958 gInterpreter->InitializeDictionaries();
00959 gInterpreter->SetClassInfo(this);
00960 if (IsZombie()) {
00961 TClass::RemoveClass(this);
00962 return;
00963 }
00964 }
00965 }
00966 }
00967 if (!silent && !fClassInfo && !isStl && fName.First('@')==kNPOS)
00968 ::Warning("TClass::TClass", "no dictionary for class %s is available", fName.Data());
00969
00970 fgClassCount++;
00971 SetUniqueID(fgClassCount);
00972
00973
00974
00975
00976
00977 TString resolvedThis;
00978 if (strchr (name, '<')) {
00979 if ( fName != name) {
00980 if (!fgClassTypedefHash) {
00981 fgClassTypedefHash = new THashTable (100, 5);
00982 fgClassTypedefHash->SetOwner (kTRUE);
00983 }
00984
00985 fgClassTypedefHash->Add (new TNameMapNode (name, fName));
00986 SetBit (kHasNameMapNode);
00987
00988 TString resolvedShort = TClassEdit::ResolveTypedef(fName, kTRUE);
00989 if (resolvedShort != fName) {
00990 fgClassShortTypedefHash->Add (new TNameMapNode (resolvedShort, fName));
00991 }
00992 }
00993 resolvedThis = TClassEdit::ResolveTypedef (name, kTRUE);
00994 if (resolvedThis != name) {
00995 if (!fgClassTypedefHash) {
00996 fgClassTypedefHash = new THashTable (100, 5);
00997 fgClassTypedefHash->SetOwner (kTRUE);
00998 }
00999
01000 fgClassTypedefHash->Add (new TNameMapNode (resolvedThis, fName));
01001 SetBit (kHasNameMapNode);
01002 }
01003
01004 }
01005
01006
01007
01008
01009 if (oldcl) {
01010
01011 oldcl->ReplaceWith(this);
01012 delete oldcl;
01013
01014 } else if (resolvedThis.Length() > 0 && fgClassTypedefHash) {
01015
01016
01017
01018 if (resolvedThis != fName) {
01019 oldcl = (TClass*)gROOT->GetListOfClasses()->FindObject(resolvedThis);
01020 if (oldcl && oldcl != this)
01021 ForceReload (oldcl);
01022 }
01023 TIter next( fgClassTypedefHash->GetListForObject(resolvedThis) );
01024 while ( TNameMapNode* htmp = static_cast<TNameMapNode*> (next()) ) {
01025 if (resolvedThis != htmp->String()) continue;
01026 oldcl = (TClass*)gROOT->GetListOfClasses()->FindObject(htmp->fOrigName);
01027 if (oldcl && oldcl != this) {
01028 ForceReload (oldcl);
01029 }
01030 }
01031 }
01032 if (fClassInfo) SetTitle(gCint->ClassInfo_Title(fClassInfo));
01033
01034 ResetBit(kLoading);
01035
01036 if ( isStl || !strncmp(GetName(),"stdext::hash_",13) || !strncmp(GetName(),"__gnu_cxx::hash_",16) ) {
01037 fCollectionProxy = TVirtualStreamerInfo::Factory()->GenEmulatedProxy( GetName() );
01038 if (fCollectionProxy) {
01039 fSizeof = fCollectionProxy->Sizeof();
01040 } else if (!silent) {
01041 Warning("Init","Collection proxy for %s was not properly initialized!",GetName());
01042 }
01043 if (fStreamer==0) {
01044 fStreamer = TVirtualStreamerInfo::Factory()->GenEmulatedClassStreamer( GetName() );
01045 }
01046 }
01047
01048 }
01049
01050
01051 TClass::TClass(const TClass& cl) :
01052 TDictionary(cl),
01053 fStreamerInfo(cl.fStreamerInfo),
01054 fConversionStreamerInfo(cl.fConversionStreamerInfo),
01055 fRealData(cl.fRealData),
01056 fBase(cl.fBase),
01057 fData(cl.fData),
01058 fMethod(cl.fMethod),
01059 fAllPubData(cl.fAllPubData),
01060 fAllPubMethod(cl.fAllPubMethod),
01061 fClassMenuList(0),
01062 fDeclFileName(cl.fDeclFileName),
01063 fImplFileName(cl.fImplFileName),
01064 fDeclFileLine(cl.fDeclFileLine),
01065 fImplFileLine(cl.fImplFileLine),
01066 fInstanceCount(cl.fInstanceCount),
01067 fOnHeap(cl.fOnHeap),
01068 fCheckSum(cl.fCheckSum),
01069 fCollectionProxy(cl.fCollectionProxy),
01070 fClassVersion(cl.fClassVersion),
01071 fClassInfo(cl.fClassInfo),
01072 fContextMenuTitle(cl.fContextMenuTitle),
01073 fTypeInfo(cl.fTypeInfo),
01074 fShowMembers(cl.fShowMembers),
01075 fInterShowMembers(cl.fInterShowMembers),
01076 fStreamer(cl.fStreamer),
01077 fSharedLibs(cl.fSharedLibs),
01078 fIsA(cl.fIsA),
01079 fGlobalIsA(cl.fGlobalIsA),
01080 fIsAMethod(cl.fIsAMethod),
01081 fNew(cl.fNew),
01082 fNewArray(cl.fNewArray),
01083 fDelete(cl.fDelete),
01084 fDeleteArray(cl.fDeleteArray),
01085 fDestructor(cl.fDestructor),
01086 fDirAutoAdd(cl.fDirAutoAdd),
01087 fStreamerFunc(cl.fStreamerFunc),
01088 fSizeof(cl.fSizeof),
01089 fProperty(cl.fProperty),
01090 fVersionUsed(cl.fVersionUsed),
01091 fIsOffsetStreamerSet(cl.fIsOffsetStreamerSet),
01092 fOffsetStreamer(cl.fOffsetStreamer),
01093 fStreamerType(cl.fStreamerType),
01094 fCurrentInfo(cl.fCurrentInfo),
01095 fRefStart(cl.fRefStart),
01096 fRefProxy(cl.fRefProxy),
01097 fSchemaRules(cl.fSchemaRules),
01098 fStreamerImpl(cl.fStreamerImpl)
01099 {
01100
01101
01102 R__ASSERT(0 );
01103 }
01104
01105
01106 TClass& TClass::operator=(const TClass& cl)
01107 {
01108
01109 if(this!=&cl) {
01110 R__ASSERT(0 );
01111 }
01112 return *this;
01113 }
01114
01115
01116
01117 TClass::~TClass()
01118 {
01119
01120
01121 R__LOCKGUARD(gCINTMutex);
01122
01123
01124 if (fgClassTypedefHash && TestBit (kHasNameMapNode)) {
01125 TString resolvedThis = TClassEdit::ResolveTypedef (GetName(), kTRUE);
01126 TIter next (fgClassTypedefHash->GetListForObject (resolvedThis));
01127 while ( TNameMapNode* htmp = static_cast<TNameMapNode*> (next()) ) {
01128 if (resolvedThis == htmp->String() && htmp->fOrigName == GetName()) {
01129 fgClassTypedefHash->Remove (htmp);
01130 delete htmp;
01131 break;
01132 }
01133 }
01134 }
01135 if (fgClassShortTypedefHash && TestBit (kHasNameMapNode)) {
01136 TString resolvedShort =
01137 TClassEdit::ResolveTypedef
01138 (TClassEdit::ShortType(GetName(),
01139 TClassEdit::kDropStlDefault).c_str(),
01140 kTRUE);
01141 TIter next (fgClassShortTypedefHash->GetListForObject (resolvedShort));
01142 while ( TNameMapNode* htmp = static_cast<TNameMapNode*> (next()) ) {
01143 if (resolvedShort == htmp->String() && htmp->fOrigName == GetName()) {
01144 fgClassShortTypedefHash->Remove (htmp);
01145 delete htmp;
01146 break;
01147 }
01148 }
01149 }
01150
01151
01152
01153
01154
01155 delete fStreamer; fStreamer =0;
01156 delete fAllPubData; fAllPubData =0;
01157 delete fAllPubMethod; fAllPubMethod=0;
01158
01159 if (fRefStart) {
01160
01161 fRefStart->ListReset();
01162 fRefStart = 0;
01163 }
01164 if (fBase)
01165 fBase->Delete();
01166 delete fBase; fBase=0;
01167
01168 if (fData)
01169 fData->Delete();
01170 delete fData; fData = 0;
01171
01172 if (fMethod)
01173 fMethod->Delete();
01174 delete fMethod; fMethod=0;
01175
01176 if (fRealData)
01177 fRealData->Delete();
01178 delete fRealData; fRealData=0;
01179
01180 if (fStreamerInfo)
01181 fStreamerInfo->Delete();
01182 delete fStreamerInfo; fStreamerInfo=0;
01183
01184 if (fDeclFileLine >= -1)
01185 TClass::RemoveClass(this);
01186
01187 gCint->ClassInfo_Delete(fClassInfo);
01188 fClassInfo=0;
01189
01190 if (fClassMenuList)
01191 fClassMenuList->Delete();
01192 delete fClassMenuList; fClassMenuList=0;
01193
01194 fIsOffsetStreamerSet=kFALSE;
01195
01196 if (fInterShowMembers) gCint->CallFunc_Delete(fInterShowMembers);
01197
01198 if ( fIsA ) delete fIsA;
01199
01200 if ( fRefProxy ) fRefProxy->Release();
01201 fRefProxy = 0;
01202
01203 delete fStreamer;
01204 delete fCollectionProxy;
01205 delete fIsAMethod;
01206 delete fSchemaRules;
01207 if (fConversionStreamerInfo) {
01208 std::map<std::string, TObjArray*>::iterator it;
01209 std::map<std::string, TObjArray*>::iterator end = fConversionStreamerInfo->end();
01210 for( it = fConversionStreamerInfo->begin(); it != end; ++it ) {
01211 delete it->second;
01212 }
01213 delete fConversionStreamerInfo;
01214 }
01215 }
01216
01217
01218 namespace {
01219 Int_t ReadRulesContent(FILE *f)
01220 {
01221
01222
01223
01224
01225
01226 R__ASSERT(f!=0);
01227 TString rule(1024);
01228 int c, state = 0;
01229 Int_t count = 0;
01230
01231 while ((c = fgetc(f)) != EOF) {
01232 if (c == 13)
01233 continue;
01234 if (c == '\n') {
01235 if (state != 3) {
01236 state = 0;
01237 if (rule.Length() > 0) {
01238 if (TClass::AddRule(rule)) {
01239 ++count;
01240 }
01241 rule.Clear();
01242 }
01243 }
01244 continue;
01245 }
01246 switch (state) {
01247 case 0:
01248 switch (c) {
01249 case ' ':
01250 case '\t':
01251 break;
01252 case '#':
01253 state = 1;
01254 break;
01255 default:
01256 state = 2;
01257 break;
01258 }
01259 break;
01260
01261 case 1:
01262 break;
01263
01264 case 2:
01265 switch (c) {
01266 case '\\':
01267 state = 3;
01268 default:
01269 break;
01270 }
01271 break;
01272 }
01273 switch (state) {
01274 case 2:
01275 rule.Append(c);
01276 break;
01277 }
01278 }
01279 return count;
01280 }
01281 }
01282
01283
01284 Int_t TClass::ReadRules()
01285 {
01286
01287
01288
01289 static const char *suffix = "class.rules";
01290 TString sname = suffix;
01291 #ifdef ROOTETCDIR
01292 gSystem->PrependPathName(ROOTETCDIR, sname);
01293 #else
01294 TString etc = gRootDir;
01295 #ifdef WIN32
01296 etc += "\\etc";
01297 #else
01298 etc += "/etc";
01299 #endif
01300 gSystem->PrependPathName(etc, sname);
01301 #endif
01302
01303 Int_t res = -1;
01304
01305 FILE * f = fopen(sname,"r");
01306 if (f != 0) {
01307 res = ReadRulesContent(f);
01308 fclose(f);
01309 }
01310 return res;
01311 }
01312
01313
01314 Int_t TClass::ReadRules( const char *filename )
01315 {
01316
01317
01318
01319
01320
01321 if (!filename || !strlen(filename)) {
01322 ::Error("TClass::ReadRules", "no file name specified");
01323 return -1;
01324 }
01325
01326 FILE * f = fopen(filename,"r");
01327 if (f == 0) {
01328 ::Error("TClass::ReadRules","Failed to open %s\n",filename);
01329 return -1;
01330 }
01331 Int_t count = ReadRulesContent(f);
01332
01333 fclose(f);
01334 return count;
01335
01336 }
01337
01338
01339 Bool_t TClass::AddRule( const char *rule )
01340 {
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364 ROOT::TSchemaRule *ruleobj = new ROOT::TSchemaRule();
01365 if (! ruleobj->SetFromRule( rule ) ) {
01366 delete ruleobj;
01367 return kFALSE;
01368 }
01369
01370 TClass *cl = TClass::GetClass( ruleobj->GetTargetClass() );
01371 if (!cl) {
01372
01373 cl = new TClass(ruleobj->GetTargetClass(), 1, 0, 0, -1, -1, kTRUE);
01374 cl->SetBit(TClass::kIsEmulation);
01375 }
01376 ROOT::TSchemaRuleSet* rset = cl->GetSchemaRules( kTRUE );
01377
01378 if( !rset->AddRule( ruleobj, ROOT::TSchemaRuleSet::kCheckConflict ) ) {
01379 ::Warning( "TClass::AddRule", "The rule for class: \"%s\": version, \"%s\" and data members: \"%s\" has been skipped because it conflicts with one of the other rules.",
01380 ruleobj->GetTargetClass(), ruleobj->GetVersion(), ruleobj->GetTargetString() );
01381 delete ruleobj;
01382 return kFALSE;
01383 }
01384 return kTRUE;
01385 }
01386
01387
01388 void TClass::AdoptSchemaRules( ROOT::TSchemaRuleSet *rules )
01389 {
01390
01391
01392 R__LOCKGUARD(gCINTMutex);
01393
01394 delete fSchemaRules;
01395 fSchemaRules = rules;
01396 fSchemaRules->SetClass( this );
01397 }
01398
01399
01400 const ROOT::TSchemaRuleSet* TClass::GetSchemaRules() const
01401 {
01402
01403 return fSchemaRules;
01404 }
01405
01406
01407 ROOT::TSchemaRuleSet* TClass::GetSchemaRules(Bool_t create)
01408 {
01409
01410
01411 if (create && fSchemaRules == 0) {
01412 fSchemaRules = new ROOT::TSchemaRuleSet();
01413 fSchemaRules->SetClass( this );
01414 }
01415 return fSchemaRules;
01416 }
01417
01418
01419 void TClass::AddImplFile(const char* filename, int line) {
01420
01421
01422
01423
01424
01425 fImplFileName = filename;
01426 fImplFileLine = line;
01427 }
01428
01429
01430 void TClass::AddRef(TClassRef *ref)
01431 {
01432
01433
01434
01435 R__LOCKGUARD(gCINTMutex);
01436 if (fRefStart==0) {
01437 fRefStart = ref;
01438 } else {
01439 fRefStart->fPrevious = ref;
01440 ref->fNext = fRefStart;
01441 fRefStart = ref;
01442 }
01443 }
01444
01445
01446 Int_t TClass::AutoBrowse(TObject *obj, TBrowser *b)
01447 {
01448
01449
01450
01451
01452 if (!obj) return 0;
01453
01454 TAutoInspector insp(b);
01455 obj->ShowMembers(insp);
01456 return insp.fCount;
01457 }
01458
01459
01460 Int_t TClass::Browse(void *obj, TBrowser *b) const
01461 {
01462
01463
01464 if (!obj) return 0;
01465
01466 TClass *actual = GetActualClass(obj);
01467 if (IsTObject()) {
01468
01469
01470 if (!fIsOffsetStreamerSet) {
01471 CalculateStreamerOffset();
01472 }
01473 TObject* realTObject = (TObject*)((size_t)obj + fOffsetStreamer);
01474 realTObject->Browse(b);
01475 return 1;
01476 } else if (actual != this) {
01477 return actual->Browse(obj, b);
01478 } else if (GetCollectionProxy()) {
01479
01480
01481
01482 } else {
01483 TAutoInspector insp(b);
01484 CallShowMembers(obj,insp,0);
01485 return insp.fCount;
01486 }
01487
01488 return 0;
01489 }
01490
01491
01492 void TClass::Browse(TBrowser *b)
01493 {
01494
01495
01496 if (!fClassInfo) return;
01497
01498 if (b) {
01499 if (!fRealData) BuildRealData();
01500
01501 b->Add(GetListOfDataMembers(), "Data Members");
01502 b->Add(GetListOfRealData(), "Real Data Members");
01503 b->Add(GetListOfMethods(), "Methods");
01504 b->Add(GetListOfBases(), "Base Classes");
01505 }
01506 }
01507
01508
01509 void TClass::BuildRealData(void* pointer, Bool_t isTransient)
01510 {
01511
01512
01513
01514
01515
01516
01517
01518
01519 R__LOCKGUARD(gCINTMutex);
01520
01521
01522 if (fRealData) {
01523 return;
01524 }
01525
01526
01527
01528 TMmallocDescTemp setreset;
01529
01530
01531 if (!fClassInfo || TClassEdit::IsSTLCont(GetName(), 0) || TClassEdit::IsSTLBitset(GetName())) {
01532
01533 fRealData = new TList;
01534 BuildEmulatedRealData("", 0, this);
01535 return;
01536 }
01537
01538 void* realDataObject = pointer;
01539
01540
01541
01542 if ((!pointer) && (Property() & kIsAbstract)) {
01543 return;
01544 }
01545
01546
01547
01548 if (!realDataObject) {
01549 if (!strcmp(GetName(), "TROOT")) {
01550 realDataObject = gROOT;
01551 } else if (!strcmp(GetName(), "TGWin32")) {
01552 realDataObject = gVirtualX;
01553 } else if (!strcmp(GetName(), "TGQt")) {
01554 realDataObject = gVirtualX;
01555 } else {
01556 realDataObject = New();
01557
01558
01559
01560
01561
01562
01563 if (fRealData) {
01564 Int_t delta = GetBaseClassOffset(TObject::Class());
01565 if (delta >= 0) {
01566 TObject* tobj = (TObject*) (((char*) realDataObject) + delta);
01567 tobj->SetBit(kZombie);
01568 delete tobj;
01569 tobj = 0;
01570 } else {
01571 Destructor(realDataObject);
01572 realDataObject = 0;
01573 }
01574 return;
01575 }
01576 }
01577 }
01578
01579
01580
01581 if (realDataObject) {
01582 fRealData = new TList;
01583 TBuildRealData brd(realDataObject, this);
01584
01585
01586
01587
01588 Bool_t wasTransient = brd.TestBit(TRealData::kTransient);
01589 if (isTransient) {
01590 brd.SetBit(TRealData::kTransient);
01591 }
01592 if ( ! CallShowMembers(realDataObject, brd) ) {
01593 if ( brd.TestBit(TRealData::kTransient) ) {
01594
01595
01596
01597
01598 delete fRealData;
01599 fRealData = 0;
01600 } else {
01601 Error("BuildRealData", "Cannot find any ShowMembers function for %s!", GetName());
01602 }
01603 }
01604 if (isTransient && !wasTransient) {
01605 brd.ResetBit(TRealData::kTransient);
01606 }
01607
01608
01609
01610
01611 TBaseClass* base = 0;
01612 TIter next(GetListOfBases());
01613 while ((base = (TBaseClass*) next())) {
01614 if (base->IsSTLContainer()) {
01615 continue;
01616 }
01617 TClass* c = base->GetClassPointer();
01618 if (c) {
01619 c->BuildRealData(((char*) realDataObject) + base->GetDelta(), isTransient);
01620 }
01621 }
01622 }
01623
01624
01625 if (!pointer && realDataObject && (realDataObject != gROOT) && (realDataObject != gVirtualX)) {
01626 Int_t delta = GetBaseClassOffset(TObject::Class());
01627 if (delta >= 0) {
01628 TObject* tobj = (TObject*) (((char*) realDataObject) + delta);
01629 tobj->SetBit(kZombie);
01630 delete tobj;
01631 tobj = 0;
01632 } else {
01633 Destructor(realDataObject);
01634 realDataObject = 0;
01635 }
01636 }
01637 }
01638
01639
01640 void TClass::BuildEmulatedRealData(const char *name, Long_t offset, TClass *cl)
01641 {
01642
01643
01644 R__LOCKGUARD(gCINTMutex);
01645
01646 TIter next(GetStreamerInfo()->GetElements());
01647 TStreamerElement *element;
01648 while ((element = (TStreamerElement*)next())) {
01649 Int_t etype = element->GetType();
01650 Long_t eoffset = element->GetOffset();
01651 TClass *cle = element->GetClassPointer();
01652 if (element->IsBase() || etype == TVirtualStreamerInfo::kBase) {
01653
01654 continue;
01655 } else if (etype == TVirtualStreamerInfo::kTObject ||
01656 etype == TVirtualStreamerInfo::kTNamed ||
01657 etype == TVirtualStreamerInfo::kObject ||
01658 etype == TVirtualStreamerInfo::kAny) {
01659
01660 TRealData *rd = new TRealData(Form("%s%s",name,element->GetFullName()),offset+eoffset,0);
01661 if (gDebug > 0) printf(" Class: %s, adding TRealData=%s, offset=%ld\n",cl->GetName(),rd->GetName(),rd->GetThisOffset());
01662 cl->GetListOfRealData()->Add(rd);
01663 TString rdname(Form("%s%s.",name,element->GetFullName()));
01664 if (cle) cle->BuildEmulatedRealData(rdname,offset+eoffset,cl);
01665 } else {
01666
01667 TString rdname(Form("%s%s",name,element->GetFullName()));
01668 TRealData *rd = new TRealData(rdname,offset+eoffset,0);
01669 if (gDebug > 0) printf(" Class: %s, adding TRealData=%s, offset=%ld\n",cl->GetName(),rd->GetName(),rd->GetThisOffset());
01670 cl->GetListOfRealData()->Add(rd);
01671 }
01672
01673
01674
01675
01676
01677 }
01678
01679 next.Reset();
01680 while ((element = (TStreamerElement*)next())) {
01681 Int_t etype = element->GetType();
01682 if (element->IsBase() || etype == TVirtualStreamerInfo::kBase) {
01683
01684 Long_t eoffset = element->GetOffset();
01685 TClass *cle = element->GetClassPointer();
01686 if (cle) cle->BuildEmulatedRealData(name,offset+eoffset,cl);
01687 }
01688 }
01689 }
01690
01691
01692
01693 void TClass::CalculateStreamerOffset() const
01694 {
01695
01696
01697
01698
01699 R__LOCKGUARD(gCINTMutex);
01700 if (!fIsOffsetStreamerSet && fClassInfo) {
01701
01702
01703 TMmallocDescTemp setreset;
01704 fIsOffsetStreamerSet = kTRUE;
01705 fOffsetStreamer = const_cast<TClass*>(this)->GetBaseClassOffset(TObject::Class());
01706 if (fStreamerType == kTObject) {
01707 fStreamerImpl = &TClass::StreamerTObjectInitialized;
01708 }
01709 }
01710 }
01711
01712
01713
01714 Bool_t TClass::CallShowMembers(void* obj, TMemberInspector &insp,
01715 Int_t isATObject) const
01716 {
01717
01718
01719
01720
01721 if (fShowMembers) {
01722
01723
01724 fShowMembers(obj, insp);
01725 return kTRUE;
01726 } else {
01727
01728 if (isATObject == -1 && IsLoaded()) {
01729
01730
01731
01732 isATObject = (Int_t) (InheritsFrom(TObject::Class()));
01733 }
01734
01735 if (isATObject == 1) {
01736
01737 if (!fIsOffsetStreamerSet) {
01738 CalculateStreamerOffset();
01739 }
01740 TObject* realTObject = (TObject*)((size_t)obj + fOffsetStreamer);
01741 realTObject->ShowMembers(insp);
01742 return kTRUE;
01743 } else if (fClassInfo) {
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754 if (!fInterShowMembers) {
01755 CallFunc_t* ism = gCint->CallFunc_Factory();
01756 Long_t offset = 0;
01757
01758 R__LOCKGUARD2(gCINTMutex);
01759 gCint->CallFunc_SetFuncProto(ism,fClassInfo,"ShowMembers", "TMemberInspector&", &offset);
01760 if (fIsOffsetStreamerSet && offset != fOffsetStreamer) {
01761 Error("CallShowMembers", "Logic Error: offset for Streamer() and ShowMembers() differ!");
01762 fInterShowMembers = 0;
01763 return kFALSE;
01764 }
01765
01766 fInterShowMembers = ism;
01767 }
01768 if (!gCint->CallFunc_IsValid(fInterShowMembers)) {
01769 if (strcmp(GetName(), "string") == 0) {
01770
01771
01772 return kTRUE;
01773 }
01774
01775
01776 return kFALSE;
01777 } else {
01778 R__LOCKGUARD2(gCINTMutex);
01779 gCint->CallFunc_ResetArg(fInterShowMembers);
01780 gCint->CallFunc_SetArg(fInterShowMembers,(long) &insp);
01781 void* address = (void*) (((long) obj) + fOffsetStreamer);
01782 gCint->CallFunc_Exec((CallFunc_t*)fInterShowMembers,address);
01783 return kTRUE;
01784 }
01785 } else if (TVirtualStreamerInfo* sinfo = GetStreamerInfo()) {
01786 sinfo->CallShowMembers(obj,insp);
01787 return kTRUE;
01788 }
01789 }
01790
01791 return kFALSE;
01792 }
01793
01794
01795 void TClass::InterpretedShowMembers(void* obj, TMemberInspector &insp)
01796 {
01797
01798
01799
01800
01801 if (!fClassInfo) return;
01802
01803 DataMemberInfo_t* dmi = gCint->DataMemberInfo_Factory(fClassInfo);
01804
01805 TString name("*");
01806 while (gCint->DataMemberInfo_Next(dmi)) {
01807 name.Remove(1);
01808 name += gCint->DataMemberInfo_Name(dmi);
01809 if (name == "*G__virtualinfo") continue;
01810
01811
01812
01813 Long_t prop = gCint->DataMemberInfo_Property(dmi) | gCint->DataMemberInfo_TypeProperty(dmi);
01814 if (prop & (G__BIT_ISSTATIC | G__BIT_ISENUM))
01815 continue;
01816 Bool_t isPointer = gCint->DataMemberInfo_TypeProperty(dmi) & G__BIT_ISPOINTER;
01817
01818
01819 if (prop & G__BIT_ISARRAY) {
01820 int arrdim = gCint->DataMemberInfo_ArrayDim(dmi);
01821 for (int dim = 0; dim < arrdim; dim++) {
01822 int nelem = gCint->DataMemberInfo_MaxIndex(dmi, dim);
01823 name += TString::Format("[%d]", nelem);
01824 }
01825 }
01826
01827 const char* inspname = name;
01828 if (!isPointer) {
01829
01830 ++inspname;
01831 }
01832 void* maddr = ((char*)obj) + gCint->DataMemberInfo_Offset(dmi);
01833 insp.Inspect(this, insp.GetParent(), inspname, maddr);
01834
01835
01836 if (!isPointer && !(prop & G__BIT_ISFUNDAMENTAL)) {
01837 std::string clmName(TClassEdit::ShortType(gCint->DataMemberInfo_TypeName(dmi),
01838 TClassEdit::kDropTrailStar) );
01839 TClass* clm = TClass::GetClass(clmName.c_str());
01840 if (clm) {
01841 insp.InspectMember(clm, maddr, name);
01842 }
01843 }
01844 }
01845 gCint->DataMemberInfo_Delete(dmi);
01846
01847
01848 BaseClassInfo_t* bci = gCint->BaseClassInfo_Factory(fClassInfo);
01849 while (gCint->BaseClassInfo_Next(bci)) {
01850 const char* bclname = gCint->BaseClassInfo_Name(bci);
01851 TClass* bcl = TClass::GetClass(bclname);
01852 void* baddr = ((char*)obj) + gCint->BaseClassInfo_Offset(bci);
01853 if (bcl) {
01854 bcl->CallShowMembers(baddr, insp);
01855 } else {
01856 Warning("InterpretedShowMembers()", "Unknown class %s", bclname);
01857 }
01858 }
01859 gCint->BaseClassInfo_Delete(bci);
01860 }
01861
01862
01863 Bool_t TClass::CanSplit() const
01864 {
01865
01866
01867
01868
01869
01870 if (fRefProxy) return kFALSE;
01871 if (InheritsFrom("TRef")) return kFALSE;
01872 if (InheritsFrom("TRefArray")) return kFALSE;
01873 if (InheritsFrom("TArray")) return kFALSE;
01874 if (fName.BeginsWith("TVectorT<")) return kFALSE;
01875 if (fName.BeginsWith("TMatrixT<")) return kFALSE;
01876 if (InheritsFrom("TCollection") && !InheritsFrom("TClonesArray")) return kFALSE;
01877 if (InheritsFrom("TTree")) return kFALSE;
01878
01879
01880
01881
01882 if (GetShowMembersWrapper()==0 && GetStreamer()!=0) {
01883
01884
01885 if (GetCollectionProxy()==0) {
01886
01887 return kFALSE;
01888
01889 } else {
01890
01891
01892
01893
01894
01895
01896
01897 if (GetCollectionProxy()->HasPointers()) return kFALSE;
01898
01899 TClass *valueClass = GetCollectionProxy()->GetValueClass();
01900 if (valueClass == 0) return kFALSE;
01901 if (valueClass==TString::Class() || valueClass==TClass::GetClass("string"))
01902 return kFALSE;
01903 if (!valueClass->CanSplit()) return kFALSE;
01904 if (valueClass->GetCollectionProxy() != 0) return kFALSE;
01905
01906 Int_t stl = -TClassEdit::IsSTLCont(GetName(), 0);
01907 if ((stl==TClassEdit::kMap || stl==TClassEdit::kMultiMap)
01908 && valueClass->GetClassInfo()==0)
01909 {
01910 return kFALSE;
01911 }
01912 }
01913 }
01914
01915 if (Size()==1) {
01916
01917 return kFALSE;
01918 }
01919
01920 TClass *ncThis = const_cast<TClass*>(this);
01921 TIter nextb(ncThis->GetListOfBases());
01922 TBaseClass *base;
01923 while((base = (TBaseClass*)nextb())) {
01924 if (!TClass::GetClass(base->GetName())) return kFALSE;
01925 }
01926
01927 return kTRUE;
01928 }
01929
01930
01931 TObject *TClass::Clone(const char *new_name) const
01932 {
01933
01934
01935
01936 if (new_name == 0 || new_name[0]=='\0' || fName == new_name) {
01937 Error("Clone","The name of the class must be changed when cloning a TClass object.");
01938 return 0;
01939 }
01940
01941 TClass::RemoveClass(const_cast<TClass*>(this));
01942
01943 TClass *copy;
01944 if (fTypeInfo) {
01945 copy = new TClass(GetName(),
01946 fClassVersion,
01947 *fTypeInfo,
01948 new TIsAProxy(*fTypeInfo),
01949 fShowMembers,
01950 GetDeclFileName(),
01951 GetImplFileName(),
01952 GetDeclFileLine(),
01953 GetImplFileLine());
01954 } else {
01955 copy = new TClass(GetName(),
01956 fClassVersion,
01957 GetDeclFileName(),
01958 GetImplFileName(),
01959 GetDeclFileLine(),
01960 GetImplFileLine());
01961 copy->fShowMembers = fShowMembers;
01962 }
01963
01964 TClass::RemoveClass(copy);
01965 copy->SetName(new_name);
01966 TClass::AddClass(copy);
01967
01968 copy->SetNew(fNew);
01969 copy->SetNewArray(fNewArray);
01970 copy->SetDelete(fDelete);
01971 copy->SetDeleteArray(fDeleteArray);
01972 copy->SetDestructor(fDestructor);
01973 copy->SetDirectoryAutoAdd(fDirAutoAdd);
01974 copy->fStreamerFunc = fStreamerFunc;
01975 if (fStreamer) {
01976 copy->AdoptStreamer(fStreamer->Generate());
01977 }
01978
01979
01980 if (fCollectionProxy && !copy->IsZombie()) {
01981 copy->CopyCollectionProxy(*fCollectionProxy);
01982 }
01983 copy->SetClassSize(fSizeof);
01984 if (fRefProxy) {
01985 copy->AdoptReferenceProxy( fRefProxy->Clone() );
01986 }
01987 TClass::AddClass(const_cast<TClass*>(this));
01988 return copy;
01989 }
01990
01991
01992 void TClass::CopyCollectionProxy(const TVirtualCollectionProxy &orig)
01993 {
01994
01995
01996
01997
01998
01999
02000 delete fCollectionProxy;
02001 fCollectionProxy = orig.Generate();
02002 }
02003
02004
02005
02006 void TClass::Draw(Option_t *option)
02007 {
02008
02009
02010
02011
02012
02013
02014 if (!fClassInfo) return;
02015
02016 TVirtualPad *padsav = gPad;
02017
02018
02019 TString opt=option;
02020 if (!padsav || !opt.Contains("same")) {
02021 TVirtualPad *padclass = (TVirtualPad*)(gROOT->GetListOfCanvases())->FindObject("R__class");
02022 if (!padclass) {
02023 gROOT->ProcessLine("new TCanvas(\"R__class\",\"class\",20,20,1000,750);");
02024 } else {
02025 padclass->cd();
02026 }
02027 }
02028
02029 if (gPad) gPad->DrawClassObject(this,option);
02030
02031 if (padsav) padsav->cd();
02032 }
02033
02034
02035 void TClass::Dump(void *obj) const
02036 {
02037
02038
02039
02040
02041
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059 Printf("==>Dumping object at:%lx, class=%s\n",(Long_t)obj,GetName());
02060 TDumpMembers dm;
02061 if (!CallShowMembers(obj, dm)) {
02062 Info("Dump", "No ShowMembers function, dumping disabled");
02063 }
02064 }
02065
02066
02067 char *TClass::EscapeChars(const char *text) const
02068 {
02069
02070
02071
02072 static char name[128];
02073 Int_t nch = strlen(text);
02074 if (nch > 127) nch = 127;
02075 Int_t icur = -1;
02076 for (Int_t i = 0; i < nch; i++) {
02077 icur++;
02078 if (text[i] == '\"' || text[i] == '[' || text[i] == '~' ||
02079 text[i] == ']' || text[i] == '&' || text[i] == '#' ||
02080 text[i] == '!' || text[i] == '^' || text[i] == '<' ||
02081 text[i] == '?' || text[i] == '>') {
02082 name[icur] = '@';
02083 icur++;
02084 }
02085 name[icur] = text[i];
02086 }
02087 name[icur+1] = 0;
02088 return name;
02089 }
02090
02091
02092 TClass *TClass::GetActualClass(const void *object) const
02093 {
02094
02095
02096
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107 if (object==0) return (TClass*)this;
02108 if (!IsLoaded()) {
02109 TVirtualStreamerInfo* sinfo = GetStreamerInfo();
02110 if (sinfo) {
02111 return sinfo->GetActualClass(object);
02112 }
02113 return (TClass*)this;
02114 }
02115 if (fIsA) {
02116 return (*fIsA)(object);
02117 } else if (fGlobalIsA) {
02118 return fGlobalIsA(this,object);
02119 } else {
02120
02121
02122
02123
02124 if (fIsAMethod==0) {
02125 fIsAMethod = new TMethodCall((TClass*)this, "IsA", "");
02126
02127 if (!fIsAMethod->GetMethod()) {
02128 delete fIsAMethod;
02129 fIsAMethod = 0;
02130 Error("IsA","Can not find any IsA function for %s!",GetName());
02131 return (TClass*)this;
02132 }
02133
02134 }
02135 char * char_result = 0;
02136 fIsAMethod->Execute((void*)object, &char_result);
02137 return (TClass*)char_result;
02138 }
02139 }
02140
02141
02142 TClass *TClass::GetBaseClass(const char *classname)
02143 {
02144
02145
02146
02147
02148 if (strcmp(GetName(), classname) == 0) return this;
02149
02150 if (!fClassInfo) return 0;
02151
02152 TObjLink *lnk = GetListOfBases() ? fBase->FirstLink() : 0;
02153
02154
02155 while (lnk) {
02156 TClass *c, *c1;
02157 TBaseClass *base = (TBaseClass*) lnk->GetObject();
02158 c = base->GetClassPointer();
02159 if (c) {
02160 if (strcmp(c->GetName(), classname) == 0) return c;
02161 c1 = c->GetBaseClass(classname);
02162 if (c1) return c1;
02163 }
02164 lnk = lnk->Next();
02165 }
02166 return 0;
02167 }
02168
02169
02170 TClass *TClass::GetBaseClass(const TClass *cl)
02171 {
02172
02173
02174
02175
02176 if (cl == this) return this;
02177
02178 if (!fClassInfo) return 0;
02179
02180 TObjLink *lnk = GetListOfBases() ? fBase->FirstLink() : 0;
02181
02182
02183 while (lnk) {
02184 TClass *c, *c1;
02185 TBaseClass *base = (TBaseClass*) lnk->GetObject();
02186 c = base->GetClassPointer();
02187 if (c) {
02188 if (cl == c) return c;
02189 c1 = c->GetBaseClass(cl);
02190 if (c1) return c1;
02191 }
02192 lnk = lnk->Next();
02193 }
02194 return 0;
02195 }
02196
02197
02198 Int_t TClass::GetBaseClassOffsetRecurse(const TClass *cl)
02199 {
02200
02201
02202
02203
02204
02205
02206
02207 if (cl == this) return 0;
02208
02209 if (!fClassInfo) {
02210 TVirtualStreamerInfo *sinfo = GetCurrentStreamerInfo();
02211 if (!sinfo) return -1;
02212 TStreamerElement *element;
02213 Int_t offset = 0;
02214
02215 TObjArray &elems = *(sinfo->GetElements());
02216 Int_t size = elems.GetLast()+1;
02217 for(Int_t i=0; i<size; i++) {
02218 element = (TStreamerElement*)elems[i];
02219 if (element->IsA() == TStreamerBase::Class()) {
02220 TStreamerBase *base = (TStreamerBase*)element;
02221 TClass *baseclass = base->GetClassPointer();
02222 if (!baseclass) return -1;
02223 Int_t subOffset = baseclass->GetBaseClassOffsetRecurse(cl);
02224 if (subOffset == -2) return -2;
02225 if (subOffset != -1) return offset+subOffset;
02226 offset += baseclass->Size();
02227 }
02228 }
02229 return -1;
02230 }
02231
02232 TClass *c;
02233 Int_t off;
02234 TBaseClass *inh;
02235 TObjLink *lnk = 0;
02236 if (fBase==0) lnk = GetListOfBases()->FirstLink();
02237 else lnk = fBase->FirstLink();
02238
02239
02240 while (lnk) {
02241 inh = (TBaseClass *)lnk->GetObject();
02242
02243
02244
02245
02246 c = inh->GetClassPointer(kTRUE);
02247 if (c) {
02248 if (cl == c) {
02249 if ((inh->Property() & G__BIT_ISVIRTUALBASE) != 0)
02250 return -2;
02251 return inh->GetDelta();
02252 }
02253 off = c->GetBaseClassOffsetRecurse(cl);
02254 if (off == -2) return -2;
02255 if (off != -1) return off + inh->GetDelta();
02256 }
02257 lnk = lnk->Next();
02258 }
02259 return -1;
02260 }
02261
02262
02263 Int_t TClass::GetBaseClassOffset(const TClass *cl)
02264 {
02265
02266
02267
02268
02269 Int_t offset = GetBaseClassOffsetRecurse (cl);
02270 if (offset == -2) {
02271
02272 if (cl->GetClassInfo()) {
02273 R__LOCKGUARD(gCINTMutex);
02274 Long_t base_tagnum = gCint->ClassInfo_Tagnum(cl->GetClassInfo());
02275 BaseClassInfo_t *t = gCint->BaseClassInfo_Factory(GetClassInfo());
02276 while (gCint->BaseClassInfo_Next(t,0)) {
02277 if (gCint->BaseClassInfo_Tagnum(t) == base_tagnum) {
02278 if ((gCint->BaseClassInfo_Property(t) & G__BIT_ISVIRTUALBASE) != 0) {
02279 break;
02280 }
02281 int off = gCint->BaseClassInfo_Offset(t);
02282 gCint->BaseClassInfo_Delete(t);
02283 return off;
02284 }
02285 }
02286 gCint->BaseClassInfo_Delete(t);
02287 }
02288 offset = -1;
02289 }
02290 return offset;
02291 }
02292
02293
02294 TClass *TClass::GetBaseDataMember(const char *datamember)
02295 {
02296
02297
02298 if (!fClassInfo) return 0;
02299
02300
02301 TDataMember *dm = GetDataMember(datamember);
02302 if (dm) return this;
02303
02304
02305 TBaseClass *inh;
02306 TIter next(GetListOfBases());
02307 while ((inh = (TBaseClass *) next())) {
02308 TClass *c = inh->GetClassPointer();
02309 if (c) {
02310 TClass *cdm = c->GetBaseDataMember(datamember);
02311 if (cdm) return cdm;
02312 }
02313 }
02314
02315 return 0;
02316 }
02317
02318 namespace {
02319
02320
02321
02322 struct TClassLocalStorage {
02323 TClassLocalStorage() : fCollectionProxy(0), fStreamer(0) {};
02324
02325 TVirtualCollectionProxy *fCollectionProxy;
02326 TClassStreamer *fStreamer;
02327
02328 static TClassLocalStorage *GetStorage(const TClass *cl) {
02329 void **thread_ptr = (*gThreadTsd)(0,1);
02330 if (thread_ptr) {
02331 if (*thread_ptr==0) *thread_ptr = new TExMap();
02332 TExMap *lmap = (TExMap*)(*thread_ptr);
02333 ULong_t hash = TString::Hash(&cl, sizeof(void*));
02334 ULong_t local = 0;
02335 UInt_t slot;
02336 if ((local = (ULong_t)lmap->GetValue(hash, (Long_t)cl, slot)) != 0) {
02337 } else {
02338 local = (ULong_t) new TClassLocalStorage();
02339 lmap->AddAt(slot, hash, (Long_t)cl, local);
02340 }
02341 return (TClassLocalStorage*)local;
02342 }
02343 return 0;
02344 }
02345 };
02346 }
02347
02348
02349 TVirtualCollectionProxy *TClass::GetCollectionProxy() const
02350 {
02351
02352
02353 if (gThreadTsd && fCollectionProxy) {
02354 TClassLocalStorage *local = TClassLocalStorage::GetStorage(this);
02355 if (local == 0) return fCollectionProxy;
02356 if (local->fCollectionProxy==0) local->fCollectionProxy = fCollectionProxy->Generate();
02357 return local->fCollectionProxy;
02358 }
02359 return fCollectionProxy;
02360 }
02361
02362
02363 TClassStreamer *TClass::GetStreamer() const
02364 {
02365
02366
02367 if (gThreadTsd && fStreamer) {
02368 TClassLocalStorage *local = TClassLocalStorage::GetStorage(this);
02369 if (local==0) return fStreamer;
02370 if (local->fStreamer==0) {
02371 local->fStreamer = fStreamer->Generate();
02372 const type_info &orig = ( typeid(*fStreamer) );
02373 const type_info © = ( typeid(*local->fStreamer) );
02374 if (strcmp(orig.name(),copy.name())!=0) {
02375 Warning("GetStreamer","For %s, the TClassStreamer passed does not properly implement the Generate method (%s vs %s\n",GetName(),orig.name(),copy.name());
02376 }
02377 }
02378 return local->fStreamer;
02379 }
02380 return fStreamer;
02381 }
02382
02383 ClassStreamerFunc_t TClass::GetStreamerFunc() const
02384 {
02385
02386
02387 return fStreamerFunc;
02388 }
02389
02390
02391 TVirtualIsAProxy* TClass::GetIsAProxy() const
02392 {
02393
02394
02395 return fIsA;
02396 }
02397
02398
02399
02400 TClass *TClass::GetClass(const char *name, Bool_t load, Bool_t silent)
02401 {
02402
02403
02404
02405
02406
02407
02408
02409 if (!name || !strlen(name)) return 0;
02410 if (!gROOT->GetListOfClasses()) return 0;
02411
02412 TClass *cl = (TClass*)gROOT->GetListOfClasses()->FindObject(name);
02413
02414 TClassEdit::TSplitType splitname( name, TClassEdit::kLong64 );
02415
02416 if (!cl) {
02417
02418 std::string resolvedName;
02419 splitname.ShortType(resolvedName, TClassEdit::kDropStlDefault);
02420 if (resolvedName != name) cl = (TClass*)gROOT->GetListOfClasses()->FindObject(resolvedName.c_str());
02421 if (!cl) {
02422
02423 resolvedName = TClassEdit::ResolveTypedef(resolvedName.c_str(),kTRUE);
02424 if (resolvedName != name) cl = (TClass*)gROOT->GetListOfClasses()->FindObject(resolvedName.c_str());
02425 }
02426 if (!cl) {
02427
02428 resolvedName = TClassEdit::GetLong64_Name(resolvedName);
02429 if (resolvedName != name) cl = (TClass*)gROOT->GetListOfClasses()->FindObject(resolvedName.c_str());
02430 }
02431 }
02432
02433 if (cl) {
02434
02435 if (cl->IsLoaded()) return cl;
02436
02437
02438 load = kTRUE;
02439
02440 if (splitname.IsSTLCont()) {
02441
02442 const char * itypename = gCint->GetInterpreterTypeName(name);
02443 if (itypename) {
02444 std::string altname( TClassEdit::ShortType(itypename, TClassEdit::kDropStlDefault) );
02445 if (altname != name) {
02446
02447
02448
02449 gROOT->GetListOfClasses()->Remove(cl);
02450 TClass *newcl = GetClass(altname.c_str(),load);
02451
02452
02453
02454 assert(newcl!=cl);
02455 newcl->ForceReload(cl);
02456 return newcl;
02457 }
02458 }
02459 }
02460
02461 } else {
02462
02463 if (!splitname.IsSTLCont()) {
02464
02465
02466
02467
02468
02469 TDataType *objType = gROOT->GetType(name, load);
02470 if (objType) {
02471 const char *typdfName = objType->GetTypeName();
02472 if (typdfName && strcmp(typdfName, name)) {
02473 cl = TClass::GetClass(typdfName, load);
02474 return cl;
02475 }
02476 }
02477
02478 } else {
02479
02480 cl = gROOT->FindSTLClass(name,kFALSE,silent);
02481
02482 if (cl) {
02483 if (cl->IsLoaded()) return cl;
02484
02485
02486
02487 return TClass::GetClass(cl->GetName(),kTRUE);
02488 }
02489
02490 }
02491
02492 }
02493
02494 if (!load) return 0;
02495
02496 TClass *loadedcl = 0;
02497 if (cl) loadedcl = gROOT->LoadClass(cl->GetName(),silent);
02498 else loadedcl = gROOT->LoadClass(name,silent);
02499
02500 if (loadedcl) return loadedcl;
02501
02502 if (cl) return cl;
02503
02504 static const char *full_string_name = "basic_string<char,char_traits<char>,allocator<char> >";
02505 if (strcmp(name,full_string_name)==0
02506 || ( strncmp(name,"std::",5)==0 && ((strcmp(name+5,"string")==0)||(strcmp(name+5,full_string_name)==0)))) {
02507 return TClass::GetClass("string");
02508 }
02509 if (splitname.IsSTLCont()) {
02510
02511 return gROOT->FindSTLClass(name,kTRUE,silent);
02512
02513 } else if ( strncmp(name,"std::",5)==0 ) {
02514
02515 return TClass::GetClass(name+5,load);
02516
02517 } else if ( strstr(name,"std::") != 0 ) {
02518
02519
02520 TString rname( TClassEdit::ResolveTypedef(name,kTRUE) );
02521 if (rname != name) {
02522 return TClass::GetClass( rname, load );
02523 }
02524 }
02525
02526 if (!strcmp(name, "long long")||!strcmp(name,"unsigned long long"))
02527 return 0;
02528
02529
02530
02531
02532
02533
02534 Int_t nch = strlen(name)*2;
02535 char *modifiable_name = new char[nch];
02536 strlcpy(modifiable_name,name,nch);
02537 if (gInterpreter->CheckClassInfo(modifiable_name)) {
02538 const char *altname = gInterpreter->GetInterpreterTypeName(modifiable_name,kTRUE);
02539 if (strcmp(altname,name)!=0) {
02540
02541
02542 delete [] modifiable_name;
02543 return GetClass(altname,load);
02544 }
02545 TClass *ncl = new TClass(name, 1, 0, 0, -1, -1, silent);
02546 if (!ncl->IsZombie()) {
02547 delete [] modifiable_name;
02548 return ncl;
02549 }
02550 delete ncl;
02551 }
02552 delete [] modifiable_name;
02553 return 0;
02554 }
02555
02556
02557 THashTable *TClass::GetClassShortTypedefHash() {
02558
02559 return fgClassShortTypedefHash;
02560 }
02561
02562
02563 TClass *TClass::GetClass(const type_info& typeinfo, Bool_t load, Bool_t )
02564 {
02565
02566
02567 if (!gROOT->GetListOfClasses()) return 0;
02568
02569
02570 TClass* cl = fgIdMap->Find(typeinfo.name());
02571
02572 if (cl) {
02573 if (cl->IsLoaded()) return cl;
02574
02575 load = kTRUE;
02576 } else {
02577
02578
02579
02580
02581
02582
02583
02584
02585
02586
02587 }
02588
02589 if (!load) return 0;
02590
02591 VoidFuncPtr_t dict = TClassTable::GetDict(typeinfo);
02592 if (dict) {
02593 (dict)();
02594 cl = GetClass(typeinfo,kFALSE);
02595 if (cl) cl->PostLoadCheck();
02596 return cl;
02597 }
02598 if (cl) return cl;
02599
02600 TIter next(gROOT->GetListOfClassGenerators());
02601 TClassGenerator *gen;
02602 while( (gen = (TClassGenerator*) next()) ) {
02603 cl = gen->GetClass(typeinfo,load);
02604 if (cl) {
02605 cl->PostLoadCheck();
02606 return cl;
02607 }
02608 }
02609
02610
02611
02612
02613
02614
02615
02616 return 0;
02617 }
02618
02619
02620 VoidFuncPtr_t TClass::GetDict (const char *cname)
02621 {
02622
02623
02624
02625 return TClassTable::GetDict(cname);
02626 }
02627
02628
02629 VoidFuncPtr_t TClass::GetDict (const type_info& info)
02630 {
02631
02632
02633
02634 return TClassTable::GetDict(info);
02635 }
02636
02637
02638 TDataMember *TClass::GetDataMember(const char *datamember) const
02639 {
02640
02641
02642 if (!fClassInfo) return 0;
02643
02644
02645 const Int_t size_buffer = 256;
02646 char memb[size_buffer];
02647 char *s = (char*)datamember;
02648 while (*s == '*') s++;
02649
02650 size_t len = strlen(s);
02651 if (len > size_buffer - 2)
02652 len = size_buffer - 2;
02653 strncpy(memb, s, len);
02654 memb[len] = 0;
02655
02656 if ((s = strchr(memb, '['))) {
02657 *s = 0;
02658 len = strlen(memb);
02659 }
02660
02661 TDataMember *dm;
02662 TIter next(((TClass*)this)->GetListOfDataMembers());
02663
02664 while ((dm = (TDataMember *) next()))
02665 if (len >= size_buffer - 2) {
02666 if (strncmp(memb, dm->GetName(), len) == 0)
02667 return dm;
02668 } else
02669 if (strcmp(memb, dm->GetName()) == 0)
02670 return dm;
02671 return 0;
02672 }
02673
02674
02675 Long_t TClass::GetDataMemberOffset(const char *name) const
02676 {
02677
02678
02679
02680
02681
02682
02683 TRealData *rd = GetRealData(name);
02684 if (rd) return rd->GetThisOffset();
02685 if (strchr(name,'[')==0) {
02686
02687
02688
02689
02690 TVirtualStreamerInfo *info = const_cast<TClass*>(this)->GetCurrentStreamerInfo();
02691 if (info) {
02692 return info->GetOffset(name);
02693 }
02694 }
02695 return 0;
02696 }
02697
02698
02699 TRealData* TClass::GetRealData(const char* name) const
02700 {
02701
02702
02703
02704
02705
02706
02707
02708
02709
02710 if (!fRealData) {
02711 const_cast<TClass*>(this)->BuildRealData();
02712 }
02713
02714 if (!fRealData) {
02715 return 0;
02716 }
02717
02718 if (!name) {
02719 return 0;
02720 }
02721
02722
02723 TRealData* rd = (TRealData*) fRealData->FindObject(name);
02724 if (rd) {
02725 return rd;
02726 }
02727
02728 std::string givenName(name);
02729
02730
02731 std::string::size_type firstBracket = givenName.find_first_of("[");
02732 if (firstBracket != std::string::npos) {
02733
02734 std::string nameNoDim(givenName.substr(0, firstBracket));
02735 TObjLink* lnk = fRealData->FirstLink();
02736 while (lnk) {
02737 TObject* obj = lnk->GetObject();
02738 std::string objName(obj->GetName());
02739 std::string::size_type pos = objName.find_first_of("[");
02740
02741 if (pos != std::string::npos) {
02742 objName.erase(pos);
02743 if (objName == nameNoDim) {
02744 return static_cast<TRealData*>(obj);
02745 }
02746 }
02747 lnk = lnk->Next();
02748 }
02749 }
02750
02751
02752 std::ostringstream ptrname;
02753 ptrname << "*" << givenName;
02754 rd = (TRealData*) fRealData->FindObject(ptrname.str().c_str());
02755 if (rd) {
02756 return rd;
02757 }
02758
02759
02760 std::string::size_type firstDot = givenName.find_first_of(".");
02761 if (firstDot == std::string::npos) {
02762
02763 return 0;
02764 }
02765
02766
02767
02768
02769
02770
02771
02772 std::string::size_type lastDot = givenName.find_last_of(".");
02773 std::ostringstream starname;
02774 starname << givenName.substr(0, lastDot) << ".*" << givenName.substr(lastDot + 1);
02775 rd = (TRealData*) fRealData->FindObject(starname.str().c_str());
02776 if (rd) {
02777 return rd;
02778 }
02779
02780
02781
02782 std::string firstDotName(givenName.substr(firstDot + 1));
02783
02784
02785
02786
02787 rd = (TRealData*) fRealData->FindObject(firstDotName.c_str());
02788 if (rd) {
02789 return rd;
02790 }
02791
02792
02793
02794
02795
02796 std::string::size_type firstDotBracket = firstDotName.find_first_of("[");
02797 if (firstDotBracket != std::string::npos) {
02798
02799 std::string nameNoDim(firstDotName.substr(0, firstDotBracket));
02800 TObjLink* lnk = fRealData->FirstLink();
02801 while (lnk) {
02802 TObject* obj = lnk->GetObject();
02803 std::string objName(obj->GetName());
02804 std::string::size_type pos = objName.find_first_of("[");
02805
02806 if (pos != std::string::npos) {
02807 objName.erase(pos);
02808 if (objName == nameNoDim) {
02809 return static_cast<TRealData*>(obj);
02810 }
02811 }
02812 lnk = lnk->Next();
02813 }
02814 }
02815
02816
02817
02818
02819
02820 ptrname.str("");
02821 ptrname << "*" << firstDotName;
02822 rd = (TRealData*) fRealData->FindObject(ptrname.str().c_str());
02823 if (rd) {
02824 return rd;
02825 }
02826
02827
02828
02829
02830
02831
02832
02833
02834
02835
02836
02837 std::string::size_type bracket = starname.str().find_first_of("[");
02838 if (bracket == std::string::npos) {
02839 return 0;
02840 }
02841 rd = (TRealData*) fRealData->FindObject(starname.str().substr(0, bracket).c_str());
02842 if (rd) {
02843 return rd;
02844 }
02845
02846
02847 return 0;
02848 }
02849
02850
02851 const char *TClass::GetSharedLibs()
02852 {
02853
02854
02855
02856
02857
02858 if (!gInterpreter) return 0;
02859
02860 if (fSharedLibs.IsNull())
02861 fSharedLibs = gInterpreter->GetClassSharedLibs(fName);
02862
02863 return !fSharedLibs.IsNull() ? fSharedLibs.Data() : 0;
02864 }
02865
02866
02867 TList *TClass::GetListOfBases()
02868 {
02869
02870
02871 if (!fBase) {
02872 if (!fClassInfo) return 0;
02873
02874 if (!gInterpreter)
02875 Fatal("GetListOfBases", "gInterpreter not initialized");
02876
02877 gInterpreter->CreateListOfBaseClasses(this);
02878 }
02879 return fBase;
02880 }
02881
02882
02883 TList *TClass::GetListOfDataMembers()
02884 {
02885
02886
02887 R__LOCKGUARD(gCINTMutex);
02888 if (!fClassInfo) {
02889 if (!fData) fData = new TList;
02890 return fData;
02891 }
02892
02893 if (!fData) {
02894 if (!gInterpreter)
02895 Fatal("GetListOfDataMembers", "gInterpreter not initialized");
02896
02897 gInterpreter->CreateListOfDataMembers(this);
02898 }
02899 return fData;
02900 }
02901
02902
02903 TList *TClass::GetListOfMethods()
02904 {
02905
02906
02907 R__LOCKGUARD(gCINTMutex);
02908 if (!fClassInfo) {
02909 if (!fMethod) fMethod = new THashList;
02910 return fMethod;
02911 }
02912
02913 if (!fMethod) {
02914 if (!gInterpreter)
02915 Fatal("GetListOfMethods", "gInterpreter not initialized");
02916
02917 TMmallocDescTemp setreset;
02918 gInterpreter->CreateListOfMethods(this);
02919 } else {
02920 gInterpreter->UpdateListOfMethods(this);
02921 }
02922 return fMethod;
02923 }
02924
02925
02926 TList *TClass::GetListOfAllPublicMethods()
02927 {
02928
02929
02930
02931
02932
02933
02934
02935
02936
02937
02938
02939 R__LOCKGUARD(gCINTMutex);
02940 if (!fAllPubMethod) {
02941 fAllPubMethod = new TList;
02942
02943
02944 fAllPubMethod->AddAll(GetListOfMethods());
02945
02946
02947 TIter nextBaseClass(GetListOfBases());
02948 TBaseClass *pB;
02949 TMethod *p;
02950 while ((pB = (TBaseClass*) nextBaseClass())) {
02951 if (!pB->GetClassPointer()) continue;
02952 TIter next(pB->GetClassPointer()->GetListOfAllPublicMethods());
02953 TList temp;
02954 while ((p = (TMethod*) next()))
02955 if (!fAllPubMethod->Contains(p->GetName()))
02956 temp.Add(p);
02957 fAllPubMethod->AddAll(&temp);
02958 temp.Clear();
02959 }
02960
02961
02962 TIter next(fAllPubMethod);
02963 while ((p = (TMethod*) next()))
02964 if (!(p->Property() & kIsPublic)) fAllPubMethod->Remove(p);
02965 }
02966 return fAllPubMethod;
02967 }
02968
02969
02970 TList *TClass::GetListOfAllPublicDataMembers()
02971 {
02972
02973
02974
02975
02976 R__LOCKGUARD(gCINTMutex);
02977 if (!fAllPubData) {
02978 fAllPubData = new TList;
02979 TIter next(GetListOfDataMembers());
02980 TDataMember *p;
02981
02982 while ((p = (TDataMember*) next()))
02983 if (p->Property() & kIsPublic) fAllPubData->Add(p);
02984
02985 TIter next_BaseClass(GetListOfBases());
02986 TBaseClass *pB;
02987 while ((pB = (TBaseClass*) next_BaseClass())) {
02988 if (!pB->GetClassPointer()) continue;
02989 fAllPubData->AddAll(pB->GetClassPointer()->GetListOfAllPublicDataMembers() );
02990 }
02991 }
02992 return fAllPubData;
02993 }
02994
02995
02996 void TClass::GetMenuItems(TList *list)
02997 {
02998
02999
03000 if (!fClassInfo) return;
03001
03002
03003 TIter nextBase(GetListOfBases(), kIterBackward);
03004 TBaseClass *baseClass;
03005 while ((baseClass = (TBaseClass *) nextBase())) {
03006 TClass *base = baseClass->GetClassPointer();
03007 if (base) base->GetMenuItems(list);
03008 }
03009
03010
03011 TMethod *method, *m;
03012 TIter next(GetListOfMethods(), kIterBackward);
03013 while ((method = (TMethod*)next())) {
03014 m = (TMethod*)list->FindObject(method->GetName());
03015 if (method->IsMenuItem() != kMenuNoMenu) {
03016 if (!m)
03017 list->AddFirst(method);
03018 } else {
03019 if (m && m->GetNargs() == method->GetNargs())
03020 list->Remove(m);
03021 }
03022 }
03023 }
03024
03025
03026 Bool_t TClass::IsFolder(void *obj) const
03027 {
03028
03029
03030 return Browse(obj,(TBrowser*)0);
03031 }
03032
03033
03034 void TClass::RemoveRef(TClassRef *ref)
03035 {
03036
03037
03038 R__LOCKGUARD(gCINTMutex);
03039 if (ref==fRefStart) {
03040 fRefStart = ref->fNext;
03041 if (fRefStart) fRefStart->fPrevious = 0;
03042 ref->fPrevious = ref->fNext = 0;
03043 } else {
03044 TClassRef *next = ref->fNext;
03045 ref->fPrevious->fNext = next;
03046 if (next) next->fPrevious = ref->fPrevious;
03047 ref->fPrevious = ref->fNext = 0;
03048 }
03049 }
03050
03051
03052 void TClass::ReplaceWith(TClass *newcl, Bool_t recurse) const
03053 {
03054
03055
03056 R__LOCKGUARD(gCINTMutex);
03057
03058 TIter nextClass(gROOT->GetListOfClasses());
03059 TClass *acl;
03060 TVirtualStreamerInfo *info;
03061 TList tobedeleted;
03062
03063 TString corename( TClassEdit::ResolveTypedef(newcl->GetName()) );
03064
03065 if ( strchr( corename.Data(), '<' ) == 0 ) {
03066
03067 recurse = kFALSE;
03068 }
03069
03070 while ((acl = (TClass*)nextClass())) {
03071 if (recurse && acl!=newcl && acl!=this) {
03072
03073 TString aclCorename( TClassEdit::ResolveTypedef(acl->GetName()) );
03074
03075 if (aclCorename == corename) {
03076
03077
03078
03079 acl->ReplaceWith(newcl, kFALSE);
03080 tobedeleted.Add(acl);
03081 }
03082 }
03083
03084 TIter nextInfo(acl->GetStreamerInfos());
03085 while ((info = (TVirtualStreamerInfo*)nextInfo())) {
03086
03087 info->Update(this, newcl);
03088 }
03089
03090 if (acl->GetCollectionProxy() && acl->GetCollectionProxy()->GetValueClass()==this) {
03091 acl->GetCollectionProxy()->SetValueClass(newcl);
03092
03093 }
03094 }
03095
03096 TIter delIter( &tobedeleted );
03097 while ((acl = (TClass*)delIter())) {
03098 delete acl;
03099 }
03100
03101 }
03102
03103
03104 void TClass::ResetClassInfo(Long_t tagnum)
03105 {
03106
03107
03108 if (fClassInfo && gCint->ClassInfo_Tagnum(fClassInfo) != tagnum) {
03109 gCint->ClassInfo_Init(fClassInfo,(Int_t)tagnum);
03110 if (fBase) {
03111 fBase->Delete();
03112 delete fBase; fBase = 0;
03113 }
03114 }
03115 }
03116
03117
03118 void TClass::ResetMenuList()
03119 {
03120
03121
03122 if (fClassMenuList)
03123 fClassMenuList->Delete();
03124 else
03125 fClassMenuList = new TList();
03126 fClassMenuList->Add(new TClassMenuItem(TClassMenuItem::kPopupStandardList, this));
03127 }
03128
03129
03130 void TClass::ls(Option_t *options) const
03131 {
03132
03133
03134
03135
03136
03137 TNamed::ls(options);
03138 if (options==0 || options[0]==0) return;
03139
03140 if (strstr(options,"streamerinfo")!=0) {
03141 GetStreamerInfos()->ls(options);
03142
03143 if (fConversionStreamerInfo) {
03144 std::map<std::string, TObjArray*>::iterator it;
03145 std::map<std::string, TObjArray*>::iterator end = fConversionStreamerInfo->end();
03146 for( it = fConversionStreamerInfo->begin(); it != end; ++it ) {
03147 it->second->ls(options);
03148 }
03149 }
03150 }
03151 }
03152
03153
03154 void TClass::MakeCustomMenuList()
03155 {
03156
03157
03158
03159
03160
03161
03162 R__LOCKGUARD(gCINTMutex);
03163 TClassMenuItem *menuItem;
03164
03165
03166 GetMenuList()->Delete();
03167
03168 TList* methodList = new TList;
03169 GetMenuItems(methodList);
03170
03171 TMethod *method;
03172 TMethodArg *methodArg;
03173 TClass *classPtr = 0;
03174 TIter next(methodList);
03175
03176 while ((method = (TMethod*) next())) {
03177
03178 if (classPtr != method->GetClass()) {
03179 menuItem = new TClassMenuItem(TClassMenuItem::kPopupSeparator, this);
03180 fClassMenuList->AddLast(menuItem);
03181 classPtr = method->GetClass();
03182 }
03183
03184 TString sig;
03185 TList* margsList = method->GetListOfMethodArgs();
03186 TIter nextarg(margsList);
03187 while ((methodArg = (TMethodArg*)nextarg())) {
03188 sig = sig+","+methodArg->GetFullTypeName();
03189 }
03190 if (sig.Length()!=0) sig.Remove(0,1);
03191 menuItem = new TClassMenuItem(TClassMenuItem::kPopupUserFunction, this,
03192 method->GetName(), method->GetName(),0,
03193 sig.Data(),-1,TClassMenuItem::kIsSelf);
03194 if (method->IsMenuItem() == kMenuToggle) menuItem->SetToggle();
03195 fClassMenuList->Add(menuItem);
03196 }
03197 delete methodList;
03198 }
03199
03200
03201 void TClass::Move(void *arenaFrom, void *arenaTo) const
03202 {
03203
03204
03205
03206
03207
03208
03209
03210 if (!fClassInfo && !fCollectionProxy) {
03211 MoveAddressInRepository("TClass::Move",arenaFrom,arenaTo,this);
03212 }
03213 }
03214
03215
03216 TList *TClass::GetMenuList() const {
03217
03218 if (!fClassMenuList) {
03219 fClassMenuList = new TList();
03220 fClassMenuList->Add(new TClassMenuItem(TClassMenuItem::kPopupStandardList, const_cast<TClass*>(this)));
03221 }
03222 return fClassMenuList;
03223 }
03224
03225
03226
03227 TMethod *TClass::GetMethodAny(const char *method)
03228 {
03229
03230
03231
03232 if (!fClassInfo) return 0;
03233 return (TMethod*) GetListOfMethods()->FindObject(method);
03234 }
03235
03236
03237 TMethod *TClass::GetMethodAllAny(const char *method)
03238 {
03239
03240
03241
03242 if (!fClassInfo) return 0;
03243
03244 TMethod* m = GetMethodAny(method);
03245 if (m) return m;
03246
03247 TBaseClass *base;
03248 TIter nextb(GetListOfBases());
03249 while ((base = (TBaseClass *) nextb())) {
03250 TClass *c = base->GetClassPointer();
03251 if (c) {
03252 m = c->GetMethodAllAny(method);
03253 if (m) return m;
03254 }
03255 }
03256
03257 return 0;
03258 }
03259
03260
03261 TMethod *TClass::GetMethod(const char *method, const char *params)
03262 {
03263
03264
03265
03266
03267
03268
03269 if (!fClassInfo) return 0;
03270
03271 if (!gInterpreter)
03272 Fatal("GetMethod", "gInterpreter not initialized");
03273
03274 Long_t faddr = (Long_t)gInterpreter->GetInterfaceMethod(this, method,
03275 params);
03276 if (!faddr) return 0;
03277
03278
03279
03280
03281
03282 TMethod *m;
03283
03284 #if defined(R__WIN32)
03285
03286
03287
03288
03289 m = GetClassMethod(method,params);
03290
03291 #else
03292 if (faddr == (Long_t)gCint->GetExecByteCode()) {
03293
03294
03295
03296 m = GetClassMethod(method,params);
03297 } else {
03298 m = GetClassMethod(faddr);
03299 }
03300 #endif
03301
03302 if (m) return m;
03303
03304 TBaseClass *base;
03305 TIter next(GetListOfBases());
03306 while ((base = (TBaseClass *) next())) {
03307 TClass *c = base->GetClassPointer();
03308 if (c) {
03309 m = c->GetMethod(method,params);
03310 if (m) return m;
03311 }
03312 }
03313 Error("GetMethod",
03314 "\nDid not find matching TMethod <%s> with \"%s\" for %s",
03315 method,params,GetName());
03316 return 0;
03317 }
03318
03319
03320 TMethod *TClass::GetMethodWithPrototype(const char *method, const char *proto)
03321 {
03322
03323
03324
03325 if (!fClassInfo) return 0;
03326
03327 if (!gInterpreter)
03328 Fatal("GetMethod", "gInterpreter not initialized");
03329
03330 Long_t faddr = (Long_t)gInterpreter->GetInterfaceMethodWithPrototype(this,
03331 method, proto);
03332 if (!faddr) return 0;
03333
03334
03335
03336
03337 TMethod *m = GetClassMethod(faddr);
03338 if (m) return m;
03339
03340 TBaseClass *base;
03341 TIter next(GetListOfBases());
03342 while ((base = (TBaseClass *) next())) {
03343 TClass *c = base->GetClassPointer();
03344 if (c) {
03345 m = c->GetMethodWithPrototype(method,proto);
03346 if (m) return m;
03347 }
03348 }
03349 Error("GetMethod", "Did not find matching TMethod (should never happen)");
03350 return 0;
03351 }
03352
03353
03354 TMethod *TClass::GetClassMethod(Long_t faddr)
03355 {
03356
03357
03358
03359 if (!fClassInfo) return 0;
03360
03361 TMethod *m;
03362 TIter next(GetListOfMethods());
03363 while ((m = (TMethod *) next())) {
03364 if (faddr == (Long_t)m->InterfaceMethod())
03365 return m;
03366 }
03367 return 0;
03368 }
03369
03370
03371 TMethod *TClass::GetClassMethod(const char *name, const char* params)
03372 {
03373
03374
03375
03376 if (!fClassInfo) return 0;
03377
03378
03379
03380
03381 TList* bucketForMethod = ((THashList*)GetListOfMethods())->GetListForObject(name);
03382 if (bucketForMethod) {
03383 R__LOCKGUARD2(gCINTMutex);
03384 CallFunc_t *func = gCint->CallFunc_Factory();
03385 Long_t offset;
03386 gCint->CallFunc_SetFunc(func,GetClassInfo(), name, params, &offset);
03387 MethodInfo_t *info = gCint->CallFunc_FactoryMethod(func);
03388 TMethod request(info,this);
03389 TMethod *m;
03390 TIter next(bucketForMethod);
03391 while ((m = (TMethod *) next())) {
03392 if (!strcmp(name,m->GetName())
03393 &&!strcmp(request.GetSignature(),m->GetSignature())) {
03394 gCint->CallFunc_Delete(func);
03395 return m;
03396 }
03397 }
03398 gCint->CallFunc_Delete(func);
03399 }
03400 return 0;
03401 }
03402
03403
03404 Int_t TClass::GetNdata()
03405 {
03406
03407
03408
03409
03410 if (!fClassInfo) return 0;
03411
03412 TList *lm = GetListOfDataMembers();
03413 if (lm)
03414 return lm->GetSize();
03415 else
03416 return 0;
03417 }
03418
03419
03420 Int_t TClass::GetNmethods()
03421 {
03422
03423
03424
03425
03426 if (!fClassInfo) return 0;
03427
03428 TList *lm = GetListOfMethods();
03429 if (lm)
03430 return lm->GetSize();
03431 else
03432 return 0;
03433 }
03434
03435
03436 TVirtualStreamerInfo* TClass::GetStreamerInfo(Int_t version) const
03437 {
03438
03439
03440
03441
03442
03443
03444
03445
03446
03447
03448
03449
03450
03451
03452 R__LOCKGUARD(gCINTMutex);
03453
03454
03455
03456 if (version == 0) {
03457 version = fClassVersion;
03458 }
03459 if (!fStreamerInfo) {
03460 TMmallocDescTemp setreset;
03461 fStreamerInfo = new TObjArray(version + 10, -1);
03462 } else {
03463 Int_t ninfos = fStreamerInfo->GetSize();
03464 if ((version < -1) || (version >= ninfos)) {
03465 Error("GetStreamerInfo", "class: %s, attempting to access a wrong version: %d", GetName(), version);
03466
03467 version = 0;
03468 }
03469 }
03470 TVirtualStreamerInfo* sinfo = (TVirtualStreamerInfo*) fStreamerInfo->At(version);
03471 if (!sinfo && (version != fClassVersion)) {
03472
03473
03474
03475
03476
03477 sinfo = (TVirtualStreamerInfo*) fStreamerInfo->At(fClassVersion);
03478 }
03479 if (!sinfo) {
03480
03481 TMmallocDescTemp setreset;
03482 sinfo = TVirtualStreamerInfo::Factory()->NewInfo(const_cast<TClass*>(this));
03483 fStreamerInfo->AddAtAndExpand(sinfo, fClassVersion);
03484 if (gDebug > 0) {
03485 printf("Creating StreamerInfo for class: %s, version: %d\n", GetName(), fClassVersion);
03486 }
03487 if (fClassInfo || fCollectionProxy) {
03488
03489
03490
03491
03492
03493
03494
03495
03496 sinfo->Build();
03497 }
03498 } else {
03499 if (!sinfo->IsCompiled()) {
03500
03501
03502
03503 sinfo->BuildOld();
03504 } else if (sinfo->IsOptimized() && !TVirtualStreamerInfo::CanOptimize()) {
03505
03506 sinfo->Compile();
03507 }
03508 }
03509
03510 if (version == fClassVersion) {
03511 fCurrentInfo = sinfo;
03512 }
03513 return sinfo;
03514 }
03515
03516
03517 void TClass::IgnoreTObjectStreamer(Bool_t ignore)
03518 {
03519
03520
03521
03522
03523
03524
03525
03526
03527
03528
03529
03530
03531 if ( ignore && TestBit(kIgnoreTObjectStreamer)) return;
03532 if (!ignore && !TestBit(kIgnoreTObjectStreamer)) return;
03533 TVirtualStreamerInfo *sinfo = GetCurrentStreamerInfo();
03534 if (sinfo) {
03535 if (sinfo->IsCompiled()) {
03536
03537
03538
03539
03540
03541
03542
03543
03544
03545 Error("IgnoreTObjectStreamer","Must be called before the creation of StreamerInfo");
03546 return;
03547 }
03548 }
03549 if (ignore) SetBit (kIgnoreTObjectStreamer);
03550 else ResetBit(kIgnoreTObjectStreamer);
03551 }
03552
03553
03554 Bool_t TClass::InheritsFrom(const char *classname) const
03555 {
03556
03557
03558
03559 if (strcmp(GetName(), classname) == 0) return kTRUE;
03560
03561 if (!fClassInfo) return InheritsFrom(TClass::GetClass("classname"));
03562
03563
03564 if (((TClass *)this)->GetBaseClass(classname)) return kTRUE;
03565 return kFALSE;
03566 }
03567
03568
03569 Bool_t TClass::InheritsFrom(const TClass *cl) const
03570 {
03571
03572
03573
03574 if (cl == this) return kTRUE;
03575
03576 if (!fClassInfo) {
03577 TVirtualStreamerInfo *sinfo = ((TClass *)this)->GetCurrentStreamerInfo();
03578 if (sinfo==0) sinfo = GetStreamerInfo();
03579 TIter next(sinfo->GetElements());
03580 TStreamerElement *element;
03581 while ((element = (TStreamerElement*)next())) {
03582 if (element->IsA() == TStreamerBase::Class()) {
03583 TClass *clbase = element->GetClassPointer();
03584 if (!clbase) return kFALSE;
03585 if (clbase->InheritsFrom(cl)) return kTRUE;
03586 }
03587 }
03588 return kFALSE;
03589 }
03590
03591 if (((TClass *)this)->GetBaseClass(cl)) return kTRUE;
03592 return kFALSE;
03593 }
03594
03595
03596 void *TClass::DynamicCast(const TClass *cl, void *obj, Bool_t up)
03597 {
03598
03599
03600
03601
03602
03603 if (cl == this) return obj;
03604
03605 if (!fClassInfo) return 0;
03606
03607 Int_t off;
03608 if ((off = GetBaseClassOffset(cl)) != -1) {
03609 if (up)
03610 return (void*)((Long_t)obj+off);
03611 else
03612 return (void*)((Long_t)obj-off);
03613 }
03614 return 0;
03615 }
03616
03617
03618 void *TClass::New(ENewType defConstructor) const
03619 {
03620
03621
03622
03623
03624
03625
03626
03627
03628
03629
03630
03631
03632
03633
03634
03635
03636
03637
03638
03639
03640
03641
03642
03643
03644
03645 void* p = 0;
03646
03647 if (fNew) {
03648
03649
03650
03651
03652 fgCallingNew = defConstructor;
03653 p = fNew(0);
03654 fgCallingNew = kRealNew;
03655 if (!p) {
03656
03657 Error("New", "cannot create object of class %s", GetName());
03658 }
03659 } else if (fClassInfo) {
03660
03661
03662
03663
03664
03665
03666
03667
03668 fgCallingNew = defConstructor;
03669 R__LOCKGUARD2(gCINTMutex);
03670 p = gCint->ClassInfo_New(GetClassInfo());
03671 fgCallingNew = kRealNew;
03672 if (!p) {
03673
03674 Error("New", "cannot create object of class %s", GetName());
03675 }
03676 } else if (!fClassInfo && fCollectionProxy) {
03677
03678
03679
03680 fgCallingNew = defConstructor;
03681 p = fCollectionProxy->New();
03682 fgCallingNew = kRealNew;
03683 if (!p) {
03684
03685 Error("New", "cannot create object of class %s", GetName());
03686 }
03687 } else if (!fClassInfo && !fCollectionProxy) {
03688
03689
03690
03691
03692
03693
03694
03695
03696
03697
03698
03699
03700
03701 Bool_t statsave = GetObjectStat();
03702 SetObjectStat(kFALSE);
03703
03704 TVirtualStreamerInfo* sinfo = GetStreamerInfo();
03705 if (!sinfo) {
03706 Error("New", "Cannot construct class '%s' version %d, no streamer info available!", GetName(), fClassVersion);
03707 return 0;
03708 }
03709
03710 fgCallingNew = defConstructor;
03711 p = sinfo->New();
03712 fgCallingNew = kRealNew;
03713
03714
03715
03716 SetObjectStat(statsave);
03717
03718
03719 if (p) {
03720 RegisterAddressInRepository("New",p,this);
03721 }
03722 } else {
03723 Error("New", "This cannot happen!");
03724 }
03725
03726 return p;
03727 }
03728
03729
03730 void *TClass::New(void *arena, ENewType defConstructor) const
03731 {
03732
03733
03734
03735
03736 void* p = 0;
03737
03738 if (fNew) {
03739
03740
03741
03742
03743 fgCallingNew = defConstructor;
03744 p = fNew(arena);
03745 fgCallingNew = kRealNew;
03746 if (!p) {
03747 Error("New with placement", "cannot create object of class %s version %d at address %p", GetName(), fClassVersion, arena);
03748 }
03749 } else if (fClassInfo) {
03750
03751
03752
03753
03754
03755
03756
03757
03758 fgCallingNew = defConstructor;
03759 R__LOCKGUARD2(gCINTMutex);
03760 p = gCint->ClassInfo_New(GetClassInfo(),arena);
03761 fgCallingNew = kRealNew;
03762 if (!p) {
03763 Error("New with placement", "cannot create object of class %s version %d at address %p", GetName(), fClassVersion, arena);
03764 }
03765 } else if (!fClassInfo && fCollectionProxy) {
03766
03767
03768
03769 fgCallingNew = defConstructor;
03770 p = fCollectionProxy->New(arena);
03771 fgCallingNew = kRealNew;
03772 } else if (!fClassInfo && !fCollectionProxy) {
03773
03774
03775
03776
03777
03778
03779
03780
03781
03782
03783
03784 Bool_t statsave = GetObjectStat();
03785 SetObjectStat(kFALSE);
03786
03787 TVirtualStreamerInfo* sinfo = GetStreamerInfo();
03788 if (!sinfo) {
03789 Error("New with placement", "Cannot construct class '%s' version %d at address %p, no streamer info available!", GetName(), fClassVersion, arena);
03790 return 0;
03791 }
03792
03793 fgCallingNew = defConstructor;
03794 p = sinfo->New(arena);
03795 fgCallingNew = kRealNew;
03796
03797
03798
03799 SetObjectStat(statsave);
03800
03801
03802 if (p) {
03803 RegisterAddressInRepository("TClass::New with placement",p,this);
03804 }
03805 } else {
03806 Error("New with placement", "This cannot happen!");
03807 }
03808
03809 return p;
03810 }
03811
03812
03813 void *TClass::NewArray(Long_t nElements, ENewType defConstructor) const
03814 {
03815
03816
03817
03818
03819
03820 void* p = 0;
03821
03822 if (fNewArray) {
03823
03824
03825
03826
03827 fgCallingNew = defConstructor;
03828 p = fNewArray(nElements, 0);
03829 fgCallingNew = kRealNew;
03830 if (!p) {
03831 Error("NewArray", "cannot create object of class %s version %d", GetName(), fClassVersion);
03832 }
03833 } else if (fClassInfo) {
03834
03835
03836
03837
03838
03839
03840
03841
03842 fgCallingNew = defConstructor;
03843 R__LOCKGUARD2(gCINTMutex);
03844 p = gCint->ClassInfo_New(GetClassInfo(),nElements);
03845 fgCallingNew = kRealNew;
03846 if (!p) {
03847 Error("NewArray", "cannot create object of class %s version %d", GetName(), fClassVersion);
03848 }
03849 } else if (!fClassInfo && fCollectionProxy) {
03850
03851
03852
03853 fgCallingNew = defConstructor;
03854 p = fCollectionProxy->NewArray(nElements);
03855 fgCallingNew = kRealNew;
03856 } else if (!fClassInfo && !fCollectionProxy) {
03857
03858
03859
03860
03861
03862
03863
03864
03865
03866
03867
03868 Bool_t statsave = GetObjectStat();
03869 SetObjectStat(kFALSE);
03870
03871 TVirtualStreamerInfo* sinfo = GetStreamerInfo();
03872 if (!sinfo) {
03873 Error("NewArray", "Cannot construct class '%s' version %d, no streamer info available!", GetName(), fClassVersion);
03874 return 0;
03875 }
03876
03877 fgCallingNew = defConstructor;
03878 p = sinfo->NewArray(nElements);
03879 fgCallingNew = kRealNew;
03880
03881
03882
03883 SetObjectStat(statsave);
03884
03885
03886 if (p) {
03887 RegisterAddressInRepository("TClass::NewArray",p,this);
03888 }
03889 } else {
03890 Error("NewArray", "This cannot happen!");
03891 }
03892
03893 return p;
03894 }
03895
03896
03897 void *TClass::NewArray(Long_t nElements, void *arena, ENewType defConstructor) const
03898 {
03899
03900
03901
03902
03903 void* p = 0;
03904
03905 if (fNewArray) {
03906
03907
03908
03909
03910 fgCallingNew = defConstructor;
03911 p = fNewArray(nElements, arena);
03912 fgCallingNew = kRealNew;
03913 if (!p) {
03914 Error("NewArray with placement", "cannot create object of class %s version %d at address %p", GetName(), fClassVersion, arena);
03915 }
03916 } else if (fClassInfo) {
03917
03918
03919
03920
03921
03922
03923
03924
03925 fgCallingNew = defConstructor;
03926 R__LOCKGUARD2(gCINTMutex);
03927 p = gCint->ClassInfo_New(GetClassInfo(),nElements, arena);
03928 fgCallingNew = kRealNew;
03929 if (!p) {
03930 Error("NewArray with placement", "cannot create object of class %s version %d at address %p", GetName(), fClassVersion, arena);
03931 }
03932 } else if (!fClassInfo && fCollectionProxy) {
03933
03934
03935
03936 fgCallingNew = defConstructor;
03937 p = fCollectionProxy->NewArray(nElements, arena);
03938 fgCallingNew = kRealNew;
03939 } else if (!fClassInfo && !fCollectionProxy) {
03940
03941
03942
03943
03944
03945
03946
03947
03948
03949
03950
03951 Bool_t statsave = GetObjectStat();
03952 SetObjectStat(kFALSE);
03953
03954 TVirtualStreamerInfo* sinfo = GetStreamerInfo();
03955 if (!sinfo) {
03956 Error("NewArray with placement", "Cannot construct class '%s' version %d at address %p, no streamer info available!", GetName(), fClassVersion, arena);
03957 return 0;
03958 }
03959
03960 fgCallingNew = defConstructor;
03961 p = sinfo->NewArray(nElements, arena);
03962 fgCallingNew = kRealNew;
03963
03964
03965
03966 SetObjectStat(statsave);
03967
03968 if (fStreamerType & kEmulated) {
03969
03970
03971 }
03972
03973
03974 if (p) {
03975 RegisterAddressInRepository("TClass::NewArray with placement",p,this);
03976 }
03977 } else {
03978 Error("NewArray with placement", "This cannot happen!");
03979 }
03980
03981 return p;
03982 }
03983
03984
03985 void TClass::Destructor(void *obj, Bool_t dtorOnly)
03986 {
03987
03988
03989
03990 if (obj == 0) return;
03991
03992 void* p = obj;
03993
03994 if (dtorOnly && fDestructor) {
03995
03996 fDestructor(p);
03997 } else if ((!dtorOnly) && fDelete) {
03998
03999 fDelete(p);
04000 } else if (fClassInfo) {
04001
04002
04003
04004
04005
04006
04007
04008
04009 if (dtorOnly) {
04010 gCint->ClassInfo_Destruct(fClassInfo,p);
04011 } else {
04012 gCint->ClassInfo_Delete(fClassInfo,p);
04013 }
04014 } else if (!fClassInfo && fCollectionProxy) {
04015
04016
04017
04018 fCollectionProxy->Destructor(p, dtorOnly);
04019 } else if (!fClassInfo && !fCollectionProxy) {
04020
04021
04022
04023
04024
04025 Bool_t inRepo = kTRUE;
04026 Bool_t verFound = kFALSE;
04027
04028
04029 std::multiset<Version_t> knownVersions;
04030 std::multimap<void*, Version_t>::iterator iter = gObjectVersionRepository.find(p);
04031 if (iter == gObjectVersionRepository.end()) {
04032
04033
04034 inRepo = kFALSE;
04035 } else {
04036
04037 for (; (iter != gObjectVersionRepository.end()) && (iter->first == p); ++iter) {
04038 Version_t ver = iter->second;
04039 knownVersions.insert(ver);
04040 if (ver == fClassVersion) {
04041 verFound = kTRUE;
04042 }
04043 }
04044 }
04045
04046 if (!inRepo || verFound) {
04047
04048
04049 TVirtualStreamerInfo* si = GetStreamerInfo();
04050 if (si) {
04051 si->Destructor(p, dtorOnly);
04052 } else {
04053 Error("Destructor", "No streamer info available for class '%s' version %d at address %p, cannot destruct emulated object!", GetName(), fClassVersion, p);
04054 Error("Destructor", "length of fStreamerInfo is %d", fStreamerInfo->GetSize());
04055 Int_t i = fStreamerInfo->LowerBound();
04056 for (Int_t v = 0; v < fStreamerInfo->GetSize(); ++v, ++i) {
04057 Error("Destructor", "fStreamerInfo->At(%d): %p", i, fStreamerInfo->At(i));
04058 if (fStreamerInfo->At(i) != 0) {
04059 Error("Destructor", "Doing Dump() ...");
04060 ((TVirtualStreamerInfo*)fStreamerInfo->At(i))->Dump();
04061 }
04062 }
04063 }
04064 } else {
04065
04066
04067
04068 Error("Destructor", "Loaded class %s version %d is not registered for addr %p", GetName(), fClassVersion, p);
04069 #if 0
04070 TVirtualStreamerInfo* si = (TVirtualStreamerInfo*) fStreamerInfo->At(objVer);
04071 if (si) {
04072 si->Destructor(p, dtorOnly);
04073 } else {
04074 Error("Destructor2", "No streamer info available for class '%s' version %d, cannot destruct object at addr: %p", GetName(), objVer, p);
04075 Error("Destructor2", "length of fStreamerInfo is %d", fStreamerInfo->GetSize());
04076 Int_t i = fStreamerInfo->LowerBound();
04077 for (Int_t v = 0; v < fStreamerInfo->GetSize(); ++v, ++i) {
04078 Error("Destructor2", "fStreamerInfo->At(%d): %p", i, fStreamerInfo->At(i));
04079 if (fStreamerInfo->At(i) != 0) {
04080
04081 Error("Destructor2", "Doing Dump() ...");
04082 ((TVirtualStreamerInfo*)fStreamerInfo->At(i))->Dump();
04083 }
04084 }
04085 }
04086 #endif
04087 }
04088
04089 if (inRepo && verFound && p) {
04090 UnregisterAddressInRepository("TClass::Destructor",p,this);
04091 }
04092 } else {
04093 Error("Destructor", "This cannot happen! (class %s)", GetName());
04094 }
04095 }
04096
04097
04098 void TClass::DeleteArray(void *ary, Bool_t dtorOnly)
04099 {
04100
04101
04102
04103 if (ary == 0) return;
04104
04105
04106 void* p = ary;
04107
04108 if (fDeleteArray) {
04109 if (dtorOnly) {
04110 Error("DeleteArray", "Destructor only is not supported!");
04111 } else {
04112
04113 fDeleteArray(ary);
04114 }
04115 } else if (fClassInfo) {
04116
04117
04118
04119
04120
04121
04122
04123 R__LOCKGUARD2(gCINTMutex);
04124 gCint->ClassInfo_DeleteArray(GetClassInfo(),ary, dtorOnly);
04125 } else if (!fClassInfo && fCollectionProxy) {
04126
04127
04128
04129 fCollectionProxy->DeleteArray(ary, dtorOnly);
04130 } else if (!fClassInfo && !fCollectionProxy) {
04131
04132
04133
04134
04135
04136 Bool_t inRepo = kTRUE;
04137 Bool_t verFound = kFALSE;
04138
04139
04140 std::multiset<Version_t> knownVersions;
04141 std::multimap<void*, Version_t>::iterator iter = gObjectVersionRepository.find(p);
04142 if (iter == gObjectVersionRepository.end()) {
04143
04144
04145 inRepo = kFALSE;
04146 } else {
04147 for (; (iter != gObjectVersionRepository.end()) && (iter->first == p); ++iter) {
04148 Version_t ver = iter->second;
04149 knownVersions.insert(ver);
04150 if (ver == fClassVersion) {
04151 verFound = kTRUE;
04152 }
04153 }
04154 }
04155
04156 if (!inRepo || verFound) {
04157
04158
04159 TVirtualStreamerInfo* si = GetStreamerInfo();
04160 if (si) {
04161 si->DeleteArray(ary, dtorOnly);
04162 } else {
04163 Error("DeleteArray", "No streamer info available for class '%s' version %d at address %p, cannot destruct object!", GetName(), fClassVersion, ary);
04164 Error("DeleteArray", "length of fStreamerInfo is %d", fStreamerInfo->GetSize());
04165 Int_t i = fStreamerInfo->LowerBound();
04166 for (Int_t v = 0; v < fStreamerInfo->GetSize(); ++v, ++i) {
04167 Error("DeleteArray", "fStreamerInfo->At(%d): %p", v, fStreamerInfo->At(i));
04168 if (fStreamerInfo->At(i)) {
04169 Error("DeleteArray", "Doing Dump() ...");
04170 ((TVirtualStreamerInfo*)fStreamerInfo->At(i))->Dump();
04171 }
04172 }
04173 }
04174 } else {
04175
04176
04177
04178 Error("DeleteArray", "Loaded class version %d is not registered for addr %p", fClassVersion, p);
04179
04180
04181
04182 #if 0
04183 TVirtualStreamerInfo* si = (TVirtualStreamerInfo*) fStreamerInfo->At(objVer);
04184 if (si) {
04185 si->DeleteArray(ary, dtorOnly);
04186 } else {
04187 Error("DeleteArray", "No streamer info available for class '%s' version %d at address %p, cannot destruct object!", GetName(), objVer, ary);
04188 Error("DeleteArray", "length of fStreamerInfo is %d", fStreamerInfo->GetSize());
04189 Int_t i = fStreamerInfo->LowerBound();
04190 for (Int_t v = 0; v < fStreamerInfo->GetSize(); ++v, ++i) {
04191 Error("DeleteArray", "fStreamerInfo->At(%d): %p", v, fStreamerInfo->At(i));
04192 if (fStreamerInfo->At(i)) {
04193
04194 Error("DeleteArray", "Doing Dump() ...");
04195 ((TVirtualStreamerInfo*)fStreamerInfo->At(i))->Dump();
04196 }
04197 }
04198 }
04199 #endif
04200
04201
04202 }
04203
04204
04205 if (inRepo && verFound && p) {
04206 UnregisterAddressInRepository("TClass::DeleteArray",p,this);
04207 }
04208 } else {
04209 Error("DeleteArray", "This cannot happen! (class '%s')", GetName());
04210 }
04211 }
04212
04213
04214 void TClass::SetClassVersion(Version_t version)
04215 {
04216
04217
04218
04219
04220
04221
04222
04223
04224
04225
04226
04227 fClassVersion = version;
04228 fCurrentInfo = 0;
04229 }
04230
04231
04232 void TClass::SetCurrentStreamerInfo(TVirtualStreamerInfo *info)
04233 {
04234
04235
04236 fCurrentInfo = info;
04237 }
04238
04239
04240 Int_t TClass::Size() const
04241 {
04242
04243
04244 if (fSizeof!=-1) return fSizeof;
04245 if (fCollectionProxy) return fCollectionProxy->Sizeof();
04246 if (fClassInfo) return gCint->ClassInfo_Size(GetClassInfo());
04247 return GetStreamerInfo()->GetSize();
04248 }
04249
04250
04251 TClass *TClass::Load(TBuffer &b)
04252 {
04253
04254
04255 UInt_t maxsize = 256;
04256 char *s = new char[maxsize];
04257
04258 Int_t pos = b.Length();
04259
04260 b.ReadString(s, maxsize);
04261 while (strlen(s) == (maxsize - 1)) {
04262
04263 b.SetBufferOffset(pos);
04264 maxsize = 2*maxsize;
04265 delete [] s;
04266 s = new char[maxsize];
04267 b.ReadString(s, maxsize);
04268 }
04269
04270 TClass *cl = TClass::GetClass(s, kTRUE);
04271 if (!cl)
04272 ::Error("TClass::Load", "dictionary of class %s not found", s);
04273
04274 delete [] s;
04275 return cl;
04276 }
04277
04278
04279 void TClass::Store(TBuffer &b) const
04280 {
04281
04282
04283 b.WriteString(GetName());
04284 }
04285
04286
04287 TClass *ROOT::CreateClass(const char *cname, Version_t id,
04288 const type_info &info, TVirtualIsAProxy *isa,
04289 ShowMembersFunc_t show,
04290 const char *dfil, const char *ifil,
04291 Int_t dl, Int_t il)
04292 {
04293
04294
04295
04296
04297
04298 TMmallocDescTemp setreset;
04299 return new TClass(cname, id, info, isa, show, dfil, ifil, dl, il);
04300 }
04301
04302
04303 TClass *ROOT::CreateClass(const char *cname, Version_t id,
04304 const char *dfil, const char *ifil,
04305 Int_t dl, Int_t il)
04306 {
04307
04308
04309
04310
04311
04312 TMmallocDescTemp setreset;
04313 return new TClass(cname, id, dfil, ifil, dl, il);
04314 }
04315
04316
04317 TClass::ENewType TClass::IsCallingNew()
04318 {
04319
04320
04321
04322
04323
04324
04325
04326 return fgCallingNew;
04327 }
04328
04329
04330 Bool_t TClass::IsLoaded() const
04331 {
04332
04333
04334
04335
04336 return (GetImplFileLine()>=0 && !TestBit(kUnloaded));
04337 }
04338
04339
04340 Bool_t TClass::IsStartingWithTObject() const
04341 {
04342
04343
04344
04345
04346
04347
04348
04349
04350
04351 if (fProperty==(-1)) Property();
04352 return TestBit(kStartWithTObject);
04353 }
04354
04355
04356 Bool_t TClass::IsTObject() const
04357 {
04358
04359
04360 if (fProperty==(-1)) Property();
04361 return TestBit(kIsTObject);
04362 }
04363
04364
04365 Bool_t TClass::IsForeign() const
04366 {
04367
04368
04369 if (fProperty==(-1)) Property();
04370 return TestBit(kIsForeign);
04371 }
04372
04373
04374 void TClass::PostLoadCheck()
04375 {
04376
04377
04378
04379
04380
04381
04382
04383 if (IsLoaded() && fClassInfo && fClassVersion==1
04384 && IsForeign() )
04385 {
04386 SetClassVersion(-1);
04387 }
04388 else if (IsLoaded() && fClassInfo && fStreamerInfo && (!IsForeign()||fClassVersion>1) )
04389 {
04390 TVirtualStreamerInfo *info = (TVirtualStreamerInfo*)(fStreamerInfo->At(fClassVersion));
04391
04392
04393
04394
04395 if (info && GetListOfDataMembers() && !GetCollectionProxy()
04396 && (info->GetCheckSum()!=GetCheckSum() && info->GetCheckSum()!=GetCheckSum(1) && info->GetCheckSum()!=GetCheckSum(2)))
04397 {
04398 Bool_t warn = ! TestBit(kWarned);
04399 if (warn && info->GetOldVersion()<=2) {
04400
04401
04402 TIter nextBC(GetListOfBases());
04403 TBaseClass *bc;
04404 while ((bc=(TBaseClass*)nextBC()))
04405 {if (TClassEdit::IsSTLCont(bc->GetName())) warn = kFALSE;}
04406 }
04407
04408 if (warn) {
04409 if (info->GetOnFileClassVersion()==1 && fClassVersion>1) {
04410 Warning("PostLoadCheck","\n\
04411 The class %s transitioned from not having a specified class version\n\
04412 to having a specified class version (the current class version is %d).\n\
04413 However too many different non-versioned layouts of the class have\n\
04414 already been loaded so far. To work around this problem you can\n\
04415 load fewer 'old' file in the same ROOT session or load the C++ library\n\
04416 describing the class %s before opening the files or increase the version\n\
04417 number of the class for example ClassDef(%s,%d).\n\
04418 Do not try to write objects with the current class definition,\n\
04419 the files might not be readable.\n",
04420 GetName(), fClassVersion, GetName(), GetName(), fStreamerInfo->GetLast()+1);
04421 } else {
04422 Warning("PostLoadCheck","\n\
04423 The StreamerInfo version %d for the class %s which was read\n\
04424 from a file previously opened has the same version as the active class\n\
04425 but a different checksum. You should update the version to ClassDef(%s,%d).\n\
04426 Do not try to write objects with the current class definition,\n\
04427 the files will not be readable.\n"
04428 , fClassVersion, GetName(), GetName(), fStreamerInfo->GetLast()+1);
04429 }
04430 info->CompareContent(this,0,kTRUE,kTRUE);
04431 SetBit(kWarned);
04432 }
04433 }
04434 }
04435 }
04436
04437
04438 Long_t TClass::Property() const
04439 {
04440
04441
04442
04443
04444
04445
04446
04447
04448
04449
04450
04451
04452 R__LOCKGUARD(gCINTMutex);
04453
04454 if (fProperty!=(-1)) return fProperty;
04455
04456
04457
04458 TMmallocDescTemp setreset;
04459
04460 Long_t dummy;
04461 TClass *kl = const_cast<TClass*>(this);
04462
04463 kl->fStreamerType = kNone;
04464 kl->fStreamerImpl = &TClass::StreamerDefault;
04465
04466 if (InheritsFrom(TObject::Class())) {
04467 kl->SetBit(kIsTObject);
04468
04469
04470 Int_t delta = kl->GetBaseClassOffset(TObject::Class());
04471 if (delta==0) kl->SetBit(kStartWithTObject);
04472
04473 kl->fStreamerType = kTObject;
04474 kl->fStreamerImpl = &TClass::StreamerTObject;
04475 }
04476
04477 if (fClassInfo) {
04478
04479 kl->fProperty = gCint->ClassInfo_Property(fClassInfo);
04480
04481 if (!gCint->ClassInfo_HasMethod(fClassInfo,"Streamer") ||
04482 !gCint->ClassInfo_IsValidMethod(fClassInfo,"Streamer","TBuffer&",&dummy) ) {
04483
04484 kl->SetBit(kIsForeign);
04485 kl->fStreamerType = kForeign;
04486 kl->fStreamerImpl = &TClass::StreamerStreamerInfo;
04487
04488 } else if ( kl->fStreamerType == kNone ) {
04489 if ( gCint->ClassInfo_FileName(fClassInfo)
04490 && strcmp( gCint->ClassInfo_FileName(fClassInfo),"{CINTEX dictionary translator}")==0) {
04491 kl->SetBit(kIsForeign);
04492 }
04493 if (kl->fStreamerFunc) {
04494 kl->fStreamerType = kInstrumented;
04495 kl->fStreamerImpl = &TClass::StreamerInstrumented;
04496 } else {
04497
04498
04499 kl->fStreamerType = kInstrumented;
04500 kl->fStreamerImpl = &TClass::StreamerStreamerInfo;
04501 }
04502 }
04503
04504 if (fStreamer) {
04505 kl->fStreamerType = kExternal;
04506 kl->fStreamerImpl = &TClass::StreamerExternal;
04507 }
04508
04509 } else {
04510
04511 if (fStreamer) {
04512 kl->fStreamerType = kExternal;
04513 kl->fStreamerImpl = &TClass::StreamerExternal;
04514 }
04515
04516 kl->fStreamerType |= kEmulated;
04517 switch (fStreamerType) {
04518 case kEmulated:
04519 case kForeign|kEmulated:
04520 case kInstrumented|kEmulated: kl->fStreamerImpl = &TClass::StreamerStreamerInfo; break;
04521 case kExternal|kEmulated: kl->fStreamerImpl = &TClass::StreamerExternal; break;
04522 case kTObject|kEmulated: kl->fStreamerImpl = &TClass::StreamerTObjectEmulated; break;
04523 }
04524 return 0;
04525 }
04526
04527 return fProperty;
04528 }
04529
04530
04531 void TClass::SetCollectionProxy(const ROOT::TCollectionProxyInfo &info)
04532 {
04533
04534
04535
04536 R__LOCKGUARD(gCINTMutex);
04537
04538 delete fCollectionProxy;
04539
04540
04541
04542
04543
04544 TVirtualCollectionProxy *p = TVirtualStreamerInfo::Factory()->GenExplicitProxy(info,this);
04545 fCollectionProxy = p;
04546
04547 AdoptStreamer(TVirtualStreamerInfo::Factory()->GenExplicitClassStreamer(info,this));
04548 }
04549
04550
04551 void TClass::SetContextMenuTitle(const char *title)
04552 {
04553
04554
04555 fContextMenuTitle = title;
04556 }
04557
04558
04559 void TClass::SetGlobalIsA(IsAGlobalFunc_t func)
04560 {
04561
04562
04563
04564
04565
04566
04567
04568
04569
04570
04571
04572
04573
04574
04575
04576
04577
04578
04579
04580
04581
04582 fGlobalIsA = func;
04583 }
04584
04585
04586 void TClass::SetUnloaded()
04587 {
04588
04589
04590
04591 delete fIsA; fIsA = 0;
04592
04593
04594 int autoload_old = gCint->SetClassAutoloading(0);
04595 gInterpreter->SetClassInfo(this,kTRUE);
04596 gCint->SetClassAutoloading(autoload_old);
04597 fDeclFileName = 0;
04598 fDeclFileLine = 0;
04599 fImplFileName = 0;
04600 fImplFileLine = 0;
04601 fTypeInfo = 0;
04602
04603 if (fMethod) {
04604 fMethod->Delete();
04605 delete fMethod;
04606 fMethod=0;
04607 }
04608
04609 SetBit(kUnloaded);
04610 }
04611
04612
04613 TVirtualStreamerInfo *TClass::SetStreamerInfo(Int_t , const char * )
04614 {
04615
04616
04617
04618
04619
04620
04621
04622
04623
04624
04625
04626
04627
04628
04629
04630
04631
04632
04633
04634
04635
04636
04637
04638
04639
04640
04641
04642
04643
04644
04645
04646
04647
04648
04649
04650
04651
04652
04653
04654
04655
04656
04657
04658
04659
04660
04661
04662
04663
04664
04665
04666
04667
04668
04669
04670
04671
04672
04673
04674
04675
04676
04677
04678
04679
04680
04681
04682
04683
04684
04685
04686
04687
04688
04689
04690
04691
04692 delete [] final;
04693 delete [] save;
04694 return;
04695 }
04696
04697 //info is empty. Let's build the default Streamer descriptor
04698
04699 char *temp = new char[10000];
04700 temp[0] = 0;
04701 char local[100];
04702
04703 //add list of base classes
04704 TIter nextb(GetListOfBases());
04705 TBaseClass *base;
04706 while ((base = (TBaseClass*) nextb())) {
04707 snprintf(local,100,"%s;",base->GetName());
04708 strlcat(temp,local,10000);
04709 }
04710
04711 //add list of data members and types
04712 TIter nextd(GetListOfDataMembers());
04713 while ((dm = (TDataMember *) nextd())) {
04714 if (dm->IsEnum()) continue;
04715 if (!dm->IsPersistent()) continue;
04716 Long_t property = dm->Property();
04717 if (property & kIsStatic) continue;
04718 TClass *acl = TClass::GetClass(dm->GetTypeName(),update);
04719 update = kFALSE;
04720 if (acl) {
04721 if (acl->GetClassVersion() == 0) continue;
04722 }
04723
04724 // dm->GetArrayIndex() returns an empty string if it does not
04725 // applies
04726 const char * index = dm->GetArrayIndex();
04727 if (strlen(index)==0)
04728 snprintf(local,100,"%s %s;",dm->GetFullTypeName(),dm->GetName());
04729 else
04730 snprintf(local,100,"%s %s[%s];",dm->GetFullTypeName(),dm->GetName(),index);
04731 strlcat(temp,local,10000);
04732 }
04733 //fStreamerInfo = temp;
04734 delete [] temp;
04735 */
04736 return 0;
04737 }
04738
04739
04740 UInt_t TClass::GetCheckSum(UInt_t code) const
04741 {
04742
04743
04744
04745
04746
04747
04748
04749
04750
04751
04752
04753
04754
04755
04756
04757
04758 R__LOCKGUARD(gCINTMutex);
04759
04760 if (fCheckSum && code == 0) return fCheckSum;
04761
04762 UInt_t id = 0;
04763
04764 int il;
04765 TString name = GetName();
04766 TString type;
04767 il = name.Length();
04768 for (int i=0; i<il; i++) id = id*3+name[i];
04769
04770 TList *tlb = ((TClass*)this)->GetListOfBases();
04771 if (tlb) {
04772
04773 TIter nextBase(tlb);
04774
04775 TBaseClass *tbc=0;
04776 while((tbc=(TBaseClass*)nextBase())) {
04777 name = tbc->GetName();
04778 il = name.Length();
04779 for (int i=0; i<il; i++) id = id*3+name[i];
04780 }
04781 }
04782 TList *tlm = ((TClass*)this)->GetListOfDataMembers();
04783 if (tlm) {
04784 TIter nextMemb(tlm);
04785 TDataMember *tdm=0;
04786 Long_t prop = 0;
04787 while((tdm=(TDataMember*)nextMemb())) {
04788 if (!tdm->IsPersistent()) continue;
04789
04790 prop = (tdm->Property());
04791 TDataType* tdt = tdm->GetDataType();
04792 if (tdt) prop |= tdt->Property();
04793
04794 if ( prop&kIsStatic) continue;
04795 name = tdm->GetName(); il = name.Length();
04796 if ( (code != 1) && prop&kIsEnum) id = id*3 + 1;
04797
04798 int i;
04799 for (i=0; i<il; i++) id = id*3+name[i];
04800 type = tdm->GetFullTypeName();
04801 if (TClassEdit::IsSTLCont(type))
04802 type = TClassEdit::ShortType( type, TClassEdit::kDropStlDefault );
04803
04804 il = type.Length();
04805 for (i=0; i<il; i++) id = id*3+type[i];
04806
04807 int dim = tdm->GetArrayDim();
04808 if (prop&kIsArray) {
04809 for (int ii=0;ii<dim;ii++) id = id*3+tdm->GetMaxIndex(ii);
04810 }
04811 if (code != 2) {
04812 const char *left = strstr(tdm->GetTitle(),"[");
04813 if (left) {
04814 const char *right = strstr(left,"]");
04815 if (right) {
04816 ++left;
04817 while (left != right) {
04818 id = id*3 + *left;
04819 ++left;
04820 }
04821 }
04822 }
04823 }
04824 }
04825 }
04826 if (code==0) fCheckSum = id;
04827 return id;
04828 }
04829
04830
04831 void TClass::AdoptReferenceProxy(TVirtualRefProxy* proxy)
04832 {
04833
04834
04835
04836
04837 R__LOCKGUARD(gCINTMutex);
04838
04839 if ( fRefProxy ) {
04840 fRefProxy->Release();
04841 }
04842 fRefProxy = proxy;
04843 if ( fRefProxy ) {
04844 fRefProxy->SetClass(this);
04845 }
04846 }
04847
04848
04849 void TClass::AdoptMemberStreamer(const char *name, TMemberStreamer *p)
04850 {
04851
04852
04853
04854 if (!fRealData) return;
04855
04856 R__LOCKGUARD(gCINTMutex);
04857
04858 TIter next(fRealData);
04859 TRealData *rd;
04860 while ((rd = (TRealData*)next())) {
04861 if (strcmp(rd->GetName(),name) == 0) {
04862
04863
04864 rd->AdoptStreamer(p);
04865 break;
04866 }
04867 }
04868
04869
04870
04871
04872
04873
04874
04875
04876
04877
04878
04879
04880
04881
04882
04883
04884 return;
04885 }
04886
04887
04888 void TClass::SetMemberStreamer(const char *name, MemberStreamerFunc_t p)
04889 {
04890
04891
04892 AdoptMemberStreamer(name,new TMemberStreamer(p));
04893 }
04894
04895
04896 Int_t TClass::ReadBuffer(TBuffer &b, void *pointer, Int_t version, UInt_t start, UInt_t count)
04897 {
04898
04899
04900
04901
04902
04903
04904
04905
04906 return b.ReadClassBuffer(this,pointer,version,start,count);
04907 }
04908
04909
04910 Int_t TClass::ReadBuffer(TBuffer &b, void *pointer)
04911 {
04912
04913
04914
04915 return b.ReadClassBuffer(this,pointer);
04916 }
04917
04918
04919 Int_t TClass::WriteBuffer(TBuffer &b, void *pointer, const char * )
04920 {
04921
04922
04923
04924
04925
04926
04927 b.WriteClassBuffer(this,pointer);
04928 return 0;
04929 }
04930
04931
04932 void TClass::StreamerExternal(void *object, TBuffer &b, const TClass *onfile_class) const
04933 {
04934
04935
04936
04937
04938
04939 TClassStreamer *streamer = gThreadTsd ? GetStreamer() : fStreamer;
04940 streamer->Stream(b,object,onfile_class);
04941 }
04942
04943
04944 void TClass::StreamerTObject(void *object, TBuffer &b, const TClass * ) const
04945 {
04946
04947
04948
04949
04950 if (!fIsOffsetStreamerSet) {
04951 CalculateStreamerOffset();
04952 }
04953 TObject *tobj = (TObject*)((Long_t)object + fOffsetStreamer);
04954 tobj->Streamer(b);
04955 }
04956
04957
04958 void TClass::StreamerTObjectInitialized(void *object, TBuffer &b, const TClass * ) const
04959 {
04960
04961
04962 TObject *tobj = (TObject*)((Long_t)object + fOffsetStreamer);
04963 tobj->Streamer(b);
04964 }
04965
04966
04967 void TClass::StreamerTObjectEmulated(void *object, TBuffer &b, const TClass *onfile_class) const
04968 {
04969
04970
04971
04972 if (b.IsReading()) {
04973 b.ReadClassEmulated(this, object, onfile_class);
04974 } else {
04975 b.WriteClassBuffer(this, object);
04976 }
04977 }
04978
04979
04980 void TClass::StreamerInstrumented(void *object, TBuffer &b, const TClass * ) const
04981 {
04982
04983
04984
04985 fStreamerFunc(b,object);
04986 }
04987
04988
04989 void TClass::StreamerStreamerInfo(void *object, TBuffer &b, const TClass *onfile_class) const
04990 {
04991
04992
04993
04994
04995
04996
04997 if (b.IsReading()) {
04998 b.ReadClassBuffer(this, object, onfile_class);
04999
05000 } else {
05001
05002 b.WriteClassBuffer(this, object);
05003 }
05004 }
05005
05006
05007 void TClass::StreamerDefault(void *object, TBuffer &b, const TClass *onfile_class) const
05008 {
05009
05010
05011
05012 if (fProperty==(-1)) {
05013 Property();
05014 if (fStreamerImpl == &TClass::StreamerDefault) {
05015 Fatal("StreamerDefault", "fStreamerImpl not properly initialized (%d)", fStreamerType);
05016 } else {
05017 (this->*fStreamerImpl)(object,b,onfile_class);
05018 }
05019 } else {
05020 Fatal("StreamerDefault", "fStreamerType not properly initialized (%d)", fStreamerType);
05021 }
05022 }
05023
05024
05025 void TClass::AdoptStreamer(TClassStreamer *str)
05026 {
05027
05028
05029
05030
05031
05032
05033
05034 R__LOCKGUARD(gCINTMutex);
05035
05036 if (fStreamer) delete fStreamer;
05037 if (str) {
05038 fStreamerType = kExternal | ( fStreamerType&kEmulated );
05039 fStreamer = str;
05040 fStreamerImpl = &TClass::StreamerExternal;
05041 } else if (fStreamer) {
05042
05043
05044 fStreamer = str;
05045 fStreamerType = kNone;
05046 if (fProperty != -1) {
05047 fProperty = -1;
05048 Property();
05049 }
05050 }
05051 }
05052
05053
05054 void TClass::SetStreamerFunc(ClassStreamerFunc_t strm)
05055 {
05056
05057
05058 if (fProperty != -1 &&
05059 ( (fStreamerFunc == 0 && strm != 0) || (fStreamerFunc != 0 && strm == 0) ) )
05060 {
05061
05062 fStreamerFunc = strm;
05063 fProperty = -1;
05064 Property();
05065 } else {
05066 fStreamerFunc = strm;
05067 }
05068 }
05069
05070
05071 void TClass::SetNew(ROOT::NewFunc_t newFunc)
05072 {
05073
05074
05075 fNew = newFunc;
05076 }
05077
05078
05079 void TClass::SetNewArray(ROOT::NewArrFunc_t newArrayFunc)
05080 {
05081
05082
05083 fNewArray = newArrayFunc;
05084 }
05085
05086
05087 void TClass::SetDelete(ROOT::DelFunc_t deleteFunc)
05088 {
05089
05090
05091 fDelete = deleteFunc;
05092 }
05093
05094
05095 void TClass::SetDeleteArray(ROOT::DelArrFunc_t deleteArrayFunc)
05096 {
05097
05098
05099 fDeleteArray = deleteArrayFunc;
05100 }
05101
05102
05103 void TClass::SetDestructor(ROOT::DesFunc_t destructorFunc)
05104 {
05105
05106
05107 fDestructor = destructorFunc;
05108 }
05109
05110
05111 void TClass::SetDirectoryAutoAdd(ROOT::DirAutoAdd_t autoAddFunc)
05112 {
05113
05114
05115
05116
05117
05118 fDirAutoAdd = autoAddFunc;
05119 }
05120
05121
05122 TVirtualStreamerInfo *TClass::FindStreamerInfo(UInt_t checksum) const
05123 {
05124
05125
05126 Int_t ninfos = fStreamerInfo->GetEntriesFast()-1;
05127 for (Int_t i=-1;i<ninfos;++i) {
05128
05129
05130 TVirtualStreamerInfo *info = (TVirtualStreamerInfo*)fStreamerInfo->UncheckedAt(i);
05131 if (info && info->GetCheckSum() == checksum) {
05132
05133 return info;
05134 }
05135 }
05136 return 0;
05137 }
05138
05139
05140 TVirtualStreamerInfo *TClass::FindStreamerInfo(TObjArray* arr, UInt_t checksum) const
05141 {
05142
05143
05144 Int_t ninfos = arr->GetEntriesFast()-1;
05145 for (Int_t i=-1;i<ninfos;i++) {
05146
05147
05148 TVirtualStreamerInfo *info = (TVirtualStreamerInfo*)arr->UncheckedAt(i);
05149 if (!info) continue;
05150 if (info->GetCheckSum() == checksum) {
05151 R__ASSERT(i==info->GetClassVersion() || (i==-1&&info->GetClassVersion()==1));
05152 return info;
05153 }
05154 }
05155 return 0;
05156 }
05157
05158
05159 TVirtualStreamerInfo *TClass::GetConversionStreamerInfo( const char* classname, Int_t version ) const
05160 {
05161
05162
05163 TClass *cl = TClass::GetClass( classname );
05164 if( !cl )
05165 return 0;
05166 return GetConversionStreamerInfo( cl, version );
05167 }
05168
05169
05170 TVirtualStreamerInfo *TClass::GetConversionStreamerInfo( const TClass* cl, Int_t version ) const
05171 {
05172
05173
05174
05175
05176
05177 if( !cl )
05178 return 0;
05179
05180 if( cl == this )
05181 return GetStreamerInfo( version );
05182
05183
05184
05185
05186 TObjArray* arr = 0;
05187 if (fConversionStreamerInfo) {
05188 std::map<std::string, TObjArray*>::iterator it;
05189
05190 it = fConversionStreamerInfo->find( cl->GetName() );
05191
05192 if( it != fConversionStreamerInfo->end() ) {
05193 arr = it->second;
05194 }
05195
05196 if( arr && version > -1 && version < arr->GetSize() && arr->At( version ) )
05197 return (TVirtualStreamerInfo*) arr->At( version );
05198 }
05199
05200 R__LOCKGUARD(gCINTMutex);
05201
05202
05203
05204
05205 TObjArray *clSI = cl->GetStreamerInfos();
05206 TVirtualStreamerInfo* info = 0;
05207 if( version > -1 && version < clSI->GetSize() )
05208 info = (TVirtualStreamerInfo*)clSI->At( version );
05209
05210 if( !info )
05211 return 0;
05212
05213
05214
05215
05216
05217 info = (TVirtualStreamerInfo*)info->Clone();
05218
05219 if( !info->BuildFor( this ) ) {
05220 delete info;
05221 return 0;
05222 }
05223
05224 if (!info->IsCompiled()) {
05225
05226
05227
05228 info->BuildOld();
05229 } else if (info->IsOptimized() && !TVirtualStreamerInfo::CanOptimize()) {
05230
05231 info->Compile();
05232 }
05233
05234
05235
05236
05237 if (!arr) {
05238 arr = new TObjArray(version+10, -1);
05239 if (!fConversionStreamerInfo) {
05240 fConversionStreamerInfo = new std::map<std::string, TObjArray*>();
05241 }
05242 (*fConversionStreamerInfo)[cl->GetName()] = arr;
05243 }
05244 arr->AddAtAndExpand( info, info->GetClassVersion() );
05245 return info;
05246 }
05247
05248
05249 TVirtualStreamerInfo *TClass::FindConversionStreamerInfo( const char* classname, UInt_t checksum ) const
05250 {
05251
05252
05253 TClass *cl = TClass::GetClass( classname );
05254 if( !cl )
05255 return 0;
05256 return FindConversionStreamerInfo( cl, checksum );
05257 }
05258
05259
05260 TVirtualStreamerInfo *TClass::FindConversionStreamerInfo( const TClass* cl, UInt_t checksum ) const
05261 {
05262
05263
05264
05265
05266
05267 if( !cl )
05268 return 0;
05269
05270 if( cl == this )
05271 return FindStreamerInfo( checksum );
05272
05273
05274
05275
05276 TObjArray* arr = 0;
05277 TVirtualStreamerInfo* info = 0;
05278 if (fConversionStreamerInfo) {
05279 std::map<std::string, TObjArray*>::iterator it;
05280
05281 it = fConversionStreamerInfo->find( cl->GetName() );
05282
05283 if( it != fConversionStreamerInfo->end() ) {
05284 arr = it->second;
05285 }
05286 if (arr) {
05287 info = FindStreamerInfo( arr, checksum );
05288 }
05289 }
05290
05291 if( info )
05292 return info;
05293
05294 R__LOCKGUARD(gCINTMutex);
05295
05296
05297
05298
05299 info = cl->FindStreamerInfo( checksum );
05300
05301 if( !info )
05302 return 0;
05303
05304
05305
05306
05307
05308 info = (TVirtualStreamerInfo*)info->Clone();
05309 if( !info->BuildFor( this ) ) {
05310 delete info;
05311 return 0;
05312 }
05313
05314 if (!info->IsCompiled()) {
05315
05316
05317
05318 info->BuildOld();
05319 } else if (info->IsOptimized() && !TVirtualStreamerInfo::CanOptimize()) {
05320
05321 info->Compile();
05322 }
05323
05324
05325
05326
05327 if (!arr) {
05328 arr = new TObjArray(16, -1);
05329 if (!fConversionStreamerInfo) {
05330 fConversionStreamerInfo = new std::map<std::string, TObjArray*>();
05331 }
05332 (*fConversionStreamerInfo)[cl->GetName()] = arr;
05333 }
05334 arr->AddAtAndExpand( info, info->GetClassVersion() );
05335
05336 return info;
05337 }
05338
05339
05340 Bool_t TClass::HasDefaultConstructor() const
05341 {
05342
05343
05344
05345 if (fNew) return kTRUE;
05346
05347 if (GetClassInfo()) {
05348 R__LOCKGUARD(gCINTMutex);
05349 return gCint->ClassInfo_HasDefaultConstructor(GetClassInfo());
05350 }
05351 if (fCollectionProxy) {
05352 return kTRUE;
05353 }
05354 if (fCurrentInfo) {
05355
05356 return kTRUE;
05357 }
05358 return kFALSE;
05359 }
05360
05361
05362 ROOT::NewFunc_t TClass::GetNew() const
05363 {
05364
05365
05366 return fNew;
05367 }
05368
05369
05370 ROOT::NewArrFunc_t TClass::GetNewArray() const
05371 {
05372
05373
05374 return fNewArray;
05375 }
05376
05377
05378 ROOT::DelFunc_t TClass::GetDelete() const
05379 {
05380
05381
05382 return fDelete;
05383 }
05384
05385
05386 ROOT::DelArrFunc_t TClass::GetDeleteArray() const
05387 {
05388
05389
05390 return fDeleteArray;
05391 }
05392
05393
05394 ROOT::DesFunc_t TClass::GetDestructor() const
05395 {
05396
05397
05398 return fDestructor;
05399 }
05400
05401
05402 ROOT::DirAutoAdd_t TClass::GetDirectoryAutoAdd() const
05403 {
05404
05405
05406 return fDirAutoAdd;
05407 }
05408