The Gaudi Framework  master (181af51f)
Loading...
Searching...
No Matches
RootIOHandler.cpp
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations *
3* *
4* This software is distributed under the terms of the Apache version 2 licence, *
5* copied verbatim in the file "LICENSE". *
6* *
7* In applying this licence, CERN does not waive the privileges and immunities *
8* granted to it by virtue of its status as an Intergovernmental Organization *
9* or submit itself to any jurisdiction. *
10\***********************************************************************************/
11//====================================================================
12//
13// Package : RootCnv
14//
15// Description: Generate TClassStreamers for special Gaudi classes
16// @author M.Frank
17//====================================================================
23#include <GaudiKernel/System.h>
24#include <RootCnv/PoolClasses.h>
25#include <RootCnv/RootRefs.h>
26#include <TClass.h>
27#include <TClassStreamer.h>
28#include <TInterpreter.h>
29#include <TROOT.h>
30#include <TSystem.h>
31#include <iostream>
32#include <memory>
33#include <stdexcept>
34
35using namespace std;
36
37namespace GaudiRoot {
38 static const DataObject* last_link_object = nullptr;
39 static int last_link_hint = -1;
41 last_link_object = nullptr;
42 last_link_hint = -1;
43 }
44 void pushCurrentDataObject( DataObject** pobjAddr ) {
47 }
52
60
63 template <class T>
64 class IOHandler : public TClassStreamer {
65 protected:
67 TClass* m_root;
68
69 public:
71 IOHandler( TClass* c ) : m_root( c ) {}
73 void operator()( TBuffer& b, void* obj ) override {
74 try {
75 if ( b.IsReading() )
76 get( b, obj );
77 else
78 put( b, obj );
79 } catch ( const exception& e ) {
80 string err = "Class:" + string( m_root->GetName() ) + "> Exception in object I/O";
81 err += e.what();
82 throw runtime_error( err );
83 } catch ( ... ) {
84 string err = "Class:" + string( m_root->GetName() ) + "> Exception in object I/O";
85 throw runtime_error( err );
86 }
87 }
88
89 virtual void get( TBuffer& b, void* obj );
91 virtual void put( TBuffer& b, void* obj );
92 };
93
94 template <>
95 void IOHandler<SmartRefBase>::get( TBuffer& b, void* obj ) {
96 RefAccessor r( obj );
97 UInt_t start, count;
98 Version_t version = b.ReadVersion( &start, &count, m_root );
99 m_root->ReadBuffer( b, obj, version, start, count );
100 switch ( r.Base->objectType() ) {
103 break;
106 break;
107 default:
108 cout << "Hit uninitialized smartRef!!!!" << endl;
109 break;
110 }
111 }
112
113 template <>
114 void IOHandler<SmartRefBase>::put( TBuffer& b, void* obj ) {
115 RefAccessor r( obj );
117 DataObject * curr, *pDO;
118 int hint, link;
119
121 pDO = r.ObjectRef->data();
122 hint = r.ObjectRef->hintID();
123 link = r.ObjectRef->linkID();
124 if ( pDO ) {
125 switch ( r.Base->objectType() ) {
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;
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 UInt_t start, count;
173 Version_t version = b.ReadVersion( &start, &count, m_root );
174 m_root->ReadBuffer( b, obj, version, start, count );
177 }
178
179 template <>
180 void IOHandler<ContainedObject>::put( TBuffer& b, void* obj ) {
181 m_root->WriteBuffer( b, obj );
182 }
183
184 template <>
185 void IOHandler<pool::Token>::get( TBuffer& b, void* obj ) {
186 UInt_t start, count;
187 pool::Token* t = (pool::Token*)obj;
188 b.ReadVersion( &start, &count, m_root );
189 b.ReadFastArray( &t->m_oid.first, 2 );
190 b.CheckByteCount( start, count, m_root );
191 }
192
193 template <>
194 void IOHandler<pool::Token>::put( TBuffer&, void* ) {
195 throw runtime_error( "Writing POOL files is not implemented!" );
196 }
197
198 template <class T>
199 static bool makeStreamer( MsgStream& log ) {
200 string cl_name = System::typeinfoName( typeid( T ) );
201 TClass* c = gROOT->GetClass( cl_name.c_str() );
202 if ( c ) {
203 c->AdoptStreamer( new IOHandler<T>( c ) );
204 log << MSG::DEBUG << "Installed IOHandler for class " << cl_name << endmsg;
205 return true;
206 }
207 log << MSG::ERROR << "[No ROOT TClass] Failed to install IOHandler for class " << cl_name << endmsg;
208 return false;
209 }
210
212 static bool first = true;
213 if ( first ) {
214 first = false;
215#if ROOT_VERSION_CODE < ROOT_VERSION( 5, 99, 0 )
216 gSystem->Load( "libCintex" );
217 gROOT->ProcessLine( "Cintex::Cintex::Enable()" );
218 gROOT->ProcessLine( "#include <vector>" );
219 gInterpreter->EnableAutoLoading();
220 gInterpreter->AutoLoad( "DataObject" );
221 gInterpreter->AutoLoad( "PoolDbLinkManager" );
222 gSystem->Load( "libGaudiKernelDict" );
223 gSystem->Load( "libGaudiTestSuiteDict" );
224#else
225# if ROOT_VERSION_CODE < ROOT_VERSION( 6, 19, 0 )
226 gInterpreter->EnableAutoLoading();
227# else
228 gInterpreter->LoadLibraryMap();
229# endif
230 gInterpreter->AutoLoad( "DataObject" );
231 gInterpreter->AutoLoad( "PoolDbLinkManager" );
232#endif
233
234 bool b1 = makeStreamer<SmartRefBase>( s );
235 bool b2 = makeStreamer<ContainedObject>( s );
236 bool b3 = makeStreamer<pool::Token>( s );
237 return b1 && b2 && b3;
238 }
239 return true;
240 }
241} // namespace GaudiRoot
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition MsgStream.h:198
All classes that their objects may be contained in an LHCb ObjectContainer (e.g.
void setParent(ObjectContainerBase *value)
Update parent member.
const ObjectContainerBase * parent() const
Access to parent object.
virtual long index() const
Distance in the parent container.
A DataObject is the base class of any identifiable object on any data store.
Definition DataObject.h:37
IRegistry * registry() const
Get pointer to Registry.
Definition DataObject.h:79
LinkManager * linkMgr()
Retrieve Link manager.
Definition DataObject.h:81
TClass * m_root
ROOT persistent class description.
virtual void get(TBuffer &b, void *obj)
Callback for reading the object.
IOHandler(TClass *c)
Initializing constructor.
void operator()(TBuffer &b, void *obj) override
ROOT I/O callback.
virtual void put(TBuffer &b, void *obj)
Callback for writing the object.
The IRegistry represents the entry door to the environment any data object residing in a transient da...
Definition IRegistry.h:29
virtual const id_type & identifier() const =0
Full identifier (or key)
Definition of the MsgStream class used to transmit messages.
Definition MsgStream.h:29
ObjectContainerBase is the base class for Gaudi container classes.
User example objects: SmartRefBase.
void set(DataObject *pObj, long hint_id, long link_id)
Setup smart reference when reading. Must be allowed from external sources.
long objectType() const
Kernel objects: SmartRef.
Definition SmartRef.h:64
Shadow class to mimik POOL tokens.
Definition PoolClasses.h:35
GAUDI_API void pushCurrentDataObject(DataObject **pobjAddr)
GAUDI_API void popCurrentDataObject()
GAUDI_API DataObject * getCurrentDataObject()
void popCurrentDataObject()
void resetLastLink()
bool patchStreamers(MsgStream &log)
void pushCurrentDataObject(DataObject **pobjAddr)
@ DEBUG
Definition IMessageSvc.h:22
@ ERROR
Definition IMessageSvc.h:22
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition System.cpp:260
STL namespace.
SmartRef< DataObject > * ObjectRef
SmartRef< ContainedObject > * ContainedRef