ATLAS Offline Software
AthDictLoaderSvc.cxx
Go to the documentation of this file.
1 
3 /*
4  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
5 */
6 
7 // AthDictLoaderSvc.cxx
8 // Implementation file for class AthDictLoaderSvc
9 // Author: S.Binet<binet@cern.ch>
11 
12 // AthenaServices includes
13 #include "AthDictLoaderSvc.h"
14 
15 // STL includes
16 
17 // FrameWork includes
18 #include "Gaudi/Property.h"
19 #include "GaudiKernel/System.h"
20 #include "AthenaKernel/BaseInfo.h"
22 #include "AthenaKernel/ITPCnvSvc.h"
24 #include "TClassEdit.h"
25 
26 
27 namespace {
28 
29 bool startsWith (const std::string& a, const std::string& b)
30 {
31  return (a.compare (0, b.size(), b) == 0);
32 }
33 
34 } // anonymous namespace
35 
36 // Constructors
39  ISvcLocator* pSvcLocator) :
40  ::AthService( name, pSvcLocator ),
41  m_dsodb (nullptr),
42  m_clidSvc ("ClassIDSvc", name),
43  m_tpCnvSvc("AthTPCnvSvc", name)
44 {
45 }
46 
47 // Destructor
50 {}
51 
52 // Athena Service's Hooks
55 {
56  ATH_MSG_INFO ("in initialize...");
58  if (!m_dsodb) {
59  ATH_MSG_ERROR("could not acquire Dso-registry");
60  return StatusCode::FAILURE;
61  }
62  ATH_MSG_INFO ("acquired Dso-registry");
63 
64  ATH_CHECK( m_clidSvc.retrieve() );
65  ATH_CHECK( m_tpCnvSvc.retrieve() );
66 
67  return StatusCode::SUCCESS;
68 }
69 
71 {
72  ATH_MSG_INFO ("in finalize...");
73  return StatusCode::SUCCESS;
74 }
75 
76 // Query the interfaces.
77 // Input: riid, Requested interface ID
78 // ppvInterface, Pointer to requested interface
79 // Return: StatusCode indicating SUCCESS or FAILURE.
80 // N.B. Don't forget to release the interface after use!!!
82 AthDictLoaderSvc::queryInterface(const InterfaceID& riid, void** ppvInterface)
83 {
84  if ( IDictLoaderSvc::interfaceID().versionMatch(riid) ) {
85  *ppvInterface = dynamic_cast<IDictLoaderSvc*>(this);
86  } else {
87  // Interface is not directly available : try out a base class
88  return ::AthService::queryInterface(riid, ppvInterface);
89  }
90  addRef();
91  return StatusCode::SUCCESS;
92 }
93 
96 bool
97 AthDictLoaderSvc::has_type (const std::string& type_name)
98 {
99  if (!m_dsodb)
100  return false;
101 
102  bool has_type = m_dsodb->has_type(type_name);
103  if (!has_type) {
104  ATH_MSG_DEBUG ("no reflex dict. for type [" << type_name << "]");
105  }
106 
107  return has_type;
108 }
109 
112 bool
113 AthDictLoaderSvc::has_type (const std::type_info& typeinfo)
114 {
115  return has_type (System::typeinfoName(typeinfo).c_str());
116 }
117 
120 bool
122 {
123  bool ret = false;
124  std::string name = "<N/A>";
125  if (m_clidSvc->getTypeNameOfID(clid, name).isSuccess()) {
126  ret = has_type (name);
127  if (ret) {
128  return ret;
129  }
130  }
131 
132  // try out the typeinfoname...
133  if (m_clidSvc->getTypeInfoNameOfID(clid, name).isSuccess()) {
134  ret = has_type (name);
135  if (ret) {
136  return ret;
137  }
138  }
139 
140  return ret;
141 }
142 
147 const RootType
148 AthDictLoaderSvc::load_type (const std::string& type_name,
149  bool recursive /* = false*/)
150 {
151  ATH_MSG_DEBUG ("loading [" << type_name << "]...");
152 
153  // MN: short-cutting all the dance with type names done in DSODB...
154  // may need verification
155  // return RootType::ByName (m_dsodb->load_type(type_name));
156  RootType rt = RootType::ByNameNoQuiet(type_name);
157 
158  if (recursive) {
159  load_recursive (rt);
160  }
161  return rt;
162 }
163 
170 const RootType
171 AthDictLoaderSvc::load_type (const std::type_info& typeinfo,
172  bool recursive /*= false*/)
173 {
175  ("loading [" << System::typeinfoName(typeinfo) << " (from typeinfo)]...");
176  return load_type (System::typeinfoName(typeinfo), recursive);
177 }
178 
183 const RootType
185 {
186  std::string name = "<N/A>";
187  if (!m_clidSvc->getTypeNameOfID(clid, name).isSuccess()) {
188  ATH_MSG_INFO ("could not retrieve typename for clid [" << clid << "]");
189  // try out the bare std::type_info if available...
190  const SG::BaseInfoBase* bib = SG::BaseInfoBase::find(clid);
191  if (bib) {
192  return load_type(bib->typeinfo(), recursive);
193  }
194  // fail early...
195  return RootType();
196  }
197 
198  ATH_MSG_DEBUG("loading [" << name << " (from clid="<<clid<<")]...");
199 
201  if (type) {
202  return type;
203  }
204 
205  // try out the typeinfo-name
206  m_clidSvc->getTypeInfoNameOfID(clid, name).ignore();
208  if (type) {
209  return type;
210  }
211 
212  // try out the bare std::type_info if available...
213  const SG::BaseInfoBase* bib = SG::BaseInfoBase::find(clid);
214  if (bib) {
215  return load_type(bib->typeinfo(), recursive);
216  }
217  // cppcheck-suppress identicalConditionAfterEarlyExit
218  return type;
219 }
220 
221 
223 {
224  Memo_t memo;
225  RootUtils::WithRootErrorHandler hand ([] (int, bool, const char*, const char*) { return false; });
226  load_recursive1 (typ, memo);
227 }
228 
229 void AthDictLoaderSvc::load_recursive1 (const std::string& tnam,
230  Memo_t& memo)
231 {
232  if (startsWith (tnam, "const ")) {
233  load_recursive1 (RootType::ByNameNoQuiet (tnam.substr (6, std::string::npos)),
234  memo);
235  }
236  else {
238  }
239 }
241 {
242  if (!typ) return;
243  if (typ.IsFundamental() || typ.IsPointer() || typ.IsEnum()) return;
244  if (!typ.IsClass()) return;
245  std::string nam = typ.Name();
246  if (!memo.insert (nam).second) return;
247  if (nam == "string" || nam == "std::string" ||
248  startsWith (nam, "basic_string<") ||
249  startsWith (nam, "std::basic_string<"))
250  {
251  return;
252  }
253  if (startsWith (nam, "vector<") || startsWith (nam, "std::vector<")) {
254  std::string eltclass;
255  {
256  // Protect against data race inside TClassEdit.
257  // https://github.com/root-project/root/issues/10353
258  // Should be fixed in root 6.26.02.
259  R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
260  TClassEdit::TSplitType split (nam.c_str());
261  if (split.fElements.size() > 1) {
262  eltclass = split.fElements[1];
263  }
264  }
265  if (!eltclass.empty()) {
266  load_recursive1 (eltclass, memo);
267  return;
268  }
269 
270  }
271  else if (startsWith (nam, "DataVector<")) {
272  std::string eltclass;
273  {
274  // Protect against data race inside TClassEdit.
275  // https://github.com/root-project/root/issues/10353
276  // Should be fixed in root 6.26.02.
277  R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
278  TClassEdit::TSplitType split (nam.c_str());
279  if (split.fElements.size() > 1) {
280  eltclass = split.fElements[1];
281  }
282  }
283  if (!eltclass.empty()) {
284  load_recursive1 (eltclass, memo);
285  return;
286  }
287  }
288  else if (startsWith (nam, "pair<") || startsWith (nam, "std::pair<")) {
289  std::string pclass1, pclass2;
290  {
291  // Protect against data race inside TClassEdit.
292  // https://github.com/root-project/root/issues/10353
293  // Should be fixed in root 6.26.02.
294  R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
295  TClassEdit::TSplitType split (nam.c_str());
296  if (split.fElements.size() > 2) {
297  pclass1 = split.fElements[1];
298  pclass2 = split.fElements[2];
299  }
300  }
301  if (!pclass1.empty()) {
302  load_recursive1 (pclass1, memo);
303  load_recursive1 (pclass2, memo);
304  return;
305  }
306  }
307  else if (startsWith (nam, "map<") || startsWith (nam, "std::map<")) {
308  std::string pclass1, pclass2;
309  {
310  // Protect against data race inside TClassEdit.
311  // https://github.com/root-project/root/issues/10353
312  // Should be fixed in root 6.26.02.
313  R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
314  TClassEdit::TSplitType split (nam.c_str());
315  if (split.fElements.size() > 2) {
316  pclass1 = split.fElements[1];
317  pclass2 = split.fElements[2];
318  }
319  }
320  if (!pclass1.empty()) {
321  load_recursive1 (pclass1, memo);
322  load_recursive1 (pclass2, memo);
323  // For ROOT persistency.
324  std::string pname = "std::pair<" + pclass1 + "," + pclass2 + ">";
325  load_type (pname);
326  return;
327  }
328  }
329  else if (startsWith (nam, "LArConditionsContainer<")) {
330  std::string pname;
331  {
332  // Protect against data race inside TClassEdit.
333  // https://github.com/root-project/root/issues/10353
334  // Should be fixed in root 6.26.02.
335  R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
336  TClassEdit::TSplitType split (nam.c_str());
337  if (split.fElements.size() > 1) {
338  pname = "LArConditionsSubset<" + split.fElements[1] + ">";
339  }
340  }
341  if (!pname.empty()) {
342  load_recursive1 (pname, memo);
343 
344  std::unique_ptr<ITPCnvBase> tpcnv = m_tpCnvSvc->t2p_cnv_unique (pname);
345  if (tpcnv) {
346  load_type (tpcnv->persistentTInfo(), true);
347  }
348  return;
349  }
350  }
351 
352  size_t nbase = typ.BaseSize();
353  for (size_t i = 0; i < nbase; i++) {
354  load_recursive1 (typ.BaseAt(i).Name(), memo);
355  }
356 
357  size_t nmem = typ.DataMemberSize();
358  for (size_t i = 0; i < nmem; i++) {
359  RootType mem = typ.DataMemberAt(i).TypeOf();
360  load_recursive1 (mem, memo);
361  }
362 }
TScopeAdapter::DataMemberSize
size_t DataMemberSize() const
Definition: RootType.cxx:797
TScopeAdapter::ByNameNoQuiet
static TScopeAdapter ByNameNoQuiet(const std::string &name, Bool_t load=kTRUE)
Definition: RootType.cxx:581
AthDictLoaderSvc::m_tpCnvSvc
ServiceHandle< ITPCnvSvc > m_tpCnvSvc
Definition: AthDictLoaderSvc.h:123
AthDictLoaderSvc::Memo_t
std::unordered_set< std::string > Memo_t
Definition: AthDictLoaderSvc.h:126
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
Ath::DsoDb::instance
static const DsoDb * instance()
factory for the DsoDb
Definition: DsoDb.cxx:237
IDictLoaderSvc
Definition: IDictLoaderSvc.h:37
ITPCnvSvc.h
AthDictLoaderSvc::~AthDictLoaderSvc
virtual ~AthDictLoaderSvc()
Destructor:
Definition: AthDictLoaderSvc.cxx:49
AthDictLoaderSvc.h
ITPCnvBase.h
TScopeAdapter::IsClass
Bool_t IsClass() const
Definition: RootType.cxx:911
RootType
TTypeAdapter RootType
Definition: RootType.h:211
Ath::DsoDb::has_type
bool has_type(const std::string &type_name) const
Definition: DsoDb.cxx:263
AthDictLoaderSvc::load_recursive
void load_recursive(const RootType &typ)
Definition: AthDictLoaderSvc.cxx:222
TMemberAdapter::TypeOf
TTypeAdapter TypeOf() const
Definition: RootType.cxx:160
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
lumiFormat.i
int i
Definition: lumiFormat.py:92
BaseInfo.h
Provide an interface for finding inheritance information at run time.
AthDictLoaderSvc::queryInterface
virtual StatusCode queryInterface(const InterfaceID &riid, void **ppvInterface) override
Definition: AthDictLoaderSvc.cxx:82
ret
T ret(T t)
Definition: rootspy.cxx:260
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
AthService
Definition: AthService.h:32
TScopeAdapter::IsPointer
Bool_t IsPointer() const
Definition: RootType.cxx:697
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
AthDictLoaderSvc::AthDictLoaderSvc
AthDictLoaderSvc()
Default constructor:
CLID
uint32_t CLID
The Class ID type.
Definition: Event/xAOD/xAODCore/xAODCore/ClassID_traits.h:47
AthDictLoaderSvc::m_dsodb
const Ath::DsoDb * m_dsodb
dictionary of all known (reflex) types
Definition: AthDictLoaderSvc.h:117
TScopeAdapter::Name
std::string Name(unsigned int mod=Reflex::SCOPED) const
Definition: RootType.cxx:607
IDictLoaderSvc::interfaceID
static const InterfaceID & interfaceID()
Definition: IDictLoaderSvc.h:99
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
SG::BaseInfoBase::find
static const BaseInfoBase * find(CLID clid)
Find the BaseInfoBase instance for clid.
Definition: BaseInfo.cxx:569
RootUtils::WithRootErrorHandler
Run a MT piece of code with an alternate root error handler.
Definition: WithRootErrorHandler.h:56
AthDictLoaderSvc::m_clidSvc
ServiceHandle< IClassIDSvc > m_clidSvc
handle to a IClassIDSvc to handle loading of types by CLID
Definition: AthDictLoaderSvc.h:121
WithRootErrorHandler.h
Run a MT piece of code with an alternate root error handler.
AthDictLoaderSvc::finalize
virtual StatusCode finalize() override
Definition: AthDictLoaderSvc.cxx:70
TScopeAdapter::IsFundamental
Bool_t IsFundamental() const
Definition: RootType.cxx:726
a
TList * a
Definition: liststreamerinfos.cxx:10
TBaseAdapter::Name
std::string Name() const
Definition: RootType.cxx:356
AthDictLoaderSvc::load_recursive1
void load_recursive1(const std::string &tnam, Memo_t &memo)
Definition: AthDictLoaderSvc.cxx:229
ITPCnvBase::persistentTInfo
virtual const std::type_info & persistentTInfo() const =0
return C++ type id of the persistent class this converter is for
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
SG::BaseInfoBase
The non-template portion of the BaseInfo implementation.
Definition: Control/AthenaKernel/AthenaKernel/BaseInfo.h:451
TScopeAdapter::IsEnum
Bool_t IsEnum() const
Definition: RootType.cxx:733
AthDictLoaderSvc::load_type
virtual const RootType load_type(const std::string &type_name, bool recursive=false) override
retrieve a Reflex::Type by name (auto)loading the dictionary by any necessary means.
Definition: AthDictLoaderSvc.cxx:148
TScopeAdapter::BaseSize
size_t BaseSize() const
Definition: RootType.cxx:749
generateReferenceFile.recursive
recursive
Definition: generateReferenceFile.py:12
TScopeAdapter::DataMemberAt
TMemberAdapter DataMemberAt(size_t nth) const
Definition: RootType.cxx:807
SG::BaseInfoBase::typeinfo
const std::type_info & typeinfo() const
Return the std::type_info for this class.
Definition: BaseInfo.cxx:151
AthDictLoaderSvc::has_type
virtual bool has_type(const std::string &type_name) override
check a Reflex dictionary exists for a given type
Definition: AthDictLoaderSvc.cxx:97
Trk::split
@ split
Definition: LayerMaterialProperties.h:38
TScopeAdapter
Definition: RootType.h:119
AthDictLoaderSvc::initialize
virtual StatusCode initialize() override
Gaudi Service Implementation.
Definition: AthDictLoaderSvc.cxx:54
TScopeAdapter::BaseAt
TBaseAdapter BaseAt(size_t nth) const
Definition: RootType.cxx:773