| The Gaudi Framework v32r1 (f65d50dc)

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 //====================================================================
8 #include "GaudiKernel/IRegistry.h"
9 #include "GaudiKernel/LinkManager.h"
10 #include "GaudiKernel/MsgStream.h"
11 #include "GaudiKernel/ObjectContainerBase.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 }
38 void popCurrentDataObject() {
39 Gaudi::popCurrentDataObject();
40 resetLastLink();
41 }
42
43 union RefAccessor {
44 void* Ptr;
45 SmartRefBase* Base;
46 SmartRef<DataObject>* ObjectRef;
47 SmartRef<ContainedObject>* ContainedRef;
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() ) {
91 case SmartRefBase::DATAOBJECT:
92 ( *r.ObjectRef )( Gaudi::getCurrentDataObject() );
93 break;
94 case SmartRefBase::CONTAINEDOBJECT:
95 ( *r.ContainedRef )( Gaudi::getCurrentDataObject() );
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
110 curr = Gaudi::getCurrentDataObject();
111 pDO = r.ObjectRef->data();
112 hint = r.ObjectRef->hintID();
113 link = r.ObjectRef->linkID();
114 if ( pDO ) {
115 switch ( r.Base->objectType() ) {
116 case SmartRefBase::CONTAINEDOBJECT:
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;
134 case SmartRefBase::DATAOBJECT:
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;
166 p->setParent( (ObjectContainerBase*)Gaudi::getCurrentDataObject() );
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
201 bool patchStreamers( MsgStream& s ) {
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
GaudiRoot::IOHandler::IOHandler
IOHandler(TClass *c)
Initializing constructor.
Definition: RootIOHandler.cpp:61
System.h
GaudiRoot::RefAccessor
Definition: RootIOHandler.cpp:43
MsgStream
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
GaudiRoot::RefAccessor::Base
SmartRefBase * Base
Definition: RootIOHandler.cpp:45
gaudirun.c
c
Definition: gaudirun.py:487
DataObject::registry
IRegistry * registry() const
Get pointer to Registry.
Definition: DataObject.h:72
GaudiRoot::popCurrentDataObject
void popCurrentDataObject()
Definition: RootIOHandler.cpp:38
LinkManager.h
GaudiRoot
Definition: RootCnvSvc.cpp:39
MsgStream.h
System::typeinfoName
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:298
Gaudi::popCurrentDataObject
GAUDI_API void popCurrentDataObject()
Definition: RootIOHandler.cpp:38
Gaudi::getCurrentDataObject
GAUDI_API DataObject * getCurrentDataObject()
DataObject::linkMgr
LinkManager * linkMgr() const
Retrieve Link manager.
Definition: DataObject.h:74
std::log
T log(T... args)
GaudiRoot::pushCurrentDataObject
void pushCurrentDataObject(DataObject **pobjAddr)
Definition: RootIOHandler.cpp:34
MSG::DEBUG
Definition: IMessageSvc.h:15
std::endl
T endl(T... args)
PoolClasses.h
std
STL namespace.
ObjectContainerBase.h
GaudiRoot::patchStreamers
bool patchStreamers(MsgStream &log)
Definition: RootIOHandler.cpp:201
SmartRef< DataObject >
SmartRefBase
User example objects: SmartRefBase.
Definition: SmartRefBase.h:47
GaudiRoot::IOHandler::m_root
TClass * m_root
ROOT persistent class description.
Definition: RootIOHandler.cpp:57
SmartRefBase::DATAOBJECT
Definition: SmartRefBase.h:60
IOTest.start
def start
Definition: IOTest.py:97
SmartRefBase::CONTAINEDOBJECT
Definition: SmartRefBase.h:60
std::string
STL class.
pool::Token::m_oid
std::pair< int, int > m_oid
Object global identifier.
Definition: PoolClasses.h:31
pool::Token
Shadow class to mimik POOL tokens.
Definition: PoolClasses.h:24
CFinViewTest.b1
b1
Definition: CFinViewTest.py:79
GaudiRoot::RefAccessor::RefAccessor
RefAccessor(void *obj)
Definition: RootIOHandler.cpp:48
RootRefs.h
std::exception::what
T what(T... args)
CFinViewTest.b2
b2
Definition: CFinViewTest.py:82
std::runtime_error
STL class.
GaudiRoot::IOHandler::operator()
void operator()(TBuffer &b, void *obj) override
ROOT I/O callback.
Definition: RootIOHandler.cpp:63
IRegistry.h
IRegistry
The IRegistry represents the entry door to the environment any data object residing in a transient da...
Definition: IRegistry.h:22
Gaudi::pushCurrentDataObject
GAUDI_API void pushCurrentDataObject(DataObject **pobjAddr)
Definition: RootIOHandler.cpp:34
GaudiRoot::RefAccessor::Ptr
void * Ptr
Definition: RootIOHandler.cpp:44
std::exception
STL class.
std::count
T count(T... args)
ContainedObject::index
virtual long index() const
Distance in the parent container.
Definition: ContainedObject.h:56
SmartRefBase::objectType
int objectType() const
Definition: SmartRefBase.h:104
ContainedObject
All classes that their objects may be contained in an LHCb ObjectContainer (e.g.
Definition: ContainedObject.h:31
Gaudi::Functional::details::get
auto get(const Handle &handle, const Algo &, const EventContext &) -> decltype(details::deref(handle.get()))
Definition: FunctionalDetails.h:332
Gaudi::Functional::details::put
Out1 * put(const DataObjectHandle< Out1 > &out_handle, Out2 &&out)
Definition: FunctionalDetails.h:121
std::string::c_str
T c_str(T... args)
SmartRef.h
GaudiRoot::IOHandler
Definition: RootIOHandler.cpp:54
ContainedObject::setParent
void setParent(ObjectContainerBase *value)
Update parent member.
Definition: ContainedObject.h:53
gaudirun.s
string s
Definition: gaudirun.py:316
MSG::ERROR
Definition: IMessageSvc.h:15
GaudiRoot::RefAccessor::ObjectRef
SmartRef< DataObject > * ObjectRef
Definition: RootIOHandler.cpp:46
ContainedObject::parent
const ObjectContainerBase * parent() const
Access to parent object.
Definition: ContainedObject.h:51
IRegistry::identifier
virtual const id_type & identifier() const =0
Full identifier (or key)
ObjectContainerBase
ObjectContainerBase is the base class for Gaudi container classes.
Definition: ObjectContainerBase.h:19
StreamBuffer::INVALID
Definition: StreamBuffer.h:111
SmartRefBase::set
void set(DataObject *pObj, long hint_id, long link_id)
Setup smart reference when reading. Must be allowed from external sources.
Definition: SmartRefBase.cpp:26
GaudiRoot::resetLastLink
void resetLastLink()
Definition: RootIOHandler.cpp:30
GaudiRoot::RefAccessor::ContainedRef
SmartRef< ContainedObject > * ContainedRef
Definition: RootIOHandler.cpp:47
DataObject
A DataObject is the base class of any identifiable object on any data store.
Definition: DataObject.h:30
std::cout
LinkManager
A LinkManager is the object aggregated into a DataObject, which is responsible for the handling of no...
Definition: LinkManager.h:21
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:192
LinkManager::addLink
long addLink(const std::string &path, const DataObject *pObject) const
Add link by object reference and path.
Definition: LinkManager.cpp:54