| The Gaudi Framework v27r1

- 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/ObjectContainerBase.h"
9 #include "GaudiKernel/LinkManager.h"
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) {
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> 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() ) {
92 case SmartRefBase::DATAOBJECT:
93 (*r.ObjectRef)(Gaudi::getCurrentDataObject());
94 break;
95 case SmartRefBase::CONTAINEDOBJECT:
96 (*r.ContainedRef)(Gaudi::getCurrentDataObject());
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
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."
130 << endl;
131 throw runtime_error("IOHandler<SmartRefBase>::onWrite> "
132 "Found invalid smart reference with object "
133 "having no parent.");
134 break;
135 case SmartRefBase::DATAOBJECT:
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;
168 p->setParent((ObjectContainerBase*)Gaudi::getCurrentDataObject());
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
199 bool patchStreamers(MsgStream& s) {
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 }
GaudiRoot::IOHandler::IOHandler
IOHandler(TClass *c)
Initializing constructor.
Definition: RootIOHandler.cpp:59
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
GaudiRoot::popCurrentDataObject
void popCurrentDataObject()
Definition: RootIOHandler.cpp:38
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:297
Gaudi::popCurrentDataObject
GAUDI_API void popCurrentDataObject()
Definition: RootIOHandler.cpp:38
Gaudi::getCurrentDataObject
GAUDI_API DataObject * getCurrentDataObject()
std::log
T log(T...args)
gaudirun.c
tuple c
Definition: gaudirun.py:391
GaudiRoot::pushCurrentDataObject
void pushCurrentDataObject(DataObject **pobjAddr)
Definition: RootIOHandler.cpp:34
MSG::DEBUG
Definition: IMessageSvc.h:18
std::endl
T endl(T...args)
ContainedObject::index
virtual long index() const
Distance in the parent container.
Definition: ContainedObject.h:54
PoolClasses.h
std
STL namespace.
ObjectContainerBase.h
GaudiRoot::patchStreamers
bool patchStreamers(MsgStream &log)
Definition: RootIOHandler.cpp:199
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:58
GaudiRoot::IOHandler::m_root
TClass * m_root
ROOT persistent class description.
Definition: RootIOHandler.cpp:56
ContainedObject::parent
const ObjectContainerBase * parent() const
Access to parent object.
Definition: ContainedObject.h:49
DataObject::registry
IRegistry * registry() const
Get pointer to Registry.
Definition: DataObject.h:74
DataObject::linkMgr
LinkManager * linkMgr() const
Retrieve Link manager.
Definition: DataObject.h:78
std::string
STL class.
pool::Token::m_oid
std::pair< int, int > m_oid
Object global identifier.
Definition: PoolClasses.h:27
pool::Token
Shadow class to mimik POOL tokens.
Definition: PoolClasses.h:20
GaudiRoot::RefAccessor::RefAccessor
RefAccessor(void *obj)
Definition: RootIOHandler.cpp:48
RootRefs.h
SmartRefBase::CONTAINEDOBJECT
Definition: SmartRefBase.h:60
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: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
All classes that their objects may be contained in an LHCb ObjectContainer (e.g.
Definition: ContainedObject.h:29
GaudiPython.Persistency.get
def get(type_)
Definition: Persistency.py:23
SmartRefBase::DATAOBJECT
Definition: SmartRefBase.h:60
std::string::c_str
T c_str(T...args)
SmartRef.h
GaudiRoot::IOHandler
Definition: RootIOHandler.cpp:53
ContainedObject::setParent
void setParent(ObjectContainerBase *value)
Update parent member.
Definition: ContainedObject.h:51
gaudirun.s
string s
Definition: gaudirun.py:245
MSG::ERROR
Definition: IMessageSvc.h:21
GaudiRoot::RefAccessor::ObjectRef
SmartRef< DataObject > * ObjectRef
Definition: RootIOHandler.cpp:46
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:117
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
SmartRefBase::objectType
int objectType() const
Definition: SmartRefBase.h:111
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
IOTest.start
tuple start
Definition: IOTest.py:88