00001 #include "GaudiMP/TESSerializer.h"
00002
00003
00004 #include "GaudiKernel/IRegistry.h"
00005 #include "GaudiKernel/IDataManagerSvc.h"
00006 #include "GaudiKernel/IDataProviderSvc.h"
00007 #include "GaudiKernel/LinkManager.h"
00008 #include "GaudiKernel/DataObject.h"
00009 #include "GaudiKernel/DataStoreItem.h"
00010 #include "GaudiKernel/System.h"
00011 #include "GaudiKernel/GaudiException.h"
00012
00013
00014 #include "GaudiKernel/IOpaqueAddress.h"
00015 #include "GaudiKernel/GenericAddress.h"
00016 #include "GaudiKernel/ClassID.h"
00017 #include "GaudiKernel/KeyedContainer.h"
00018
00019 #include "GaudiKernel/MsgStream.h"
00020
00021
00022 #include "TROOT.h"
00023 #include "TClass.h"
00024 #include "TInterpreter.h"
00025 #include "TBufferFile.h"
00026
00027 #include <map>
00028
00029
00030 #define SERIALIZER_END "EOF"
00031
00032 namespace {
00033 struct DataObjectPush {
00034 DataObjectPush(DataObject*& p) {
00035 Gaudi::pushCurrentDataObject(&p);
00036 }
00037 ~DataObjectPush() {
00038 Gaudi::popCurrentDataObject();
00039 }
00040 };
00041 }
00042
00043 using namespace std;
00044
00045 bool GaudiMP::TESSerializer::analyse(IRegistry* dir, int level) {
00046 if ( level < m_currentItem->depth() ) {
00047 if ( dir->object() != 0 ) {
00048 m_objects.push_back(dir->object());
00049 return true;
00050 }
00051 }
00052 return false;
00053 }
00054
00056 GaudiMP::TESSerializer::TESSerializer( IDataProviderSvc* svc, IAddressCreator* ac )
00057 : m_TES(svc)
00058 , m_TESMgr(dynamic_cast<IDataManagerSvc*>(svc))
00059 , m_currentItem(0)
00060 , m_verifyItems(false)
00061 , m_strict(false)
00062 , m_addressCreator(ac)
00063 {
00064 }
00065
00067 void GaudiMP::TESSerializer::dumpBuffer(TBufferFile& buffer) {
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 StatusCode status;
00079 DataObject* obj;
00080
00081
00082 m_objects.erase(m_objects.begin(), m_objects.end());
00083
00084
00085 for ( Items::iterator i = m_itemList.begin(); i != m_itemList.end(); i++ ) {
00086 m_currentItem = (*i);
00087
00088 status = m_TES->retrieveObject(m_currentItem->path(), obj);
00089 if ( status.isSuccess() ) {
00090 m_TESMgr->traverseSubTree(obj, this);
00091 }
00092 else {
00093 string text("WARNING: Cannot retrieve TES object(s) for serialisation: ");
00094 text += m_currentItem->path();
00095 if ( m_strict ) {
00096 throw GaudiException(text + m_currentItem->path(), "", status);
00097 } else {
00098 cout << text << endl;
00099
00100 }
00101 }
00102 }
00103
00104 for ( Items::iterator i = m_optItemList.begin(); i != m_optItemList.end(); i++ ) {
00105 m_currentItem = (*i);
00106
00107 status= m_TES->retrieveObject(m_currentItem->path(), obj);
00108 if ( status.isSuccess() ) {
00109 m_TESMgr->traverseSubTree(obj, this);
00110 }
00111 }
00112
00113
00114 buffer.WriteInt(m_objects.size());
00115
00116 for(Objects::iterator i = m_objects.begin(); i != m_objects.end(); ++i) {
00117 DataObject* pObj = (*i);
00118 DataObjectPush p(pObj);
00119
00120
00121 TClass* cl;
00122 const type_info& objClass = typeid(*pObj);
00123
00124 string objClassName = System::typeinfoName(objClass);
00125
00126
00127
00128 if (m_classMap[objClassName]) {
00129 cl=m_classMap[objClassName];
00130 } else {
00131
00132 const char* clName = objClassName.c_str();
00133
00134 cl = gROOT->GetClass(clName);
00135 m_classMap[objClassName]=cl;
00136 }
00137
00138
00139 if (cl==0){
00140 if ( m_strict ) {
00141 throw GaudiException("gROOT->GetClass cannot find clName", objClassName, StatusCode::FAILURE);
00142 } else {
00143 cout << "WARNING: gROOT->GetClass fails for clname : "
00144 << objClassName.c_str() << endl;
00145 cout << "WARNING: Disregarding " << objClassName.c_str()
00146 << "erasing from object list" << endl;
00147 m_objects.erase( i );
00148 continue;
00149 }
00150 }
00151
00152
00153 std::string loc=pObj->registry()->identifier();
00154 buffer.WriteString(loc.c_str());
00155 buffer.WriteString(cl->GetName());
00156 cl->Streamer(pObj,buffer);
00157
00158
00159 LinkManager* linkMgr = pObj->linkMgr();
00160 int numLinks = linkMgr->size();
00161 buffer.WriteInt(numLinks);
00162
00163 for (int it = 0; it != numLinks; it++) {
00164 const string& link = linkMgr->link(it)->path();
00165 buffer.WriteString(link.c_str());
00166 }
00167
00168
00169
00170 IOpaqueAddress* iop = pObj->registry()->address();
00171 if (iop) {
00172 buffer.WriteInt(1);
00173 const string * par = iop->par();
00174 long svcType = iop->svcType();
00175 long clid = iop->clID();
00176 buffer.WriteLong(svcType);
00177 buffer.WriteLong(clid);
00178 buffer.WriteString(par->c_str());
00179 } else {
00180 buffer.WriteInt(0);
00181 }
00182
00183 }
00184
00185
00186
00187 buffer.WriteString(SERIALIZER_END);
00188
00189 }
00190
00192 void GaudiMP::TESSerializer::loadBuffer(TBufferFile& buffer) {
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 int nObjects;
00207
00208
00209 StatusCode sc, registerStat, createAddressStat;
00210
00211
00212 buffer.SetReadMode();
00213 buffer.SetBufferOffset();
00214
00215 buffer.ReadInt(nObjects);
00216 for (int i=0; i<nObjects; ++i) {
00217 char text[4096];
00218 buffer.ReadString(text,sizeof(text));
00219 string location(text);
00220 if (!location.compare("EOF")) {
00221
00222
00223 break;
00224 }
00225 buffer.ReadString(text,sizeof(text));
00226 TClass* cl = gROOT->GetClass(text);
00227 if (cl==0){
00228 if ( m_strict ) {
00229 throw GaudiException("gROOT->GetClass cannot find clName", text, StatusCode::FAILURE);
00230 } else {
00231 cout << "TESSerializer WARNING : gROOT->GetClass fails for clname : " << location.c_str() << endl;
00232 continue;
00233 }
00234 }
00235
00237 DataObject* obj = (DataObject*)cl->New();
00238 DataObjectPush push(obj);
00239 cl->Streamer(obj, buffer);
00240
00241
00242
00243 if ( obj ) {
00244 int nlink = 0;
00245 LinkManager* lnkMgr = obj->linkMgr();
00246 buffer.ReadInt(nlink);
00247
00248 for (int j = 0; j < nlink; ++j) {
00249 buffer.ReadString(text,sizeof(text));
00250 lnkMgr->addLink(text,0);
00251 }
00252 }
00253
00254
00255 registerStat = m_TES->registerObject(location, obj);
00256 if (registerStat.isFailure()) {
00257 DataObject* dummy = NULL;
00258 if ( location == "/Event" ) {
00259 sc = m_TESMgr->setRoot(location, obj);
00260 if(sc.isFailure())
00261 throw GaudiException("Cannot set root at location " + location, "", sc);
00262 }
00263 else {
00264 m_TES->findObject(location, dummy);
00265 if(!dummy)
00266 m_TES->registerObject(location, obj);
00267 else {
00268
00269
00270 int flag(0);
00271 buffer.ReadInt(flag);
00272 if (flag) {
00273 long svcType;
00274 buffer.ReadLong(svcType);
00275 long clid;
00276 buffer.ReadLong(clid);
00277 buffer.ReadString(text, sizeof(text));
00278 }
00279 continue;
00280 }
00281 }
00282 }
00283
00284
00285
00286
00287
00288 int flag(0);
00289 buffer.ReadInt(flag);
00290
00291 if (flag==1) {
00292
00293 IOpaqueAddress* iop;
00294 IOpaqueAddress*& iopref = iop;
00295
00296 long svcType;
00297 buffer.ReadLong(svcType);
00298
00299 long clid;
00300 buffer.ReadLong(clid);
00301 const CLID classid(clid);
00302
00303 char * cp;
00304 cp = buffer.ReadString(text, sizeof(text));
00305 const string opaque(cp);
00306
00307
00308 const string& p2="";
00309 unsigned long ip1(0);
00310 unsigned long ip2(0);
00311 GenericAddress gadd(svcType, classid, opaque, p2, ip1, ip2);
00312
00313
00314 createAddressStat = m_addressCreator->createAddress( gadd.svcType(), gadd.clID(), gadd.par(), gadd.ipar(), iopref );
00315 if (createAddressStat.isFailure()) {
00316 throw GaudiException("Failure in creating OpaqueAddress for reconstructed registry", "", createAddressStat);
00317 }
00318
00319 obj->registry()->setAddress(iop);
00320 }
00321
00322 }
00323 }
00324
00325
00327 void GaudiMP::TESSerializer::addItem(Items& itms, const std::string& descriptor) {
00328
00329 int level = 0;
00330
00331 std::string slevel;
00332 std::string obj_path;
00333
00334
00335 size_t sep = descriptor.rfind("#");
00336 if (sep > descriptor.length()) {
00337
00338 obj_path = descriptor;
00339 slevel = "1";
00340 } else {
00341
00342 obj_path = descriptor.substr(0,sep);
00343 slevel = descriptor.substr(sep+1);
00344 }
00345
00346
00347 if ( slevel == "*" ) {
00348 level = 9999999;
00349 }
00350 else {
00351 level = atoi(slevel.c_str());
00352 }
00353
00354
00355 if ( m_verifyItems ) {
00356 size_t idx = obj_path.find("/",1);
00357 while(idx != std::string::npos) {
00358 std::string sub_item = obj_path.substr(0,idx);
00359 if ( 0 == findItem(sub_item) ) {
00360 cout << "... calling addItem with arg : " << sub_item << endl;
00361 addItem(itms, sub_item);
00362 }
00363 idx = obj_path.find("/",idx+1);
00364 }
00365 }
00366 DataStoreItem* item = new DataStoreItem(obj_path, level);
00367
00368
00369
00370 itms.push_back( item );
00371 }
00372
00374 void GaudiMP::TESSerializer::addItem(const std::string& path) {
00375
00376 addItem( m_itemList, path );
00377 }
00378
00380 void GaudiMP::TESSerializer::addOptItem(const std::string& path) {
00381
00382 addItem( m_optItemList, path);
00383 }
00384
00386 void GaudiMP::TESSerializer::checkItems( ) {
00387 cout << "TESSerializer m_itemList : " << m_itemList.size() << " Items"<< endl;
00388 for(Items::const_iterator i=m_itemList.begin(); i != m_itemList.end(); ++i) {
00389 cout << "\tItem : " << (*i)->path() << endl;
00390 }
00391 cout << "TESSerializer m_optItemList : " << m_optItemList.size() << " Items" << endl;
00392 for(Items::const_iterator i=m_optItemList.begin(); i != m_optItemList.end(); ++i) {
00393 cout << "\tItem : " << (*i)->path() << endl;
00394 }
00395 }
00396
00398 DataStoreItem*
00399 GaudiMP::TESSerializer::findItem(const std::string& path) {
00400 for(Items::const_iterator i=m_itemList.begin(); i != m_itemList.end(); ++i) {
00401 if ( (*i)->path() == path ) return (*i);
00402 }
00403 for(Items::const_iterator j=m_optItemList.begin(); j != m_optItemList.end(); ++j) {
00404 if ( (*j)->path() == path ) return (*j);
00405 }
00406 return 0;
00407 }
00408