All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
RootIOHandler.cpp
Go to the documentation of this file.
1 //====================================================================
2 //
3 // Package : RootCnv
4 //
5 // Description: Generate TClassStreamers for special Gaudi classes
6 // @author M.Frank
7 //====================================================================
10 #include "GaudiKernel/IRegistry.h"
11 #include "GaudiKernel/MsgStream.h"
12 #include "GaudiKernel/SmartRef.h"
13 #include "GaudiKernel/System.h"
14 #include "RootCnv/RootRefs.h"
15 #include "RootCnv/PoolClasses.h"
16 #include <stdexcept>
17 #include <iostream>
18 #include "TROOT.h"
19 #include "TClass.h"
20 #include "TSystem.h"
21 #include "TInterpreter.h"
22 #include "TClassStreamer.h"
23 #include <memory>
24 
25 using namespace std;
26 
27 namespace GaudiRoot {
28  static const DataObject* last_link_object = nullptr;
29  static int last_link_hint = -1;
30  void resetLastLink() {
31  last_link_object = nullptr;
32  last_link_hint = -1;
33  }
34  void pushCurrentDataObject(DataObject** pobjAddr) {
36  resetLastLink();
37  }
40  resetLastLink();
41  }
42 
43  union RefAccessor {
44  void* Ptr;
48  RefAccessor(void* obj) { Ptr = obj; }
49  };
50 
53  template <class T> class IOHandler : public TClassStreamer {
54  protected:
56  TClass* m_root;
57  public:
59  IOHandler(TClass* c) : m_root(c) { }
61  ~IOHandler() override = default;
63  void operator()(TBuffer &b, void *obj) override {
64  try {
65  if ( b.IsReading() )
66  get(b,obj);
67  else
68  put(b,obj);
69  }
70  catch( const exception& e ) {
71  string err = "Class:" + string(m_root->GetName()) + "> Exception in object I/O";
72  err += e.what();
73  throw runtime_error(err);
74  }
75  catch( ... ) {
76  string err = "Class:" + string(m_root->GetName()) + "> Exception in object I/O";
77  throw runtime_error(err);
78  }
79  }
81  virtual void get(TBuffer &b, void* obj);
83  virtual void put(TBuffer &b, void* obj);
84  };
85 
86  template <> void IOHandler<SmartRefBase>::get(TBuffer &b, void* obj) {
87  RefAccessor r(obj);
88  UInt_t start, count;
89  Version_t version = b.ReadVersion(&start, &count, m_root);
90  m_root->ReadBuffer(b, obj, version, start, count);
91  switch( r.Base->objectType() ) {
94  break;
97  break;
98  default:
99  cout << "Hit uninitialized smartRef!!!!" << endl;
100  break;
101  }
102  }
103 
104  template <> void IOHandler<SmartRefBase>::put(TBuffer &b, void* obj) {
105  RefAccessor r(obj);
106  ContainedObject* p;
107  DataObject* curr, *pDO;
108  int hint, link;
109 
111  pDO = r.ObjectRef->data();
112  hint = r.ObjectRef->hintID();
113  link = r.ObjectRef->linkID();
114  if ( pDO ) {
115  switch( r.Base->objectType() ) {
117  p = r.ContainedRef->data();
118  if ( p ) {
119  const ObjectContainerBase* parent = p->parent();
120  if ( parent ) {
121  link = p->index();
122  pDO = const_cast<ObjectContainerBase*>(parent);
123  break;
124  }
125  }
126  pDO = nullptr;
127  cout << "IOHandler<SmartRefBase>::onWrite> "
128  << "Found invalid smart reference with object "
129  << "having no parent."
130  << endl;
131  throw runtime_error("IOHandler<SmartRefBase>::onWrite> "
132  "Found invalid smart reference with object "
133  "having no parent.");
134  break;
136  link = StreamBuffer::INVALID;
137  break;
138  default:
139  break;
140  }
141  if ( pDO == last_link_object ) {
142  r.Base->set(curr, last_link_hint, link);
143  m_root->WriteBuffer(b, obj);
144  return;
145  }
146  else if ( pDO ) {
147  LinkManager* mgr = curr->linkMgr();
148  IRegistry* reg = pDO->registry();
149  if ( reg && mgr ) {
150  hint = mgr->addLink(reg->identifier(), pDO);
151  last_link_hint = hint;
152  last_link_object = pDO;
153  }
154  }
155  else {
156  hint = link = StreamBuffer::INVALID;
157  }
158  }
159  r.Base->set(curr, hint, link);
160  m_root->WriteBuffer(b, obj);
161  }
162 
163  template <> void IOHandler<ContainedObject>::get(TBuffer &b, void* obj) {
164  UInt_t start, count;
165  Version_t version = b.ReadVersion(&start, &count, m_root);
166  m_root->ReadBuffer(b, obj, version, start, count);
167  ContainedObject* p = (ContainedObject*)obj;
169  }
170 
171  template <> void IOHandler<ContainedObject>::put(TBuffer &b, void* obj) {
172  m_root->WriteBuffer(b, obj);
173  }
174 
175  template <> void IOHandler<pool::Token>::get(TBuffer &b, void* obj) {
176  UInt_t start, count;
177  pool::Token* t = (pool::Token*)obj;
178  b.ReadVersion(&start, &count, m_root);
179  b.ReadFastArray(&t->m_oid.first, 2);
180  b.CheckByteCount(start, count, m_root);
181  }
182 
183  template <> void IOHandler<pool::Token>::put(TBuffer &, void* ) {
184  throw runtime_error("Writing POOL files is not implemented!");
185  }
186 
187  template <class T> static bool makeStreamer(MsgStream& log) {
188  string cl_name = System::typeinfoName(typeid(T));
189  TClass* c = gROOT->GetClass(cl_name.c_str());
190  if ( c ) {
191  c->AdoptStreamer(new IOHandler<T>(c));
192  log << MSG::DEBUG << "Installed IOHandler for class " << cl_name << endmsg;
193  return true;
194  }
195  log << MSG::ERROR << "[No ROOT TClass] Failed to install IOHandler for class " << cl_name << endmsg;
196  return false;
197  }
198 
200  static bool first = true;
201  if ( first ) {
202  first = false;
203 #if ROOT_VERSION_CODE < ROOT_VERSION(5,99,0)
204  gSystem->Load("libCintex");
205  gROOT->ProcessLine("Cintex::Cintex::Enable()");
206  gROOT->ProcessLine("#include <vector>");
207  gInterpreter->EnableAutoLoading();
208  gInterpreter->AutoLoad("DataObject");
209  gInterpreter->AutoLoad("PoolDbLinkManager");
210  gSystem->Load("libGaudiKernelDict");
211  gSystem->Load("libGaudiExamplesDict");
212 #else
213  gInterpreter->EnableAutoLoading();
214  gInterpreter->AutoLoad("DataObject");
215  gInterpreter->AutoLoad("PoolDbLinkManager");
216 #endif
217 
218 
219  bool b1 = makeStreamer<SmartRefBase>(s);
220  bool b2 = makeStreamer<ContainedObject>(s);
221  bool b3 = makeStreamer<pool::Token>(s);
222  return b1 && b2 && b3;
223  }
224  return true;
225  }
226 }
IOHandler(TClass *c)
Initializing constructor.
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
void popCurrentDataObject()
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:299
GAUDI_API void popCurrentDataObject()
GAUDI_API DataObject * getCurrentDataObject()
T log(T...args)
void pushCurrentDataObject(DataObject **pobjAddr)
T endl(T...args)
virtual long index() const
Distance in the parent container.
STL namespace.
bool patchStreamers(MsgStream &log)
User example objects: SmartRefBase.
Definition: SmartRefBase.h:47
TClass * m_root
ROOT persistent class description.
const ObjectContainerBase * parent() const
Access to parent object.
IRegistry * registry() const
Get pointer to Registry.
Definition: DataObject.h:74
LinkManager * linkMgr() const
Retrieve Link manager.
Definition: DataObject.h:78
STL class.
std::pair< int, int > m_oid
Object global identifier.
Definition: PoolClasses.h:27
Shadow class to mimik POOL tokens.
Definition: PoolClasses.h:20
virtual const id_type & identifier() const =0
Full identifier (or key)
T what(T...args)
void operator()(TBuffer &b, void *obj) override
ROOT I/O callback.
start
Definition: IOTest.py:88
The IRegistry represents the entry door to the environment any data object residing in a transient da...
Definition: IRegistry.h:22
GAUDI_API void pushCurrentDataObject(DataObject **pobjAddr)
STL class.
T count(T...args)
All classes that their objects may be contained in an LHCb ObjectContainer (e.g.
T c_str(T...args)
void setParent(ObjectContainerBase *value)
Update parent member.
string s
Definition: gaudirun.py:245
SmartRef< DataObject > * ObjectRef
ObjectContainerBase is the base class for Gaudi container classes.
void set(DataObject *pObj, long hint_id, long link_id)
Setup smart reference when reading. Must be allowed from external sources.
void resetLastLink()
SmartRef< ContainedObject > * ContainedRef
A DataObject is the base class of any identifiable object on any data store.
Definition: DataObject.h:30
int objectType() const
Definition: SmartRefBase.h:111
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244