00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "RConfig.h"
00022 #include <stdlib.h>
00023 #include <string>
00024 #include <map>
00025 #include <typeinfo>
00026 #include "Riostream.h"
00027
00028 #include "TClassTable.h"
00029 #include "TClass.h"
00030 #include "TClassEdit.h"
00031 #include "TROOT.h"
00032 #include "TString.h"
00033 #include "TError.h"
00034 #include "TRegexp.h"
00035
00036 #include "TObjString.h"
00037 #include "TMap.h"
00038
00039 TClassTable *gClassTable;
00040
00041 TClassRec **TClassTable::fgTable;
00042 TClassRec **TClassTable::fgSortedTable;
00043 int TClassTable::fgSize;
00044 int TClassTable::fgTally;
00045 Bool_t TClassTable::fgSorted;
00046 int TClassTable::fgCursor;
00047 TClassTable::IdMap_t *TClassTable::fgIdMap;
00048
00049 ClassImp(TClassTable)
00050
00051
00052 namespace ROOT {
00053
00054 class TMapTypeToClassRec {
00055 #if defined R__USE_STD_MAP
00056
00057
00058 public:
00059 #ifdef R__GLOBALSTL
00060 typedef map<string, TClassRec*> IdMap_t;
00061 #else
00062 typedef std::map<std::string, TClassRec*> IdMap_t;
00063 #endif
00064 typedef IdMap_t::key_type key_type;
00065 typedef IdMap_t::const_iterator const_iterator;
00066 typedef IdMap_t::size_type size_type;
00067 #ifdef R__WIN32
00068
00069 typedef TClassRec* mapped_type;
00070 #else
00071 typedef IdMap_t::mapped_type mapped_type;
00072 #endif
00073
00074 private:
00075 IdMap_t fMap;
00076
00077 public:
00078 void Add(const key_type &key, mapped_type &obj) {
00079 fMap[key] = obj;
00080 }
00081
00082 mapped_type Find(const key_type &key) const {
00083
00084 IdMap_t::const_iterator iter = fMap.find(key);
00085 mapped_type cl = 0;
00086 if (iter != fMap.end()) cl = iter->second;
00087 return cl;
00088 }
00089
00090 void Remove(const key_type &key) { fMap.erase(key); }
00091
00092 void Print() {
00093 Info("TMapTypeToClassRec::Print", "printing the typeinfo map in TClassTable");
00094 for (const_iterator iter = fMap.begin(); iter != fMap.end(); iter++) {
00095 printf("Key: %40s 0x%lx\n", iter->first.c_str(), iter->second);
00096 }
00097 }
00098 #else
00099 private:
00100 TMap fMap;
00101 public:
00102 #ifdef R__COMPLETE_MEM_TERMINATION
00103 ~TMapTypeToClassRec() {
00104 TIter next(&fMap);
00105 TObjString *key;
00106 while((key = (TObjString*)next())) {
00107 delete key;
00108 }
00109 }
00110 #endif
00111
00112 void Add(const char *key, TClassRec *&obj) {
00113 TObjString *realkey = new TObjString(key);
00114 fMap.Add(realkey, (TObject*)obj);
00115 }
00116
00117 TClassRec *Find(const char *key) const {
00118 const TPair *a = (const TPair *)fMap.FindObject(key);
00119 if (a) return (TClassRec*) a->Value();
00120 return 0;
00121 }
00122
00123 void Remove(const char *key) {
00124 TObjString realkey(key);
00125 TObject *actual = fMap.Remove(&realkey);
00126 delete actual;
00127 }
00128
00129 void Print() {
00130 Info("TMapTypeToClassRec::Print", "printing the typeinfo map in TClassTable");
00131 TIter next(&fMap);
00132 TObjString *key;
00133 while((key = (TObjString*)next())) {
00134 printf("Key: %s\n",key->String().Data());
00135 TClassRec *data = (TClassRec*)fMap.GetValue(key);
00136 if (data) {
00137 printf(" class: %s %d\n",data->fName,data->fId);
00138 } else {
00139 printf(" no class: \n");
00140 }
00141 }
00142 }
00143 #endif
00144 };
00145 }
00146
00147
00148 TClassTable::TClassTable()
00149 {
00150
00151
00152 if (gClassTable) return;
00153
00154 fgSize = 1009;
00155 fgTable = new TClassRec* [fgSize];
00156 fgIdMap = new IdMap_t;
00157 memset(fgTable, 0, fgSize*sizeof(TClassRec*));
00158 gClassTable = this;
00159 }
00160
00161
00162 TClassTable::~TClassTable()
00163 {
00164
00165
00166
00167 if (gClassTable != this) return;
00168
00169 for (Int_t i = 0; i < fgSize; i++) {
00170 TClassRec *r = fgTable[i];
00171 while (r) {
00172 delete [] r->fName;
00173 TClassRec *next = r->fNext;
00174 delete r;
00175 r = next;
00176 }
00177 }
00178 delete [] fgTable; fgTable = 0;
00179 delete [] fgSortedTable; fgSortedTable = 0;
00180 delete fgIdMap; fgIdMap = 0;
00181 }
00182
00183
00184 void TClassTable::Print(Option_t *option) const
00185 {
00186
00187
00188
00189
00190
00191 if (fgTally == 0 || !fgTable)
00192 return;
00193
00194 SortTable();
00195
00196 int n = 0, ninit = 0, nl = 0;
00197
00198 int nch = strlen(option);
00199 TRegexp re(option, kTRUE);
00200
00201 Printf("\nDefined classes");
00202 Printf("class version bits initialized");
00203 Printf("================================================================");
00204 for (int i = 0; i < fgTally; i++) {
00205 if (!fgTable[i]) continue;
00206 TClassRec *r = fgSortedTable[i];
00207 if (!r) break;
00208 n++;
00209 TString s = r->fName;
00210 if (nch && strcmp(option,r->fName) && s.Index(re) == kNPOS) continue;
00211 nl++;
00212 if (TClass::GetClass(r->fName, kFALSE)) {
00213 ninit++;
00214 Printf("%-35s %6d %7d Yes", r->fName, r->fId, r->fBits);
00215 } else
00216 Printf("%-35s %6d %7d No", r->fName, r->fId, r->fBits);
00217 }
00218 Printf("----------------------------------------------------------------");
00219 Printf("Listed Classes: %4d Total classes: %4d initialized: %4d",nl, n, ninit);
00220 Printf("================================================================\n");
00221 }
00222
00223
00224
00225
00226 char *TClassTable::At(int index)
00227 {
00228
00229
00230
00231
00232
00233 SortTable();
00234 if (index >= 0 && index < fgTally) {
00235 TClassRec *r = fgSortedTable[index];
00236 if (r) return r->fName;
00237 }
00238 return 0;
00239 }
00240
00241
00242 int TClassTable::Classes() { return fgTally; }
00243
00244 void TClassTable::Init() { fgCursor = 0; SortTable(); }
00245
00246 namespace ROOT { class TForNamespace {}; }
00247
00248
00249 void TClassTable::Add(const char *cname, Version_t id, const type_info &info,
00250 VoidFuncPtr_t dict, Int_t pragmabits)
00251 {
00252
00253
00254 if (!gClassTable)
00255 new TClassTable;
00256
00257
00258 TClassEdit::TSplitType splitname( cname, TClassEdit::kLong64 );
00259 std::string shortName;
00260 splitname.ShortType(shortName, TClassEdit::kDropStlDefault);
00261
00262
00263 TClassRec *r = FindElementImpl(shortName.c_str(), kTRUE);
00264 if (r->fName) {
00265 if ( strcmp(r->fInfo->name(),typeid(ROOT::TForNamespace).name())==0
00266 && strcmp(info.name(),typeid(ROOT::TForNamespace).name())==0 ) {
00267
00268
00269 return;
00270 }
00271 if (splitname.IsSTLCont()==0) {
00272
00273 ::Warning("TClassTable::Add", "class %s already in TClassTable", cname);
00274 }
00275 return;
00276 }
00277
00278 r->fName = StrDup(shortName.c_str());
00279 r->fId = id;
00280 r->fBits = pragmabits;
00281 r->fDict = dict;
00282 r->fInfo = &info;
00283
00284 fgIdMap->Add(info.name(),r);
00285
00286 fgTally++;
00287 fgSorted = kFALSE;
00288 }
00289
00290
00291 void TClassTable::Remove(const char *cname)
00292 {
00293
00294
00295
00296 if (!gClassTable || !fgTable) return;
00297
00298 int slot = 0;
00299 const char *p = cname;
00300
00301 while (*p) slot = slot<<1 ^ *p++;
00302 if (slot < 0) slot = -slot;
00303 slot %= fgSize;
00304
00305 TClassRec *r;
00306 TClassRec *prev = 0;
00307 for (r = fgTable[slot]; r; r = r->fNext) {
00308 if (!strcmp(r->fName, cname)) {
00309 if (prev)
00310 prev->fNext = r->fNext;
00311 else
00312 fgTable[slot] = r->fNext;
00313 fgIdMap->Remove(r->fInfo->name());
00314 delete [] r->fName;
00315 delete r;
00316 fgTally--;
00317 fgSorted = kFALSE;
00318 break;
00319 }
00320 prev = r;
00321 }
00322 }
00323
00324
00325 TClassRec *TClassTable::FindElementImpl(const char *cname, Bool_t insert)
00326 {
00327
00328
00329
00330
00331 int slot = 0;
00332 const char *p = cname;
00333
00334 while (*p) slot = slot<<1 ^ *p++;
00335 if (slot < 0) slot = -slot;
00336 slot %= fgSize;
00337
00338 TClassRec *r;
00339
00340 for (r = fgTable[slot]; r; r = r->fNext)
00341 if (strcmp(cname,r->fName)==0) return r;
00342
00343 if (!insert) return 0;
00344
00345 r = new TClassRec;
00346 r->fName = 0;
00347 r->fId = 0;
00348 r->fDict = 0;
00349 r->fInfo = 0;
00350 r->fNext = fgTable[slot];
00351 fgTable[slot] = r;
00352
00353 return r;
00354 }
00355
00356
00357 TClassRec *TClassTable::FindElement(const char *cname, Bool_t insert)
00358 {
00359
00360
00361
00362
00363 if (!fgTable) return 0;
00364
00365
00366 TClassEdit::TSplitType splitname( cname, TClassEdit::kLong64 );
00367 std::string shortName;
00368 splitname.ShortType(shortName, TClassEdit::kDropStlDefault);
00369
00370 return FindElementImpl(shortName.c_str(), insert);
00371 }
00372
00373
00374 Version_t TClassTable::GetID(const char *cname)
00375 {
00376
00377
00378 TClassRec *r = FindElement(cname);
00379 if (r) return r->fId;
00380 return -1;
00381 }
00382
00383
00384 Int_t TClassTable::GetPragmaBits(const char *cname)
00385 {
00386
00387
00388 TClassRec *r = FindElement(cname);
00389 if (r) return r->fBits;
00390 return 0;
00391 }
00392
00393
00394 VoidFuncPtr_t TClassTable::GetDict(const char *cname)
00395 {
00396
00397
00398
00399 if (gDebug > 9) {
00400 ::Info("GetDict", "searches for %s", cname);
00401 fgIdMap->Print();
00402 }
00403
00404 TClassRec *r = FindElement(cname);
00405 if (r) return r->fDict;
00406 return 0;
00407 }
00408
00409
00410 VoidFuncPtr_t TClassTable::GetDict(const type_info& info)
00411 {
00412
00413
00414
00415 if (gDebug > 9) {
00416 ::Info("GetDict", "searches for %s at 0x%lx", info.name(), (Long_t)&info);
00417 fgIdMap->Print();
00418 }
00419
00420 TClassRec *r = fgIdMap->Find(info.name());
00421 if (r) return r->fDict;
00422 return 0;
00423 }
00424
00425
00426
00427 extern "C" {
00428 static int ClassComp(const void *a, const void *b)
00429 {
00430
00431
00432 return strcmp((*(TClassRec **)a)->fName, (*(TClassRec **)b)->fName);
00433 }
00434 }
00435
00436
00437 char *TClassTable::Next()
00438 {
00439
00440
00441
00442
00443 if (fgCursor < fgTally) {
00444 TClassRec *r = fgSortedTable[fgCursor++];
00445 return r->fName;
00446 } else
00447 return 0;
00448 }
00449
00450
00451 void TClassTable::PrintTable()
00452 {
00453
00454
00455
00456 if (fgTally == 0 || !fgTable)
00457 return;
00458
00459 SortTable();
00460
00461 int n = 0, ninit = 0;
00462
00463 Printf("\nDefined classes");
00464 Printf("class version bits initialized");
00465 Printf("================================================================");
00466 for (int i = 0; i < fgTally; i++) {
00467 if (!fgTable[i]) continue;
00468 TClassRec *r = fgSortedTable[i];
00469 if (!r) break;
00470 n++;
00471 if (TClass::GetClass(r->fName, kFALSE)) {
00472 ninit++;
00473 Printf("%-35s %6d %7d Yes", r->fName, r->fId, r->fBits);
00474 } else
00475 Printf("%-35s %6d %7d No", r->fName, r->fId, r->fBits);
00476 }
00477 Printf("----------------------------------------------------------------");
00478 Printf("Total classes: %4d initialized: %4d", n, ninit);
00479 Printf("================================================================\n");
00480 }
00481
00482
00483 void TClassTable::SortTable()
00484 {
00485
00486
00487 if (!fgSorted) {
00488 delete [] fgSortedTable;
00489 fgSortedTable = new TClassRec* [fgTally];
00490
00491 int j = 0;
00492 for (int i = 0; i < fgSize; i++)
00493 for (TClassRec *r = fgTable[i]; r; r = r->fNext)
00494 fgSortedTable[j++] = r;
00495
00496 ::qsort(fgSortedTable, fgTally, sizeof(TClassRec *), ::ClassComp);
00497 fgSorted = kTRUE;
00498 }
00499 }
00500
00501
00502 void TClassTable::Terminate()
00503 {
00504
00505
00506 if (gClassTable) {
00507 for (int i = 0; i < fgSize; i++)
00508 for (TClassRec *r = fgTable[i]; r; ) {
00509 TClassRec *t = r;
00510 r = r->fNext;
00511 fgIdMap->Remove(r->fInfo->name());
00512 delete [] t->fName;
00513 delete t;
00514 }
00515 delete [] fgTable; fgTable = 0;
00516 delete [] fgSortedTable; fgSortedTable = 0;
00517 delete fgIdMap; fgIdMap = 0;
00518 fgSize = 0;
00519 SafeDelete(gClassTable);
00520 }
00521 }
00522
00523
00524 void ROOT::AddClass(const char *cname, Version_t id,
00525 const type_info& info,
00526 VoidFuncPtr_t dict,
00527 Int_t pragmabits)
00528 {
00529
00530
00531
00532 TClassTable::Add(cname, id, info, dict, pragmabits);
00533 }
00534
00535
00536 void ROOT::ResetClassVersion(TClass *cl, const char *cname, Short_t newid)
00537 {
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551 if (cname && cname!=(void*)-1) {
00552 TClassRec *r = TClassTable::FindElement(cname,kFALSE);
00553 if (r) r->fId = newid;
00554 }
00555 if (cl) {
00556 if (cl->fVersionUsed) {
00557
00558 if (cname!=(void*)-1)
00559 Error("ResetClassVersion","Version number of %s can not be changed after first usage!",
00560 cl->GetName());
00561 } else {
00562 if (newid < 0) {
00563 Error("SetClassVersion","The class version (for %s) must be positive (value %d is ignored)",cl->GetName(),newid);
00564 }
00565 if (cname==(void*)-1) {
00566 if (cl->fClassVersion<newid && 2<=newid) {
00567 cl->SetClassVersion(newid);
00568 }
00569 } else {
00570 cl->SetClassVersion(newid);
00571 }
00572 }
00573 }
00574 }
00575
00576
00577
00578 void ROOT::RemoveClass(const char *cname)
00579 {
00580
00581
00582
00583
00584
00585 if (cname) {
00586
00587
00588
00589
00590
00591 if (gROOT && gROOT->GetListOfClasses()) {
00592 TObject *pcname;
00593 if ((pcname=gROOT->GetListOfClasses()->FindObject(cname))) {
00594 TClass *cl = dynamic_cast<TClass*>(pcname);
00595 if (cl) cl->SetUnloaded();
00596 }
00597 }
00598 TClassTable::Remove(cname);
00599 }
00600 }
00601
00602
00603 TNamed *ROOT::RegisterClassTemplate(const char *name, const char *file,
00604 Int_t line)
00605 {
00606
00607
00608
00609 static TList table;
00610 static Bool_t isInit = kFALSE;
00611 if (!isInit) {
00612 table.SetOwner(kTRUE);
00613 isInit = kTRUE;
00614 }
00615
00616 TString classname(name);
00617 Ssiz_t loc = classname.Index("<");
00618 if (loc >= 1) classname.Remove(loc);
00619 if (file) {
00620 TNamed *obj = new TNamed((const char*)classname, file);
00621 obj->SetUniqueID(line);
00622 table.Add(obj);
00623 return obj;
00624 } else {
00625 return (TNamed*)table.FindObject(classname);
00626 }
00627 }