The Gaudi Framework  master (b9786168)
Loading...
Searching...
No Matches
RootIOHandler.cpp
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2025 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 TClassStreamer* Generate() const override { return new IOHandler( *this ); }
93 };
94
95 template <>
96 void IOHandler<SmartRefBase>::get( TBuffer& b, void* obj ) {
97 RefAccessor r( obj );
98 UInt_t start, count;
99 Version_t version = b.ReadVersion( &start, &count, m_root );
100 m_root->ReadBuffer( b, obj, version, start, count );
101 switch ( r.Base->objectType() ) {
104 break;
107 break;
108 default:
109 cout << "Hit uninitialized smartRef!!!!" << endl;
110 break;
111 }
112 }
113
114 template <>
115 void IOHandler<SmartRefBase>::put( TBuffer& b, void* obj ) {
116 RefAccessor r( obj );
118 DataObject * curr, *pDO;
119 int hint, link;
120
122 pDO = r.ObjectRef->data();
123 hint = r.ObjectRef->hintID();
124 link = r.ObjectRef->linkID();
125 if ( pDO ) {
126 switch ( r.Base->objectType() ) {
128 p = r.ContainedRef->data();
129 if ( p ) {
130 const ObjectContainerBase* parent = p->parent();
131 if ( parent ) {
132 link = p->index();
133 pDO = const_cast<ObjectContainerBase*>( parent );
134 break;
135 }
136 }
137 pDO = nullptr;
138 cout << "IOHandler<SmartRefBase>::onWrite> "
139 << "Found invalid smart reference with object "
140 << "having no parent." << endl;
141 throw runtime_error( "IOHandler<SmartRefBase>::onWrite> "
142 "Found invalid smart reference with object "
143 "having no parent." );
144 break;
147 break;
148 default:
149 break;
150 }
151 if ( pDO == last_link_object ) {
152 r.Base->set( curr, last_link_hint, link );
153 m_root->WriteBuffer( b, obj );
154 return;
155 } else if ( pDO ) {
156 LinkManager* mgr = curr->linkMgr();
157 IRegistry* reg = pDO->registry();
158 if ( reg && mgr ) {
159 hint = mgr->addLink( reg->identifier(), pDO );
160 last_link_hint = hint;
161 last_link_object = pDO;
162 }
163 } else {
164 hint = link = StreamBuffer::INVALID;
165 }
166 }
167 r.Base->set( curr, hint, link );
168 m_root->WriteBuffer( b, obj );
169 }
170
171 template <>
172 void IOHandler<ContainedObject>::get( TBuffer& b, void* obj ) {
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 = static_cast<ContainedObject*>( obj );
178 }
179
180 template <>
181 void IOHandler<ContainedObject>::put( TBuffer& b, void* obj ) {
182 m_root->WriteBuffer( b, obj );
183 }
184
185 template <>
186 void IOHandler<pool::Token>::get( TBuffer& b, void* obj ) {
187 UInt_t start, count;
188 pool::Token* t = (pool::Token*)obj;
189 b.ReadVersion( &start, &count, m_root );
190 b.ReadFastArray( &t->m_oid.first, 2 );
191 b.CheckByteCount( start, count, m_root );
192 }
193
194 template <>
195 void IOHandler<pool::Token>::put( TBuffer&, void* ) {
196 throw runtime_error( "Writing POOL files is not implemented!" );
197 }
198
199 template <class T>
200 static bool makeStreamer( MsgStream& log ) {
201 string cl_name = System::typeinfoName( typeid( T ) );
202 TClass* c = gROOT->GetClass( cl_name.c_str() );
203 if ( c ) {
204 c->AdoptStreamer( new IOHandler<T>( c ) );
205 log << MSG::DEBUG << "Installed IOHandler for class " << cl_name << endmsg;
206 return true;
207 }
208 log << MSG::ERROR << "[No ROOT TClass] Failed to install IOHandler for class " << cl_name << endmsg;
209 return false;
210 }
211
213 static bool first = true;
214 if ( first ) {
215 first = false;
216 gInterpreter->LoadLibraryMap();
217 gInterpreter->AutoLoad( "DataObject" );
218 gInterpreter->AutoLoad( "PoolDbLinkManager" );
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
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.
TClassStreamer * Generate() const override
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