Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TVirtualStreamerInfo.cxx
Go to the documentation of this file.
1 // @(#)root/base:$Id$
2 // Author: Rene Brun 05/02/2007
3 /*************************************************************************
4  * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. *
5  * All rights reserved. *
6  * *
7  * For the licensing terms see $ROOTSYS/LICENSE. *
8  * For the list of contributors see $ROOTSYS/README/CREDITS. *
9  *************************************************************************/
10 
11 /** \class TVirtualStreamerInfo
12 Abstract Interface class describing Streamer information for one class.
13 */
14 
15 #include "TROOT.h"
16 #include "TSystem.h"
17 #include "TClass.h"
18 #include "TVirtualMutex.h"
19 #include "TInterpreter.h"
20 #include "TVirtualStreamerInfo.h"
21 #include "TPluginManager.h"
22 #include "TStreamerElement.h"
23 #include "TError.h"
24 
25 
26 TVirtualStreamerInfo *TVirtualStreamerInfo::fgInfoFactory = 0;
27 
28 Bool_t TVirtualStreamerInfo::fgCanDelete = kTRUE;
29 Bool_t TVirtualStreamerInfo::fgOptimize = kTRUE;
30 Bool_t TVirtualStreamerInfo::fgStreamMemberWise = kTRUE;
31 
32 ClassImp(TVirtualStreamerInfo);
33 
34 ////////////////////////////////////////////////////////////////////////////////
35 /// Default constructor.
36 
37 TVirtualStreamerInfo::TVirtualStreamerInfo() : fOptimized(kFALSE), fIsBuilt(kFALSE), fIsCompiled(kFALSE)
38 {
39 }
40 
41 ////////////////////////////////////////////////////////////////////////////////
42 /// Default constructor.
43 
44 TVirtualStreamerInfo::TVirtualStreamerInfo(TClass *cl)
45  : TNamed(cl->GetName(),""), fOptimized(kFALSE), fIsBuilt(kFALSE), fIsCompiled(kFALSE)
46 {
47 }
48 
49 ////////////////////////////////////////////////////////////////////////////////
50 ///copy constructor
51 
52 TVirtualStreamerInfo::TVirtualStreamerInfo(const TVirtualStreamerInfo& info)
53  : TNamed(info), fOptimized(kFALSE), fIsBuilt(kFALSE), fIsCompiled(kFALSE)
54 {
55 }
56 
57 ////////////////////////////////////////////////////////////////////////////////
58 ///assignment operator
59 
60 TVirtualStreamerInfo& TVirtualStreamerInfo::operator=(const TVirtualStreamerInfo& info)
61 {
62  if(this!=&info) {
63  TNamed::operator=(info);
64  }
65  return *this;
66 }
67 
68 ////////////////////////////////////////////////////////////////////////////////
69 /// Destructor
70 
71 TVirtualStreamerInfo::~TVirtualStreamerInfo()
72 {
73 }
74 
75 ////////////////////////////////////////////////////////////////////////////////
76 /// static function returning true if ReadBuffer can delete object
77 
78 Bool_t TVirtualStreamerInfo::CanDelete()
79 {
80  return fgCanDelete;
81 }
82 
83 ////////////////////////////////////////////////////////////////////////////////
84 /// static function returning true if optimization can be on
85 
86 Bool_t TVirtualStreamerInfo::CanOptimize()
87 {
88  return fgOptimize;
89 }
90 
91 ////////////////////////////////////////////////////////////////////////////////
92 /// Given a comment/title declaring an array counter, for example:
93 /// ~~~ {.cpp}
94 /// //[fArraySize] array of size fArraySize
95 /// ~~~
96 /// return the start of the array dimension declaration start in the string
97 /// (so the location of the 'f'.
98 
99 const char *TVirtualStreamerInfo::GetElementCounterStart(const char *dmTitle)
100 {
101  for (const char *lbracket = dmTitle; *lbracket; ++lbracket) {
102  // = ::strchr(dmTitle, '[');
103  if ( (*lbracket) == '[' ) return lbracket;
104  if ( (*lbracket) != '/' && !isspace(*lbracket) ) {
105  // Allow only comment delimiters and white spaces
106  // before the array information.
107  return 0;
108  }
109  }
110  return 0;
111 }
112 
113 ////////////////////////////////////////////////////////////////////////////////
114 /// Get pointer to a TStreamerBasicType in TClass *cl
115 ///static function
116 
117 TStreamerBasicType *TVirtualStreamerInfo::GetElementCounter(const char *countName, TClass *cl)
118 {
119  TVirtualStreamerInfo *info;
120  {
121  R__LOCKGUARD(gInterpreterMutex);
122  const TObjArray *sinfos = cl->GetStreamerInfos();
123  info = (TVirtualStreamerInfo *)sinfos->At(cl->GetClassVersion());
124  }
125 
126  if (!info || !info->IsCompiled()) {
127  // Even if the streamerInfo exist, it could still need to be 'build'
128  // It is important to figure this out, because
129  // a) if it is not build, we need to build
130  // b) if is build, we should not build it (or we could end up in an
131  // infinite loop, if the element and its counter are in the same
132  // class!
133  // Checking IsCompiled is sufficient here even-though it is set only at
134  // the end of the call to Build as this function has an
135  // internal recursion prevention (setting and testing kBuildRunning).
136  info = cl->GetStreamerInfo();
137  }
138  if (!info) return 0;
139  TStreamerElement *element = (TStreamerElement *)info->GetElements()->FindObject(countName);
140  if (!element) return 0;
141  if (element->IsA() == TStreamerBasicType::Class()) return (TStreamerBasicType*)element;
142  return 0;
143 }
144 
145 ////////////////////////////////////////////////////////////////////////////////
146 /// Return whether the TStreamerInfos will save the collections in
147 /// "member-wise" order whenever possible. The default is to store member-wise.
148 /// - kTRUE indicates member-wise storing
149 /// - kFALSE inddicates object-wise storing
150 ///
151 /// A collection can be saved member wise when it contain is guaranteed to be
152 /// homogeneous. For example std::vector<THit> can be stored member wise,
153 /// while std::vector<THit*> can not (possible use of polymorphism).
154 
155 Bool_t TVirtualStreamerInfo::GetStreamMemberWise()
156 {
157  return fgStreamMemberWise;
158 }
159 
160 ////////////////////////////////////////////////////////////////////////////////
161 /// This is a static function.
162 /// Set optimization option.
163 /// When this option is activated (default), consecutive data members
164 /// of the same type are merged into an array (faster).
165 /// Optimization must be off in TTree split mode.
166 
167 void TVirtualStreamerInfo::Optimize(Bool_t opt)
168 {
169  fgOptimize = opt;
170 }
171 
172 ////////////////////////////////////////////////////////////////////////////////
173 /// Static function returning a pointer to a new TVirtualStreamerInfo object.
174 /// If the Info factory does not exist, it is created via the plugin manager.
175 /// In reality the factory is an empty TStreamerInfo object.
176 
177 TVirtualStreamerInfo *TVirtualStreamerInfo::Factory()
178 {
179  if (!fgInfoFactory) {
180  R__LOCKGUARD(gInterpreterMutex);
181  TPluginHandler *h;
182  if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualStreamerInfo","TStreamerInfo"))) {
183  if (h->LoadPlugin() == -1) {
184  ::Fatal("TVirtualStreamerInfo::Factory",
185  "The plugin handler for TVirtualStreamerInfo was found but failed to load!");
186  }
187  fgInfoFactory = (TVirtualStreamerInfo*) h->ExecPlugin(0);
188  if (fgInfoFactory == 0) {
189  ::Fatal("TVirtualStreamerInfo::Factory",
190  "The plugin handler for TVirtualStreamerInfo was found but failed to create the factory object!");
191  }
192  } else {
193  TString filename("$ROOTSYS/etc/plugins/TVirtualStreamerInfo");
194  gSystem->ExpandPathName(filename);
195  if (gSystem->AccessPathName(filename)) {
196  ::Fatal("TVirtualStreamerInfo::Factory",
197  "Cannot find the plugin handler for TVirtualStreamerInfo! "
198  "$ROOTSYS/etc/plugins/TVirtualStreamerInfo does not exist "
199  "or is inaccessible.");
200  } else {
201  ::Fatal("TVirtualStreamerInfo::Factory",
202  "Cannot find the plugin handler for TVirtualStreamerInfo! "
203  "However $ROOTSYS/etc/plugins/TVirtualStreamerInfo is accessible, "
204  "Check the content of this directory!");
205  }
206  }
207  }
208 
209  return fgInfoFactory;
210 }
211 
212 ////////////////////////////////////////////////////////////////////////////////
213 /// This is a static function.
214 /// Set object delete option.
215 /// When this option is activated (default), ReadBuffer automatically
216 /// delete objects when a data member is a pointer to an object.
217 /// If your constructor is not presetting pointers to 0, you must
218 /// call this static function TStreamerInfo::SetCanDelete(kFALSE);
219 
220 void TVirtualStreamerInfo::SetCanDelete(Bool_t opt)
221 {
222  fgCanDelete = opt;
223 }
224 
225 ////////////////////////////////////////////////////////////////////////////////
226 ///static function: Set the StreamerInfo factory
227 
228 void TVirtualStreamerInfo::SetFactory(TVirtualStreamerInfo *factory)
229 {
230  R__LOCKGUARD(gInterpreterMutex);
231  auto old = fgInfoFactory;
232  fgInfoFactory = factory;
233  if (old) delete old;
234 }
235 
236 ////////////////////////////////////////////////////////////////////////////////
237 /// Set whether the TStreamerInfos will save the collections in
238 /// "member-wise" order whenever possible. The default is to store member-wise.
239 /// - kTRUE indicates member-wise storing
240 /// - kFALSE indicates object-wise storing
241 /// This function returns the previous value of fgStreamMemberWise.
242 
243 Bool_t TVirtualStreamerInfo::SetStreamMemberWise(Bool_t enable)
244 {
245  // A collection can be saved member wise when it contain is guaranteed to be
246  // homogeneous. For example std::vector<THit> can be stored member wise,
247  // while std::vector<THit*> can not (possible use of polymorphism).
248 
249  Bool_t prev = fgStreamMemberWise;
250  fgStreamMemberWise = enable;
251  return prev;
252 }
253 
254 ////////////////////////////////////////////////////////////////////////////////
255 /// Stream an object of class TVirtualStreamerInfo.
256 
257 void TVirtualStreamerInfo::Streamer(TBuffer &R__b)
258 {
259  TNamed::Streamer(R__b);
260 }