Gaudi Framework, version v20r2

Generated: 18 Jul 2008

HConverter.cpp

Go to the documentation of this file.
00001 // $Header: /local/reps/Gaudi/HbookCnv/src/HConverter.cpp,v 1.9 2005/10/03 15:42:55 hmd Exp $
00002 #define HBOOKCNV_HCONVERTER_CPP
00003 
00004 
00005 // Include files
00006 #include "GaudiKernel/xtoa.h"
00007 #include "GaudiKernel/strcasecmp.h"
00008 #include "GaudiKernel/MsgStream.h"
00009 #include "GaudiKernel/IRegistry.h"
00010 #include "GaudiKernel/CnvFactory.h"
00011 #include "GaudiKernel/DataObject.h"
00012 #include "GaudiKernel/GenericAddress.h"
00013 #include "GaudiKernel/IDataProviderSvc.h"
00014 
00015 #include "HConverter.h"
00016 #include "HbookDef.h"
00017 
00018 // Maximum length of RZ directory names
00019 static const long MAX_RZ_DIR_LENGTH = 16;
00020 
00021 //------------------------------------------------------------------------------
00022 //
00023 // Implementation of class :  HbookCnv::HConverter
00024 //
00025 // Author :                   Markus Frank
00026 //
00027 //------------------------------------------------------------------------------
00028 
00029 // Create RZ sub directories if they do not exist according to the store location
00030 StatusCode HbookCnv::HConverter::createSubDirs(const std::string& top, const std::string& loc)    {
00031   MsgStream log(msgSvc(), "HConverter");
00032   std::string loc2 = top;
00033   ::HCDIR(loc2," ");
00034   long ll = loc.find("/", 1);
00035   ll += (ll==1) ? 2 : 1;
00036 
00037  Again:
00038   if ( ll > 0 )   {
00039     long idh = 0;
00040     std::string nloc = loc.substr(ll, loc.length());
00041     while( 1 )    {
00042       std::string type, title = "", opt = "D";
00043       ::HLNEXT(idh, type, title, opt);
00044       long ind = nloc.find("/", 1);
00045       long indSlash = ind;
00046       bool badName  = false;
00047       long nlocLen  = nloc.length();
00048       if ( ind > MAX_RZ_DIR_LENGTH )    {
00049         ind = MAX_RZ_DIR_LENGTH;
00050         badName = true;
00051       }
00052       else if ( ind < 0 && nlocLen > MAX_RZ_DIR_LENGTH )    {
00053         ind += (ind>0) ? MAX_RZ_DIR_LENGTH : MAX_RZ_DIR_LENGTH+1;
00054         badName = true;
00055       }
00056 
00057       std::string dd = nloc.substr(0, (ind>0) ? ind : nlocLen);
00058       long ddLen = dd.length();
00059       if ( idh == 0 || title.length() == 0 )   {
00060         loc2 += '/';
00061         // loc2 += (indSlash < 0) ? nloc : dd;
00062         loc2 += dd;
00063         if ( (nlocLen <= MAX_RZ_DIR_LENGTH && ind < 0) ||
00064              (ddLen   <  MAX_RZ_DIR_LENGTH && ind > 0) ||
00065              badName )
00066         {
00067           ::HMDIR(loc2,"S");
00068           if ( badName )   {
00069             log << MSG::WARNING << "Truncated directory name to "
00070                 << loc2 << "> (Name too long)" << endreq;
00071           }
00072           else  {
00073             log << MSG::VERBOSE << "Create dir <" << loc2 << ">" << endreq;
00074           }
00075           if ( indSlash >= 0 )   {
00076             ll += indSlash + 1;
00077             goto Again;
00078           }
00079         }
00080         else  {
00081           log << MSG::ERROR << "Cannot create dir <" << loc2 << "> (unknown reason)" << endreq;
00082           return StatusCode::FAILURE;
00083         }
00084         break;
00085       }
00086       else if ( type[0] == 'D' && ::strncasecmp(dd.c_str(),title.c_str(),MAX_RZ_DIR_LENGTH)==0 )  {
00087         loc2 += '/';
00088         loc2 += (indSlash < 0) ? nloc : dd;
00089         log << MSG::VERBOSE << "Set dir <" << loc2 << ">" << endreq;
00090         ::HCDIR(loc2," ");
00091         if ( indSlash >= 0 )   {
00092           ll += indSlash + 1;
00093           goto Again;
00094         }
00095         break;
00096       }
00097       else if ( type[0] == 0 )      {
00098         goto Again;
00099       }
00100     }
00101     ::HCDIR(loc2, " ");
00102     return StatusCode::SUCCESS;
00103   }
00104   return StatusCode::SUCCESS;
00105 }
00106 
00107 
00109 StatusCode HbookCnv::HConverter::createDirectory(const std::string& loc)    {
00110   StatusCode status=StatusCode::SUCCESS;
00111   long ll = loc.find("/", 1);
00112   std::string disk = "";
00113   long ll2 = loc.find("/", 1+((ll=1) ? 2 : 1));
00114   if ( ll2 >= 0 )    {
00115     long ll3 = loc.find("/", ll2+1);
00116     disk = "/" + loc.substr(ll2, (ll3 > 0 ? ll3 : loc.length())-ll2);
00117     std::string sub = loc.substr(ll2, loc.length());
00118     status=createSubDirs( "//PAWC", loc );
00119     if ( status.isSuccess() )   {
00120       status=createSubDirs( disk, sub );
00121     }
00122   }
00123   return status;
00124 }
00125 
00126 
00128 std::string HbookCnv::HConverter::diskDirectory(const std::string& loc)   {
00129   long ll = loc.find("/", 1);
00130   ll = loc.find("/", (ll=1) ? loc.find("/", 2) : ll);
00131   return "/" + loc.substr(ll, loc.length());
00132 }
00133 
00134 
00136 std::string HbookCnv::HConverter::directory(const std::string& loc)   {
00137   long ll = loc.find("/", 1);
00138   std::string pawc = "//PAWC";
00139   if ( ll == 1 ) ll = loc.find("/", 2);
00140   if ( ll > 0 )   {
00141     pawc += loc.substr(ll>0 ? ll : 0, loc.length());
00142   }
00143   return pawc;
00144 }
00145 
00146 
00147 // Set RZ sub directories if they do not exist according to the store location
00148 void HbookCnv::HConverter::setDirectory(const std::string& loc)    {
00149   ::HCDIR(directory(loc), " ");
00150 }
00151 
00152 
00153 // Set RZ sub directories if they do not exist according to the store location
00154 void HbookCnv::HConverter::setDiskDirectory(const std::string& loc)    {
00155   ::HCDIR(diskDirectory(loc), " ");
00156 }
00157 
00159 StatusCode HbookCnv::HConverter::createAddress(const std::string& rzdir,
00160                                                const CLID& clid,
00161                                                const std::string& title,
00162                                                IOpaqueAddress*& refpAddress)   {
00163   GenericAddress* pA = new GenericAddress(repSvcType(),
00164                                           clid,
00165                                           rzdir,
00166                                           title,
00167                                           0,
00168                                           0);
00169   refpAddress = pA;
00170   return StatusCode::SUCCESS;
00171 }
00172 
00173 
00175 StatusCode HbookCnv::HConverter::createAddress(const std::string& rzdir,
00176                                                const CLID& clid,
00177                                                long id,
00178                                                IOpaqueAddress*& refpAddress)   {
00179   char obj[32];
00180   StatusCode status = createAddress(rzdir, clid, ::_itoa(id, obj, 10), refpAddress);
00181   if ( status.isSuccess() )   {
00182     unsigned long* ipar = (unsigned long*)refpAddress->ipar();
00183     ipar[0] = id;
00184   }
00185   return status;
00186 }
00187 
00188 
00190 StatusCode HbookCnv::HConverter::readObject(const std::string& loc, long id)   {
00191   long icycle = 999999, ioff = 0;
00192   long l = loc.rfind('/');
00193   if ( l > 0 )    {
00194     std::string dir = loc.substr(0,l);
00195     setDiskDirectory(dir);
00196     setDirectory(dir);
00197     ::HRIN(id, icycle, ioff);
00198     if ( ::HEXIST( id ) )    {
00199       //::HLDIR(directory(dir)," ");
00200       return StatusCode::SUCCESS;
00201     }
00202   }
00203   return StatusCode::FAILURE;
00204 }
00205 
00207 StatusCode HbookCnv::HConverter::writeObject(const std::string& loc, long id)   {
00208   setDirectory( loc );
00209   setDiskDirectory( loc );
00210   if ( ::HEXIST( id ) )    {
00211     MsgStream log(msgSvc(), "HConverter");
00212     int icycle;
00213     ::HROUT( id , &icycle, " ", 1);
00214     log << MSG::INFO;
00215     if ( log.isActive() )       {
00216       ::HPRINT( id );
00217     }
00218     if ( m_deleteAfterSave )    {
00219       ::HDELET( id );
00220     }
00221     return StatusCode::SUCCESS;
00222   }
00223   return StatusCode::FAILURE;
00224 }
00225 
00227 StatusCode HbookCnv::HConverter::createRep(DataObject* pObject, IOpaqueAddress*& refpAddress)  {
00228   refpAddress = 0;
00229   typedef std::pair<std::string,long> hID;
00230   typedef std::map< hID, bool > hIDMap;
00231   static hIDMap usedIDs;
00232   if ( 0 != pObject )   {
00233     IRegistry* pDir  = pObject->registry();
00234     if ( 0 != pDir )    {
00235       StatusCode status = StatusCode::SUCCESS;
00236       refpAddress = pDir->address();
00237       if ( 0 == refpAddress )   {
00238         const std::string & loc   = pDir->name();
00239         const std::string full  = m_prefix + pDir->identifier();
00240         std::string rzLoc = full.substr(0, full.rfind('/'));
00241         long histoID = atol(loc.c_str()+1); // Histogram ID
00242         // test if the hID is invalid (non-numeric) or already assigned
00243         if ( 0 >= histoID || usedIDs.find(hID(rzLoc,histoID)) != usedIDs.end() ) 
00244         {
00245           MsgStream log(msgSvc(), "HbookCnv");
00246           if ( 0 >= histoID )
00247           { 
00248             // Numeric representation of the histogram ID not valid
00249             log << MSG::WARNING << "Histogram ID '" << pDir->identifier() 
00250                 << "' is an invalid HBOOK identifier" << endreq;
00251           }
00252           else
00253           {
00254             // ID is already used 
00255             log << MSG::WARNING << "Histogram ID '" << pDir->identifier() 
00256                 << "' is already used" << endreq;
00257           }
00258           histoID = 1001;
00259           while ( usedIDs.find(hID(rzLoc,histoID)) != usedIDs.end() ) { ++histoID; }
00260           const std::string root = pDir->identifier().substr(0, pDir->identifier().rfind('/'));
00261           log << MSG::WARNING 
00262               << "  -> Adjusting PERSISTENT ID to '" << root << "/" << histoID << "'" << endreq;
00263         }
00264         usedIDs[hID(rzLoc,histoID)] = true;
00265         status = createAddress(rzLoc, objType(), histoID, refpAddress);
00266         if ( status.isSuccess() )   {
00267           setDiskDirectory(rzLoc);
00268           setDirectory(rzLoc);
00269           status = book(refpAddress, pObject);
00270         }
00271       }
00272       if ( status.isSuccess() )   {
00273         const std::string& rzLoc = refpAddress->par()[0];
00274         setDiskDirectory(rzLoc);
00275         setDirectory(rzLoc);
00276         status = updateRep(refpAddress, pObject);
00277         if ( status.isSuccess() )   {
00278           status = writeObject(rzLoc, refpAddress->ipar()[0]);
00279           if ( status.isSuccess() )   {
00280             return status;
00281           }
00282         }
00283         delete refpAddress;
00284         refpAddress = 0;
00285       }
00286     }
00287   }
00288   return StatusCode::FAILURE;
00289 }
00290 
00292 long HbookCnv::HConverter::storageType()      {
00293   return HBOOK_StorageType;
00294 }
00295 
00297 HbookCnv::HConverter::HConverter( const CLID& clid, ISvcLocator* svc )
00298   : Converter(HbookCnv::HConverter::storageType(), clid, svc)  
00299 {
00300   m_deleteAfterSave = false;
00301 }
00302 
00303 
00305 HbookCnv::HConverter::~HConverter()                          {
00306 }

Generated at Fri Jul 18 11:59:26 2008 for Gaudi Framework, version v20r2 by Doxygen version 1.5.1 written by Dimitri van Heesch, © 1997-2004