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 <stdlib.h>
00034 #include <stdio.h>
00035 #include <errno.h>
00036
00037 #include "config.h"
00038
00039 #ifdef HAVE_BZLIB_H
00040 #include <bzlib.h>
00041 #endif
00042
00043 #include <sstream>
00044
00045 using std::ostringstream ;
00046
00047 #include "BESUncompressBZ2.h"
00048 #include "BESContainerStorageException.h"
00049 #include "BESDebug.h"
00050
00051 #define CHUNK 4096
00052
00053 void
00054 bz_internal_error ( int errcode )
00055 {
00056 ostringstream strm ;
00057 strm << "internal error in bz2 library occurred: " << errcode ;
00058 throw BESContainerStorageException( strm.str(), __FILE__, __LINE__ ) ;
00059 }
00060
00067 string
00068 BESUncompressBZ2::uncompress( const string &src_name, const string &target )
00069 {
00070 #ifndef HAVE_BZLIB_H
00071 string err = "Unable to uncompress bz2 files, not available" ;
00072 throw BESContainerStorageException( err, __FILE__, __LINE__ ) ;
00073 #else
00074 FILE *src = fopen( src_name.c_str(), "rb" ) ;
00075 if( !src )
00076 {
00077 char *serr = strerror( errno ) ;
00078 string err = "Unable to open the compressed file "
00079 + src_name + ": " ;
00080 if( serr )
00081 {
00082 err.append( serr ) ;
00083 }
00084 else
00085 {
00086 err.append( "unknown error occurred" ) ;
00087 }
00088 throw BESContainerStorageException( err, __FILE__, __LINE__ ) ;
00089 }
00090
00091 FILE *dest = fopen( target.c_str(), "wb" ) ;
00092 if( !dest )
00093 {
00094 char *serr = strerror( errno ) ;
00095 string err = "Unable to create the uncompressed file "
00096 + target + ": " ;
00097 if( serr )
00098 {
00099 err.append( serr ) ;
00100 }
00101 else
00102 {
00103 err.append( "unknown error occurred" ) ;
00104 }
00105 fclose( src ) ;
00106 throw BESContainerStorageException( err, __FILE__, __LINE__ ) ;
00107 }
00108
00109 int bzerror = 0 ;
00110 int verbosity = 0 ;
00111 int small = 0 ;
00112 void *unused = NULL ;
00113 int nunused = 0 ;
00114 char in[CHUNK] ;
00115
00116 BZFILE *bsrc = NULL ;
00117
00118 bsrc = BZ2_bzReadOpen( &bzerror, src, verbosity, small, NULL, 0 ) ;
00119 if( bsrc == NULL )
00120 {
00121 const char *berr = BZ2_bzerror( bsrc, &bzerror ) ;
00122 string err = "bzReadOpen failed on " + src_name + ": " ;
00123 if( berr )
00124 {
00125 err.append( berr ) ;
00126 }
00127 else
00128 {
00129 err.append( "Unknown error" ) ;
00130 }
00131 fclose( dest ) ;
00132 fclose( src ) ;
00133
00134 throw BESContainerStorageException( err, __FILE__, __LINE__ ) ;
00135 }
00136
00137 bool done = false ;
00138 while( !done )
00139 {
00140 int bytes_read = BZ2_bzRead( &bzerror, bsrc, in, CHUNK ) ;
00141 if( bzerror != BZ_OK && bzerror != BZ_STREAM_END )
00142 {
00143 const char *berr = BZ2_bzerror( bsrc, &bzerror ) ;
00144 string err = "bzRead failed on " + src_name + ": " ;
00145 if( berr )
00146 {
00147 err.append( berr ) ;
00148 }
00149 else
00150 {
00151 err.append( "Unknown error" ) ;
00152 }
00153
00154 BZ2_bzReadClose( &bzerror, bsrc ) ;
00155 fclose( dest ) ;
00156 fclose( src ) ;
00157
00158 throw BESContainerStorageException( err, __FILE__, __LINE__ ) ;
00159 }
00160
00161 if( bzerror == BZ_STREAM_END )
00162 {
00163 done = true ;
00164 }
00165 int bytes_written = fwrite( in, 1, bytes_read, dest) ;
00166 if( bytes_written < bytes_read )
00167 {
00168 ostringstream strm ;
00169 strm << "Error writing uncompressed data "
00170 << "to dest file " << target << ": "
00171 << "wrote " << bytes_written << " "
00172 << "instead of " << bytes_read ;
00173
00174 BZ2_bzReadClose( &bzerror, bsrc ) ;
00175 fclose( dest ) ;
00176 fclose( src ) ;
00177
00178 throw BESContainerStorageException( strm.str(), __FILE__, __LINE__ ) ;
00179 }
00180 }
00181
00182 BZ2_bzReadClose( &bzerror, bsrc ) ;
00183 fclose( dest ) ;
00184 fclose( src ) ;
00185
00186 return target ;
00187 #endif
00188 }
00189