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 ;
00066 TheBESKeys::TheKeys()->get_value( key, val, found ) ;
00067 if( !found || val.empty() )
00068 {
00069 _retry = 2000 ;
00070 }
00071 else
00072 {
00073 istringstream is( val ) ;
00074 is >> _retry ;
00075 }
00076
00077 key = "BES.Uncompress.NumTries" ;
00078 val = "" ;
00079 TheBESKeys::TheKeys()->get_value( key, val, found ) ;
00080 if( !found || val.empty() )
00081 {
00082 _num_tries = 10 ;
00083 }
00084 else
00085 {
00086 istringstream is( val ) ;
00087 is >> _num_tries ;
00088 }
00089 }
00090
00100 bool
00101 BESUncompressManager::add_method( const string &name,
00102 p_bes_uncompress method )
00103 {
00104 BESUncompressManager::UCIter i ;
00105 i = _uncompress_list.find( name ) ;
00106 if( i == _uncompress_list.end() )
00107 {
00108 _uncompress_list[name] = method ;
00109 return true ;
00110 }
00111 return false ;
00112 }
00113
00122 bool
00123 BESUncompressManager::remove_method( const string &name )
00124 {
00125 BESUncompressManager::UIter i ;
00126 i = _uncompress_list.find( name ) ;
00127 if( i != _uncompress_list.end() )
00128 {
00129 _uncompress_list.erase( i ) ;
00130 return true ;
00131 }
00132 return false ;
00133 }
00134
00143 p_bes_uncompress
00144 BESUncompressManager::find_method( const string &name )
00145 {
00146 BESUncompressManager::UCIter i ;
00147 i = _uncompress_list.find( name ) ;
00148 if( i != _uncompress_list.end() )
00149 {
00150 return (*i).second ;
00151 }
00152 return 0 ;
00153 }
00154
00160 string
00161 BESUncompressManager::get_method_names()
00162 {
00163 string ret ;
00164 bool first_name = true ;
00165 BESUncompressManager::UCIter i = _uncompress_list.begin() ;
00166 for( ; i != _uncompress_list.end(); i++ )
00167 {
00168 if( !first_name )
00169 ret += ", " ;
00170 ret += (*i).first ;
00171 first_name = false ;
00172 }
00173 return ret ;
00174 }
00175
00206 bool
00207 BESUncompressManager::uncompress( const string &src, string &target,
00208 BESCache &cache )
00209 {
00210 BESDEBUG( "bes", "BESUncompressManager::uncompress - src = " << src << endl ) ;
00211 string::size_type dot = src.rfind( "." ) ;
00212 if( dot != string::npos )
00213 {
00214 string ext = src.substr( dot+1, src.length() - dot ) ;
00215
00216
00217
00218
00219 for( int i = 0; i < ext.length(); i++ )
00220 {
00221 ext[i] = tolower( ext[i] ) ;
00222 }
00223
00224
00225
00226
00227 p_bes_uncompress p = find_method( ext ) ;
00228 if( p )
00229 {
00230
00231
00232
00233 if( cache.lock( _retry, _num_tries ) )
00234 {
00235 try
00236 {
00237
00238
00239
00240 BESDEBUG( "bes", "BESUncompressManager::uncompress - is cached? " << src << endl ) ;
00241 if( cache.is_cached( src, target ) )
00242 {
00243 BESDEBUG( "bes", "BESUncompressManager::uncompress - " << "is cached " << target << endl ) ;
00244 cache.unlock() ;
00245 return true ;
00246 }
00247
00248
00249
00250
00251 BESDEBUG( "bes", "BESUncompressManager::uncompress - " << "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 " << endl ) ;
00293 }
00294 }
00295 else
00296 {
00297 BESDEBUG( "bes", "BESUncompressmanager::uncompress - not file extension" << endl ) ;
00298 #if 0
00299
00300
00301 string err = "Unable to determine type of file from "
00302 + src ;
00303 throw BESInternalError( err, __FILE__, __LINE__ ) ;
00304 #endif
00305 }
00306
00307 return false ;
00308 }
00309
00317 void
00318 BESUncompressManager::dump( ostream &strm ) const
00319 {
00320 strm << BESIndent::LMarg << "BESUncompressManager::dump - ("
00321 << (void *)this << ")" << endl ;
00322 BESIndent::Indent() ;
00323 if( _uncompress_list.size() )
00324 {
00325 strm << BESIndent::LMarg << "registered uncompression methods:" << endl;
00326 BESIndent::Indent() ;
00327 BESUncompressManager::UCIter i = _uncompress_list.begin() ;
00328 BESUncompressManager::UCIter ie = _uncompress_list.end() ;
00329 for( ; i != ie; i++ )
00330 {
00331 strm << BESIndent::LMarg << (*i).first << endl ;
00332 }
00333 BESIndent::UnIndent() ;
00334 }
00335 else
00336 {
00337 strm << BESIndent::LMarg << "registered uncompress methods: none" << endl ;
00338 }
00339 BESIndent::UnIndent() ;
00340 }
00341
00342 BESUncompressManager *
00343 BESUncompressManager::TheManager()
00344 {
00345 if( _instance == 0 )
00346 {
00347 _instance = new BESUncompressManager ;
00348 }
00349 return _instance ;
00350 }