Loading [MathJax]/extensions/tex2jax.js
The Gaudi Framework  v31r0 (aeb156f0)
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/MsgStream.h"
12 #include "GaudiKernel/SmartRef.h"
13 #include "GaudiKernel/System.h"
14 #include "RootCnv/PoolClasses.h"
15 #include "RootCnv/RootRefs.h"
16 #include "TClass.h"
17 #include "TClassStreamer.h"
18 #include "TInterpreter.h"
19 #include "TROOT.h"
20 #include "TSystem.h"
21 #include <iostream>
22 #include <memory>
23 #include <stdexcept>
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 ) {
35  Gaudi::pushCurrentDataObject( 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>
54  class IOHandler : public TClassStreamer {
55  protected:
57  TClass* m_root;
58 
59  public:
61  IOHandler( TClass* c ) : m_root( c ) {}
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  } catch ( const exception& e ) {
70  string err = "Class:" + string( m_root->GetName() ) + "> Exception in object I/O";
71  err += e.what();
72  throw runtime_error( err );
73  } catch ( ... ) {
74  string err = "Class:" + string( m_root->GetName() ) + "> Exception in object I/O";
75  throw runtime_error( err );
76  }
77  }
79  virtual void get( TBuffer& b, void* obj );
81  virtual void put( TBuffer& b, void* obj );
82  };
83 
84  template <>
85  void IOHandler<SmartRefBase>::get( TBuffer& b, void* obj ) {
86  RefAccessor r( obj );
87  UInt_t start, count;
88  Version_t version = b.ReadVersion( &start, &count, m_root );
89  m_root->ReadBuffer( b, obj, version, start, count );
90  switch ( r.Base->objectType() ) {
93  break;
96  break;
97  default:
98  cout << "Hit uninitialized smartRef!!!!" << endl;
99  break;
100  }
101  }
102 
103  template <>
104  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." << endl;
130  throw runtime_error( "IOHandler<SmartRefBase>::onWrite> "
131  "Found invalid smart reference with object "
132  "having no parent." );
133  break;
135  link = StreamBuffer::INVALID;
136  break;
137  default:
138  break;
139  }
140  if ( pDO == last_link_object ) {
141  r.Base->set( curr, last_link_hint, link );
142  m_root->WriteBuffer( b, obj );
143  return;
144  } else if ( pDO ) {
145  LinkManager* mgr = curr->linkMgr();
146  IRegistry* reg = pDO->registry();
147  if ( reg && mgr ) {
148  hint = mgr->addLink( reg->identifier(), pDO );
149  last_link_hint = hint;
150  last_link_object = pDO;
151  }
152  } else {
153  hint = link = StreamBuffer::INVALID;
154  }
155  }
156  r.Base->set( curr, hint, link );
157  m_root->WriteBuffer( b, obj );
158  }
159 
160  template <>
161  void IOHandler<ContainedObject>::get( TBuffer& b, void* obj ) {
162  UInt_t start, count;
163  Version_t version = b.ReadVersion( &start, &count, m_root );
164  m_root->ReadBuffer( b, obj, version, start, count );
165  ContainedObject* p = (ContainedObject*)obj;
167  }
168 
169  template <>
170  void IOHandler<ContainedObject>::put( TBuffer& b, void* obj ) {
171  m_root->WriteBuffer( b, obj );
172  }
173 
174  template <>
175  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 <>
184  void IOHandler<pool::Token>::put( TBuffer&, void* ) {
185  throw runtime_error( "Writing POOL files is not implemented!" );
186  }
187 
188  template <class T>
189  static bool makeStreamer( MsgStream& log ) {
190  string cl_name = System::typeinfoName( typeid( T ) );
191  TClass* c = gROOT->GetClass( cl_name.c_str() );
192  if ( c ) {
193  c->AdoptStreamer( new IOHandler<T>( c ) );
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  bool b1 = makeStreamer<SmartRefBase>( s );
221  bool b2 = makeStreamer<ContainedObject>( s );
222  bool b3 = makeStreamer<pool::Token>( s );
223  return b1 && b2 && b3;
224  }
225  return true;
226  }
227 } // namespace GaudiRoot
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:309
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:72
LinkManager * linkMgr() const
Retrieve Link manager.
Definition: DataObject.h:74
STL class.
std::pair< int, int > m_oid
Object global identifier.
Definition: PoolClasses.h:31
Shadow class to mimik POOL tokens.
Definition: PoolClasses.h:24
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:97
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:312
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:104
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:192
Out1 * put(DataObjectHandle< Out1 > &out_handle, Out2 &&out)