| # Gaudi Framework, version v20r3
Generated: 24 Nov 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 }