The Gaudi Framework  master (e98cfcff)
Loading...
Searching...
No Matches
RootIOHandler.cpp
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2026 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/RootRefs.h>
25#include <TClass.h>
26#include <TClassStreamer.h>
27#include <TInterpreter.h>
28#include <TROOT.h>
29#include <TSystem.h>
30#include <iostream>
31#include <memory>
32#include <stdexcept>
33
34using namespace std;
35
36namespace GaudiRoot {
37 static const DataObject* last_link_object = nullptr;
38 static int last_link_hint = -1;
40 last_link_object = nullptr;
41 last_link_hint = -1;
42 }
43 void pushCurrentDataObject( DataObject** pobjAddr ) {
46 }
51
59
62 template <class T>
63 class IOHandler : public TClassStreamer {
64 protected:
66 TClass* m_root;
67
68 public:
70 IOHandler( TClass* c ) : m_root( c ) {}
72 void operator()( TBuffer& b, void* obj ) override {
73 try {
74 if ( b.IsReading() )
75 get( b, obj );
76 else
77 put( b, obj );
78 } catch ( const exception& e ) {
79 string err = "Class:" + string( m_root->GetName() ) + "> Exception in object I/O";
80 err += e.what();
81 throw runtime_error( err );
82 } catch ( ... ) {
83 string err = "Class:" + string( m_root->GetName() ) + "> Exception in object I/O";
84 throw runtime_error( err );
85 }
86 }
87
88 virtual void get( TBuffer& b, void* obj );
90 virtual void put( TBuffer& b, void* obj );
91 TClassStreamer* Generate() const override { return new IOHandler( *this ); }
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 );
175 ContainedObject* p = static_cast<ContainedObject*>( obj );
177 }
178
179 template <>
180 void IOHandler<ContainedObject>::put( TBuffer& b, void* obj ) {
181 m_root->WriteBuffer( b, obj );
182 }
183
184 template <class T>
185 static bool makeStreamer( MsgStream& log ) {
186 string cl_name = System::typeinfoName( typeid( T ) );
187 TClass* c = gROOT->GetClass( cl_name.c_str() );
188 if ( c ) {
189 c->AdoptStreamer( new IOHandler<T>( c ) );
190 log << MSG::DEBUG << "Installed IOHandler for class " << cl_name << endmsg;
191 return true;
192 }
193 log << MSG::ERROR << "[No ROOT TClass] Failed to install IOHandler for class " << cl_name << endmsg;
194 return false;
195 }
196
198 static bool first = true;
199 if ( first ) {
200 first = false;
201 gInterpreter->LoadLibraryMap();
202 gInterpreter->AutoLoad( "DataObject" );
203
204 bool b1 = makeStreamer<SmartRefBase>( s );
205 bool b2 = makeStreamer<ContainedObject>( s );
206 return b1 && b2;
207 }
208 return true;
209 }
210} // 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
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