1*59cc4ca5SDavid du Colombier /* THIS FILE HAS BEEN MODIFIED -- rsc split bzlib.c into bzlib.c, 2*59cc4ca5SDavid du Colombier bzlibcompress.c, bzlibdecompress.c, bzlibread.c, bzlibwrite.c 3*59cc4ca5SDavid du Colombier */ 4*59cc4ca5SDavid du Colombier /*-------------------------------------------------------------*/ 5*59cc4ca5SDavid du Colombier /*--- Library top-level functions. ---*/ 6*59cc4ca5SDavid du Colombier /*--- bzlib.c ---*/ 7*59cc4ca5SDavid du Colombier /*-------------------------------------------------------------*/ 8*59cc4ca5SDavid du Colombier 9*59cc4ca5SDavid du Colombier /*-- 10*59cc4ca5SDavid du Colombier This file is a part of bzip2 and/or libbzip2, a program and 11*59cc4ca5SDavid du Colombier library for lossless, block-sorting data compression. 12*59cc4ca5SDavid du Colombier 13*59cc4ca5SDavid du Colombier Copyright (C) 1996-2000 Julian R Seward. All rights reserved. 14*59cc4ca5SDavid du Colombier 15*59cc4ca5SDavid du Colombier Redistribution and use in source and binary forms, with or without 16*59cc4ca5SDavid du Colombier modification, are permitted provided that the following conditions 17*59cc4ca5SDavid du Colombier are met: 18*59cc4ca5SDavid du Colombier 19*59cc4ca5SDavid du Colombier 1. Redistributions of source code must retain the above copyright 20*59cc4ca5SDavid du Colombier notice, this list of conditions and the following disclaimer. 21*59cc4ca5SDavid du Colombier 22*59cc4ca5SDavid du Colombier 2. The origin of this software must not be misrepresented; you must 23*59cc4ca5SDavid du Colombier not claim that you wrote the original software. If you use this 24*59cc4ca5SDavid du Colombier software in a product, an acknowledgment in the product 25*59cc4ca5SDavid du Colombier documentation would be appreciated but is not required. 26*59cc4ca5SDavid du Colombier 27*59cc4ca5SDavid du Colombier 3. Altered source versions must be plainly marked as such, and must 28*59cc4ca5SDavid du Colombier not be misrepresented as being the original software. 29*59cc4ca5SDavid du Colombier 30*59cc4ca5SDavid du Colombier 4. The name of the author may not be used to endorse or promote 31*59cc4ca5SDavid du Colombier products derived from this software without specific prior written 32*59cc4ca5SDavid du Colombier permission. 33*59cc4ca5SDavid du Colombier 34*59cc4ca5SDavid du Colombier THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 35*59cc4ca5SDavid du Colombier OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 36*59cc4ca5SDavid du Colombier WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 37*59cc4ca5SDavid du Colombier ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 38*59cc4ca5SDavid du Colombier DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 39*59cc4ca5SDavid du Colombier DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 40*59cc4ca5SDavid du Colombier GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 41*59cc4ca5SDavid du Colombier INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 42*59cc4ca5SDavid du Colombier WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 43*59cc4ca5SDavid du Colombier NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 44*59cc4ca5SDavid du Colombier SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 45*59cc4ca5SDavid du Colombier 46*59cc4ca5SDavid du Colombier Julian Seward, Cambridge, UK. 47*59cc4ca5SDavid du Colombier jseward@acm.org 48*59cc4ca5SDavid du Colombier bzip2/libbzip2 version 1.0 of 21 March 2000 49*59cc4ca5SDavid du Colombier 50*59cc4ca5SDavid du Colombier This program is based on (at least) the work of: 51*59cc4ca5SDavid du Colombier Mike Burrows 52*59cc4ca5SDavid du Colombier David Wheeler 53*59cc4ca5SDavid du Colombier Peter Fenwick 54*59cc4ca5SDavid du Colombier Alistair Moffat 55*59cc4ca5SDavid du Colombier Radford Neal 56*59cc4ca5SDavid du Colombier Ian H. Witten 57*59cc4ca5SDavid du Colombier Robert Sedgewick 58*59cc4ca5SDavid du Colombier Jon L. Bentley 59*59cc4ca5SDavid du Colombier 60*59cc4ca5SDavid du Colombier For more information on these sources, see the manual. 61*59cc4ca5SDavid du Colombier --*/ 62*59cc4ca5SDavid du Colombier 63*59cc4ca5SDavid du Colombier /*-- 64*59cc4ca5SDavid du Colombier CHANGES 65*59cc4ca5SDavid du Colombier ~~~~~~~ 66*59cc4ca5SDavid du Colombier 0.9.0 -- original version. 67*59cc4ca5SDavid du Colombier 68*59cc4ca5SDavid du Colombier 0.9.0a/b -- no changes in this file. 69*59cc4ca5SDavid du Colombier 70*59cc4ca5SDavid du Colombier 0.9.0c 71*59cc4ca5SDavid du Colombier * made zero-length BZ_FLUSH work correctly in bzCompress(). 72*59cc4ca5SDavid du Colombier * fixed bzWrite/bzRead to ignore zero-length requests. 73*59cc4ca5SDavid du Colombier * fixed bzread to correctly handle read requests after EOF. 74*59cc4ca5SDavid du Colombier * wrong parameter order in call to bzDecompressInit in 75*59cc4ca5SDavid du Colombier bzBuffToBuffDecompress. Fixed. 76*59cc4ca5SDavid du Colombier --*/ 77*59cc4ca5SDavid du Colombier 78*59cc4ca5SDavid du Colombier #include "os.h" 79*59cc4ca5SDavid du Colombier #include "bzlib.h" 80*59cc4ca5SDavid du Colombier #include "bzlib_private.h" 81*59cc4ca5SDavid du Colombier #include "bzlib_stdio.h" 82*59cc4ca5SDavid du Colombier #include "bzlib_stdio_private.h" 83*59cc4ca5SDavid du Colombier 84*59cc4ca5SDavid du Colombier /*---------------------------------------------------*/ 85*59cc4ca5SDavid du Colombier BZFILE* BZ_API(BZ2_bzReadOpen) 86*59cc4ca5SDavid du Colombier ( int* bzerror, 87*59cc4ca5SDavid du Colombier FILE* f, 88*59cc4ca5SDavid du Colombier int verbosity, 89*59cc4ca5SDavid du Colombier int small, 90*59cc4ca5SDavid du Colombier void* unused, 91*59cc4ca5SDavid du Colombier int nUnused ) 92*59cc4ca5SDavid du Colombier { 93*59cc4ca5SDavid du Colombier bzFile* bzf = NULL; 94*59cc4ca5SDavid du Colombier int ret; 95*59cc4ca5SDavid du Colombier 96*59cc4ca5SDavid du Colombier BZ_SETERR(BZ_OK); 97*59cc4ca5SDavid du Colombier 98*59cc4ca5SDavid du Colombier if (f == NULL || 99*59cc4ca5SDavid du Colombier (small != 0 && small != 1) || 100*59cc4ca5SDavid du Colombier (verbosity < 0 || verbosity > 4) || 101*59cc4ca5SDavid du Colombier (unused == NULL && nUnused != 0) || 102*59cc4ca5SDavid du Colombier (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED))) 103*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_PARAM_ERROR); return NULL; }; 104*59cc4ca5SDavid du Colombier 105*59cc4ca5SDavid du Colombier if (ferror(f)) 106*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_IO_ERROR); return NULL; }; 107*59cc4ca5SDavid du Colombier 108*59cc4ca5SDavid du Colombier bzf = malloc ( sizeof(bzFile) ); 109*59cc4ca5SDavid du Colombier if (bzf == NULL) 110*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_MEM_ERROR); return NULL; }; 111*59cc4ca5SDavid du Colombier 112*59cc4ca5SDavid du Colombier BZ_SETERR(BZ_OK); 113*59cc4ca5SDavid du Colombier 114*59cc4ca5SDavid du Colombier bzf->initialisedOk = False; 115*59cc4ca5SDavid du Colombier bzf->handle = f; 116*59cc4ca5SDavid du Colombier bzf->bufN = 0; 117*59cc4ca5SDavid du Colombier bzf->writing = False; 118*59cc4ca5SDavid du Colombier bzf->strm.bzalloc = NULL; 119*59cc4ca5SDavid du Colombier bzf->strm.bzfree = NULL; 120*59cc4ca5SDavid du Colombier bzf->strm.opaque = NULL; 121*59cc4ca5SDavid du Colombier 122*59cc4ca5SDavid du Colombier while (nUnused > 0) { 123*59cc4ca5SDavid du Colombier bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++; 124*59cc4ca5SDavid du Colombier unused = ((void*)( 1 + ((UChar*)(unused)) )); 125*59cc4ca5SDavid du Colombier nUnused--; 126*59cc4ca5SDavid du Colombier } 127*59cc4ca5SDavid du Colombier 128*59cc4ca5SDavid du Colombier ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small ); 129*59cc4ca5SDavid du Colombier if (ret != BZ_OK) 130*59cc4ca5SDavid du Colombier { BZ_SETERR(ret); free(bzf); return NULL; }; 131*59cc4ca5SDavid du Colombier 132*59cc4ca5SDavid du Colombier bzf->strm.avail_in = bzf->bufN; 133*59cc4ca5SDavid du Colombier bzf->strm.next_in = bzf->buf; 134*59cc4ca5SDavid du Colombier 135*59cc4ca5SDavid du Colombier bzf->initialisedOk = True; 136*59cc4ca5SDavid du Colombier return bzf; 137*59cc4ca5SDavid du Colombier } 138*59cc4ca5SDavid du Colombier 139*59cc4ca5SDavid du Colombier 140*59cc4ca5SDavid du Colombier /*---------------------------------------------------*/ 141*59cc4ca5SDavid du Colombier void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b ) 142*59cc4ca5SDavid du Colombier { 143*59cc4ca5SDavid du Colombier bzFile* bzf = (bzFile*)b; 144*59cc4ca5SDavid du Colombier 145*59cc4ca5SDavid du Colombier BZ_SETERR(BZ_OK); 146*59cc4ca5SDavid du Colombier if (bzf == NULL) 147*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_OK); return; }; 148*59cc4ca5SDavid du Colombier 149*59cc4ca5SDavid du Colombier if (bzf->writing) 150*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_SEQUENCE_ERROR); return; }; 151*59cc4ca5SDavid du Colombier 152*59cc4ca5SDavid du Colombier if (bzf->initialisedOk) 153*59cc4ca5SDavid du Colombier (void)BZ2_bzDecompressEnd ( &(bzf->strm) ); 154*59cc4ca5SDavid du Colombier free ( bzf ); 155*59cc4ca5SDavid du Colombier } 156*59cc4ca5SDavid du Colombier 157*59cc4ca5SDavid du Colombier 158*59cc4ca5SDavid du Colombier /*---------------------------------------------------*/ 159*59cc4ca5SDavid du Colombier int BZ_API(BZ2_bzRead) 160*59cc4ca5SDavid du Colombier ( int* bzerror, 161*59cc4ca5SDavid du Colombier BZFILE* b, 162*59cc4ca5SDavid du Colombier void* buf, 163*59cc4ca5SDavid du Colombier int len ) 164*59cc4ca5SDavid du Colombier { 165*59cc4ca5SDavid du Colombier Int32 n, ret; 166*59cc4ca5SDavid du Colombier bzFile* bzf = (bzFile*)b; 167*59cc4ca5SDavid du Colombier 168*59cc4ca5SDavid du Colombier BZ_SETERR(BZ_OK); 169*59cc4ca5SDavid du Colombier 170*59cc4ca5SDavid du Colombier if (bzf == NULL || buf == NULL || len < 0) 171*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_PARAM_ERROR); return 0; }; 172*59cc4ca5SDavid du Colombier 173*59cc4ca5SDavid du Colombier if (bzf->writing) 174*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; }; 175*59cc4ca5SDavid du Colombier 176*59cc4ca5SDavid du Colombier if (len == 0) 177*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_OK); return 0; }; 178*59cc4ca5SDavid du Colombier 179*59cc4ca5SDavid du Colombier bzf->strm.avail_out = len; 180*59cc4ca5SDavid du Colombier bzf->strm.next_out = buf; 181*59cc4ca5SDavid du Colombier 182*59cc4ca5SDavid du Colombier while (True) { 183*59cc4ca5SDavid du Colombier 184*59cc4ca5SDavid du Colombier if (ferror(bzf->handle)) 185*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_IO_ERROR); return 0; }; 186*59cc4ca5SDavid du Colombier 187*59cc4ca5SDavid du Colombier if (bzf->strm.avail_in == 0 && !bz_feof(bzf->handle)) { 188*59cc4ca5SDavid du Colombier n = fread ( bzf->buf, sizeof(UChar), 189*59cc4ca5SDavid du Colombier BZ_MAX_UNUSED, bzf->handle ); 190*59cc4ca5SDavid du Colombier if (ferror(bzf->handle)) 191*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_IO_ERROR); return 0; }; 192*59cc4ca5SDavid du Colombier bzf->bufN = n; 193*59cc4ca5SDavid du Colombier bzf->strm.avail_in = bzf->bufN; 194*59cc4ca5SDavid du Colombier bzf->strm.next_in = bzf->buf; 195*59cc4ca5SDavid du Colombier } 196*59cc4ca5SDavid du Colombier 197*59cc4ca5SDavid du Colombier ret = BZ2_bzDecompress ( &(bzf->strm) ); 198*59cc4ca5SDavid du Colombier 199*59cc4ca5SDavid du Colombier if (ret != BZ_OK && ret != BZ_STREAM_END) 200*59cc4ca5SDavid du Colombier { BZ_SETERR(ret); return 0; }; 201*59cc4ca5SDavid du Colombier 202*59cc4ca5SDavid du Colombier if (ret == BZ_OK && bz_feof(bzf->handle) && 203*59cc4ca5SDavid du Colombier bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0) 204*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; }; 205*59cc4ca5SDavid du Colombier 206*59cc4ca5SDavid du Colombier if (ret == BZ_STREAM_END) 207*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_STREAM_END); 208*59cc4ca5SDavid du Colombier return len - bzf->strm.avail_out; }; 209*59cc4ca5SDavid du Colombier if (bzf->strm.avail_out == 0) 210*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_OK); return len; }; 211*59cc4ca5SDavid du Colombier 212*59cc4ca5SDavid du Colombier } 213*59cc4ca5SDavid du Colombier 214*59cc4ca5SDavid du Colombier return 0; /*not reached*/ 215*59cc4ca5SDavid du Colombier } 216*59cc4ca5SDavid du Colombier 217*59cc4ca5SDavid du Colombier 218*59cc4ca5SDavid du Colombier /*---------------------------------------------------*/ 219*59cc4ca5SDavid du Colombier void BZ_API(BZ2_bzReadGetUnused) 220*59cc4ca5SDavid du Colombier ( int* bzerror, 221*59cc4ca5SDavid du Colombier BZFILE* b, 222*59cc4ca5SDavid du Colombier void** unused, 223*59cc4ca5SDavid du Colombier int* nUnused ) 224*59cc4ca5SDavid du Colombier { 225*59cc4ca5SDavid du Colombier bzFile* bzf = (bzFile*)b; 226*59cc4ca5SDavid du Colombier if (bzf == NULL) 227*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_PARAM_ERROR); return; }; 228*59cc4ca5SDavid du Colombier if (bzf->lastErr != BZ_STREAM_END) 229*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_SEQUENCE_ERROR); return; }; 230*59cc4ca5SDavid du Colombier if (unused == NULL || nUnused == NULL) 231*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_PARAM_ERROR); return; }; 232*59cc4ca5SDavid du Colombier 233*59cc4ca5SDavid du Colombier BZ_SETERR(BZ_OK); 234*59cc4ca5SDavid du Colombier *nUnused = bzf->strm.avail_in; 235*59cc4ca5SDavid du Colombier *unused = bzf->strm.next_in; 236*59cc4ca5SDavid du Colombier } 237