bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
BESUncompress3BZ2.cc
1// BESUncompress3BZ2.cc
2
3// This file is part of bes, A C++ back-end server implementation framework
4// for the OPeNDAP Data Access Protocol.
5
6// Copyright (c) 2004-2009 University Corporation for Atmospheric Research
7// Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
8//
9// This library is free software; you can redistribute it and/or
10// modify it under the terms of the GNU Lesser General Public
11// License as published by the Free Software Foundation; either
12// version 2.1 of the License, or (at your option) any later version.
13//
14// This library is distributed in the hope that it will be useful,
15// but WITHOUT ANY WARRANTY; without even the implied warranty of
16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17// Lesser General Public License for more details.
18//
19// You should have received a copy of the GNU Lesser General Public
20// License along with this library; if not, write to the Free Software
21// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22//
23// You can contact University Corporation for Atmospheric Research at
24// 3080 Center Green Drive, Boulder, CO 80301
25
26// (c) COPYRIGHT University Corporation for Atmospheric Research 2004-2005
27// Please read the full copyright statement in the file COPYRIGHT_UCAR.
28//
29// Authors:
30// pwest Patrick West <pwest@ucar.edu>
31// jgarcia Jose Garcia <jgarcia@ucar.edu>
32
33
34#include "config.h"
35
36#ifdef HAVE_BZLIB_H
37#include <bzlib.h>
38#endif
39
40#include <cstring>
41#include <cerrno>
42#include <sstream>
43#include <unistd.h>
44
45using std::ostringstream;
46using std::string;
47
48#include "BESUncompress3BZ2.h"
49#include "BESInternalError.h"
50#include "BESDebug.h"
51
52#define CHUNK 4096
53
54#if 0
55static void bz_internal_error(int errcode)
56{
57 ostringstream strm;
58 strm << "internal error in bz2 library occurred: " << errcode;
59 throw BESInternalError(strm.str(), __FILE__, __LINE__);
60}
61#endif
62
69void
70BESUncompress3BZ2::uncompress( const string &src_name, int fd )
71{
72#ifndef HAVE_BZLIB_H
73 string err = "Unable to uncompress bz2 files, feature not built. Check config.h in bes directory for HAVE_BZLIB_H flag set to 1";
74 throw BESInternalError( err, __FILE__, __LINE__ );
75#else
76 FILE *src = fopen( src_name.c_str(), "rb" );
77 if( !src )
78 {
79 char *serr = strerror( errno );
80 string err = "Unable to open the compressed file "
81 + src_name + ": ";
82 if( serr )
83 {
84 err.append( serr );
85 }
86 else
87 {
88 err.append( "unknown error occurred" );
89 }
90 throw BESInternalError( err, __FILE__, __LINE__ );
91 }
92
93 int bzerror = 0; // any error flags will be stored here
94 int verbosity = 0; // 0 is silent up to 4 which is very verbose
95 int small = 0; // if non zero then memory management is different
96 // unused void *unused = NULL; // any unused bytes would be stored in here
97 // unused int nunused = 0; // the size of the unused buffer
98 char in[CHUNK]; // input buffer used to read uncompressed data in bzRead
99
100 BZFILE *bsrc = NULL;
101
102 bsrc = BZ2_bzReadOpen( &bzerror, src, verbosity, small, NULL, 0 );
103 if( bsrc == NULL )
104 {
105 const char *berr = BZ2_bzerror( bsrc, &bzerror );
106 string err = "bzReadOpen failed on " + src_name + ": ";
107 if( berr )
108 {
109 err.append( berr );
110 }
111 else
112 {
113 err.append( "Unknown error" );
114 }
115 fclose( src );
116
117 throw BESInternalError( err, __FILE__, __LINE__ );
118 }
119
120 bool done = false;
121 while( !done )
122 {
123 int bytes_read = BZ2_bzRead( &bzerror, bsrc, in, CHUNK );
124 if( bzerror != BZ_OK && bzerror != BZ_STREAM_END )
125 {
126 const char *berr = BZ2_bzerror( bsrc, &bzerror );
127 string err = "bzRead failed on " + src_name + ": ";
128 if( berr )
129 {
130 err.append( berr );
131 }
132 else
133 {
134 err.append( "Unknown error" );
135 }
136
137 BZ2_bzReadClose( &bzerror, bsrc );
138 fclose( src );
139
140 throw BESInternalError( err, __FILE__, __LINE__ );
141 }
142 //if( bytes_read == 0 || bzerror == BZ_STREAM_END )
143 if( bzerror == BZ_STREAM_END )
144 {
145 done = true;
146 }
147 int bytes_written = write(fd, in, bytes_read);
148 if( bytes_written < bytes_read )
149 {
150 ostringstream strm;
151 strm << "Error writing uncompressed data: "
152 << "wrote " << bytes_written
153 << " instead of " << bytes_read;
154
155 BZ2_bzReadClose( &bzerror, bsrc );
156 fclose( src );
157
158 throw BESInternalError( strm.str(), __FILE__, __LINE__ );
159 }
160 }
161
162 BZ2_bzReadClose( &bzerror, bsrc );
163 fclose( src );
164#endif
165}
166
exception thrown if internal error encountered
static void uncompress(const std::string &src, int fd)
uncompress a file with the .bz2 file extension