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