BESUncompressBZ2.cc

Go to the documentation of this file.
00001 // BESUncompressBZ2.cc
00002 
00003 // This file is part of bes, A C++ back-end server implementation framework
00004 // for the OPeNDAP Data Access Protocol.
00005 
00006 // Copyright (c) 2004,2005 University Corporation for Atmospheric Research
00007 // Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
00008 //
00009 // This library is free software; you can redistribute it and/or
00010 // modify it under the terms of the GNU Lesser General Public
00011 // License as published by the Free Software Foundation; either
00012 // version 2.1 of the License, or (at your option) any later version.
00013 // 
00014 // This library is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 // Lesser General Public License for more details.
00018 // 
00019 // You should have received a copy of the GNU Lesser General Public
00020 // License along with this library; if not, write to the Free Software
00021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 //
00023 // You can contact University Corporation for Atmospheric Research at
00024 // 3080 Center Green Drive, Boulder, CO 80301
00025  
00026 // (c) COPYRIGHT University Corporation for Atmostpheric Research 2004-2005
00027 // Please read the full copyright statement in the file COPYRIGHT_UCAR.
00028 //
00029 // Authors:
00030 //      pwest       Patrick West <pwest@ucar.edu>
00031 //      jgarcia     Jose Garcia <jgarcia@ucar.edu>
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 ; // any error flags will be stored here
00110     int verbosity = 0 ; // 0 is silent up to 4 which is very verbose
00111     int small = 0 ; // if non zero then memory management is different
00112     void *unused = NULL ; // any unused bytes would be stored in here
00113     int nunused = 0 ; // the size of the unused buffer
00114     char in[CHUNK] ; // input buffer used to read uncompressed data in bzRead
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         //if( bytes_read == 0 || bzerror == BZ_STREAM_END )
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 

Generated on Wed Aug 29 02:59:01 2007 for OPeNDAP Back End Server (BES) by  doxygen 1.5.2