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 <unistd.h>
00035 #include <errno.h>
00036 #include <sys/types.h>
00037 #include <sys/stat.h>
00038 #include <fcntl.h>
00039
00040
00041 #include "BESUncompressZ.h"
00042 #include "BESContainerStorageException.h"
00043 #include "BESDebug.h"
00044
00045
00052 string
00053 BESUncompressZ::uncompress( const string &src, const string &target )
00054 {
00055
00056
00057
00058
00059
00060 int srcFile ;
00061 srcFile=open( src.c_str(), O_RDONLY ) ;
00062 BESDEBUG( "bes", "BESUncompressZ::uncompress - src=" << src.c_str() << endl ) ;
00063 if( srcFile == -1 )
00064 {
00065 string err = "Could not open the compressed file " + src ;
00066 throw BESContainerStorageException( err, __FILE__, __LINE__ ) ;
00067 }
00068
00069
00070
00071
00072 int destFile ;
00073 destFile = open( target.c_str(), O_WRONLY | O_CREAT | O_TRUNC
00074 , S_IRUSR | S_IWUSR ) ;
00075 BESDEBUG( "bes", "BESUncompressZ::uncompress - target="
00076 << target.c_str()
00077 << endl ) ;
00078
00079 if( destFile == -1)
00080 {
00081 char *serr = strerror( errno ) ;
00082 string err = "Unable to create the uncompressed file "
00083 + target + ": " ;
00084 BESDEBUG( "bes", "BESUncompressZ::uncompress - cant open file"
00085 << errno
00086 << endl);
00087
00088 if( serr )
00089 {
00090 err.append( serr ) ;
00091 }
00092 else
00093 {
00094 err.append( "unknown error occurred" ) ;
00095 }
00096 close( srcFile ) ;
00097 throw BESContainerStorageException( err, __FILE__, __LINE__ ) ;
00098 }
00099
00100
00101
00102
00103
00104
00105 BESDEBUG( "bes", "BESUncompressZ::uncompress - start decompress" << endl);
00106
00107 #define FIRSTBYTE (unsigned char)'\037'
00108 #define SECONDBYTE (unsigned char)'\235'
00109 #define FIRST 257
00110 #define BIT_MASK 0x1f
00111 #define BLOCK_MODE 0x80
00112 #define MAXCODE(n) (1L << (n))
00113 #define BITS 16
00114 #define INIT_BITS 9
00115 #define CLEAR 256
00116 #define HBITS 17
00117 #define HSIZE (1<<HBITS)
00118 #define HMASK (HSIZE-1)
00119 #define BITS 16
00120 #define de_stack ((unsigned char *)&(htab[HSIZE-1]))
00121 #define BYTEORDER 0000
00122 #define NOALLIGN 0
00123
00124 unsigned char htab[HSIZE*4];
00125 unsigned short codetab[HSIZE];
00126
00127 int block_mode = BLOCK_MODE;
00128 int maxbits = BITS;
00129 unsigned char inbuf[BUFSIZ+64];
00130 unsigned char outbuf[BUFSIZ+2048];
00131 unsigned char *stackp;
00132 long int code;
00133 int finchar;
00134 long int oldcode;
00135 long int incode;
00136 int inbits;
00137 int posbits;
00138 int outpos;
00139 int insize;
00140 int bitmask;
00141 long int free_ent;
00142 long int maxcode;
00143 long int maxmaxcode;
00144 int n_bits;
00145 int rsize;
00146
00147 insize = 0;
00148
00149 BESDEBUG( "bes", "BESUncompressZ::uncompress - read file" << endl);
00150
00151
00152
00153 while( insize < 3 && (rsize = read(srcFile, inbuf+insize, BUFSIZ)) > 0) {
00154 insize += rsize;
00155 }
00156 BESDEBUG( "bes", "BESUncompressZ::uncompress - insize: " << insize << endl);
00157
00158
00159
00160
00161 if( (insize < 3) || (inbuf[0] != FIRSTBYTE) || (inbuf[1] != SECONDBYTE)) {
00162 BESDEBUG( "bes", "BESUncompressZ::uncompress - in here!!!!! " << endl);
00163 if( rsize < 0) {
00164 string err = "Could not read file ";
00165 err += src.c_str() ;
00166 throw BESContainerStorageException( err, __FILE__, __LINE__ ) ;
00167 }
00168
00169 if( insize > 0) {
00170 string err = src.c_str();
00171 err += ": not in compressed format";
00172 throw BESContainerStorageException( err, __FILE__, __LINE__ ) ;
00173 }
00174
00175 string err = "unknown error";
00176 throw BESContainerStorageException( err, __FILE__, __LINE__ ) ;
00177
00178 }
00179
00180
00181
00182
00183 maxbits = inbuf[2] & BIT_MASK;
00184 block_mode = inbuf[2] & BLOCK_MODE;
00185 maxmaxcode = MAXCODE(maxbits);
00186
00187 if( maxbits > BITS ) {
00188 string err = src.c_str();
00189 err += ": compressed with " ;
00190 err += maxbits ;
00191 err += " bits, can only handle";
00192 err += BITS;
00193 throw BESContainerStorageException( err, __FILE__, __LINE__ ) ;
00194 }
00195
00196 maxcode = MAXCODE(n_bits = INIT_BITS)-1;
00197 bitmask = (1<<n_bits)-1;
00198 oldcode = -1;
00199 finchar = 0;
00200 outpos = 0;
00201 posbits = 3<<3;
00202
00203 free_ent = ((block_mode) ? FIRST : 256);
00204
00205 BESDEBUG( "bes", "BESUncompressZ::uncompress - entering loop" << endl);
00206
00207 memset(codetab, 0, 256);
00208
00209 for (code = 255 ; code >= 0 ; --code){
00210 ((unsigned char *)(htab))[code] = (unsigned char) code;
00211 }
00212
00213 do
00214 {
00215 resetbuf: ;
00216 {
00217 int i;
00218 int e;
00219 int o;
00220
00221 e = insize - ( o = ( posbits >> 3 ) );
00222
00223 for (i = 0 ; i < e ; ++i)
00224 inbuf[i] = inbuf[i+o];
00225
00226 insize = e;
00227 posbits = 0;
00228 }
00229
00230 if( insize < sizeof( inbuf ) - BUFSIZ ) {
00231 if( ( rsize = read( srcFile, inbuf + insize, BUFSIZ )) < 0) {
00232 string err = "Could not read file ";
00233 err += src.c_str() ;
00234 throw BESContainerStorageException( err,
00235 __FILE__,
00236 __LINE__ ) ;
00237 }
00238
00239 insize += rsize;
00240 }
00241
00242 inbits = ( ( rsize > 0 ) ? ( insize - insize % n_bits ) << 3 :
00243 ( insize << 3 ) - ( n_bits - 1 ));
00244
00245 while( inbits > posbits ){
00246 if( free_ent > maxcode ) {
00247 posbits = ( ( posbits-1 ) +
00248 ( ( n_bits << 3 ) -
00249 ( posbits-1 + ( n_bits << 3)) %
00250 ( n_bits<<3 ) )
00251 );
00252
00253 ++n_bits;
00254 if( n_bits == maxbits)
00255 maxcode = maxmaxcode;
00256 else
00257 maxcode = MAXCODE(n_bits)-1;
00258
00259 bitmask = (1<<n_bits)-1;
00260 goto resetbuf;
00261 }
00262
00263 unsigned char*p = &inbuf[posbits>>3];
00264
00265 code = ( ( ( (long) ( p[0] ) ) | ( ( long )( p[1] ) << 8 ) |
00266 ( (long) ( p[2] ) << 16 ) ) >> ( posbits & 0x7 ) ) &
00267 bitmask;
00268
00269 posbits += n_bits;
00270
00271
00272 if( oldcode == -1) {
00273 if( code >= 256) {
00274 string err = "oldcode:-1 code: ";
00275 err += code ;
00276 err += " !!!! uncompress: corrupt input!!!";
00277 throw BESContainerStorageException( err,
00278 __FILE__,
00279 __LINE__ ) ;
00280 }
00281 outbuf[outpos++] = (unsigned char)(finchar =
00282 (int)(oldcode = code));
00283 continue;
00284 }
00285
00286
00287 if( code == CLEAR && block_mode) {
00288 memset(codetab, 0, 256);
00289 free_ent = FIRST - 1;
00290 posbits = ( ( posbits - 1 ) +
00291 ( ( n_bits << 3 ) -
00292 ( posbits - 1 + ( n_bits << 3 ) ) %
00293 ( n_bits<<3) ) );
00294 maxcode = MAXCODE( n_bits = INIT_BITS ) - 1;
00295 bitmask = ( 1 << n_bits )-1;
00296 goto resetbuf;
00297 }
00298
00299 incode = code;
00300 stackp = de_stack;
00301
00302
00303 if( code >= free_ent ) {
00304 if( code > free_ent ) {
00305 unsigned char *p;
00306 posbits -= n_bits;
00307 p = &inbuf[posbits>>3];
00308
00309 string err = "uncompress: corrupt input";
00310 throw BESContainerStorageException( err,
00311 __FILE__,
00312 __LINE__ ) ;
00313 }
00314
00315 *--stackp = ( unsigned char )finchar;
00316 code = oldcode;
00317 }
00318
00319
00320 while( (unsigned long)code >= (unsigned long)256) {
00321 *--stackp = htab[code];
00322 code = codetab[code];
00323 }
00324
00325 *--stackp = (unsigned char)(finchar = htab[code]);
00326
00327
00328 {
00329 int i;
00330 if( outpos+(i = (de_stack-stackp)) >= BUFSIZ) {
00331 do {
00332
00333 if( i > BUFSIZ-outpos) {
00334 i = BUFSIZ-outpos;
00335 }
00336
00337 if( i > 0) {
00338 memcpy(outbuf+outpos, stackp, i);
00339 outpos += i;
00340 }
00341
00342 if( outpos >= BUFSIZ) {
00343 if( write(destFile, outbuf,outpos) != outpos) {
00344 string err = "uncompress: write eror";
00345 throw BESContainerStorageException( err,
00346 __FILE__,
00347 __LINE__ ) ;
00348 }
00349 outpos = 0;
00350 }
00351 stackp+= i;
00352 }
00353 while( (i = (de_stack-stackp)) > 0) ;
00354 }
00355 else {
00356 memcpy(outbuf+outpos, stackp, i);
00357 outpos += i;
00358 }
00359 }
00360
00361 if( (code = free_ent) < maxmaxcode) {
00362 codetab[code] = (unsigned short)oldcode;
00363 htab[code] = (unsigned char)finchar;
00364 free_ent = code+1;
00365 }
00366
00367 oldcode = incode;
00368 }
00369 }
00370
00371 while( rsize > 0);
00372
00373 if( outpos > 0 && write(destFile, outbuf, outpos) != outpos) {
00374 string err = "uncompress: write eror";
00375 throw BESContainerStorageException( err,
00376 __FILE__,
00377 __LINE__ ) ;
00378 }
00379 BESDEBUG( "bes", "BESUncompressZ::uncompress - end decompres" << endl);
00380 return target.c_str();
00381
00382 }
00383