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