| The Gaudi Framework v30r0 (c919700c)

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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 {
29 static const DataObject* last_link_object = nullptr;
30 static int last_link_hint = -1;
31 void resetLastLink()
32 {
33 last_link_object = nullptr;
34 last_link_hint = -1;
35 }
36 void pushCurrentDataObject( DataObject** pobjAddr )
37 {
38 Gaudi::pushCurrentDataObject( pobjAddr );
39 resetLastLink();
40 }
41 void popCurrentDataObject()
42 {
43 Gaudi::popCurrentDataObject();
44 resetLastLink();
45 }
46
47 union RefAccessor {
48 void* Ptr;
49 SmartRefBase* Base;
50 SmartRef<DataObject>* ObjectRef;
51 SmartRef<ContainedObject>* ContainedRef;
52 RefAccessor( void* obj ) { Ptr = obj; }
53 };
54
57 template <class T>
58 class IOHandler : public TClassStreamer
59 {
60 protected:
62 TClass* m_root;
63
64 public:
66 IOHandler( TClass* c ) : m_root( c ) {}
68 ~IOHandler() override = default;
70 void operator()( TBuffer& b, void* obj ) override
71 {
72 try {
73 if ( b.IsReading() )
74 get( b, obj );
75 else
76 put( b, obj );
77 } catch ( const exception& e ) {
78 string err = "Class:" + string( m_root->GetName() ) + "> Exception in object I/O";
79 err += e.what();
80 throw runtime_error( err );
81 } catch ( ... ) {
82 string err = "Class:" + string( m_root->GetName() ) + "> Exception in object I/O";
83 throw runtime_error( err );
84 }
85 }
87 virtual void get( TBuffer& b, void* obj );
89 virtual void put( TBuffer& b, void* obj );
90 };
91
92 template <>
93 void IOHandler<SmartRefBase>::get( TBuffer& b, void* obj )
94 {
95 RefAccessor r( obj );
96 UInt_t start, count;
97 Version_t version = b.ReadVersion( &start, &count, m_root );
98 m_root->ReadBuffer( b, obj, version, start, count );
99 switch ( r.Base->objectType() ) {
100 case SmartRefBase::DATAOBJECT:
101 ( *r.ObjectRef )( Gaudi::getCurrentDataObject() );
102 break;
103 case SmartRefBase::CONTAINEDOBJECT:
104 ( *r.ContainedRef )( Gaudi::getCurrentDataObject() );
105 break;
106 default:
107 cout << "Hit uninitialized smartRef!!!!" << endl;
108 break;
109 }
110 }
111
112 template <>
113 void IOHandler<SmartRefBase>::put( TBuffer& b, void* obj )
114 {
115 RefAccessor r( obj );
116 ContainedObject* p;
117 DataObject *curr, *pDO;
118 int hint, link;
119
120 curr = Gaudi::getCurrentDataObject();
121 pDO = r.ObjectRef->data();
122 hint = r.ObjectRef->hintID();
123 link = r.ObjectRef->linkID();
124 if ( pDO ) {
125 switch ( r.Base->objectType() ) {
126 case SmartRefBase::CONTAINEDOBJECT:
127 p = r.ContainedRef->data();
128 if ( p ) {
129 const ObjectContainerBase* parent = p->parent();
130 if ( parent ) {
131 link = p->index();
132 pDO = const_cast<ObjectContainerBase*>( parent );
133 break;
134 }
135 }
136 pDO = nullptr;
137 cout << "IOHandler<SmartRefBase>::onWrite> "
138 << "Found invalid smart reference with object "
139 << "having no parent." << endl;
140 throw runtime_error( "IOHandler<SmartRefBase>::onWrite> "
141 "Found invalid smart reference with object "
142 "having no parent." );
143 break;
144 case SmartRefBase::DATAOBJECT:
145 link = StreamBuffer::INVALID;
146 break;
147 default:
148 break;
149 }
150 if ( pDO == last_link_object ) {
151 r.Base->set( curr, last_link_hint, link );
152 m_root->WriteBuffer( b, obj );
153 return;
154 } else if ( pDO ) {
155 LinkManager* mgr = curr->linkMgr();
156 IRegistry* reg = pDO->registry();
157 if ( reg && mgr ) {
158 hint = mgr->addLink( reg->identifier(), pDO );
159 last_link_hint = hint;
160 last_link_object = pDO;
161 }
162 } else {
163 hint = link = StreamBuffer::INVALID;
164 }
165 }
166 r.Base->set( curr, hint, link );
167 m_root->WriteBuffer( b, obj );
168 }
169
170 template <>
171 void IOHandler<ContainedObject>::get( TBuffer& b, void* obj )
172 {
173 UInt_t start, count;
174 Version_t version = b.ReadVersion( &start, &count, m_root );
175 m_root->ReadBuffer( b, obj, version, start, count );
176 ContainedObject* p = (ContainedObject*)obj;
177 p->setParent( (ObjectContainerBase*)Gaudi::getCurrentDataObject() );
178 }
179
180 template <>
181 void IOHandler<ContainedObject>::put( TBuffer& b, void* obj )
182 {
183 m_root->WriteBuffer( b, obj );
184 }
185
186 template <>
187 void IOHandler<pool::Token>::get( TBuffer& b, void* obj )
188 {
189 UInt_t start, count;
190 pool::Token* t = (pool::Token*)obj;
191 b.ReadVersion( &start, &count, m_root );
192 b.ReadFastArray( &t->m_oid.first, 2 );
193 b.CheckByteCount( start, count, m_root );
194 }
195
196 template <>
197 void IOHandler<pool::Token>::put( TBuffer&, void* )
198 {
199 throw runtime_error( "Writing POOL files is not implemented!" );
200 }
201
202 template <class T>
203 static bool makeStreamer( MsgStream& log )
204 {
205 string cl_name = System::typeinfoName( typeid( T ) );
206 TClass* c = gROOT->GetClass( cl_name.c_str() );
207 if ( c ) {
208 c->AdoptStreamer( new IOHandler<T>( c ) );
209 log << MSG::DEBUG << "Installed IOHandler for class " << cl_name << endmsg;
210 return true;
211 }
212 log << MSG::ERROR << "[No ROOT TClass] Failed to install IOHandler for class " << cl_name << endmsg;
213 return false;
214 }
215
216 bool patchStreamers( MsgStream& s )
217 {
218 static bool first = true;
219 if ( first ) {
220 first = false;
221 #if ROOT_VERSION_CODE < ROOT_VERSION( 5, 99, 0 )
222 gSystem->Load( "libCintex" );
223 gROOT->ProcessLine( "Cintex::Cintex::Enable()" );
224 gROOT->ProcessLine( "#include <vector>" );
225 gInterpreter->EnableAutoLoading();
226 gInterpreter->AutoLoad( "DataObject" );
227 gInterpreter->AutoLoad( "PoolDbLinkManager" );
228 gSystem->Load( "libGaudiKernelDict" );
229 gSystem->Load( "libGaudiExamplesDict" );
230 #else
231 gInterpreter->EnableAutoLoading();
232 gInterpreter->AutoLoad( "DataObject" );
233 gInterpreter->AutoLoad( "PoolDbLinkManager" );
234 #endif
235
236 bool b1 = makeStreamer<SmartRefBase>( s );
237 bool b2 = makeStreamer<ContainedObject>( s );
238 bool b3 = makeStreamer<pool::Token>( s );
239 return b1 && b2 && b3;
240 }
241 return true;
242 }
243 }
GaudiRoot::IOHandler::IOHandler
IOHandler(TClass *c)
Initializing constructor.
Definition: RootIOHandler.cpp:66
System.h
GaudiRoot::RefAccessor
Definition: RootIOHandler.cpp:47
MsgStream
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
GaudiRoot::RefAccessor::Base
SmartRefBase * Base
Definition: RootIOHandler.cpp:49
gaudirun.c
c
Definition: gaudirun.py:407
GaudiRoot::popCurrentDataObject
void popCurrentDataObject()
Definition: RootIOHandler.cpp:41
LinkManager.h
GaudiRoot
Definition: RootCnvSvc.cpp:40
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:336
Gaudi::popCurrentDataObject
GAUDI_API void popCurrentDataObject()
Definition: RootIOHandler.cpp:41
Gaudi::getCurrentDataObject
GAUDI_API DataObject * getCurrentDataObject()
std::log
T log(T...args)
GaudiRoot::pushCurrentDataObject
void pushCurrentDataObject(DataObject **pobjAddr)
Definition: RootIOHandler.cpp:36
MSG::DEBUG
Definition: IMessageSvc.h:16
std::endl
T endl(T...args)
ContainedObject::index
virtual long index() const
Distance in the parent container.
Definition: ContainedObject.h:57
PoolClasses.h
std
STL namespace.
ObjectContainerBase.h
GaudiRoot::patchStreamers
bool patchStreamers(MsgStream &log)
Definition: RootIOHandler.cpp:216
SmartRef< DataObject >
SmartRefBase
User example objects: SmartRefBase.
Definition: SmartRefBase.h:47
LinkManager::addLink
long addLink(const std::string &path, const DataObject *pObject) const
Add link by object reference and path.
Definition: LinkManager.cpp:59
GaudiRoot::IOHandler::m_root
TClass * m_root
ROOT persistent class description.
Definition: RootIOHandler.cpp:62
ContainedObject::parent
const ObjectContainerBase * parent() const
Access to parent object.
Definition: ContainedObject.h:52
DataObject::registry
IRegistry * registry() const
Get pointer to Registry.
Definition: DataObject.h:73
DataObject::linkMgr
LinkManager * linkMgr() const
Retrieve Link manager.
Definition: DataObject.h:75
std::string
STL class.
pool::Token::m_oid
std::pair< int, int > m_oid
Object global identifier.
Definition: PoolClasses.h:34
pool::Token
Shadow class to mimik POOL tokens.
Definition: PoolClasses.h:26
SmartRefBase::CONTAINEDOBJECT
Definition: SmartRefBase.h:61
SmartRefBase::DATAOBJECT
Definition: SmartRefBase.h:61
GaudiRoot::RefAccessor::RefAccessor
RefAccessor(void *obj)
Definition: RootIOHandler.cpp:52
RootRefs.h
IRegistry::identifier
virtual const id_type & identifier() const =0
Full identifier (or key)
std::exception::what
T what(T...args)
std::runtime_error
STL class.
GaudiRoot::IOHandler::operator()
void operator()(TBuffer &b, void *obj) override
ROOT I/O callback.
Definition: RootIOHandler.cpp:70
IOTest.start
start
Definition: IOTest.py:99
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:36
GaudiRoot::RefAccessor::Ptr
void * Ptr
Definition: RootIOHandler.cpp:48
std::exception
STL class.
std::count
T count(T...args)
ContainedObject
All classes that their objects may be contained in an LHCb ObjectContainer (e.g.
Definition: ContainedObject.h:31
GaudiPython.Persistency.get
def get(type_)
Definition: Persistency.py:29
std::string::c_str
T c_str(T...args)
SmartRef.h
GaudiRoot::IOHandler
Definition: RootIOHandler.cpp:58
ContainedObject::setParent
void setParent(ObjectContainerBase *value)
Update parent member.
Definition: ContainedObject.h:54
gaudirun.s
string s
Definition: gaudirun.py:253
MSG::ERROR
Definition: IMessageSvc.h:16
GaudiRoot::RefAccessor::ObjectRef
SmartRef< DataObject > * ObjectRef
Definition: RootIOHandler.cpp:50
ObjectContainerBase
ObjectContainerBase is the base class for Gaudi container classes.
Definition: ObjectContainerBase.h:19
StreamBuffer::INVALID
Definition: StreamBuffer.h:119
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:31
GaudiRoot::RefAccessor::ContainedRef
SmartRef< ContainedObject > * ContainedRef
Definition: RootIOHandler.cpp:51
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
SmartRefBase::objectType
int objectType() const
Definition: SmartRefBase.h:110
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:209
Gaudi::Functional::details::put
Out1 * put(DataObjectHandle< Out1 > &out_handle, Out2 &&out)
Definition: FunctionalDetails.h:115