| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

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

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
RootIOHandler.cpp
Go to the documentation of this file.
1 // $Id: RootIOHandler.cpp,v 1.3 2010-09-27 15:43:53 frankb Exp $
2 //====================================================================
3 //
4 // Package : RootCnv
5 //
6 // Description: Generate TClassStreamers for special Gaudi classes
7 // @author M.Frank
8 //====================================================================
9 #include "GaudiKernel/ObjectContainerBase.h"
10 #include "GaudiKernel/LinkManager.h"
11 #include "GaudiKernel/IRegistry.h"
12 #include "GaudiKernel/MsgStream.h"
13 #include "GaudiKernel/SmartRef.h"
14 #include "GaudiKernel/System.h"
15 #include "RootCnv/RootRefs.h"
16 #include "RootCnv/PoolClasses.h"
17 #include <stdexcept>
18 #include <iostream>
19 #include "TROOT.h"
20 #include "TClass.h"
21 #include "TSystem.h"
22 #include "TInterpreter.h"
23 #include "TClassStreamer.h"
24 #include <memory>
25
26 using namespace std;
27
28 namespace GaudiRoot {
29 static const DataObject* last_link_object = 0;
30 static int last_link_hint = -1;
31 void resetLastLink() {
32 last_link_object = 0;
33 last_link_hint = -1;
34 }
35 void pushCurrentDataObject(DataObject** pobjAddr) {
36 Gaudi::pushCurrentDataObject(pobjAddr);
37 resetLastLink();
38 }
39 void popCurrentDataObject() {
40 Gaudi::popCurrentDataObject();
41 resetLastLink();
42 }
43
44 union RefAccessor {
45 void* Ptr;
46 SmartRefBase* Base;
47 SmartRef<DataObject>* ObjectRef;
48 SmartRef<ContainedObject>* ContainedRef;
49 RefAccessor(void* obj) { Ptr = obj; }
50 };
51
54 template <class T> class IOHandler : public TClassStreamer {
55 protected:
57 TClass* m_root;
58 public:
60 IOHandler(TClass* c) : m_root(c) { }
62 virtual ~IOHandler() { }
64 virtual void operator()(TBuffer &b, void *obj) {
65 try {
66 if ( b.IsReading() )
67 get(b,obj);
68 else
69 put(b,obj);
70 }
71 catch( const exception& e ) {
72 string err = "Class:" + string(m_root->GetName()) + "> Exception in object I/O";
73 err += e.what();
74 throw runtime_error(err);
75 }
76 catch( ... ) {
77 string err = "Class:" + string(m_root->GetName()) + "> Exception in object I/O";
78 throw runtime_error(err);
79 }
80 }
82 virtual void get(TBuffer &b, void* obj);
84 virtual void put(TBuffer &b, void* obj);
85 };
86
87 template <> void IOHandler<SmartRefBase>::get(TBuffer &b, void* obj) {
88 RefAccessor r(obj);
89 UInt_t start, count;
90 Version_t version = b.ReadVersion(&start, &count, m_root);
91 m_root->ReadBuffer(b, obj, version, start, count);
92 switch( r.Base->objectType() ) {
93 case SmartRefBase::DATAOBJECT:
94 (*r.ObjectRef)(Gaudi::getCurrentDataObject());
95 break;
96 case SmartRefBase::CONTAINEDOBJECT:
97 (*r.ContainedRef)(Gaudi::getCurrentDataObject());
98 break;
99 default:
100 cout << "Hit uninitialized smartRef!!!!" << endl;
101 break;
102 }
103 }
104
105 template <> void IOHandler<SmartRefBase>::put(TBuffer &b, void* obj) {
106 RefAccessor r(obj);
107 ContainedObject* p;
108 DataObject* curr, *pDO;
109 int hint, link;
110
111 curr = Gaudi::getCurrentDataObject();
112 pDO = r.ObjectRef->data();
113 hint = r.ObjectRef->hintID();
114 link = r.ObjectRef->linkID();
115 if ( pDO ) {
116 switch( r.Base->objectType() ) {
117 case SmartRefBase::CONTAINEDOBJECT:
118 p = r.ContainedRef->data();
119 if ( p ) {
120 const ObjectContainerBase* parent = p->parent();
121 if ( parent ) {
122 link = p->index();
123 pDO = const_cast<ObjectContainerBase*>(parent);
124 break;
125 }
126 }
127 pDO = 0;
128 cout << "IOHandler<SmartRefBase>::onWrite> "
129 << "Found invalid smart reference with object "
130 << "having no parent."
131 << endl;
132 throw runtime_error("IOHandler<SmartRefBase>::onWrite> "
133 "Found invalid smart reference with object "
134 "having no parent.");
135 break;
136 case SmartRefBase::DATAOBJECT:
137 link = StreamBuffer::INVALID;
138 break;
139 default:
140 break;
141 }
142 if ( pDO == last_link_object ) {
143 r.Base->set(curr, last_link_hint, link);
144 m_root->WriteBuffer(b, obj);
145 return;
146 }
147 else if ( pDO ) {
148 LinkManager* mgr = curr->linkMgr();
149 IRegistry* reg = pDO->registry();
150 if ( reg && mgr ) {
151 hint = mgr->addLink(reg->identifier(), pDO);
152 last_link_hint = hint;
153 last_link_object = pDO;
154 }
155 }
156 else {
157 hint = link = StreamBuffer::INVALID;
158 }
159 }
160 r.Base->set(curr, hint, link);
161 m_root->WriteBuffer(b, obj);
162 }
163
164 template <> void IOHandler<ContainedObject>::get(TBuffer &b, void* obj) {
165 UInt_t start, count;
166 Version_t version = b.ReadVersion(&start, &count, m_root);
167 m_root->ReadBuffer(b, obj, version, start, count);
168 ContainedObject* p = (ContainedObject*)obj;
169 p->setParent((ObjectContainerBase*)Gaudi::getCurrentDataObject());
170 }
171
172 template <> void IOHandler<ContainedObject>::put(TBuffer &b, void* obj) {
173 m_root->WriteBuffer(b, obj);
174 }
175
176 template <> void IOHandler<pool::Token>::get(TBuffer &b, void* obj) {
177 UInt_t start, count;
178 pool::Token* t = (pool::Token*)obj;
179 b.ReadVersion(&start, &count, m_root);
180 b.ReadFastArray(&t->m_oid.first, 2);
181 b.CheckByteCount(start, count, m_root);
182 }
183
184 template <> void IOHandler<pool::Token>::put(TBuffer &, void* ) {
185 throw runtime_error("Writing POOL files is not implemented!");
186 }
187
188 template <class T> static bool makeStreamer(MsgStream& log) {
189 string cl_name = System::typeinfoName(typeid(T));
190 TClass* c = gROOT->GetClass(cl_name.c_str());
191 if ( c ) {
192 TClassStreamer* s = new IOHandler<T>(c);
193 c->AdoptStreamer(s);
194 log << MSG::DEBUG << "Installed IOHandler for class " << cl_name << endmsg;
195 return true;
196 }
197 log << MSG::ERROR << "[No ROOT TClass] Failed to install IOHandler for class " << cl_name << endmsg;
198 return false;
199 }
200
201 bool patchStreamers(MsgStream& s) {
202 static bool first = true;
203 if ( first ) {
204 first = false;
205 #if ROOT_VERSION_CODE < ROOT_VERSION(5,99,0)
206 gSystem->Load("libCintex");
207 gROOT->ProcessLine("Cintex::Cintex::Enable()");
208 gROOT->ProcessLine("#include <vector>");
209 gInterpreter->EnableAutoLoading();
210 gInterpreter->AutoLoad("DataObject");
211 gInterpreter->AutoLoad("PoolDbLinkManager");
212 gSystem->Load("libGaudiKernelDict");
213 gSystem->Load("libGaudiExamplesDict");
214 #else
215 gInterpreter->EnableAutoLoading();
216 gInterpreter->AutoLoad("DataObject");
217 gInterpreter->AutoLoad("PoolDbLinkManager");
218 #endif
219
220
221 bool b1 = makeStreamer<SmartRefBase>(s);
222 bool b2 = makeStreamer<ContainedObject>(s);
223 bool b3 = makeStreamer<pool::Token>(s);
224 return b1 && b2 && b3;
225 }
226 return true;
227 }
228 }