Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TGenericClassInfo.cxx
Go to the documentation of this file.
1 // @(#)root/meta:$Id$
2 // Author: Philippe Canal 08/05/2002
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2002, Rene Brun, Fons Rademakers and al. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "TROOT.h"
13 #include "TClass.h"
14 #include "TClassEdit.h"
15 #include "TVirtualStreamerInfo.h"
16 #include "TStreamer.h"
17 #include "TVirtualIsAProxy.h"
19 #include "TCollectionProxyInfo.h"
20 #include "TSchemaRule.h"
21 #include "TSchemaRuleSet.h"
22 #include "TError.h"
23 #include "TVirtualMutex.h"
24 #include "TInterpreter.h"
25 #include "TClassTable.h"
26 
27 namespace ROOT {
28 namespace Internal {
29 
30  std::string GetDemangledTypeName(const std::type_info &t)
31  {
32  int status = 0;
33  char *name = TClassEdit::DemangleName(t.name(), status);
34 
35  if (!name || status != 0)
36  return "";
37 
38  std::string ret;
39  TClassEdit::GetNormalizedName(ret, name);
40  free(name);
41  return ret;
42  }
43 
44  const TInitBehavior *DefineBehavior(void * /*parent_type*/,
45  void * /*actual_type*/)
46  {
47 
48  // This function loads the default behavior for the
49  // loading of classes.
50 
51  static TDefaultInitBehavior theDefault;
52  return &theDefault;
53  }
54 
55  void TCDGIILIBase::SetInstance(::ROOT::TGenericClassInfo& R__instance,
56  NewFunc_t New, NewArrFunc_t NewArray,
57  DelFunc_t Delete, DelArrFunc_t DeleteArray,
58  DesFunc_t Destruct) {
59  R__LOCKGUARD(gROOTMutex);
60  R__instance.SetNew(New);
61  R__instance.SetNewArray(NewArray);
62  R__instance.SetDelete(Delete);
63  R__instance.SetDeleteArray(DeleteArray);
64  R__instance.SetDestructor(Destruct);
65  R__instance.SetImplFile("", -1);
66  }
67 
68  void TCDGIILIBase::SetName(const std::string& name,
69  std::string& nameMember) {
70  R__LOCKGUARD(gInterpreterMutex);
71  if (nameMember.empty()) {
72  TClassEdit::GetNormalizedName(nameMember, name);
73  }
74  }
75 
76  void TCDGIILIBase::SetfgIsA(atomic_TClass_ptr& isA, TClass*(*dictfun)()) {
77  if (!isA.load()) {
78  R__LOCKGUARD(gInterpreterMutex);
79  dictfun();
80  }
81  }
82 } // Internal
83 
84 
85  TGenericClassInfo::TGenericClassInfo(const char *fullClassname,
86  const char *declFileName, Int_t declFileLine,
87  const std::type_info &info, const Internal::TInitBehavior *action,
88  DictFuncPtr_t dictionary,
89  TVirtualIsAProxy *isa, Int_t pragmabits, Int_t sizof)
90  : fAction(action), fClass(0), fClassName(fullClassname),
91  fDeclFileName(declFileName), fDeclFileLine(declFileLine),
92  fDictionary(dictionary), fInfo(info),
93  fImplFileName(0), fImplFileLine(0),
94  fIsA(isa),
95  fVersion(1),
96  fMerge(0),fResetAfterMerge(0),fNew(0),fNewArray(0),fDelete(0),fDeleteArray(0),fDestructor(0), fDirAutoAdd(0), fStreamer(0),
97  fStreamerFunc(0), fConvStreamerFunc(0), fCollectionProxy(0), fSizeof(sizof), fPragmaBits(pragmabits),
98  fCollectionProxyInfo(0), fCollectionStreamerInfo(0)
99  {
100  // Constructor.
101 
102  Init(pragmabits);
103  }
104 
105  TGenericClassInfo::TGenericClassInfo(const char *fullClassname, Int_t version,
106  const char *declFileName, Int_t declFileLine,
107  const std::type_info &info, const Internal::TInitBehavior *action,
108  DictFuncPtr_t dictionary,
109  TVirtualIsAProxy *isa, Int_t pragmabits, Int_t sizof)
110  : fAction(action), fClass(0), fClassName(fullClassname),
111  fDeclFileName(declFileName), fDeclFileLine(declFileLine),
112  fDictionary(dictionary), fInfo(info),
113  fImplFileName(0), fImplFileLine(0),
114  fIsA(isa),
115  fVersion(version),
116  fMerge(0),fResetAfterMerge(0),fNew(0),fNewArray(0),fDelete(0),fDeleteArray(0),fDestructor(0), fDirAutoAdd(0), fStreamer(0),
117  fStreamerFunc(0), fConvStreamerFunc(0), fCollectionProxy(0), fSizeof(sizof), fPragmaBits(pragmabits),
118  fCollectionProxyInfo(0), fCollectionStreamerInfo(0)
119 
120  {
121  // Constructor with version number and no showmembers.
122 
123  Init(pragmabits);
124  }
125 
126  class TForNamespace {}; // Dummy class to give a typeid to namespace (See also TClassTable.cc)
127 
128  TGenericClassInfo::TGenericClassInfo(const char *fullClassname, Int_t version,
129  const char *declFileName, Int_t declFileLine,
130  const Internal::TInitBehavior *action,
131  DictFuncPtr_t dictionary, Int_t pragmabits)
132  : fAction(action), fClass(0), fClassName(fullClassname),
133  fDeclFileName(declFileName), fDeclFileLine(declFileLine),
134  fDictionary(dictionary), fInfo(typeid(TForNamespace)),
135  fImplFileName(0), fImplFileLine(0),
136  fIsA(0),
137  fVersion(version),
138  fMerge(0),fResetAfterMerge(0),fNew(0),fNewArray(0),fDelete(0),fDeleteArray(0),fDestructor(0), fDirAutoAdd(0), fStreamer(0),
139  fStreamerFunc(0), fConvStreamerFunc(0), fCollectionProxy(0), fSizeof(0), fPragmaBits(pragmabits),
140  fCollectionProxyInfo(0), fCollectionStreamerInfo(0)
141 
142  {
143  // Constructor for namespace
144 
145  Init(pragmabits);
146  }
147 
148  /* TGenericClassInfo::TGenericClassInfo(const TGenericClassInfo& gci) :
149  fAction(gci.fAction),
150  fClass(gci.fClass),
151  fClassName(gci.fClassName),
152  fDeclFileName(gci.fDeclFileName),
153  fDeclFileLine(gci.fDeclFileLine),
154  fDictionary(gci.fDictionary),
155  fInfo(gci.fInfo),
156  fImplFileName(gci.fImplFileName),
157  fImplFileLine(gci.fImplFileLine),
158  fIsA(gci.fIsA),
159  fVersion(gci.fVersion),
160  fNew(gci.fNew),
161  fNewArray(gci.fNewArray),
162  fDelete(gci.fDelete),
163  fDeleteArray(gci.fDeleteArray),
164  fDestructor(gci.fDestructor),
165  fStreamer(gci.fStreamer),
166  fCollectionProxy(gci.fCollectionProxy),
167  fSizeof(gci.fSizeof)
168  { }
169 
170  TGenericClassInfo& TGenericClassInfo::operator=(const TGenericClassInfo& gci)
171  {
172  if(this!=&gci) {
173  fAction=gci.fAction;
174  fClass=gci.fClass;
175  fClassName=gci.fClassName;
176  fDeclFileName=gci.fDeclFileName;
177  fDeclFileLine=gci.fDeclFileLine;
178  fDictionary=gci.fDictionary;
179  fInfo=gci.fInfo;
180  fImplFileName=gci.fImplFileName;
181  fImplFileLine=gci.fImplFileLine;
182  fIsA=gci.fIsA;
183  fVersion=gci.fVersion;
184  fNew=gci.fNew;
185  fNewArray=gci.fNewArray;
186  fDelete=gci.fDelete;
187  fDeleteArray=gci.fDeleteArray;
188  fDestructor=gci.fDestructor;
189  fStreamer=gci.fStreamer;
190  fCollectionProxy=gci.fCollectionProxy;
191  fSizeof=gci.fSizeof;
192  } return *this;
193  }
194  */
195 
196  void TGenericClassInfo::Init(Int_t pragmabits)
197  {
198  // Initilization routine.
199 
200  //TVirtualStreamerInfo::Class_Version MUST be the same as TStreamerInfo::Class_Version
201  if (fVersion==-2) fVersion = TVirtualStreamerInfo::Class_Version();
202  if (!fAction) return;
203  GetAction().Register(fClassName,
204  fVersion,
205  fInfo, // typeid(RootClass),
206  fDictionary,
207  pragmabits);
208  }
209 
210  TGenericClassInfo::~TGenericClassInfo()
211  {
212  // Destructor.
213 
214  delete fCollectionProxyInfo;
215  delete fCollectionStreamerInfo;
216  delete fStreamer;
217  if (!fClass) delete fIsA; // fIsA is adopted by the class if any.
218  fIsA = 0;
219  using ROOT::Internal::gROOTLocal;
220  if (!gROOTLocal || !gROOTLocal->Initialized() || !gROOTLocal->GetListOfClasses()) return;
221  if (fAction) GetAction().Unregister(GetClassName());
222  }
223 
224  const Internal::TInitBehavior &TGenericClassInfo::GetAction() const
225  {
226  // Return the creator action.
227 
228  return *fAction;
229  }
230 
231  TClass *TGenericClassInfo::GetClass()
232  {
233  // Generate and return the TClass object.
234 
235  // First make sure that TROOT is initialized, do this before checking
236  // for fClass. If the request is for the TClass of TObject and TROOT
237  // is not initialized, the TROOT creation (because of the ROOT pcm files)
238  // will lead to its own request of the TClass for TObject and thus
239  // upon returning, the TClass for TObject will have already been created
240  // and fClass will have been set.
241  if (!gROOT)
242  ::Fatal("TClass::TClass", "ROOT system not initialized");
243 
244  if (!fClass && fAction) {
245  R__LOCKGUARD(gInterpreterMutex);
246  // Check again, while we waited for the lock, something else might
247  // have set fClass.
248  if (fClass) return fClass;
249 
250  fClass = GetAction().CreateClass(GetClassName(),
251  GetVersion(),
252  GetInfo(),
253  GetIsA(),
254  GetDeclFileName(),
255  GetImplFileName(),
256  GetDeclFileLine(),
257  GetImplFileLine());
258  if (fPragmaBits & TClassTable::kHasCustomStreamerMember) {
259  fClass->SetBit(TClass::kHasCustomStreamerMember);
260  }
261  fClass->SetNew(fNew);
262  fClass->SetNewArray(fNewArray);
263  fClass->SetDelete(fDelete);
264  fClass->SetDeleteArray(fDeleteArray);
265  fClass->SetDestructor(fDestructor);
266  fClass->SetDirectoryAutoAdd(fDirAutoAdd);
267  fClass->SetStreamerFunc(fStreamerFunc);
268  fClass->SetConvStreamerFunc(fConvStreamerFunc);
269  fClass->SetMerge(fMerge);
270  fClass->SetResetAfterMerge(fResetAfterMerge);
271  fClass->AdoptStreamer(fStreamer); fStreamer = 0;
272  // If IsZombie is true, something went wrong and we will not be
273  // able to properly copy the collection proxy
274  if (!fClass->IsZombie()) {
275  if (fCollectionProxy) fClass->CopyCollectionProxy(*fCollectionProxy);
276  else if (fCollectionProxyInfo) {
277  fClass->SetCollectionProxy(*fCollectionProxyInfo);
278  }
279  }
280  fClass->SetClassSize(fSizeof);
281 
282  //---------------------------------------------------------------------
283  // Attach the schema evolution information
284  ///////////////////////////////////////////////////////////////////////
285 
286  CreateRuleSet( fReadRules, true );
287  CreateRuleSet( fReadRawRules, false );
288  }
289  return fClass;
290  }
291 
292  /////////////////////////////////////////////////////////////////////////////
293  /// Attach the schema evolution information to TClassObject
294 
295  void TGenericClassInfo::CreateRuleSet( std::vector<Internal::TSchemaHelper>& vect,
296  Bool_t ProcessReadRules )
297  {
298  if ( vect.empty() ) {
299  return;
300  }
301 
302  //------------------------------------------------------------------------
303  // Get the rules set
304  //////////////////////////////////////////////////////////////////////////
305 
306  TSchemaRuleSet* rset = fClass->GetSchemaRules( kTRUE );
307 
308  //------------------------------------------------------------------------
309  // Process the rules
310  //////////////////////////////////////////////////////////////////////////
311 
312  TSchemaRule* rule;
313  TString errmsg;
314  std::vector<Internal::TSchemaHelper>::iterator it;
315  for( it = vect.begin(); it != vect.end(); ++it ) {
316  rule = new TSchemaRule();
317  rule->SetTarget( it->fTarget );
318  rule->SetTargetClass( fClass->GetName() );
319  rule->SetSourceClass( it->fSourceClass );
320  rule->SetSource( it->fSource );
321  rule->SetCode( it->fCode );
322  rule->SetVersion( it->fVersion );
323  rule->SetChecksum( it->fChecksum );
324  rule->SetEmbed( it->fEmbed );
325  rule->SetInclude( it->fInclude );
326  rule->SetAttributes( it->fAttributes );
327 
328  if( ProcessReadRules ) {
329  rule->SetRuleType( TSchemaRule::kReadRule );
330  rule->SetReadFunctionPointer( (TSchemaRule::ReadFuncPtr_t)it->fFunctionPtr );
331  }
332  else {
333  rule->SetRuleType( TSchemaRule::kReadRawRule );
334  rule->SetReadRawFunctionPointer( (TSchemaRule::ReadRawFuncPtr_t)it->fFunctionPtr );
335  }
336  if( !rset->AddRule( rule, TSchemaRuleSet::kCheckAll, &errmsg ) ) {
337  ::Warning( "TGenericClassInfo", "The rule for class: \"%s\": version, \"%s\" and data members: \"%s\" has been skipped because %s.",
338  GetClassName(), it->fVersion.c_str(), it->fTarget.c_str(), errmsg.Data() );
339  delete rule;
340  }
341  }
342  }
343 
344  const char *TGenericClassInfo::GetClassName() const
345  {
346  // Return the class name
347 
348  return fClassName;
349  }
350 
351 
352  Detail::TCollectionProxyInfo *TGenericClassInfo::GetCollectionProxyInfo() const
353  {
354  // Return the set of info we have for the CollectionProxy, if any
355 
356  return fCollectionProxyInfo;
357  }
358 
359  Detail::TCollectionProxyInfo *TGenericClassInfo::GetCollectionStreamerInfo() const
360  {
361  // Return the set of info we have for the Collection Streamer, if any
362 
363  return fCollectionProxyInfo;
364  }
365 
366  const std::type_info &TGenericClassInfo::GetInfo() const
367  {
368  // Return the typeinfo value
369 
370  return fInfo;
371  }
372 
373  const std::vector<Internal::TSchemaHelper>& TGenericClassInfo::GetReadRawRules() const
374  {
375  // Return the list of rule give raw access to the TBuffer.
376 
377  return fReadRawRules;
378  }
379 
380 
381  const std::vector<Internal::TSchemaHelper>& TGenericClassInfo::GetReadRules() const
382  {
383  // Return the list of Data Model Evolution regular read rules.
384  return fReadRules;
385  }
386 
387  void TGenericClassInfo::SetFromTemplate()
388  {
389  // Import the information from the class template.
390 
391  TNamed *info = ROOT::RegisterClassTemplate(GetClassName(), 0, 0);
392  if (info) SetImplFile(info->GetTitle(), info->GetUniqueID());
393  }
394 
395  Int_t TGenericClassInfo::SetImplFile(const char *file, Int_t line)
396  {
397  // Set the name of the implementation file.
398 
399  fImplFileName = file;
400  fImplFileLine = line;
401  if (fClass) fClass->AddImplFile(file,line);
402  return 0;
403  }
404 
405  Int_t TGenericClassInfo::SetDeclFile(const char *file, Int_t line)
406  {
407  // Set the name of the declaration file.
408 
409  fDeclFileName = file;
410  fDeclFileLine = line;
411  if (fClass) fClass->SetDeclFile(file,line);
412  return 0;
413  }
414 
415  Short_t TGenericClassInfo::SetVersion(Short_t version)
416  {
417  // Set a class version number.
418 
419  ROOT::ResetClassVersion(fClass, GetClassName(),version);
420  fVersion = version;
421  return version;
422  }
423 
424  void TGenericClassInfo::AdoptCollectionProxyInfo(TCollectionProxyInfo *info)
425  {
426  // Set the info for the CollectionProxy and take ownership of the object
427  // being passed
428 
429  delete fCollectionProxyInfo;;
430  fCollectionProxyInfo = info;
431  }
432 
433  void TGenericClassInfo::AdoptCollectionStreamerInfo(TCollectionProxyInfo *info)
434  {
435  // Set the info for the Collection Streamer and take ownership of the object
436  // being passed
437 
438  delete fCollectionStreamerInfo;
439  fCollectionStreamerInfo = info;
440  }
441 
442  Short_t TGenericClassInfo::AdoptStreamer(TClassStreamer *streamer)
443  {
444  // Set a Streamer object. The streamer object is now 'owned'
445  // by the TGenericClassInfo.
446 
447  delete fStreamer; fStreamer = 0;
448  if (fClass) {
449  fClass->AdoptStreamer(streamer);
450  } else {
451  fStreamer = streamer;
452  }
453  return 0;
454  }
455 
456  Short_t TGenericClassInfo::AdoptCollectionProxy(TVirtualCollectionProxy *collProxy)
457  {
458  // Set the CollectProxy object. The CollectionProxy object is now 'owned'
459  // by the TGenericClassInfo.
460 
461  delete fCollectionProxy; fCollectionProxy = 0;
462  fCollectionProxy = collProxy;
463  if (fClass && fCollectionProxy && !fClass->IsZombie()) {
464  fClass->CopyCollectionProxy(*fCollectionProxy);
465  }
466  return 0;
467  }
468 
469  void TGenericClassInfo::SetReadRawRules( const std::vector<Internal::TSchemaHelper>& rules )
470  {
471  // Set the list of Data Model Evolution read rules giving direct access to the TBuffer.
472  fReadRawRules = rules;
473  }
474 
475 
476  void TGenericClassInfo::SetReadRules( const std::vector<Internal::TSchemaHelper>& rules )
477  {
478  // Set the list of Data Model Evolution regular read rules.
479  fReadRules = rules;
480  }
481 
482  Short_t TGenericClassInfo::SetStreamer(ClassStreamerFunc_t streamer)
483  {
484  // Set a External Streamer function.
485 
486  delete fStreamer; fStreamer = 0;
487  if (fClass) {
488  fClass->AdoptStreamer(new TClassStreamer(streamer));
489  } else {
490  fStreamer = new TClassStreamer(streamer);
491  }
492  return 0;
493  }
494 
495  void TGenericClassInfo::SetStreamerFunc(ClassStreamerFunc_t streamer)
496  {
497  // Set a wrapper around the Streamer member function.
498 
499  fStreamerFunc = streamer;
500  if (fClass) fClass->SetStreamerFunc(streamer);
501  }
502 
503  void TGenericClassInfo::SetConvStreamerFunc(ClassConvStreamerFunc_t streamer)
504  {
505  // Set a wrapper around the Streamer member function.
506 
507  fConvStreamerFunc = streamer;
508  if (fClass) fClass->SetConvStreamerFunc(streamer);
509  }
510 
511  const char *TGenericClassInfo::GetDeclFileName() const
512  {
513  // Get the name of the declaring header file.
514 
515  return fDeclFileName;
516  }
517 
518  Int_t TGenericClassInfo::GetDeclFileLine() const
519  {
520  // Get the declaring line number.
521 
522  return fDeclFileLine;
523  }
524 
525  const char *TGenericClassInfo::GetImplFileName()
526  {
527  // Get the implementation filename.
528 
529  if (!fImplFileName) SetFromTemplate();
530  return fImplFileName;
531  }
532 
533  Int_t TGenericClassInfo::GetImplFileLine()
534  {
535  // Get the ClassImp line number.
536 
537  if (!fImplFileLine) SetFromTemplate();
538  return fImplFileLine;
539  }
540 
541  Int_t TGenericClassInfo::GetVersion() const
542  {
543  // Return the class version number.
544 
545  return fVersion;
546  }
547 
548  TClass *TGenericClassInfo::IsA(const void *obj)
549  {
550  // Return the actual type of the object.
551 
552  return (*GetIsA())(obj);
553  }
554 
555  TVirtualIsAProxy* TGenericClassInfo::GetIsA() const
556  {
557  // Return the IsA proxy.
558 
559  return fIsA;
560  }
561 
562  void TGenericClassInfo::SetNew(NewFunc_t newFunc)
563  {
564  // Install a new wrapper around 'new'.
565 
566  fNew = newFunc;
567  if (fClass) fClass->SetNew(fNew);
568  }
569 
570  void TGenericClassInfo::SetNewArray(NewArrFunc_t newArrayFunc)
571  {
572  // Install a new wrapper around 'new []'.
573 
574  fNewArray = newArrayFunc;
575  if (fClass) fClass->SetNewArray(fNewArray);
576  }
577 
578  void TGenericClassInfo::SetDelete(DelFunc_t deleteFunc)
579  {
580  // Install a new wrapper around 'delete'.
581 
582  fDelete = deleteFunc;
583  if (fClass) fClass->SetDelete(fDelete);
584  }
585 
586  void TGenericClassInfo::SetDeleteArray(DelArrFunc_t deleteArrayFunc)
587  {
588  // Install a new wrapper around 'delete []'.
589 
590  fDeleteArray = deleteArrayFunc;
591  if (fClass) fClass->SetDeleteArray(fDeleteArray);
592  }
593 
594  void TGenericClassInfo::SetDestructor(DesFunc_t destructorFunc)
595  {
596  // Install a new wrapper around the destructor.
597 
598  fDestructor = destructorFunc;
599  if (fClass) fClass->SetDestructor(fDestructor);
600  }
601 
602  void TGenericClassInfo::SetDirectoryAutoAdd(DirAutoAdd_t func)
603  {
604  // Install a new wrapper around SetDirectoryAutoAdd.
605 
606  fDirAutoAdd = func;
607  if (fClass) fClass->SetDirectoryAutoAdd(fDirAutoAdd);
608  }
609 
610  void TGenericClassInfo::SetMerge(MergeFunc_t func)
611  {
612  // Install a new wrapper around the Merge function.
613 
614  fMerge = func;
615  if (fClass) fClass->SetMerge(fMerge);
616  }
617 
618  void TGenericClassInfo::SetResetAfterMerge(ResetAfterMergeFunc_t func)
619  {
620  // Install a new wrapper around the Merge function.
621 
622  fResetAfterMerge = func;
623  if (fClass) fClass->SetResetAfterMerge(fResetAfterMerge);
624  }
625 
626  NewFunc_t TGenericClassInfo::GetNew() const
627  {
628  // Get the wrapper around 'new'.
629 
630  return fNew;
631  }
632 
633  NewArrFunc_t TGenericClassInfo::GetNewArray() const
634  {
635  // Get the wrapper around 'new []'.
636 
637  return fNewArray;
638  }
639 
640  DelFunc_t TGenericClassInfo::GetDelete() const
641  {
642  // Get the wrapper around 'delete'.
643 
644  return fDelete;
645  }
646 
647  DelArrFunc_t TGenericClassInfo::GetDeleteArray() const
648  {
649  // Get the wrapper around 'delete []'.
650 
651  return fDeleteArray;
652  }
653 
654  DesFunc_t TGenericClassInfo::GetDestructor() const
655  {
656  // Get the wrapper around the destructor.
657 
658  return fDestructor;
659  }
660 
661  DirAutoAdd_t TGenericClassInfo::GetDirectoryAutoAdd() const
662  {
663  // Get the wrapper around the directory-auto-add function .
664 
665  return fDirAutoAdd;
666  }
667 
668 }