| # Gaudi Framework, version v20r4
Generated: 8 Jan 2009

# HbookCnv::HConverter Class Reference

`#include <HConverter.h>`

Inheritance diagram for HbookCnv::HConverter:

[legend]
Collaboration diagram for HbookCnv::HConverter:

[legend]

List of all members.

## Detailed Description

Generic HBook converter class definition.

Description: Definition of the converter using HBOOK

Dependencies:

- Base class: Gaudi/Kernel/Converter.h

History :

      +---------+----------------------------------------------+--------+
      |    Date |                 Comment                      | Who    |
      +---------+----------------------------------------------+--------+
      | 21/10/99| Initial version.                             | MF     |
      +---------+----------------------------------------------+--------+

Author: M.Frank Version: 1.0

Definition at line 47 of file HConverter.h.

## Public Member Functions
virtual StatusCode | book (IOpaqueAddress *, DataObject *)
| Book the histogram/N-tuple object.
virtual StatusCode | createRep (DataObject *pObj, IOpaqueAddress *&refpAddress)
| Convert the transient object to the requested persistent representation.
virtual StatusCode | writeObject (const std::string &loc, long id)
| Update the converted representation of a transient object.
StatusCode | readObject (const std::string &loc, long id)
| Create the transient representation of an object.
StatusCode | createAddress (const std::string &rzdir, const CLID &clid, const std::string &title, IOpaqueAddress *&refpAddress)
| Create address of the transient object according to the requested representation.
StatusCode | createAddress (const std::string &rzdir, const CLID &clid, long id, IOpaqueAddress *&refpAddress)
| Create address of the transient object according to the requested representation.
std::string | diskDirectory (const std::string &loc)
| Retrieve name of disk directory from location.
std::string | directory (const std::string &loc)
| Retrieve name of memory directory from location.
void | setDirectory (const std::string &loc)
| Set RZ sub directories if they do not exist according to the store location.
void | setDiskDirectory (const std::string &loc)
| Set RZ sub directories if they do not exist according to the store location.
StatusCode | createDirectory (const std::string &loc)
| Create RZ directory if not present.
StatusCode | createDiskDirectory (const std::string &loc)
| Create disk based RZ directory if not present.
StatusCode | createSubDirs (const std::string &top, const std::string &loc)
| Create RZ sub directories if they do not exist according to the store location.
long | repSvcType () const
| Retrieve the class type of the data store the converter uses.
## Static Public Member Functions
static long | storageType ()
| Inquire storage type.
## Protected Member Functions
| HConverter (const CLID &clid, ISvcLocator *svc)
| Standard constructor.
virtual | ~HConverter ()
| Standard destructor.
## Protected Attributes
std::string | m_prefix
| Helper to fix persistent RZ directories.
bool | m_deleteAfterSave
| Flag to indicate that object should be deleted after saving.

## Constructor & Destructor Documentation

HbookCnv::HConverter::HConverter | ( | const CLID & | clid,
|  | ISvcLocator * | svc |
| ) |  |  | `[protected]`

Standard constructor.

Definition at line 297 of file HConverter.cpp.

    00298   : Converter(HbookCnv::HConverter::storageType(), clid, svc)
    00299 {
    00300   m_deleteAfterSave = false;
    00301 }

HbookCnv::HConverter::~HConverter | ( |  | ) | `[protected, virtual]`

Standard destructor.

Definition at line 305 of file HConverter.cpp.

    00305                                                          {
    00306 }

## Member Function Documentation

virtual StatusCode HbookCnv::HConverter::book | ( | IOpaqueAddress * | ,
|  | DataObject * |  |
| ) |  |  | `[inline, virtual]`

Book the histogram/N-tuple object.

Reimplemented in HbookCnv::H1DCnv, and HbookCnv::H2DCnv.

Definition at line 51 of file HConverter.h.

    00051                                                                                    {
    00052       return StatusCode::FAILURE;
    00053     }

StatusCode HbookCnv::HConverter::createRep | ( | DataObject * | pObj,
|  | IOpaqueAddress *& | refpAddress |
| ) |  |  | `[virtual]`

Convert the transient object to the requested persistent representation.

Reimplemented from Converter.

Reimplemented in HbookCnv::HDirectoryCnv, HbookCnv::HFileCnv, and HbookCnv::HNTupleCnv.

Definition at line 227 of file HConverter.cpp.

    00227                                                                                            {
    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 }

StatusCode HbookCnv::HConverter::writeObject | ( | const std::string & | loc,
|  | long | id |
| ) |  |  | `[virtual]`

Update the converted representation of a transient object.

Definition at line 207 of file HConverter.cpp.

    00207                                                                           {
    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 }

StatusCode HbookCnv::HConverter::readObject | ( | const std::string & | loc,
|  | long | id |
| ) |  |  |

Create the transient representation of an object.

Definition at line 190 of file HConverter.cpp.

    00190                                                                          {
    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 }

StatusCode HbookCnv::HConverter::createAddress | ( | const std::string & | rzdir,
|  | const CLID & | clid,
|  | const std::string & | title,
|  | IOpaqueAddress *& | refpAddress |
| ) |  |  |

Create address of the transient object according to the requested representation.

Definition at line 159 of file HConverter.cpp.

    00162                                                                                {
    00163   GenericAddress* pA = new GenericAddress(repSvcType(),
    00164                                           clid,
    00165                                           rzdir,
    00166                                           title,
    00167                                           0,
    00168                                           0);
    00169   refpAddress = pA;
    00170   return StatusCode::SUCCESS;
    00171 }

StatusCode HbookCnv::HConverter::createAddress | ( | const std::string & | rzdir,
|  | const CLID & | clid,
|  | long | id,
|  | IOpaqueAddress *& | refpAddress |
| ) |  |  |

Create address of the transient object according to the requested representation.

Definition at line 175 of file HConverter.cpp.

    00178                                                                                {
    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 }

std::string HbookCnv::HConverter::diskDirectory | ( | const std::string & | loc | ) |

Retrieve name of disk directory from location.

Retrieve name of memory directory from location.

Definition at line 128 of file HConverter.cpp.

    00128                                                                   {
    00129   long ll = loc.find("/", 1);
    00130   ll = loc.find("/", (ll=1) ? loc.find("/", 2) : ll);
    00131   return "/" + loc.substr(ll, loc.length());
    00132 }

std::string HbookCnv::HConverter::directory | ( | const std::string & | loc | ) |

Retrieve name of memory directory from location.

Definition at line 136 of file HConverter.cpp.

    00136                                                               {
    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 }

void HbookCnv::HConverter::setDirectory | ( | const std::string & | loc | ) |

Set RZ sub directories if they do not exist according to the store location.

Definition at line 148 of file HConverter.cpp.

    00148                                                              {
    00149   ::HCDIR(directory(loc), " ");
    00150 }

void HbookCnv::HConverter::setDiskDirectory | ( | const std::string & | loc | ) |

Set RZ sub directories if they do not exist according to the store location.

Definition at line 154 of file HConverter.cpp.

    00154                                                                  {
    00155   ::HCDIR(diskDirectory(loc), " ");
    00156 }

StatusCode HbookCnv::HConverter::createDirectory | ( | const std::string & | loc | ) |

Create RZ directory if not present.

Definition at line 109 of file HConverter.cpp.

    00109                                                                       {
    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 }

StatusCode HbookCnv::HConverter::createDiskDirectory | ( | const std::string & | loc | ) |

Create disk based RZ directory if not present.

StatusCode HbookCnv::HConverter::createSubDirs | ( | const std::string & | top,
|  | const std::string & | loc |
| ) |  |  |

Create RZ sub directories if they do not exist according to the store location.

Definition at line 30 of file HConverter.cpp.

    00030                                                                                           {
    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 }

long HbookCnv::HConverter::storageType | ( |  | ) | `[static]`

Inquire storage type.

Definition at line 292 of file HConverter.cpp.

    00292                                           {
    00293   return HBOOK_StorageType;
    00294 }

long HbookCnv::HConverter::repSvcType | ( |  | ) | const`[inline, virtual]`

Retrieve the class type of the data store the converter uses.

Returns:
  Class type information about the source data store type the converter will use to retrieve the information.

Implements IConverter.

Definition at line 81 of file HConverter.h.

    00081                             {
    00082       return i_repSvcType();
    00083     }

## Member Data Documentation

std::string HbookCnv::HConverter::m_prefix`[protected]`

Helper to fix persistent RZ directories.

Definition at line 91 of file HConverter.h.

bool HbookCnv::HConverter::m_deleteAfterSave`[protected]`

Flag to indicate that object should be deleted after saving.

Definition at line 93 of file HConverter.h.

The documentation for this class was generated from the following files:

- /afs/cern.ch/sw/Gaudi/releases/GAUDI/GAUDI_v20r4/HbookCnv/src/HConverter.h
- /afs/cern.ch/sw/Gaudi/releases/GAUDI/GAUDI_v20r4/HbookCnv/src/HConverter.cpp