// @(#)root/meta:$Id$ // Author: Philippe Canal 08/05/2002 /************************************************************************* * Copyright (C) 1995-2002, Rene Brun, Fons Rademakers and al. * * All rights reserved. * * * * For the licensing terms see $ROOTSYS/LICENSE. * * For the list of contributors see $ROOTSYS/README/CREDITS. * *************************************************************************/ #include "TROOT.h" #include "TClass.h" #include "TVirtualStreamerInfo.h" #include "TStreamer.h" #include "TVirtualIsAProxy.h" #include "TVirtualCollectionProxy.h" #include "TCollectionProxyInfo.h" #include "TSchemaRule.h" #include "TSchemaRuleSet.h" #include "TError.h" #include "TVirtualMutex.h" #include "TInterpreter.h" namespace ROOT { const TInitBehavior *DefineBehavior(void * /*parent_type*/, void * /*actual_type*/) { // This function loads the default behavior for the // loading of classes. static TDefaultInitBehavior theDefault; return &theDefault; } TGenericClassInfo::TGenericClassInfo(const char *fullClassname, const char *declFileName, Int_t declFileLine, const type_info &info, const TInitBehavior *action, ShowMembersFunc_t showmembers, VoidFuncPtr_t dictionary, TVirtualIsAProxy *isa, Int_t pragmabits, Int_t sizof) : fAction(action), fClass(0), fClassName(fullClassname), fDeclFileName(declFileName), fDeclFileLine(declFileLine), fDictionary(dictionary), fInfo(info), fImplFileName(0), fImplFileLine(0), fIsA(isa), fShowMembers(showmembers), fVersion(1), fMerge(0),fResetAfterMerge(0),fNew(0),fNewArray(0),fDelete(0),fDeleteArray(0),fDestructor(0), fDirAutoAdd(0), fStreamer(0), fStreamerFunc(0), fCollectionProxy(0), fSizeof(sizof), fCollectionProxyInfo(0), fCollectionStreamerInfo(0) { // Constructor. Init(pragmabits); } TGenericClassInfo::TGenericClassInfo(const char *fullClassname, Int_t version, const char *declFileName, Int_t declFileLine, const type_info &info, const TInitBehavior *action, ShowMembersFunc_t showmembers, VoidFuncPtr_t dictionary, TVirtualIsAProxy *isa, Int_t pragmabits, Int_t sizof) : fAction(action), fClass(0), fClassName(fullClassname), fDeclFileName(declFileName), fDeclFileLine(declFileLine), fDictionary(dictionary), fInfo(info), fImplFileName(0), fImplFileLine(0), fIsA(isa), fShowMembers(showmembers), fVersion(version), fMerge(0),fResetAfterMerge(0),fNew(0),fNewArray(0),fDelete(0),fDeleteArray(0),fDestructor(0), fDirAutoAdd(0), fStreamer(0), fStreamerFunc(0), fCollectionProxy(0), fSizeof(sizof), fCollectionProxyInfo(0), fCollectionStreamerInfo(0) { // Constructor with version number. Init(pragmabits); } TGenericClassInfo::TGenericClassInfo(const char *fullClassname, Int_t version, const char *declFileName, Int_t declFileLine, const type_info &info, const TInitBehavior *action, VoidFuncPtr_t dictionary, TVirtualIsAProxy *isa, Int_t pragmabits, Int_t sizof) : fAction(action), fClass(0), fClassName(fullClassname), fDeclFileName(declFileName), fDeclFileLine(declFileLine), fDictionary(dictionary), fInfo(info), fImplFileName(0), fImplFileLine(0), fIsA(isa), fShowMembers(0), fVersion(version), fMerge(0),fResetAfterMerge(0),fNew(0),fNewArray(0),fDelete(0),fDeleteArray(0),fDestructor(0), fDirAutoAdd(0), fStreamer(0), fStreamerFunc(0), fCollectionProxy(0), fSizeof(sizof), fCollectionProxyInfo(0), fCollectionStreamerInfo(0) { // Constructor with version number and no showmembers. Init(pragmabits); } class TForNamespace {}; // Dummy class to give a typeid to namespace (See also TClassTable.cc) TGenericClassInfo::TGenericClassInfo(const char *fullClassname, Int_t version, const char *declFileName, Int_t declFileLine, const TInitBehavior *action, VoidFuncPtr_t dictionary, Int_t pragmabits) : fAction(action), fClass(0), fClassName(fullClassname), fDeclFileName(declFileName), fDeclFileLine(declFileLine), fDictionary(dictionary), fInfo(typeid(TForNamespace)), fImplFileName(0), fImplFileLine(0), fIsA(0), fShowMembers(0), fVersion(version), fMerge(0),fResetAfterMerge(0),fNew(0),fNewArray(0),fDelete(0),fDeleteArray(0),fDestructor(0), fDirAutoAdd(0), fStreamer(0), fStreamerFunc(0), fCollectionProxy(0), fSizeof(0), fCollectionProxyInfo(0), fCollectionStreamerInfo(0) { // Constructor for namespace Init(pragmabits); } /* TGenericClassInfo::TGenericClassInfo(const TGenericClassInfo& gci) : fAction(gci.fAction), fClass(gci.fClass), fClassName(gci.fClassName), fDeclFileName(gci.fDeclFileName), fDeclFileLine(gci.fDeclFileLine), fDictionary(gci.fDictionary), fInfo(gci.fInfo), fImplFileName(gci.fImplFileName), fImplFileLine(gci.fImplFileLine), fIsA(gci.fIsA), fShowMembers(gci.fShowMembers), fVersion(gci.fVersion), fNew(gci.fNew), fNewArray(gci.fNewArray), fDelete(gci.fDelete), fDeleteArray(gci.fDeleteArray), fDestructor(gci.fDestructor), fStreamer(gci.fStreamer), fCollectionProxy(gci.fCollectionProxy), fSizeof(gci.fSizeof) { } TGenericClassInfo& TGenericClassInfo::operator=(const TGenericClassInfo& gci) { if(this!=&gci) { fAction=gci.fAction; fClass=gci.fClass; fClassName=gci.fClassName; fDeclFileName=gci.fDeclFileName; fDeclFileLine=gci.fDeclFileLine; fDictionary=gci.fDictionary; fInfo=gci.fInfo; fImplFileName=gci.fImplFileName; fImplFileLine=gci.fImplFileLine; fIsA=gci.fIsA; fShowMembers=gci.fShowMembers; fVersion=gci.fVersion; fNew=gci.fNew; fNewArray=gci.fNewArray; fDelete=gci.fDelete; fDeleteArray=gci.fDeleteArray; fDestructor=gci.fDestructor; fStreamer=gci.fStreamer; fCollectionProxy=gci.fCollectionProxy; fSizeof=gci.fSizeof; } return *this; } */ void TGenericClassInfo::Init(Int_t pragmabits) { // Initilization routine. //TVirtualStreamerInfo::Class_Version MUST be the same as TStreamerInfo::Class_Version if (fVersion==-2) fVersion = TVirtualStreamerInfo::Class_Version(); if (!fAction) return; GetAction().Register(fClassName, fVersion, fInfo, // typeid(RootClass), fDictionary, pragmabits); } TGenericClassInfo::~TGenericClassInfo() { // Destructor. delete fCollectionProxyInfo; delete fCollectionStreamerInfo; delete fStreamer; if (!fClass) delete fIsA; // fIsA is adopted by the class if any. fIsA = 0; if (!gROOT || !gROOT->GetListOfClasses()) return; if (fAction) GetAction().Unregister(GetClassName()); } const TInitBehavior &TGenericClassInfo::GetAction() const { // Return the creator action. return *fAction; } TClass *TGenericClassInfo::GetClass() { // Generate and return the TClass object. if (!fClass && fAction) { R__LOCKGUARD2(gCINTMutex); fClass = GetAction().CreateClass(GetClassName(), GetVersion(), GetInfo(), GetIsA(), GetShowMembers(), GetDeclFileName(), GetImplFileName(), GetDeclFileLine(), GetImplFileLine()); fClass->SetNew(fNew); fClass->SetNewArray(fNewArray); fClass->SetDelete(fDelete); fClass->SetDeleteArray(fDeleteArray); fClass->SetDestructor(fDestructor); fClass->SetDirectoryAutoAdd(fDirAutoAdd); fClass->SetStreamerFunc(fStreamerFunc); fClass->SetMerge(fMerge); fClass->SetResetAfterMerge(fResetAfterMerge); fClass->AdoptStreamer(fStreamer); fStreamer = 0; // If IsZombie is true, something went wront and we will not be // able to properly copy the collection proxy if (!fClass->IsZombie()) { if (fCollectionProxy) fClass->CopyCollectionProxy(*fCollectionProxy); else if (fCollectionProxyInfo) { fClass->SetCollectionProxy(*fCollectionProxyInfo); } } fClass->SetClassSize(fSizeof); //--------------------------------------------------------------------- // Attach the schema evolution information //--------------------------------------------------------------------- CreateRuleSet( fReadRules, true ); CreateRuleSet( fReadRawRules, false ); } return fClass; } //--------------------------------------------------------------------------- void TGenericClassInfo::CreateRuleSet( std::vector& vect, Bool_t ProcessReadRules ) { // Attach the schema evolution information to TClassObject if ( vect.empty() ) { return; } //------------------------------------------------------------------------ // Get the rules set //------------------------------------------------------------------------ TSchemaRuleSet* rset = fClass->GetSchemaRules( kTRUE ); //------------------------------------------------------------------------ // Process the rules //------------------------------------------------------------------------ TSchemaRule* rule; TString errmsg; std::vector::iterator it; for( it = vect.begin(); it != vect.end(); ++it ) { rule = new TSchemaRule(); rule->SetTarget( it->fTarget ); rule->SetTargetClass( fClass->GetName() ); rule->SetSourceClass( it->fSourceClass ); rule->SetSource( it->fSource ); rule->SetCode( it->fCode ); rule->SetVersion( it->fVersion ); rule->SetChecksum( it->fChecksum ); rule->SetEmbed( it->fEmbed ); rule->SetInclude( it->fInclude ); rule->SetAttributes( it->fAttributes ); if( ProcessReadRules ) { rule->SetRuleType( TSchemaRule::kReadRule ); rule->SetReadFunctionPointer( (TSchemaRule::ReadFuncPtr_t)it->fFunctionPtr ); } else { rule->SetRuleType( TSchemaRule::kReadRawRule ); rule->SetReadRawFunctionPointer( (TSchemaRule::ReadRawFuncPtr_t)it->fFunctionPtr ); } if( !rset->AddRule( rule, TSchemaRuleSet::kCheckAll, &errmsg ) ) { ::Warning( "TGenericClassInfo", "The rule for class: \"%s\": version, \"%s\" and data members: \"%s\" has been skipped because %s.", GetClassName(), it->fVersion.c_str(), it->fTarget.c_str(), errmsg.Data() ); delete rule; } } } const char *TGenericClassInfo::GetClassName() const { // Return the class name return fClassName; } TCollectionProxyInfo *TGenericClassInfo::GetCollectionProxyInfo() const { // Return the set of info we have for the CollectionProxy, if any return fCollectionProxyInfo; } TCollectionProxyInfo *TGenericClassInfo::GetCollectionStreamerInfo() const { // Return the set of info we have for the Collection Streamer, if any return fCollectionProxyInfo; } const type_info &TGenericClassInfo::GetInfo() const { // Return the typeifno value return fInfo; } const std::vector& TGenericClassInfo::GetReadRawRules() const { // Return the list of rule give raw access to the TBuffer. return fReadRawRules; } const std::vector& TGenericClassInfo::GetReadRules() const { // Return the list of Data Model Evolution regular read rules. return fReadRules; } ShowMembersFunc_t TGenericClassInfo::GetShowMembers() const { // Return the point of the ShowMembers function return fShowMembers; } void TGenericClassInfo::SetFromTemplate() { // Import the information from the class template. TNamed *info = ROOT::RegisterClassTemplate(GetClassName(), 0, 0); if (info) SetImplFile(info->GetTitle(), info->GetUniqueID()); } Int_t TGenericClassInfo::SetImplFile(const char *file, Int_t line) { // Set the name of the implementation file. fImplFileName = file; fImplFileLine = line; if (fClass) fClass->AddImplFile(file,line); return 0; } Int_t TGenericClassInfo::SetDeclFile(const char *file, Int_t line) { // Set the name of the declaration file. fDeclFileName = file; fDeclFileLine = line; if (fClass) fClass->SetDeclFile(file,line); return 0; } Short_t TGenericClassInfo::SetVersion(Short_t version) { // Set a class version number. ROOT::ResetClassVersion(fClass, GetClassName(),version); fVersion = version; return version; } void TGenericClassInfo::AdoptCollectionProxyInfo(TCollectionProxyInfo *info) { // Set the info for the CollectionProxy and take ownership of the object // being passed delete fCollectionProxyInfo;; fCollectionProxyInfo = info; } void TGenericClassInfo::AdoptCollectionStreamerInfo(TCollectionProxyInfo *info) { // Set the info for the Collection Streamer and take ownership of the object // being passed delete fCollectionStreamerInfo; fCollectionStreamerInfo = info; } Short_t TGenericClassInfo::AdoptStreamer(TClassStreamer *streamer) { // Set a Streamer object. The streamer object is now 'owned' // by the TGenericClassInfo. delete fStreamer; fStreamer = 0; if (fClass) { fClass->AdoptStreamer(streamer); } else { fStreamer = streamer; } return 0; } Short_t TGenericClassInfo::AdoptCollectionProxy(TVirtualCollectionProxy *collProxy) { // Set the CollectProxy object. The CollectionProxy object is now 'owned' // by the TGenericClassInfo. delete fCollectionProxy; fCollectionProxy = 0; fCollectionProxy = collProxy; if (fClass && fCollectionProxy && !fClass->IsZombie()) { fClass->CopyCollectionProxy(*fCollectionProxy); } return 0; } void TGenericClassInfo::SetReadRawRules( const std::vector& rules ) { // Set the list of Data Model Evolution read rules giving direct access to the TBuffer. fReadRawRules = rules; } void TGenericClassInfo::SetReadRules( const std::vector& rules ) { // Set the list of Data Model Evolution regular read rules. fReadRules = rules; } Short_t TGenericClassInfo::SetStreamer(ClassStreamerFunc_t streamer) { // Set a External Streamer function. delete fStreamer; fStreamer = 0; if (fClass) { fClass->AdoptStreamer(new TClassStreamer(streamer)); } else { fStreamer = new TClassStreamer(streamer); } return 0; } void TGenericClassInfo::SetStreamerFunc(ClassStreamerFunc_t streamer) { // Set a wrapper around the Streamer memger function. fStreamerFunc = streamer; if (fClass) fClass->SetStreamerFunc(streamer); } const char *TGenericClassInfo::GetDeclFileName() const { // Get the name of the declaring header file. return fDeclFileName; } Int_t TGenericClassInfo::GetDeclFileLine() const { // Get the declaring line number. return fDeclFileLine; } const char *TGenericClassInfo::GetImplFileName() { // Get the implementation filename. if (!fImplFileName) SetFromTemplate(); return fImplFileName; } Int_t TGenericClassInfo::GetImplFileLine() { // Get the ClassImp line number. if (!fImplFileLine) SetFromTemplate(); return fImplFileLine; } Int_t TGenericClassInfo::GetVersion() const { // Return the class version number. return fVersion; } TClass *TGenericClassInfo::IsA(const void *obj) { // Return the actual type of the object. return (*GetIsA())(obj); } TVirtualIsAProxy* TGenericClassInfo::GetIsA() const { // Return the IsA proxy. return fIsA; } void TGenericClassInfo::SetNew(NewFunc_t newFunc) { // Install a new wrapper around 'new'. fNew = newFunc; if (fClass) fClass->SetNew(fNew); } void TGenericClassInfo::SetNewArray(NewArrFunc_t newArrayFunc) { // Install a new wrapper around 'new []'. fNewArray = newArrayFunc; if (fClass) fClass->SetNewArray(fNewArray); } void TGenericClassInfo::SetDelete(DelFunc_t deleteFunc) { // Install a new wrapper around 'delete'. fDelete = deleteFunc; if (fClass) fClass->SetDelete(fDelete); } void TGenericClassInfo::SetDeleteArray(DelArrFunc_t deleteArrayFunc) { // Install a new wrapper around 'delete []'. fDeleteArray = deleteArrayFunc; if (fClass) fClass->SetDeleteArray(fDeleteArray); } void TGenericClassInfo::SetDestructor(DesFunc_t destructorFunc) { // Install a new wrapper around the destructor. fDestructor = destructorFunc; if (fClass) fClass->SetDestructor(fDestructor); } void TGenericClassInfo::SetDirectoryAutoAdd(DirAutoAdd_t func) { // Install a new wrapper around SetDirectoryAutoAdd. fDirAutoAdd = func; if (fClass) fClass->SetDirectoryAutoAdd(fDirAutoAdd); } void TGenericClassInfo::SetMerge(MergeFunc_t func) { // Install a new wrapper around the Merge function. fMerge = func; if (fClass) fClass->SetMerge(fMerge); } void TGenericClassInfo::SetResetAfterMerge(ResetAfterMergeFunc_t func) { // Install a new wrapper around the Merge function. fResetAfterMerge = func; if (fClass) fClass->SetResetAfterMerge(fResetAfterMerge); } NewFunc_t TGenericClassInfo::GetNew() const { // Get the wrapper around 'new'. return fNew; } NewArrFunc_t TGenericClassInfo::GetNewArray() const { // Get the wrapper around 'new []'. return fNewArray; } DelFunc_t TGenericClassInfo::GetDelete() const { // Get the wrapper around 'delete'. return fDelete; } DelArrFunc_t TGenericClassInfo::GetDeleteArray() const { // Get the wrapper around 'delete []'. return fDeleteArray; } DesFunc_t TGenericClassInfo::GetDestructor() const { // Get the wrapper around the destructor. return fDestructor; } DirAutoAdd_t TGenericClassInfo::GetDirectoryAutoAdd() const { // Get the wrapper around the directory-auto-add function . return fDirAutoAdd; } }