Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

NTupleSvc.cpp

Go to the documentation of this file.
00001 //====================================================================
00002 //  NTupleSvc.cpp
00003 //--------------------------------------------------------------------
00004 //
00005 //  Package   : GaudiSvc/NTupleSvc ( The LHCb Offline System)
00006 //
00007 //  Description: implementation of the NTuple service
00008 //
00009 //  Author    : M.Frank
00010 //  History   :
00011 // +---------+----------------------------------------------+---------
00012 // |    Date |                 Comment                      | Who     
00013 // +---------+----------------------------------------------+---------
00014 // | 29/10/98| Initial version                              | MF
00015 // | 29/09/99| Added access to ICnvManager for missing      | 
00016 // |         | converters                                   | MF
00017 // | 20/09/00| Connect dynamically to conversion service    |
00018 // |         | for N-tuple persistency                      | MF
00019 // +---------+----------------------------------------------+---------
00020 //
00021 //====================================================================
00022 #define  GAUDISVC_NTUPLESVC_CPP
00023 
00024 // Framework include files
00025 #include "GaudiKernel/xtoa.h"
00026 #include "GaudiKernel/SmartIF.h"
00027 #include "GaudiKernel/Tokenizer.h"
00028 #include "GaudiKernel/SvcFactory.h"
00029 #include "GaudiKernel/DataObject.h"
00030 #include "GaudiKernel/ObjectFactory.h"
00031 #include "GaudiKernel/GenericAddress.h"
00032 
00033 #include "GaudiKernel/IProperty.h"
00034 #include "GaudiKernel/ISvcManager.h"
00035 #include "GaudiKernel/ISvcLocator.h"
00036 #include "GaudiKernel/IDataSelector.h"
00037 #include "GaudiKernel/IConversionSvc.h"
00038 
00039 #include "GaudiKernel/MsgStream.h"
00040 #include "GaudiKernel/RegistryEntry.h"
00041 #include "GaudiKernel/DataSelectionAgent.h"
00042 #include "GaudiKernel/Property.h"
00043 #include "GaudiKernel/NTupleImplementation.h"
00044 #include "GaudiKernel/Selector.h"
00045 #include "GaudiKernel/ConversionSvc.h"
00046 
00047 #include "NTupleSvc.h"
00048 
00049 // Instantiation of a static factory class used by clients to create
00050 // instances of this service
00051 static SvcFactory<NTupleSvc>          s_factory;
00052 const ISvcFactory& NTupleSvcFactory = s_factory;
00053 
00055 ObjectFactory<NTuple::Selector> s_NTupleSelectorFactory;
00056 const IFactory& NTupleSelectorFactory = s_NTupleSelectorFactory;
00057 
00059 NTupleSvc::NTupleSvc(const std::string& name, ISvcLocator* svc)
00060  : DataSvc(name, svc)
00061 {
00062   declareProperty("Input",  m_input);
00063   declareProperty("Output", m_output);
00064   declareProperty("StoreName", m_storeName = "/NTUPLES");
00065 }
00066 
00068 NTupleSvc::~NTupleSvc()   {
00069 }
00070 
00072 StatusCode NTupleSvc::initialize()     {
00073   StatusCode status = DataSvc::initialize();
00074   MsgStream log ( msgSvc(), name() );
00075 
00076   if ( status.isSuccess() )   {
00077     status = setProperties();
00078     if ( status.isSuccess() )   {
00079       DataObject* root = new DataObject();
00080       status = setRoot(m_storeName, root);
00081       for ( DBaseEntries::iterator i = m_output.begin(); i != m_output.end(); i++ )    {
00082         StatusCode iret = connect(*i);
00083         if ( !iret.isSuccess() )    {
00084           status = iret;
00085         }
00086       }
00087       for ( DBaseEntries::iterator j = m_input.begin(); j != m_input.end(); j++ )    {
00088         StatusCode iret = connect(*j);
00089         if ( !iret.isSuccess() )    {
00090           status = iret;
00091         }
00092       }
00093     }
00094   }
00095   return status;
00096 }
00097 
00098 // Check if a datasource is connected
00099 bool NTupleSvc::isConnected(const std::string& identifier)   const    {
00100   Connections::const_iterator i = m_connections.find(identifier);
00101   return i==m_connections.end();
00102 }
00103 
00104 StatusCode NTupleSvc::loadObject(IDataDirectory* pDirectory)   {
00105   StatusCode status = INVALID_OBJ_ADDR;
00106   DataObject* obj = 0;
00107   if ( 0 == pDirectory->address() )  {                          // Precondition:
00108     return INVALID_OBJ_ADDR;                                    // Addres must be valid
00109   }
00110   try   {
00111     long len = m_storeName.length();
00112     std::string full = pDirectory->fullpath();
00113     std::string path = full.substr(0, full.find(IDataDirectory::SEPARATOR,len+1));
00114     Connections::iterator i = m_connections.find(path);
00115     if ( i != m_connections.end() )   {
00116       status = (*i).second->createObj(pDirectory->address(), obj);
00117       if ( status.isSuccess() )   {
00118         NTuple::TupleImp* imp = dynamic_cast<NTuple::TupleImp*>(obj);
00119         if ( 0 != imp )   {
00120           imp->setConversionSvc((*i).second);
00121           return status;
00122         }
00123       }
00124     }
00125     else    {
00126       status = NO_DATA_LOADER;
00127     }
00128   }
00129   catch(...)    {
00130     status = StatusCode::FAILURE;
00131   }
00132   return status;
00133 }
00134 
00135 StatusCode NTupleSvc::updateDirectories()   {
00136   long need_update = 0;
00137   DataObject* pO = 0;
00138   StatusCode iret = findObject(m_storeName, pO);
00139   MsgStream log ( msgSvc(), name() );
00140   //  log << MSG::DEBUG << "in finalize()" << endreq;
00141   if ( iret.isSuccess() )   {
00142     DataSelectionAgent agent;
00143     DataObject::DirIterator d;
00144     IDataSelector* selection = agent.selectedObjects();
00145     IDataSelector sel, files;
00146     // Only traverse the tree below the files
00147     for ( d = pO->dirBegin(); d != pO->dirEnd(); d++ )    {
00148       sel.erase(sel.begin(), sel.end());
00149       if ( (*d)->object() )   {
00150         IOpaqueAddress* pA = (*d)->address();
00151         if ( pA )   {
00152           char typ = pA->genericLink()->genericInfo()->m_info[1];
00153           if ( typ == 'N' || typ == 'U' )   {
00154             traverseSubTree ( (*d)->object(), &agent );
00155             while ( selection->size() > 0 )    {
00156               DataObject* o = selection->back();
00157 //              if ( o->clID() == CLID_NTupleDirectory || o->clID() == CLID_NTupleFile )    {
00158                 log << MSG::DEBUG << "Update " << o->fullpath() << endreq;
00159                 sel.push_back( o );
00160 //              }
00161               selection->pop_back();
00162             }
00163             // ...starting from the file entries: first save the directories/ntuples
00164             Connections::iterator i = m_connections.find((*d)->fullpath());
00165             if ( i != m_connections.end() )   {
00166               need_update += sel.size();
00167               iret = (*i).second->updateReps ( &sel );
00168             }
00169           }
00170         }
00171       }
00172     }
00173   }
00174   if ( !iret.isSuccess() )    {
00175     log << MSG::ERROR << "ERROR while saving NTuples" << endreq;
00176     return iret;
00177   }
00178   else if ( need_update > 0 )    {
00179     log << MSG::INFO << "ALL NTuples saved successfully" << endreq;
00180   }
00181   return iret;
00182 }
00183 
00184 // Close all open connections
00185 StatusCode NTupleSvc::disconnect(const std::string& nam)      {
00186   Connections::iterator i = m_connections.find(nam);
00187   if ( i != m_connections.end() )    {
00188     SmartIF<IService> isvc(IID_IService, (*i).second);
00189     if ( isvc.isValid( ) )   {
00190       isvc->finalize();
00191     }
00192     (*i).second->release();
00193     (*i).second = 0;
00194     m_connections.erase(i);
00195     return StatusCode::SUCCESS;
00196   }
00197   return StatusCode::FAILURE;
00198 }
00199 
00200 // Close all open connections
00201 StatusCode NTupleSvc::disconnectAll()      {
00202   for ( Connections::iterator i = m_connections.begin(); i != m_connections.end(); i++ )    {
00203     SmartIF<IService> isvc(IID_IService, (*i).second);
00204     if ( isvc.isValid( ) )   {
00205       isvc->finalize();
00206     }
00207     (*i).second->release();
00208     (*i).second = 0;
00209   }
00210   m_connections.erase(m_connections.begin(), m_connections.end());
00211   return StatusCode::SUCCESS;
00212 }
00213 
00215 StatusCode NTupleSvc::finalize()      {
00216   StatusCode status = updateDirectories();
00217   status = clearStore();
00218   status = DataSvc::finalize();
00219   status = disconnectAll();
00220   return status;
00221 }
00222 
00224 StatusCode NTupleSvc::queryInterface(const IID& riid, void** ppvInterface)  {
00225   if ( IID_INTupleSvc == riid )    {
00226     *ppvInterface = (INTupleSvc*)this;
00227   }
00228   else if ( IID_IDataSourceMgr == riid )    {
00229     *ppvInterface = (IDataSourceMgr*)this;
00230   }
00231   else  {
00232     // Interface is not directly availible: try out a base class
00233     return DataSvc::queryInterface(riid, ppvInterface);
00234   }
00235   addRef();
00236   return StatusCode::SUCCESS;
00237 }
00238 
00239 StatusCode NTupleSvc::connect(const std::string& ident)    {
00240   std::string logName;
00241   return connect(ident, logName);
00242 }
00243 
00244 StatusCode NTupleSvc::connect(const std::string& ident, std::string& logname)    {
00245   MsgStream log ( msgSvc(), name() );
00246   DataObject* pO = 0;
00247   StatusCode status = findObject(m_storeName, pO);
00248   if ( status.isSuccess() )   {
00249     IDataDirectory* dir = pO->directory();
00250     status = INVALID_ROOT;
00251     if ( 0 != dir )   {
00252       char typ;
00253       bool known_type = false;
00254       Tokenizer tok;
00255       std::vector<Prop> props;
00256       long loc = ident.find(" ");
00257       std::string filename, auth, svc = "DbCnvSvc";
00258       logname = ident.substr(0,loc);
00259       tok.analyse(ident.substr(loc+1,ident.length()), " ", "", "", "=", "'", "'");
00260       for ( Tokenizer::Items::iterator i = tok.items().begin(); i != tok.items().end(); i++)    {
00261         const std::string& tag = (*i).tag();
00262         switch( ::toupper(tag[0]) )   {
00263         case 'A':
00264           props.push_back( Prop("Server", (*i).value()));
00265           break;
00266         case 'F':   // FILE='<file name>'
00267         case 'D':   // DATAFILE='<file name>'
00268           filename = (*i).value();
00269           break;
00270         case 'O':   // OPT='<NEW<CREATE,WRITE>, UPDATE, READ>'
00271           switch( ::toupper((*i).value()[0]) )   {
00272           case 'C':
00273           case 'N':
00274           case 'W':
00275             typ = 'N';
00276             break;
00277           case 'U':
00278             typ = 'U';
00279             break;
00280           case 'O':
00281           case 'R':
00282             typ = 'O';
00283             break;
00284           default:
00285             typ = 0;
00286             break;
00287           }
00288           break;
00289         case 'S':   // SVC='<service type>'
00290           known_type = true;
00291           svc = (*i).value();
00292           break;
00293         case 'T':   // TYP='<HBOOK,ROOT,OBJY,...>'
00294           known_type = true;
00295           switch(::toupper((*i).value()[0]))  {
00296           case 'H':
00297             svc = "HbookCnv::ConvSvc";
00298             break;
00299           default:
00300             props.push_back( Prop("DbType", (*i).value()));
00301             svc = "DbCnvSvc";
00302             break;
00303           }
00304           break;
00305         default:
00306           props.push_back( Prop((*i).tag(), (*i).value()));
00307           break;
00308         }
00309       }
00310       if ( 0 != typ )    {
00311         IConversionSvc* pSvc = 0;
00312         if ( known_type )   {
00313           status = createService(name()+'.'+logname, svc, props, pSvc);
00314         }
00315         else    {
00316           status = connectToHistogramPersistency(name()+'.'+logname, svc, props, pSvc);
00317         }
00318         if ( status.isSuccess() )   {
00319           status = attachTuple(filename, logname, typ, pSvc->repSvcType());
00320           if ( status.isSuccess() )    {
00321             m_connections.insert(Connections::value_type(m_storeName+'/'+logname, pSvc));
00322             return StatusCode::SUCCESS;
00323           }
00324         }
00325       }
00326     }
00327   }
00328   log << MSG::ERROR << "Cannot add " << ident << " invalid filename!" << endreq;
00329   return StatusCode::FAILURE;
00330 }
00331 
00332 StatusCode NTupleSvc::createService(const std::string& nam, const std::string& typ, const std::vector<Prop>& props, IConversionSvc*& pSvc)   {
00333   SmartIF<ISvcManager> mgr(IID_ISvcManager, serviceLocator());
00334   StatusCode status = NO_INTERFACE;
00335   if ( mgr.isValid( ) )    {
00336     IService* isvc = 0;
00337     status = mgr->createService(typ, nam, isvc);
00338     if ( status.isSuccess() )   {
00339       status = isvc->queryInterface(IID_IConversionSvc, (void**)&pSvc);
00340       if ( status.isSuccess() )     {
00341         SmartIF<IProperty> iprop(IID_IProperty,isvc);
00342         status = NO_INTERFACE;
00343         if ( iprop.isValid( ) )    {
00344           for ( std::vector<Prop>::const_iterator j = props.begin(); j != props.end(); j++)   {
00345             iprop->setProperty(StringProperty((*j).first, (*j).second));
00346           }
00347           status = isvc->initialize();
00348           if ( status.isSuccess() )   {
00349             status = pSvc->setStore(this);
00350             if ( status.isSuccess() )   {
00351               return status;
00352             }
00353           }
00354         }
00355         pSvc->release();
00356       }
00357       isvc->release();
00358     }
00359   }
00360   pSvc = 0;
00361   return status;
00362 }
00363 
00364 StatusCode NTupleSvc::connectToHistogramPersistency(const std::string& /*nam*/, const std::string& /*typ*/, const std::vector<Prop>& /*props*/, IConversionSvc*& pSvc)   {
00365   MsgStream log ( msgSvc(), name() );
00367   // Get the value of the Stat persistancy mechanism from the AppMgr
00368   IProperty*   appPropMgr = 0;
00369   StatusCode sts;
00370 
00371   sts = serviceLocator()->queryInterface(IID_IProperty,(void **)&appPropMgr );
00372   if( sts.isFailure() ) {
00373    // Report an error and return the FAILURE status code
00374    log << MSG::ERROR << "Could not get PropMgr" << endreq;
00375    return sts;
00376   }
00377 
00378   StringProperty sp("HistogramPersistency","");
00379   sts = appPropMgr->getProperty( &sp );
00380   if (sts.isFailure()) {
00381    log << MSG::ERROR << "Could not get NTuple Persistency format"
00382        << " from ApplicationMgr properties" << endreq;
00383    return sts;
00384   }
00385 
00386   unsigned char storage_typ = (unsigned char)TEST_StorageType;
00387   if ( sp.value() == "HBOOK" ) {
00388     storage_typ = HBOOK_StorageType;
00389   } 
00390   else if ( sp.value() == "ROOT" ) {
00391     storage_typ = ROOT_StorageType;
00392   } 
00393   else {
00394     appPropMgr->release();
00395     log << MSG::ERROR << "Unknown NTuple Persistency format: " << sp.value() << endreq;
00396     return StatusCode::FAILURE;
00397   }
00398   // Clean up
00399   appPropMgr->release();
00400 
00401   //      log << MSG::DEBUG << "storage type: " << m_storageType << endreq;
00402   IService* pService = 0;
00403   IInterface* iface = new ConversionSvc(name()+"Conversions", serviceLocator(), storage_typ);
00404   StatusCode status = iface->queryInterface(IID_IService, (void**)&pService);
00405   if ( status.isSuccess() )   {
00406     status = iface->queryInterface(IID_IConversionSvc, (void**)&pSvc);
00407     if ( !status.isSuccess() )   {
00408       pService->release();
00409       return status;
00410     }
00411   }
00412   status = pService->initialize();
00413   if ( !status.isSuccess() )    {
00414     return status;
00415   }
00416   pService->release();
00417   status = pSvc->setStore(this);
00418   if ( !status.isSuccess() )    {
00419     return status;
00420   }
00421   return status;
00422 }
00423 
00425 StatusCode NTupleSvc::create(const CLID& typ, const std::string& title, NTuple::Tuple*& refpTuple)     {
00426 //  MsgStream log ( msgSvc(), name() );
00427 //  std::string styp = "ColumnWise";
00428 //  if (typ == CLID_RowWiseTuple) { styp = "RowWise"; }
00429 //    log << MSG::DEBUG << "in create() tuple type: " << styp << endreq;
00430   if ( typ == CLID_ColumnWiseTuple )    {
00431     refpTuple = new NTuple::ColumnWiseTuple( title );
00432     return StatusCode::SUCCESS;
00433   }
00434   else if ( typ == CLID_RowWiseTuple )    {
00435     refpTuple = new NTuple::RowWiseTuple( title );
00436     return StatusCode::SUCCESS;
00437   }
00438   refpTuple = 0;
00439   return StatusCode::FAILURE;
00440 }
00441 
00443 NTuple::Tuple* NTupleSvc::book (const std::string& fullPath, const CLID& type, const std::string& title)  {
00444   int sep = fullPath.rfind(IDataDirectory::SEPARATOR);
00445   if ( sep > 0 )    {
00446     std::string p_path (fullPath, 0, sep);
00447     std::string o_path (fullPath, sep, fullPath.length());
00448     DataObject* dir = createDirectory(p_path);
00449     if ( 0 != dir )   {
00450       return book( dir, o_path, type, title);
00451     }
00452   }
00453   return 0;
00454 }
00455 
00457 NTuple::Tuple* NTupleSvc::book (const std::string& dirPath, const std::string& relPath, const CLID& type, const std::string& title)  {
00458   std::string full = dirPath;
00459   full += (relPath[0]=='/') ? "" : "/";
00460   full += relPath;
00461   return book(full, type, title);
00462 }
00463 
00465 NTuple::Tuple* NTupleSvc::book (const std::string& dirPath, long id, const CLID& type, const std::string& title)  {
00466   char txt[32];
00467   return book( dirPath, _itoa(id, txt, 10), type, title);
00468 }
00469 
00471 NTuple::Tuple* NTupleSvc::book (DataObject* pParent, const std::string& relPath, const CLID& type, const std::string& title)  {
00472   NTuple::Tuple* pObj = 0;
00473   // Check if object is already present
00474   StatusCode status = findObject(pParent, relPath, (DataObject*&)pObj);
00475   // No ? Then create it!
00476   if ( !status.isSuccess() )    {
00477     status = create( type, title, pObj);
00478     if ( status.isSuccess() )   {
00479       // Finally register the created N tuple with the store
00480       status = registerObject(pParent, relPath, pObj);
00481       if ( status.isSuccess() )    {
00482         long len = m_storeName.length();
00483         std::string full = pObj->fullpath();
00484         std::string path = full.substr(0, full.find(IDataDirectory::SEPARATOR,len+1));
00485         Connections::iterator i = m_connections.find(path);
00486         if ( i != m_connections.end() )   {
00487           NTuple::TupleImp* imp = (NTuple::TupleImp*)pObj;
00488           imp->setConversionSvc((*i).second);
00489           return pObj;
00490         }
00491       }
00492       pObj->release();
00493     }
00494   }
00495   return 0;
00496 }
00497 
00499 NTuple::Tuple* NTupleSvc::book (DataObject* pParent, long id, const CLID& type, const std::string& title)  {
00500   char txt[32];
00501   return book( pParent, ::_itoa(id, txt,10), type, title);
00502 }
00503 
00505 NTuple::Directory* NTupleSvc::createDirectory (DataObject* pParent, const std::string& relPath)   {
00506   if ( 0 != pParent )   {
00507     std::string full = pParent->fullpath();
00508     full += (relPath[0]=='/') ? "" : "/";
00509     full += relPath;
00510     return createDirectory(full);
00511   }
00512   return 0;
00513 }
00514 
00516 NTuple::Directory* NTupleSvc::createDirectory (DataObject* pParent, long id)    {
00517   char txt[32];
00518   return createDirectory( pParent, ::_itoa(id, txt,10) );
00519 }
00520 
00522 NTuple::Directory* NTupleSvc::createDirectory (const std::string& dirPath, long id)    {
00523   char txt[32];
00524   return createDirectory( dirPath, ::_itoa(id, txt,10) );
00525 }
00526 
00528 NTuple::Directory* NTupleSvc::createDirectory (const std::string& dirPath, const std::string& relPath )    {
00529   std::string full = dirPath;
00530   full += (relPath[0]=='/') ? "" : "/";
00531   full += relPath;
00532   return createDirectory(full);
00533 }
00534 
00535 StatusCode NTupleSvc::attachTuple(const std::string& filename, const std::string& logname, const char typ, unsigned char t)   {
00536   MsgStream log(msgSvc(), name());
00537   DataObject* p;
00538   // First get the root object
00539   StatusCode status = retrieveObject(m_storeName, p);
00540   if ( status.isSuccess() )   {
00541     // Now add the registry entry to the store
00542     std::string entryname = m_storeName;
00543     entryname += '/';
00544     entryname += logname;
00545     RegistryEntry* ent = dynamic_cast<RegistryEntry*>(p->directory());
00546     GenericAddress* pA = 0;
00547     pA = new GenericAddress(t, CLID_NTupleFile, 0);
00548     pA->setDbName(filename);
00549     pA->setContainerName(entryname);
00550     pA->setObjectName(logname);
00551     pA->genericInfo()->m_info[1] = typ;
00552     status = ent->add( logname, pA );
00553     if ( status.isSuccess() )    {
00554       log << MSG::INFO << "Added stream file:" << filename << " as " << logname << endreq;
00555       return status;
00556     }
00557     pA->release();
00558   }
00559   log << MSG::ERROR << "Cannot add file:" << filename << " as " << logname << endreq;
00560   return status;
00561 }
00562 
00564 NTuple::Directory* NTupleSvc::createDirectory (const std::string& fullPath)   {
00565   NTuple::Directory* p = 0;
00566   StatusCode status = findObject(fullPath, (DataObject*&)p);
00567   if ( !status.isSuccess() )   {
00568     int sep2 = fullPath.rfind(IDataDirectory::SEPARATOR);
00569     if ( sep2 > 0 )   {
00570       std::string relPath = fullPath.substr(0, sep2);
00571       p = createDirectory(relPath);
00572       if ( 0 != p )    {
00573         p = new NTuple::Directory( /* m_conversionSvc */);
00574         // Finally register the created N tuple with the store
00575         status = registerObject(fullPath, p);
00576         if ( status.isSuccess() )    {
00577           IDataSelector sel;
00578           sel.push_back( p );
00579           // ...starting from the file entries
00580           long len = m_storeName.length();
00581           std::string path = fullPath.substr(0, fullPath.find(IDataDirectory::SEPARATOR,len+1));
00582           Connections::iterator i = m_connections.find(path);
00583           if ( i != m_connections.end() )   {
00584             status = (*i).second->createReps ( &sel );
00585             if ( status.isSuccess() )   {
00586               return p;
00587             }
00588           }
00589           unregisterObject(p);
00590         }
00591         p->release();
00592         p = 0;
00593       }
00594     }
00595   }
00596   try {
00597     p = dynamic_cast<NTuple::Directory*>(p);
00598     return p;
00599   }
00600   catch (...) {
00601   }
00602   return 0;
00603 }
00604 
00606 NTuple::Tuple* NTupleSvc::access(const std::string&, const std::string&)  {
00607   MsgStream log ( msgSvc(), name() );
00608   return 0;
00609 }
00610 
00612 StatusCode NTupleSvc::save(const std::string& fullPath)  {
00613   MsgStream log ( msgSvc(), name() );
00614   NTuple::Tuple* pObj = 0;
00615   StatusCode status = findObject(fullPath, (DataObject*&)pObj);  // Check if object is  present
00616   if ( status.isSuccess() )   {
00617     return save ( pObj );
00618   }
00619   return INVALID_OBJ_PATH;
00620 }
00621 
00623 StatusCode NTupleSvc::save(NTuple::Tuple* t)  {
00624   try   {
00625     NTuple::TupleImp* tuple = dynamic_cast<NTuple::TupleImp*>(t);
00626     if ( 0 != tuple )   {
00627       IConversionSvc* svc = tuple->conversionSvc();
00628       if ( 0 != svc )   {
00629         IDataSelector selector;
00630         selector.push_back( tuple );
00631         return svc->updateReps ( &selector );
00632       }
00633     }
00634   }
00635   catch (...)   {
00636   }
00637   return StatusCode::FAILURE;
00638 }
00639 
00641 StatusCode NTupleSvc::save(DataObject* pParent, const std::string& relPath)  {
00642   NTuple::Tuple* pObj = 0;
00643   StatusCode status = findObject(pParent, relPath, (DataObject*&)pObj);  // Check if object is  present
00644   if ( status.isSuccess() )   {
00645     return save ( pObj );
00646   }
00647   return INVALID_OBJ_PATH;
00648 }
00649 
00651 StatusCode NTupleSvc::writeRecord( NTuple::Tuple* t )   {
00652   try   {
00653     NTuple::TupleImp* tuple = dynamic_cast<NTuple::TupleImp*>(t);
00654     if ( 0 != tuple )   {
00655       IConversionSvc* svc = tuple->conversionSvc();
00656       if ( 0 != svc )   {
00657         IDataSelector selector;
00658         selector.push_back( tuple );
00659         return svc->createReps ( &selector );
00660       }
00661     }
00662   }
00663   catch (...)   {
00664   }
00665   return StatusCode::FAILURE;
00666 }
00667 
00669 StatusCode NTupleSvc::writeRecord(const std::string& fullPath )   {
00670   NTuple::Tuple* pObj = 0;
00671   StatusCode status = findObject(fullPath, (DataObject*&)pObj);  // Check if object is  present
00672   if ( status.isSuccess() )   {
00673     return writeRecord ( pObj );
00674   }
00675   return INVALID_OBJ_PATH;
00676 }
00677 
00679 StatusCode NTupleSvc::writeRecord( DataObject* pParent, const std::string& relPath)   {
00680   NTuple::Tuple* pObj = 0;
00681   StatusCode status = findObject(pParent, relPath, (DataObject*&)pObj);  // Check if object is  present
00682   if ( status.isSuccess() )   {
00683     return writeRecord ( pObj );
00684   }
00685   return INVALID_OBJ_PATH;
00686 }
00687 
00689 StatusCode NTupleSvc::readRecord( NTuple::Tuple* tuple )  {
00690   IDataDirectory* pDirectory = tuple->directory();
00691   if ( 0 == pDirectory )    {
00692     return INVALID_OBJ_ADDR;
00693   }
00694   NTuple::TupleImp* imp = (NTuple::TupleImp*)tuple;
00695   IConversionSvc* svc = imp->conversionSvc();
00696   if ( 0 != svc )   {
00697     return svc->updateObj(pDirectory->address(), tuple);
00698   }
00699   return NO_DATA_LOADER;
00700 }
00701 
00703 StatusCode NTupleSvc::readRecord(const std::string& fullPath)  {
00704   NTuple::Tuple* pObj = 0;
00705   StatusCode status = findObject(fullPath, (DataObject*&)pObj);  // Check if object is  present
00706   if ( status.isSuccess() )   {
00707     return readRecord ( pObj );
00708   }
00709   return INVALID_OBJ_PATH;
00710 }
00711 
00713 StatusCode NTupleSvc::readRecord(DataObject* pParent, const std::string& relPath)  {
00714   NTuple::Tuple* pObj = 0;
00715   StatusCode status = findObject(pParent, relPath, (DataObject*&)pObj);  // Check if object is  present
00716   if ( status.isSuccess() )   {
00717     return readRecord ( pObj );
00718   }
00719   return INVALID_OBJ_PATH;
00720 }
00721 

Generated at Wed Nov 21 12:22:30 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000