00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <sstream>
00034
00035 using std::istringstream ;
00036
00037 #include "BESUncompressManager.h"
00038 #include "BESUncompressGZ.h"
00039 #include "BESUncompressBZ2.h"
00040 #include "BESUncompressZ.h"
00041 #include "BESCache.h"
00042 #include "BESInternalError.h"
00043 #include "BESDebug.h"
00044 #include "TheBESKeys.h"
00045
00046 BESUncompressManager *BESUncompressManager::_instance = 0 ;
00047
00057 BESUncompressManager::BESUncompressManager()
00058 {
00059 add_method( "gz", BESUncompressGZ::uncompress ) ;
00060 add_method( "bz2", BESUncompressBZ2::uncompress ) ;
00061 add_method( "z", BESUncompressZ::uncompress ) ;
00062
00063 bool found = false ;
00064 string key = "BES.Uncompress.Retry" ;
00065 string val = TheBESKeys::TheKeys()->get_key( key, found ) ;
00066 if( !found || val.empty() )
00067 {
00068 _retry = 2000 ;
00069 }
00070 else
00071 {
00072 istringstream is( val ) ;
00073 is >> _retry ;
00074 }
00075
00076 key = "BES.Uncompress.NumTries" ;
00077 val = TheBESKeys::TheKeys()->get_key( key, found ) ;
00078 if( !found || val.empty() )
00079 {
00080 _num_tries = 10 ;
00081 }
00082 else
00083 {
00084 istringstream is( val ) ;
00085 is >> _num_tries ;
00086 }
00087 }
00088
00098 bool
00099 BESUncompressManager::add_method( const string &name,
00100 p_bes_uncompress method )
00101 {
00102 BESUncompressManager::UCIter i ;
00103 i = _uncompress_list.find( name ) ;
00104 if( i == _uncompress_list.end() )
00105 {
00106 _uncompress_list[name] = method ;
00107 return true ;
00108 }
00109 return false ;
00110 }
00111
00120 bool
00121 BESUncompressManager::remove_method( const string &name )
00122 {
00123 BESUncompressManager::UIter i ;
00124 i = _uncompress_list.find( name ) ;
00125 if( i != _uncompress_list.end() )
00126 {
00127 _uncompress_list.erase( i ) ;
00128 return true ;
00129 }
00130 return false ;
00131 }
00132
00141 p_bes_uncompress
00142 BESUncompressManager::find_method( const string &name )
00143 {
00144 BESUncompressManager::UCIter i ;
00145 i = _uncompress_list.find( name ) ;
00146 if( i != _uncompress_list.end() )
00147 {
00148 return (*i).second ;
00149 }
00150 return 0 ;
00151 }
00152
00158 string
00159 BESUncompressManager::get_method_names()
00160 {
00161 string ret ;
00162 bool first_name = true ;
00163 BESUncompressManager::UCIter i = _uncompress_list.begin() ;
00164 for( ; i != _uncompress_list.end(); i++ )
00165 {
00166 if( !first_name )
00167 ret += ", " ;
00168 ret += (*i).first ;
00169 first_name = false ;
00170 }
00171 return ret ;
00172 }
00173
00203 bool
00204 BESUncompressManager::uncompress( const string &src, string &target,
00205 BESCache &cache )
00206 {
00207 BESDEBUG( "bes", "BESUncompressManager::uncompress - src = " << src << endl )
00208 string::size_type dot = src.rfind( "." ) ;
00209 if( dot != string::npos )
00210 {
00211 string ext = src.substr( dot+1, src.length() - dot ) ;
00212
00213
00214
00215
00216 for( int i = 0; i < ext.length(); i++ )
00217 {
00218 ext[i] = tolower( ext[i] ) ;
00219 }
00220
00221
00222
00223
00224 p_bes_uncompress p = find_method( ext ) ;
00225 if( p )
00226 {
00227
00228
00229
00230 if( cache.lock( _retry, _num_tries ) )
00231 {
00232 try
00233 {
00234
00235
00236
00237 BESDEBUG( "bes", "BESUncompressManager::uncompress - is cached? " \
00238 << src << endl )
00239 if( cache.is_cached( src, target ) )
00240 {
00241 BESDEBUG( "bes", "BESUncompressManager::uncompress - " \
00242 << "is cached " << target << endl )
00243 cache.unlock() ;
00244 return true ;
00245 }
00246
00247
00248
00249
00250 BESDEBUG( "bes", "BESUncompressManager::uncompress - " \
00251 << "purging cache" << endl )
00252 cache.purge() ;
00253
00254
00255 BESDEBUG( "bes", "BESUncompressManager::uncompress - " \
00256 << "uncompress to " << target \
00257 << " using " << ext << " uncompression" \
00258 << endl )
00259
00260
00261 cache.unlock() ;
00262
00263 p( src, target ) ;
00264 return true ;
00265 }
00266 catch( BESError & )
00267 {
00268
00269
00270 cache.unlock() ;
00271 throw ;
00272 }
00273 catch( ... )
00274 {
00275
00276
00277 cache.unlock() ;
00278 string err = (string)"Problem working with the cache, "
00279 + "unknow error" ;
00280 throw BESInternalError( err, __FILE__,__LINE__);
00281 }
00282 }
00283 else
00284 {
00285 string err = "Unable to lock the cache "
00286 + cache.cache_dir() ;
00287 throw BESInternalError( err, __FILE__, __LINE__ ) ;
00288 }
00289 }
00290 else
00291 {
00292 BESDEBUG( "bes", "BESUncompressManager::uncompress - not compressed " \
00293 << endl )
00294 }
00295 }
00296 else
00297 {
00298 BESDEBUG( "bes", "BESUncompressmanager::uncompress - not file extension" \
00299 << endl )
00300 #if 0
00301
00302
00303 string err = "Unable to determine type of file from "
00304 + src ;
00305 throw BESInternalError( err, __FILE__, __LINE__ ) ;
00306 #endif
00307 }
00308
00309 return false ;
00310 }
00311
00319 void
00320 BESUncompressManager::dump( ostream &strm ) const
00321 {
00322 strm << BESIndent::LMarg << "BESUncompressManager::dump - ("
00323 << (void *)this << ")" << endl ;
00324 BESIndent::Indent() ;
00325 if( _uncompress_list.size() )
00326 {
00327 strm << BESIndent::LMarg << "registered uncompression methods:" << endl;
00328 BESIndent::Indent() ;
00329 BESUncompressManager::UCIter i = _uncompress_list.begin() ;
00330 BESUncompressManager::UCIter ie = _uncompress_list.end() ;
00331 for( ; i != ie; i++ )
00332 {
00333 strm << BESIndent::LMarg << (*i).first << endl ;
00334 }
00335 BESIndent::UnIndent() ;
00336 }
00337 else
00338 {
00339 strm << BESIndent::LMarg << "registered uncompress methods: none" << endl ;
00340 }
00341 BESIndent::UnIndent() ;
00342 }
00343
00344 BESUncompressManager *
00345 BESUncompressManager::TheManager()
00346 {
00347 if( _instance == 0 )
00348 {
00349 _instance = new BESUncompressManager ;
00350 }
00351 return _instance ;
00352 }