// @(#)root/cont:$Name: $:$Id: TClassTable.cxx,v 1.1.1.1 2000/05/16 17:00:40 rdm Exp $
// Author: Fons Rademakers 11/08/95
/*************************************************************************
* Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
//////////////////////////////////////////////////////////////////////////
// //
// This class registers for all classes their name, id and dictionary //
// function in a hash table. Classes are automatically added by the //
// ctor of a special init class when a global of this init class is //
// initialized when the program starts (see the ClassImp macro). //
// //
//////////////////////////////////////////////////////////////////////////
#include <stdlib.h>
#include "TClassTable.h"
#include "TClass.h"
#include "TROOT.h"
#include "TMath.h"
#include "TString.h"
#include "TError.h"
TClassTable *gClassTable;
ClassRec_t **TClassTable::fgTable;
ClassRec_t **TClassTable::fgSortedTable;
int TClassTable::fgSize;
int TClassTable::fgTally;
Bool_t TClassTable::fgSorted;
int TClassTable::fgCursor;
ClassImp(TClassTable)
//______________________________________________________________________________
TClassTable::TClassTable()
{
// TClassTable is a singleton (i.e. only one can exist per application).
if (gClassTable)
Error("TClassTable", "only one instance of TClassTable allowed");
fgSize = (int)TMath::NextPrime(1000);
fgTable = new ClassRec_t* [fgSize];
memset(fgTable, 0, fgSize*sizeof(ClassRec_t*));
}
//______________________________________________________________________________
TClassTable::~TClassTable()
{
// TClassTable singleton is deleted in Terminate().
}
//______________________________________________________________________________
void TClassTable::Print(Option_t *)
{
// Print the class table.
PrintTable();
}
//---- static members --------------------------------------------------------
//______________________________________________________________________________
int TClassTable::Classes() { return fgTally; }
//______________________________________________________________________________
void TClassTable::Init() { fgCursor = 0; SortTable(); }
//______________________________________________________________________________
void TClassTable::Add(const char *cname, Version_t id, VoidFuncPtr_t dict)
{
// Add a class to the class table (this is a static function).
if (!gClassTable)
gClassTable = new TClassTable;
// check if already in table, if so return
ClassRec_t *r = FindElement(cname, kTRUE);
if (r->name) {
::Warning("Add", "class %s allready in TClassTable", cname);
return;
}
r->name = StrDup(cname);
r->id = id;
r->dict = dict;
fgTally++;
fgSorted = kFALSE;
}
//______________________________________________________________________________
void TClassTable::Remove(const char *cname)
{
// Remove a class from the class table. This happens when a shared library
// is unloaded (i.e. the dtor's of the global init objects are called).
if (!gClassTable || !fgTable) return;
int slot = 0;
const char *p = cname;
while (*p) slot = slot<<1 ^ *p++;
if (slot < 0) slot = -slot;
slot %= fgSize;
ClassRec_t *r;
ClassRec_t *prev = 0;
for (r = fgTable[slot]; r; r = r->next) {
if (!strcmp(r->name, cname)) {
if (prev)
prev->next = r->next;
else
fgTable[slot] = r->next;
delete [] r->name;
delete r;
fgTally--;
fgSorted = kFALSE;
break;
}
prev = r;
}
}
//______________________________________________________________________________
ClassRec_t *TClassTable::FindElement(const char *cname, Bool_t insert)
{
// Find a class by name in the class table (using hash of name). Returns
// 0 if the class is not in the table. Unless arguments insert is true in
// which case a new entry is created and returned.
if (!fgTable) return 0;
int slot = 0;
const char *p = cname;
while (*p) slot = slot<<1 ^ *p++;
if (slot < 0) slot = -slot;
slot %= fgSize;
ClassRec_t *r;
for (r = fgTable[slot]; r; r = r->next)
if (!strcmp(r->name, cname)) return r;
if (!insert) return 0;
r = new ClassRec_t;
r->name = 0;
r->id = 0;
r->dict = 0;
r->next = fgTable[slot];
fgTable[slot] = r;
return r;
}
//______________________________________________________________________________
Version_t TClassTable::GetID(const char *cname)
{
// Returns the ID of a class.
ClassRec_t *r = FindElement(cname);
if (r) return r->id;
return -1;
}
//______________________________________________________________________________
VoidFuncPtr_t TClassTable::GetDict(const char *cname)
{
// Given the class name returns the Dictionary() function of a class
// (uses hash of name).
ClassRec_t *r = FindElement(cname);
if (r) return r->dict;
return 0;
}
//______________________________________________________________________________
static int ClassComp(const void *a, const void *b)
{
// Function used for sorting classes alphabetically.
return strcmp((*(ClassRec_t **)a)->name, (*(ClassRec_t **)b)->name);
}
//______________________________________________________________________________
char *TClassTable::Next()
{
// Returns next class from sorted class table.
if (fgCursor < fgTally) {
ClassRec_t *r = fgSortedTable[fgCursor++];
return r->name;
} else
return 0;
}
//______________________________________________________________________________
void TClassTable::PrintTable()
{
// Print the class table. Before printing the table is sorted
// alphabetically.
if (fgTally == 0 || !fgTable)
return;
SortTable();
int n = 0, ninit = 0;
Printf("");
Printf("Defined classes");
Printf("class version initialized");
Printf("=======================================================");
for (int i = 0; i < fgTally; i++) {
ClassRec_t *r = fgSortedTable[i];
n++;
if (gROOT->GetClass(r->name, kFALSE)) {
ninit++;
Printf("%-32s %7d Yes", r->name, r->id);
} else
Printf("%-32s %7d No", r->name, r->id);
}
Printf("-------------------------------------------------------");
Printf("Total classes: %4d initialized: %4d", n, ninit);
Printf("=======================================================");
Printf("");
}
//______________________________________________________________________________
void TClassTable::SortTable()
{
// Sort the class table by ascending class ID's.
if (!fgSorted) {
if (fgSortedTable) delete [] fgSortedTable;
fgSortedTable = new ClassRec_t* [fgTally];
int j = 0;
for (int i = 0; i < fgSize; i++)
for (ClassRec_t *r = fgTable[i]; r; r = r->next)
fgSortedTable[j++] = r;
::qsort(fgSortedTable, fgTally, sizeof(ClassRec_t *), &::ClassComp);
fgSorted = kTRUE;
}
}
//______________________________________________________________________________
void TClassTable::Terminate()
{
// Deletes the class table (this static class function calls the dtor).
if (gClassTable) {
for (int i = 0; i < fgSize; i++)
for (ClassRec_t *r = fgTable[i]; r; ) {
ClassRec_t *t = r;
r = r->next;
delete [] t->name;
delete t;
}
delete [] fgTable; fgTable = 0;
SafeDelete(gClassTable);
}
}
//______________________________________________________________________________
void AddClass(const char *cname, Version_t id, VoidFuncPtr_t dict)
{
// Global function called by the ctor of a class's init class
// (see the ClassImp macro).
TClassTable::Add(cname, id, dict);
}
//______________________________________________________________________________
void RemoveClass(const char *cname)
{
// Global function called by the dtor of a class's init class
// (see the ClassImp macro).
TClassTable::Remove(cname);
if (gROOT && gROOT->GetListOfClasses()) {
TClass *cl = gROOT->GetClass(cname, kFALSE);
delete cl; // interesting, for delete to call TClass::~TClass
} // Class.h needs to be included
}
ROOT page - Class index - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.