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 /*---------------------------------------------------*/
BZ_API(BZ2_bzWriteOpen)85*59cc4ca5SDavid du Colombier BZFILE* BZ_API(BZ2_bzWriteOpen)
86*59cc4ca5SDavid du Colombier ( int* bzerror,
87*59cc4ca5SDavid du Colombier FILE* f,
88*59cc4ca5SDavid du Colombier int blockSize100k,
89*59cc4ca5SDavid du Colombier int verbosity,
90*59cc4ca5SDavid du Colombier int workFactor )
91*59cc4ca5SDavid du Colombier {
92*59cc4ca5SDavid du Colombier Int32 ret;
93*59cc4ca5SDavid du Colombier bzFile* bzf = NULL;
94*59cc4ca5SDavid du Colombier
95*59cc4ca5SDavid du Colombier BZ_SETERR(BZ_OK);
96*59cc4ca5SDavid du Colombier
97*59cc4ca5SDavid du Colombier if (f == NULL ||
98*59cc4ca5SDavid du Colombier (blockSize100k < 1 || blockSize100k > 9) ||
99*59cc4ca5SDavid du Colombier (workFactor < 0 || workFactor > 250) ||
100*59cc4ca5SDavid du Colombier (verbosity < 0 || verbosity > 4))
101*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
102*59cc4ca5SDavid du Colombier
103*59cc4ca5SDavid du Colombier if (ferror(f))
104*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_IO_ERROR); return NULL; };
105*59cc4ca5SDavid du Colombier
106*59cc4ca5SDavid du Colombier bzf = malloc ( sizeof(bzFile) );
107*59cc4ca5SDavid du Colombier if (bzf == NULL)
108*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
109*59cc4ca5SDavid du Colombier
110*59cc4ca5SDavid du Colombier BZ_SETERR(BZ_OK);
111*59cc4ca5SDavid du Colombier bzf->initialisedOk = False;
112*59cc4ca5SDavid du Colombier bzf->bufN = 0;
113*59cc4ca5SDavid du Colombier bzf->handle = f;
114*59cc4ca5SDavid du Colombier bzf->writing = True;
115*59cc4ca5SDavid du Colombier bzf->strm.bzalloc = NULL;
116*59cc4ca5SDavid du Colombier bzf->strm.bzfree = NULL;
117*59cc4ca5SDavid du Colombier bzf->strm.opaque = NULL;
118*59cc4ca5SDavid du Colombier
119*59cc4ca5SDavid du Colombier if (workFactor == 0) workFactor = 30;
120*59cc4ca5SDavid du Colombier ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k,
121*59cc4ca5SDavid du Colombier verbosity, workFactor );
122*59cc4ca5SDavid du Colombier if (ret != BZ_OK)
123*59cc4ca5SDavid du Colombier { BZ_SETERR(ret); free(bzf); return NULL; };
124*59cc4ca5SDavid du Colombier
125*59cc4ca5SDavid du Colombier bzf->strm.avail_in = 0;
126*59cc4ca5SDavid du Colombier bzf->initialisedOk = True;
127*59cc4ca5SDavid du Colombier return bzf;
128*59cc4ca5SDavid du Colombier }
129*59cc4ca5SDavid du Colombier
130*59cc4ca5SDavid du Colombier
131*59cc4ca5SDavid du Colombier
132*59cc4ca5SDavid du Colombier /*---------------------------------------------------*/
BZ_API(BZ2_bzWrite)133*59cc4ca5SDavid du Colombier void BZ_API(BZ2_bzWrite)
134*59cc4ca5SDavid du Colombier ( int* bzerror,
135*59cc4ca5SDavid du Colombier BZFILE* b,
136*59cc4ca5SDavid du Colombier void* buf,
137*59cc4ca5SDavid du Colombier int len )
138*59cc4ca5SDavid du Colombier {
139*59cc4ca5SDavid du Colombier Int32 n, n2, ret;
140*59cc4ca5SDavid du Colombier bzFile* bzf = (bzFile*)b;
141*59cc4ca5SDavid du Colombier
142*59cc4ca5SDavid du Colombier BZ_SETERR(BZ_OK);
143*59cc4ca5SDavid du Colombier if (bzf == NULL || buf == NULL || len < 0)
144*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_PARAM_ERROR); return; };
145*59cc4ca5SDavid du Colombier if (!(bzf->writing))
146*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
147*59cc4ca5SDavid du Colombier if (ferror(bzf->handle))
148*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_IO_ERROR); return; };
149*59cc4ca5SDavid du Colombier
150*59cc4ca5SDavid du Colombier if (len == 0)
151*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_OK); return; };
152*59cc4ca5SDavid du Colombier
153*59cc4ca5SDavid du Colombier bzf->strm.avail_in = len;
154*59cc4ca5SDavid du Colombier bzf->strm.next_in = buf;
155*59cc4ca5SDavid du Colombier
156*59cc4ca5SDavid du Colombier while (True) {
157*59cc4ca5SDavid du Colombier bzf->strm.avail_out = BZ_MAX_UNUSED;
158*59cc4ca5SDavid du Colombier bzf->strm.next_out = bzf->buf;
159*59cc4ca5SDavid du Colombier ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
160*59cc4ca5SDavid du Colombier if (ret != BZ_RUN_OK)
161*59cc4ca5SDavid du Colombier { BZ_SETERR(ret); return; };
162*59cc4ca5SDavid du Colombier
163*59cc4ca5SDavid du Colombier if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
164*59cc4ca5SDavid du Colombier n = BZ_MAX_UNUSED - bzf->strm.avail_out;
165*59cc4ca5SDavid du Colombier n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
166*59cc4ca5SDavid du Colombier n, bzf->handle );
167*59cc4ca5SDavid du Colombier if (n != n2 || ferror(bzf->handle))
168*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_IO_ERROR); return; };
169*59cc4ca5SDavid du Colombier }
170*59cc4ca5SDavid du Colombier
171*59cc4ca5SDavid du Colombier if (bzf->strm.avail_in == 0)
172*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_OK); return; };
173*59cc4ca5SDavid du Colombier }
174*59cc4ca5SDavid du Colombier }
175*59cc4ca5SDavid du Colombier
176*59cc4ca5SDavid du Colombier
177*59cc4ca5SDavid du Colombier /*---------------------------------------------------*/
BZ_API(BZ2_bzWriteClose)178*59cc4ca5SDavid du Colombier void BZ_API(BZ2_bzWriteClose)
179*59cc4ca5SDavid du Colombier ( int* bzerror,
180*59cc4ca5SDavid du Colombier BZFILE* b,
181*59cc4ca5SDavid du Colombier int abandon,
182*59cc4ca5SDavid du Colombier unsigned int* nbytes_in,
183*59cc4ca5SDavid du Colombier unsigned int* nbytes_out )
184*59cc4ca5SDavid du Colombier {
185*59cc4ca5SDavid du Colombier BZ2_bzWriteClose64 ( bzerror, b, abandon,
186*59cc4ca5SDavid du Colombier nbytes_in, NULL, nbytes_out, NULL );
187*59cc4ca5SDavid du Colombier }
188*59cc4ca5SDavid du Colombier
189*59cc4ca5SDavid du Colombier
BZ_API(BZ2_bzWriteClose64)190*59cc4ca5SDavid du Colombier void BZ_API(BZ2_bzWriteClose64)
191*59cc4ca5SDavid du Colombier ( int* bzerror,
192*59cc4ca5SDavid du Colombier BZFILE* b,
193*59cc4ca5SDavid du Colombier int abandon,
194*59cc4ca5SDavid du Colombier unsigned int* nbytes_in_lo32,
195*59cc4ca5SDavid du Colombier unsigned int* nbytes_in_hi32,
196*59cc4ca5SDavid du Colombier unsigned int* nbytes_out_lo32,
197*59cc4ca5SDavid du Colombier unsigned int* nbytes_out_hi32 )
198*59cc4ca5SDavid du Colombier {
199*59cc4ca5SDavid du Colombier Int32 n, n2, ret;
200*59cc4ca5SDavid du Colombier bzFile* bzf = (bzFile*)b;
201*59cc4ca5SDavid du Colombier
202*59cc4ca5SDavid du Colombier if (bzf == NULL)
203*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_OK); return; };
204*59cc4ca5SDavid du Colombier if (!(bzf->writing))
205*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
206*59cc4ca5SDavid du Colombier if (ferror(bzf->handle))
207*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_IO_ERROR); return; };
208*59cc4ca5SDavid du Colombier
209*59cc4ca5SDavid du Colombier if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
210*59cc4ca5SDavid du Colombier if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
211*59cc4ca5SDavid du Colombier if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
212*59cc4ca5SDavid du Colombier if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
213*59cc4ca5SDavid du Colombier
214*59cc4ca5SDavid du Colombier if ((!abandon) && bzf->lastErr == BZ_OK) {
215*59cc4ca5SDavid du Colombier while (True) {
216*59cc4ca5SDavid du Colombier bzf->strm.avail_out = BZ_MAX_UNUSED;
217*59cc4ca5SDavid du Colombier bzf->strm.next_out = bzf->buf;
218*59cc4ca5SDavid du Colombier ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
219*59cc4ca5SDavid du Colombier if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
220*59cc4ca5SDavid du Colombier { BZ_SETERR(ret); return; };
221*59cc4ca5SDavid du Colombier
222*59cc4ca5SDavid du Colombier if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
223*59cc4ca5SDavid du Colombier n = BZ_MAX_UNUSED - bzf->strm.avail_out;
224*59cc4ca5SDavid du Colombier n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
225*59cc4ca5SDavid du Colombier n, bzf->handle );
226*59cc4ca5SDavid du Colombier if (n != n2 || ferror(bzf->handle))
227*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_IO_ERROR); return; };
228*59cc4ca5SDavid du Colombier }
229*59cc4ca5SDavid du Colombier
230*59cc4ca5SDavid du Colombier if (ret == BZ_STREAM_END) break;
231*59cc4ca5SDavid du Colombier }
232*59cc4ca5SDavid du Colombier }
233*59cc4ca5SDavid du Colombier
234*59cc4ca5SDavid du Colombier if ( !abandon && !ferror ( bzf->handle ) ) {
235*59cc4ca5SDavid du Colombier fflush ( bzf->handle );
236*59cc4ca5SDavid du Colombier if (ferror(bzf->handle))
237*59cc4ca5SDavid du Colombier { BZ_SETERR(BZ_IO_ERROR); return; };
238*59cc4ca5SDavid du Colombier }
239*59cc4ca5SDavid du Colombier
240*59cc4ca5SDavid du Colombier if (nbytes_in_lo32 != NULL)
241*59cc4ca5SDavid du Colombier *nbytes_in_lo32 = bzf->strm.total_in_lo32;
242*59cc4ca5SDavid du Colombier if (nbytes_in_hi32 != NULL)
243*59cc4ca5SDavid du Colombier *nbytes_in_hi32 = bzf->strm.total_in_hi32;
244*59cc4ca5SDavid du Colombier if (nbytes_out_lo32 != NULL)
245*59cc4ca5SDavid du Colombier *nbytes_out_lo32 = bzf->strm.total_out_lo32;
246*59cc4ca5SDavid du Colombier if (nbytes_out_hi32 != NULL)
247*59cc4ca5SDavid du Colombier *nbytes_out_hi32 = bzf->strm.total_out_hi32;
248*59cc4ca5SDavid du Colombier
249*59cc4ca5SDavid du Colombier BZ_SETERR(BZ_OK);
250*59cc4ca5SDavid du Colombier BZ2_bzCompressEnd ( &(bzf->strm) );
251*59cc4ca5SDavid du Colombier free ( bzf );
252*59cc4ca5SDavid du Colombier }
253*59cc4ca5SDavid du Colombier
254