![]() |
|
|
Generated: 18 Jul 2008 |
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 }